From ade51c1d898d8796093060b21289ac81ba4ecca1 Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sat, 9 Jul 2016 13:43:18 -0400 Subject: terminal.c: Handle more special keys --- src/nvim/terminal.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index bd7b9fc58f..bfcc123161 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -762,6 +762,7 @@ static VTermKey convert_key(int key, VTermModifier *statep) switch (key) { case K_BS: return VTERM_KEY_BACKSPACE; + case K_S_TAB: *statep |= VTERM_MOD_SHIFT; case TAB: return VTERM_KEY_TAB; case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; @@ -801,6 +802,57 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_KMULTIPLY: return VTERM_KEY_KP_MULT; case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; + case K_S_F1: *statep |= VTERM_MOD_SHIFT; + case K_F1: return VTERM_KEY_FUNCTION(1); + case K_S_F2: *statep |= VTERM_MOD_SHIFT; + case K_F2: return VTERM_KEY_FUNCTION(2); + case K_S_F3: *statep |= VTERM_MOD_SHIFT; + case K_F3: return VTERM_KEY_FUNCTION(3); + case K_S_F4: *statep |= VTERM_MOD_SHIFT; + case K_F4: return VTERM_KEY_FUNCTION(4); + case K_S_F5: *statep |= VTERM_MOD_SHIFT; + case K_F5: return VTERM_KEY_FUNCTION(5); + case K_S_F6: *statep |= VTERM_MOD_SHIFT; + case K_F6: return VTERM_KEY_FUNCTION(6); + case K_S_F7: *statep |= VTERM_MOD_SHIFT; + case K_F7: return VTERM_KEY_FUNCTION(7); + case K_S_F8: *statep |= VTERM_MOD_SHIFT; + case K_F8: return VTERM_KEY_FUNCTION(8); + case K_S_F9: *statep |= VTERM_MOD_SHIFT; + case K_F9: return VTERM_KEY_FUNCTION(9); + case K_S_F10: *statep |= VTERM_MOD_SHIFT; + case K_F10: return VTERM_KEY_FUNCTION(10); + case K_S_F11: *statep |= VTERM_MOD_SHIFT; + case K_F11: return VTERM_KEY_FUNCTION(11); + case K_S_F12: *statep |= VTERM_MOD_SHIFT; + case K_F12: return VTERM_KEY_FUNCTION(12); + + case K_F13: return VTERM_KEY_FUNCTION(13); + case K_F14: return VTERM_KEY_FUNCTION(14); + case K_F15: return VTERM_KEY_FUNCTION(15); + case K_F16: return VTERM_KEY_FUNCTION(16); + case K_F17: return VTERM_KEY_FUNCTION(17); + case K_F18: return VTERM_KEY_FUNCTION(18); + case K_F19: return VTERM_KEY_FUNCTION(19); + case K_F20: return VTERM_KEY_FUNCTION(20); + case K_F21: return VTERM_KEY_FUNCTION(21); + case K_F22: return VTERM_KEY_FUNCTION(22); + case K_F23: return VTERM_KEY_FUNCTION(23); + case K_F24: return VTERM_KEY_FUNCTION(24); + case K_F25: return VTERM_KEY_FUNCTION(25); + case K_F26: return VTERM_KEY_FUNCTION(26); + case K_F27: return VTERM_KEY_FUNCTION(27); + case K_F28: return VTERM_KEY_FUNCTION(28); + case K_F29: return VTERM_KEY_FUNCTION(29); + case K_F30: return VTERM_KEY_FUNCTION(30); + case K_F31: return VTERM_KEY_FUNCTION(31); + case K_F32: return VTERM_KEY_FUNCTION(32); + case K_F33: return VTERM_KEY_FUNCTION(33); + case K_F34: return VTERM_KEY_FUNCTION(34); + case K_F35: return VTERM_KEY_FUNCTION(35); + case K_F36: return VTERM_KEY_FUNCTION(36); + case K_F37: return VTERM_KEY_FUNCTION(37); + default: return VTERM_KEY_NONE; } } -- cgit From d23403a1df624792077559badc1f5f1037d81f5d Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sat, 9 Jul 2016 14:36:20 -0400 Subject: terminal.c: move mod logic into convert_modifiers --- src/nvim/terminal.c | 59 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index bfcc123161..94c8ef0858 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -749,27 +749,56 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data) // }}} // input handling {{{ -static void convert_modifiers(VTermModifier *statep) +static void convert_modifiers(int key, VTermModifier *statep) { if (mod_mask & MOD_MASK_SHIFT) { *statep |= VTERM_MOD_SHIFT; } if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; } if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; } + + switch(key) { + case K_S_TAB: + case K_S_LEFT: + case K_S_RIGHT: + case K_S_F1: + case K_S_F2: + case K_S_F3: + case K_S_F4: + case K_S_F5: + case K_S_F6: + case K_S_F7: + case K_S_F8: + case K_S_F9: + case K_S_F10: + case K_S_F11: + case K_S_F12: + *statep |= VTERM_MOD_SHIFT; + break; + + case K_C_LEFT: + case K_C_RIGHT: + *statep |= VTERM_MOD_CTRL; + break; + } } static VTermKey convert_key(int key, VTermModifier *statep) { - convert_modifiers(statep); + convert_modifiers(key, statep); switch (key) { case K_BS: return VTERM_KEY_BACKSPACE; - case K_S_TAB: *statep |= VTERM_MOD_SHIFT; + case K_S_TAB: case TAB: return VTERM_KEY_TAB; case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; case K_UP: return VTERM_KEY_UP; case K_DOWN: return VTERM_KEY_DOWN; + case K_S_LEFT: + case K_C_LEFT: case K_LEFT: return VTERM_KEY_LEFT; + case K_S_RIGHT: + case K_C_RIGHT: case K_RIGHT: return VTERM_KEY_RIGHT; case K_INS: return VTERM_KEY_INS; @@ -802,29 +831,29 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_KMULTIPLY: return VTERM_KEY_KP_MULT; case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; - case K_S_F1: *statep |= VTERM_MOD_SHIFT; + case K_S_F1: case K_F1: return VTERM_KEY_FUNCTION(1); - case K_S_F2: *statep |= VTERM_MOD_SHIFT; + case K_S_F2: case K_F2: return VTERM_KEY_FUNCTION(2); - case K_S_F3: *statep |= VTERM_MOD_SHIFT; + case K_S_F3: case K_F3: return VTERM_KEY_FUNCTION(3); - case K_S_F4: *statep |= VTERM_MOD_SHIFT; + case K_S_F4: case K_F4: return VTERM_KEY_FUNCTION(4); - case K_S_F5: *statep |= VTERM_MOD_SHIFT; + case K_S_F5: case K_F5: return VTERM_KEY_FUNCTION(5); - case K_S_F6: *statep |= VTERM_MOD_SHIFT; + case K_S_F6: case K_F6: return VTERM_KEY_FUNCTION(6); - case K_S_F7: *statep |= VTERM_MOD_SHIFT; + case K_S_F7: case K_F7: return VTERM_KEY_FUNCTION(7); - case K_S_F8: *statep |= VTERM_MOD_SHIFT; + case K_S_F8: case K_F8: return VTERM_KEY_FUNCTION(8); - case K_S_F9: *statep |= VTERM_MOD_SHIFT; + case K_S_F9: case K_F9: return VTERM_KEY_FUNCTION(9); - case K_S_F10: *statep |= VTERM_MOD_SHIFT; + case K_S_F10: case K_F10: return VTERM_KEY_FUNCTION(10); - case K_S_F11: *statep |= VTERM_MOD_SHIFT; + case K_S_F11: case K_F11: return VTERM_KEY_FUNCTION(11); - case K_S_F12: *statep |= VTERM_MOD_SHIFT; + case K_S_F12: case K_F12: return VTERM_KEY_FUNCTION(12); case K_F13: return VTERM_KEY_FUNCTION(13); -- cgit From 4fd4f66514da4dfcd5d84c709be89d57616be753 Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sun, 10 Jul 2016 14:57:35 -0400 Subject: terminal.c: add more arrow key support --- src/nvim/terminal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 94c8ef0858..df15921f41 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -755,8 +755,10 @@ static void convert_modifiers(int key, VTermModifier *statep) if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; } if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; } - switch(key) { + switch (key) { case K_S_TAB: + case K_S_UP: + case K_S_DOWN: case K_S_LEFT: case K_S_RIGHT: case K_S_F1: @@ -792,7 +794,9 @@ static VTermKey convert_key(int key, VTermModifier *statep) case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; + case K_S_UP: case K_UP: return VTERM_KEY_UP; + case K_S_DOWN: case K_DOWN: return VTERM_KEY_DOWN; case K_S_LEFT: case K_C_LEFT: -- cgit From 5ffa01c8b78292bef0646168da856c726c2e4bc7 Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sun, 10 Jul 2016 20:04:09 -0400 Subject: terminal.c: handle ctrl+space and ctrl+@ --- src/nvim/terminal.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index df15921f41..c4a8a52816 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -512,6 +512,12 @@ void terminal_send(Terminal *term, char *data, size_t size) void terminal_send_key(Terminal *term, int c) { VTermModifier mod = VTERM_MOD_NONE; + + // Convert K_ZERO back to ASCII + if (c == K_ZERO) { + c = Ctrl_AT; + } + VTermKey key = convert_key(c, &mod); if (key) { -- cgit From a1d545f8e521e0f58633c42407e24d533111eb6c Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Mon, 14 Nov 2016 18:33:28 -0500 Subject: terminal.c: label fallthrough on big switch --- src/nvim/terminal.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index c4a8a52816..30556a3835 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -795,20 +795,20 @@ static VTermKey convert_key(int key, VTermModifier *statep) switch (key) { case K_BS: return VTERM_KEY_BACKSPACE; - case K_S_TAB: + case K_S_TAB: // FALLTHROUGH case TAB: return VTERM_KEY_TAB; case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; - case K_S_UP: + case K_S_UP: // FALLTHROUGH case K_UP: return VTERM_KEY_UP; - case K_S_DOWN: + case K_S_DOWN: // FALLTHROUGH case K_DOWN: return VTERM_KEY_DOWN; - case K_S_LEFT: - case K_C_LEFT: + case K_S_LEFT: // FALLTHROUGH + case K_C_LEFT: // FALLTHROUGH case K_LEFT: return VTERM_KEY_LEFT; - case K_S_RIGHT: - case K_C_RIGHT: + case K_S_RIGHT: // FALLTHROUGH + case K_C_RIGHT: // FALLTHROUGH case K_RIGHT: return VTERM_KEY_RIGHT; case K_INS: return VTERM_KEY_INS; @@ -818,22 +818,22 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_PAGEUP: return VTERM_KEY_PAGEUP; case K_PAGEDOWN: return VTERM_KEY_PAGEDOWN; - case K_K0: + case K_K0: // FALLTHROUGH case K_KINS: return VTERM_KEY_KP_0; - case K_K1: + case K_K1: // FALLTHROUGH case K_KEND: return VTERM_KEY_KP_1; case K_K2: return VTERM_KEY_KP_2; - case K_K3: + case K_K3: // FALLTHROUGH case K_KPAGEDOWN: return VTERM_KEY_KP_3; case K_K4: return VTERM_KEY_KP_4; case K_K5: return VTERM_KEY_KP_5; case K_K6: return VTERM_KEY_KP_6; - case K_K7: + case K_K7: // FALLTHROUGH case K_KHOME: return VTERM_KEY_KP_7; case K_K8: return VTERM_KEY_KP_8; - case K_K9: + case K_K9: // FALLTHROUGH case K_KPAGEUP: return VTERM_KEY_KP_9; - case K_KDEL: + case K_KDEL: // FALLTHROUGH case K_KPOINT: return VTERM_KEY_KP_PERIOD; case K_KENTER: return VTERM_KEY_KP_ENTER; case K_KPLUS: return VTERM_KEY_KP_PLUS; @@ -841,29 +841,29 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_KMULTIPLY: return VTERM_KEY_KP_MULT; case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; - case K_S_F1: + case K_S_F1: // FALLTHROUGH case K_F1: return VTERM_KEY_FUNCTION(1); - case K_S_F2: + case K_S_F2: // FALLTHROUGH case K_F2: return VTERM_KEY_FUNCTION(2); - case K_S_F3: + case K_S_F3: // FALLTHROUGH case K_F3: return VTERM_KEY_FUNCTION(3); - case K_S_F4: + case K_S_F4: // FALLTHROUGH case K_F4: return VTERM_KEY_FUNCTION(4); - case K_S_F5: + case K_S_F5: // FALLTHROUGH case K_F5: return VTERM_KEY_FUNCTION(5); - case K_S_F6: + case K_S_F6: // FALLTHROUGH case K_F6: return VTERM_KEY_FUNCTION(6); - case K_S_F7: + case K_S_F7: // FALLTHROUGH case K_F7: return VTERM_KEY_FUNCTION(7); - case K_S_F8: + case K_S_F8: // FALLTHROUGH case K_F8: return VTERM_KEY_FUNCTION(8); - case K_S_F9: + case K_S_F9: // FALLTHROUGH case K_F9: return VTERM_KEY_FUNCTION(9); - case K_S_F10: + case K_S_F10: // FALLTHROUGH case K_F10: return VTERM_KEY_FUNCTION(10); - case K_S_F11: + case K_S_F11: // FALLTHROUGH case K_F11: return VTERM_KEY_FUNCTION(11); - case K_S_F12: + case K_S_F12: // FALLTHROUGH case K_F12: return VTERM_KEY_FUNCTION(12); case K_F13: return VTERM_KEY_FUNCTION(13); -- cgit From a5481957c65985fc1f885464ae9b43f92d0dc519 Mon Sep 17 00:00:00 2001 From: lonerover Date: Fri, 17 Mar 2017 22:48:42 +0800 Subject: vim-patch:7.4.2255 Problem: The script that checks translations can't handle plurals. Solution: Check for plural msgid and msgstr entries. Leave the cursor on the first error. https://github.com/vim/vim/commit/ec42059b78c1932a44f2bf36ac982109884dc7c7 --- src/nvim/po/check.vim | 76 +++++++++++++++++++++++++++++++++++++-------------- src/nvim/version.c | 2 +- 2 files changed, 56 insertions(+), 22 deletions(-) (limited to 'src') 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/version.c b/src/nvim/version.c index 5b3a7398d5..b9286c2a4e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -186,7 +186,7 @@ static int included_patches[] = { // 2258 NA // 2257 NA // 2256, - // 2255, + 2255, // 2254 NA // 2253 NA // 2252 NA -- cgit From 934137fb489f0c99c32abe32e32f683e0ba3d40f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 19 Mar 2017 13:14:49 -0400 Subject: vim-patch:8.0.0116 Problem: When reading English help and using CTRl-] the language from 'helplang' is used. Solution: Make help tag jumps keep the language. (Tatsuki, test by Hirohito Higashi, closes vim/vim#1249) https://github.com/vim/vim/commit/6dbf66aa3e2197ce41f2b1cc7602bb9c15840548 --- src/nvim/tag.c | 26 ++++++++++++++++++++------ src/nvim/testdir/test_help_tagjump.vim | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 2c70f396a1..9c9f24b9c0 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1135,6 +1135,7 @@ find_tags ( 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; @@ -1232,6 +1233,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) { @@ -1247,13 +1256,18 @@ 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. */ diff --git a/src/nvim/testdir/test_help_tagjump.vim b/src/nvim/testdir/test_help_tagjump.vim index aabfe40537..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 +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("\", '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 -- cgit From b87cb77570a53b3c0507d5acded0d103e9ab52f9 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 09:56:55 +0100 Subject: vim-patch:7.4.2315 Problem: Insufficient testing for Normal mode commands. Solution: Add a big test. (Christian Brabandt, closes vim/vim#1029) https://github.com/vim/vim/commit/87bc3f74598ae8c648957e5755000cc6cdbc89ce --- src/nvim/testdir/Makefile | 1 + src/nvim/testdir/test_normal.vim | 1994 ++++++++++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 3 files changed, 1996 insertions(+), 1 deletion(-) create mode 100644 src/nvim/testdir/test_normal.vim (limited to 'src') diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 9f9ecbc6c9..d090ace432 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -47,6 +47,7 @@ NEW_TESTS ?= \ test_match.res \ test_matchadd_conceal.res \ test_nested_function.res \ + test_normal.res \ test_quickfix.res \ test_signs.res \ test_syntax.res \ diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim new file mode 100644 index 0000000000..1371ccfd5e --- /dev/null +++ b/src/nvim/testdir/test_normal.vim @@ -0,0 +1,1994 @@ +" 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 +endfu + +function! 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 +endfunction + +fun! Test_normal00_optrans() + " Attention: This needs to be the very first test, + " it will fail, if it runs later, don't know why! + " Test for S s and alike comamnds, that are internally handled aliased + 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\" + call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$')) + 2 + " Test does not work + " TODO: Why does it not work? + " Adds an additional linebreak if used in visual mode... + " When run in the test, this returns: + " ,-------- + " |foobar + " |2 This is + " |the second + " |one + " |3 this is the third line + " `----------- + " instead of + " ,-------- + " |foobar + " |2 This is the second one + " |3 this is the third line + " `----------- + exe "norm! $vbsone" + call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$')) + " When run in the test, this returns: + " ,-------- + " |foobar + " |Second line + " |here + " |3 this is the third line + " `----------- + " instead of + " ,-------- + " |foobar + " |Second line here + " |3 this is the third line + " `----------- + 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,'$')) + 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! +endfu + +func! Test_normal01_keymodel() + call Setup_NewWindow() + " Test 1: depending on 'keymodel' does something different + :50 + call feedkeys("V\y", 'tx') + call assert_equal(['47', '48', '49', '50'], getline("'<", "'>")) + :set keymodel=startsel + :50 + call feedkeys("V\y", 'tx') + call assert_equal(['49', '50'], getline("'<", "'>")) + " Start visual mode when keymodel = startsel + :50 + call feedkeys("\y", 'tx') + call assert_equal(['49', '5'], getreg(0, 0, 1)) + " Do not start visual mode when keymodel= + :set keymodel= + :50 + call feedkeys("\y$", 'tx') + call assert_equal(['42'], 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\y" + call assert_equal('y60', getline('.')) + " clean up + bw! +endfu + +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! +endfu + +func! Test_normal04_filter() + " basic filter test + " only test on non windows platform + if has("win32") || has("win64") || has("win95") + 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 , 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! +endfu + +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! +endfu + +func! Test_normal06_formatprg() + " basic test for formatprg + " only test on non windows platform + if has("win32") || has("win64") || has("win95") + return + else + " 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') + endif + call Setup_NewWindow() + %d + call setline(1, ['a', '', 'c', '', ' ', 'd', 'e']) + set formatprg=./Xsed_format.sh + norm! gggqG + call assert_equal(['1 a', '', '3 c', '', '5 ', '6 d', '7 e'], getline(1, '$')) + " clean up + set formatprg= + call delete('Xsed_format.sh') + bw! +endfu + +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 formatprg= + bw! +endfu + +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! +endfu + +func! Test_normal09_operatorfunc() + " Test operatorfunc + call Setup_NewWindow() + " Add some spaces for counting + 50,60s/$/ / + unlet! g:a + let g:a=0 + nmap ,, :set opfunc=CountSpacesg@ + vmap ,, :call CountSpaces(visualmode(), 1) + 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\10j2l,," + call assert_equal(11, g:a) + 50 + norm V10j,, + call assert_equal(22, g:a) + + " clean up + unmap ,, + set opfunc= + bw! +endfu + +func! Test_normal10_expand() + " Test for expand() + 10new + call setline(1, ['1', 'ifooar,,cbar']) + 2 + norm! $ + let a=expand('') + let b=expand('') + call assert_equal('cbar', a) + call assert_equal('ifooar,,cbar', b) + " clean up + bw! +endfu + +func! Test_normal11_showcmd() + " test for 'showcmd' + 10new + exe "norm! ofoobar\" + call assert_equal(2, line('$')) + set showcmd + exe "norm! ofoobar2\" + call assert_equal(3, line('$')) + exe "norm! VAfoobar3\" + call assert_equal(3, line('$')) + exe "norm! 0d3\2l" + call assert_equal('obar2foobar3', getline('.')) + bw! +endfu + +func! Test_normal12_nv_error() + " Test for nv_error + 10new + call setline(1, range(1,5)) + " should not do anything, just beep + exe "norm! " + call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$')) + bw! +endfu + +func! Test_normal13_help() + " Test for F1 + call assert_equal(1, winnr()) + call feedkeys("\", 'txi') + call assert_match('help\.txt', bufname('%')) + call assert_equal(2, winnr('$')) + bw! +endfu + +func! Test_normal14_page() + " basic test for Ctrl-F and Ctrl-B + call Setup_NewWindow() + exe "norm! \" + call assert_equal('9', getline('.')) + exe "norm! 2\" + call assert_equal('25', getline('.')) + exe "norm! 2\" + call assert_equal('18', getline('.')) + 1 + set scrolloff=5 + exe "norm! 2\" + call assert_equal('21', getline('.')) + exe "norm! \" + call assert_equal('13', getline('.')) + 1 + set scrolloff=99 + exe "norm! \" + call assert_equal('13', getline('.')) + set scrolloff=0 + 100 + exe "norm! $\" + call assert_equal('92', getline('.')) + call assert_equal([0, 92, 1, 0, 1], getcurpos()) + 100 + set nostartofline + exe "norm! $\" + call assert_equal('92', getline('.')) + call assert_equal([0, 92, 2, 0, 2147483647], getcurpos()) + " cleanup + set startofline + bw! +endfu + +func! Test_normal15_z_scroll_vert() + " basic test for z commands that scroll the window + call Setup_NewWindow() + 100 + norm! >> + " Test for z + exe "norm! z\" + 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} + call assert_equal(10, winheight(0)) + exe "norm! z12\" + call assert_equal(12, winheight(0)) + exe "norm! z10\" + 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! +endfu + +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! +endfu + +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! +endfu + +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! +endfu + +func! Test_normal19_z_spell() + if !has("spell") || !has('syntax') + return + endif + new + call append(0, ['1 good', '2 goood', '3 goood']) + set spell spellfile=./Xspellfile.add spelllang=en + let oldlang=v:lang + lang C + + " Test for zg + 1 + norm! ]s + call assert_equal('2 goood', getline('.')) + norm! zg + 1 + let a=execute('unsilent :norm! ]s') + call assert_equal('1 good', getline('.')) + call assert_equal('search hit BOTTOM, continuing at TOP', a[1:]) + let cnt=readfile('./Xspellfile.add') + call assert_equal('goood', cnt[0]) + + " Test for zw + 2 + norm! $zw + 1 + norm! ]s + call assert_equal('2 goood', getline('.')) + let cnt=readfile('./Xspellfile.add') + call assert_equal('#oood', cnt[0]) + call assert_equal('goood/!', cnt[1]) + + " Test for zg in visual mode + let a=execute('unsilent :norm! V$zg') + call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:]) + 1 + norm! ]s + call assert_equal('3 goood', getline('.')) + let cnt=readfile('./Xspellfile.add') + call assert_equal('2 goood', cnt[2]) + " Remove "2 good" from spellfile + 2 + let a=execute('unsilent norm! V$zw') + call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:]) + let cnt=readfile('./Xspellfile.add') + call assert_equal('2 goood/!', cnt[3]) + + " Test for zG + let a=execute('unsilent norm! V$zG') + call assert_match("Word '2 goood' added to .*", a) + let fname=matchstr(a, 'to\s\+\zs\f\+$') + let 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") + + " 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! +endfu + +func! Test_normal20_exmode() + if !(has("win32") || has("win64")) + 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! +endfu + +func! Test_normal21_nv_hat() + set hidden + e Xfoobar + e Xfile2 + call feedkeys("\", 't') + call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t')) + call feedkeys("f\", 't') + call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t')) + " clean up + set nohidden + bw! +endfu + +func! Test_normal22_zet() + " Test for ZZ + let shell = &shell + let &shell = 'sh' + call writefile(['1', '2'], 'Xfile') + let args = ' -u NONE -N -U NONE -i NONE --noplugins -X --not-a-term' + call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile') + let a = readfile('Xfile') + call assert_equal([], a) + " Test for ZQ + call writefile(['1', '2'], 'Xfile') + call system(v:progpath . args . ' -c "%d" -c ":norm! ZQ" Xfile') + let a = readfile('Xfile') + call assert_equal(['1', '2'], a) + + " clean up + for file in ['Xfile'] + call delete(file) + endfor + let &shell = shell +endfu + +func! Test_normal23_K() + " Test for K command + new + call append(0, ['version8.txt', 'man']) + let k = &keywordprg + set keywordprg=:help + 1 + norm! VK + call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t')) + call assert_equal('help', &ft) + call assert_match('\*version8.txt\*', getline('.')) + helpclose + norm! 0K + call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t')) + call assert_equal('help', &ft) + call assert_match('\*version8\.0\*', getline('.')) + helpclose + + if !(has("win32") || has("win64")) + 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! +endfu + +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! +endfu + +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('\$') + exe "norm! \" + call assert_equal("change.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*x*", @0) + exe ":norm \" + + " Test for g_CTRL-] + call search('\$') + exe "norm! g\" + call assert_equal("change.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*v_u*", @0) + exe ":norm \" + + " Test for g] + call search('\$') + let a = execute(":norm! g]") + call assert_match('i_.*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_*", @0) + exe ":norm \" + " Test for CTRL-W g] + exe "norm! \g]" + call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*i_*", @0) + call assert_equal(3, winnr('$')) + helpclose + set nocst + endif + + " Test for CTRL-W g] + let a = execute("norm! \g]") + call assert_match('i_.*insert.txt', a) + + " Test for CTRL-W CTRL-] + exe "norm! \\" + call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*i_*", @0) + call assert_equal(3, winnr('$')) + helpclose + + " Test for CTRL-W g CTRL-] + exe "norm! \g\" + call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*i_*", @0) + call assert_equal(3, winnr('$')) + helpclose + + " clean up + helpclose +endfu + +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! +endfu + +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! +endfu + +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! +endfu + +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) + 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! +endfu + +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('.')) + + " clean up + bw! +endfu + +fun! Test_normal31_r_cmd() + " Test for r command + new + call append(0, 'This is a simple test: abcd') + exe "norm! 1gg$r\" + call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$')) + exe "norm! 1gg2wlr\" + call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$')) + exe "norm! 2gg0W5r\" + call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$')) + set autoindent + call setline(2, ['simple test: abc', '']) + exe "norm! 2gg0W5r\" + call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$')) + exe "norm! 1ggVr\" + 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! +endfu + +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! +endfu + +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]\" + 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\2j2ly" + call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1)) + " in visual mode, gv swaps current and last selected region + exe "norm! G0\4k4lgvd" + call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$')) + exe "norm! G0\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 + let a=execute(":norm! 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! +endfu + +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! +endfu + +fun! Test_normal35_g_cmd4() + " Test for g< + " Cannot capture its output, + " probably a bug, therefore, test disabled: + return + echo "a\nb\nc\nd" + let b=execute(':norm! g<') + call assert_true(!empty(b), 'failed `execute(g<)`') +endfu + +fun! Test_normal36_g_cmd5() + new + call append(0, 'abcdefghijklmnopqrstuvwxyz') + " 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! +endfu + +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') +endfu + +fun! Test_normal38_nvhome() + " Test for and key + new + call setline(1, range(10)) + $ + setl et sw=2 + norm! V10>$ + " count is ignored + exe "norm! 10\" + call assert_equal(1, col('.')) + exe "norm! \" + call assert_equal([0, 10, 1, 0, 1], getcurpos()) + exe "norm! 5\" + call assert_equal([0, 5, 1, 0, 1], getcurpos()) + exe "norm! \" + call assert_equal([0, 1, 1, 0, 1], getcurpos()) + + " clean up + bw! +endfu + +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('.')) + 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! +endfu + +fun! Test_normal40_ctrl_bsl() + " Basic test for CTRL-\ commands + new + call append(0, 'here are some words') + exe "norm! 1gg0a\\" + call assert_equal('n', mode()) + call assert_equal(1, col('.')) + call assert_equal('', visualmode()) + exe "norm! 1gg0viw\\" + call assert_equal('n', mode()) + call assert_equal(4, col('.')) + exe "norm! 1gg0a\\" + call assert_equal('n', mode()) + call assert_equal(1, col('.')) + "imap , + set im + exe ":norm! \\dw" + set noim + call assert_equal('are some words', getline(1)) + call assert_false(&insertmode) + + " clean up + bw! +endfu + +fun! Test_normal41_insert_reg() + " Test for =, = and = + " 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\=a\" + norm! 3gg0 + exe "norm! a\\=a\" + norm! 4gg0 + exe "norm! a\\=a\" + 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! +endfu + +func! Test_normal42_halfpage() + " basic test for Ctrl-D and Ctrl-U + call Setup_NewWindow() + call assert_equal(5, &scroll) + exe "norm! \" + call assert_equal('6', getline('.')) + exe "norm! 2\" + call assert_equal('8', getline('.')) + call assert_equal(2, &scroll) + set scroll=5 + exe "norm! \" + call assert_equal('3', getline('.')) + 1 + set scrolloff=5 + exe "norm! \" + call assert_equal('10', getline('.')) + exe "norm! \" + call assert_equal('5', getline('.')) + 1 + set scrolloff=99 + exe "norm! \" + call assert_equal('10', getline('.')) + set scrolloff=0 + 100 + exe "norm! $\" + call assert_equal('95', getline('.')) + call assert_equal([0, 95, 1, 0, 1], getcurpos()) + 100 + set nostartofline + exe "norm! $\" + call assert_equal('95', getline('.')) + call assert_equal([0, 95, 2, 0, 2147483647], getcurpos()) + " cleanup + set startofline + bw! +endfu + +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! +endfu + +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, ['
','xyz','
', ' ']) + " a< + norm! 1gg0da< + call assert_equal([' ', 'xyz', ' ', ' '], getline(1,'$')) + norm! 1pj + call assert_equal(['
', 'xyz', '
', ' '], getline(1,'$')) + " at + norm! d2at + call assert_equal([' '], getline(1,'$')) + %d + call setline(1, ['
','xyz','
', ' ']) + " i< + norm! 1gg0di< + call assert_equal(['<> ', 'xyz', ' ', ' '], getline(1,'$')) + norm! 1Pj + call assert_equal(['
', 'xyz', '
', ' '], getline(1,'$')) + norm! d2it + call assert_equal(['
',' '], 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! +endfu + +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! +endfu + +func! Test_normal46_ignore() + new + " How to test this? + " let's just for now test, that the buffer + " does not change + call feedkeys("\", 't') + call assert_equal([''], getline(1,'$')) + + " clean up + bw! +endfu diff --git a/src/nvim/version.c b/src/nvim/version.c index ab3ccdab3d..bef92d40dd 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -126,7 +126,7 @@ static int included_patches[] = { // 2318, // 2317, // 2316 NA - // 2315, + 2315, 2314, 2313, 2312, -- cgit From afd8eacb4e0268d6ce4dbcca9f188fc8f660cb3c Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 10:21:14 +0100 Subject: vim-patch:7.4.2317 Problem: Normal mode tests fail on MS-Windows. Solution: Do some tests only on Unix. Set 'fileformat' to "unix". https://github.com/vim/vim/commit/0913a1089a07ac7b17abc3a1343dfa7cd25613f4 --- src/nvim/testdir/test_normal.vim | 14 +++++++++----- src/nvim/version.c | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 1371ccfd5e..ff6710218d 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -1137,7 +1137,8 @@ func! Test_normal19_z_spell() endfu func! Test_normal20_exmode() - if !(has("win32") || has("win64")) + if !has("unix") + " Reading from redirected file doesn't work on MS-Windows return endif call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript') @@ -1168,8 +1169,8 @@ endfu func! Test_normal22_zet() " Test for ZZ - let shell = &shell - let &shell = 'sh' + " let shell = &shell + " let &shell = 'sh' call writefile(['1', '2'], 'Xfile') let args = ' -u NONE -N -U NONE -i NONE --noplugins -X --not-a-term' call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile') @@ -1185,7 +1186,7 @@ func! Test_normal22_zet() for file in ['Xfile'] call delete(file) endfor - let &shell = shell + " let &shell = shell endfu func! Test_normal23_K() @@ -1206,7 +1207,8 @@ func! Test_normal23_K() call assert_match('\*version8\.0\*', getline('.')) helpclose - if !(has("win32") || has("win64")) + " Only expect "man" to work on Unix + if !has("unix") let &keywordprg = k bw! return @@ -1642,6 +1644,7 @@ fun! Test_normal33_g_cmd2() call assert_equal('l', getreg(0)) " Test for g Ctrl-G + set ff=unix let a=execute(":norm! g\") call assert_match('Col 15 of 43; Line 2 of 2; Word 2 of 2; Byte 16 of 45', a) @@ -1692,6 +1695,7 @@ endfu fun! Test_normal36_g_cmd5() new call append(0, 'abcdefghijklmnopqrstuvwxyz') + set ff=unix " Test for gp gP call append(1, range(1,10)) 1 diff --git a/src/nvim/version.c b/src/nvim/version.c index bef92d40dd..207b561cc3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -124,7 +124,7 @@ static int included_patches[] = { // 2320, // 2319 NA // 2318, - // 2317, + 2317, // 2316 NA 2315, 2314, -- cgit From 42caeccce6e50fa3b8b25fe3076ac2fbd555b152 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 10:27:15 +0100 Subject: vim-patch:7.4.2322 Problem: Access memory beyond the end of the line. (Dominique Pelle) Solution: Adjust the cursor column. https://github.com/vim/vim/commit/bc54f3f3fed4dc3556df8c46cee6739d211b0eb2 --- src/nvim/move.c | 2 +- src/nvim/testdir/test_normal.vim | 9 +++++++++ src/nvim/version.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/move.c b/src/nvim/move.c index 4c1b8a8411..9ba515f209 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1877,7 +1877,7 @@ int onepage(int dir, long count) } } foldAdjustCursor(); - cursor_correct(); + check_cursor_col(); if (retval == OK) beginline(BL_SOL | BL_FIX); curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL); diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index ff6710218d..98cb7754bb 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -398,6 +398,15 @@ func! Test_normal14_page() bw! endfu +func! Test_normal14_page_eol() + 10new + norm oxxxxxxx + exe "norm 2\" + " check with valgrind that cursor is put back in column 1 + exe "norm 2\" + bw! +endfunc + func! Test_normal15_z_scroll_vert() " basic test for z commands that scroll the window call Setup_NewWindow() diff --git a/src/nvim/version.c b/src/nvim/version.c index 207b561cc3..7f07e5a287 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -119,7 +119,7 @@ static int included_patches[] = { // 2325 NA // 2324, // 2323, - // 2322, + 2322, 2321, // 2320, // 2319 NA -- cgit From e888864c28033546b827c07d9dd095348fff23bd Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 11:33:15 +0100 Subject: vim-patch:7.4.2326 Problem: Illegal memory access when Visual selection starts in invalid position. (Dominique Pelle) Solution: Correct position when needed. https://github.com/vim/vim/commit/d5824ce1b5491df7d2eb0b66189d366fa67b4585 --- src/nvim/cursor.c | 18 ++++++++++++++++++ src/nvim/normal.c | 1 + src/nvim/version.c | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 3ba9da34f2..01476627de 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -294,6 +294,24 @@ 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. */ diff --git a/src/nvim/normal.c b/src/nvim/normal.c index ee3c3f9f11..1fd03257ec 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -7831,6 +7831,7 @@ static void get_op_vcol( // prevent from moving onto a trail byte if (has_mbyte) { + check_pos(curwin->w_buffer, &oap->end); mb_adjustpos(curwin->w_buffer, &oap->end); } diff --git a/src/nvim/version.c b/src/nvim/version.c index 7f07e5a287..09fe1d029b 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -115,7 +115,7 @@ static int included_patches[] = { // 2329, // 2328, // 2327 NA - // 2326, + 2326, // 2325 NA // 2324, // 2323, -- cgit From 1e33c886856abcdac13c3eb368c127bda40e1e84 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 10:42:07 +0100 Subject: vim-patch:7.4.2333 Problem: Outdated comments in test. Solution: Cleanup normal mode test. (Christian Brabandt) https://github.com/vim/vim/commit/31845093b7f1b33e0c7e9e592bef65528674a1f2 --- src/nvim/ops.c | 9 +++++- src/nvim/testdir/test_normal.vim | 63 +++++++++++++++++----------------------- src/nvim/version.c | 4 +-- 3 files changed, 37 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 1e4d392754..3a682b6f96 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3847,6 +3847,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. @@ -3856,16 +3857,22 @@ fex_format ( set_vim_var_nr(VV_COUNT, (varnumber_T)count); set_vim_var_char(c); + // 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 = eval_to_number(curbuf->b_p_fex); + r = (int)eval_to_number(fex); if (use_sandbox) --sandbox; set_vim_var_string(VV_CHAR, NULL, -1); + xfree(fex); return r; } diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 98cb7754bb..9a8f8f83be 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -36,47 +36,14 @@ function! CountSpaces(type, ...) endfunction fun! Test_normal00_optrans() - " Attention: This needs to be the very first test, - " it will fail, if it runs later, don't know why! - " Test for S s and alike comamnds, that are internally handled aliased 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\" call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$')) 2 - " Test does not work - " TODO: Why does it not work? - " Adds an additional linebreak if used in visual mode... - " When run in the test, this returns: - " ,-------- - " |foobar - " |2 This is - " |the second - " |one - " |3 this is the third line - " `----------- - " instead of - " ,-------- - " |foobar - " |2 This is the second one - " |3 this is the third line - " `----------- exe "norm! $vbsone" call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$')) - " When run in the test, this returns: - " ,-------- - " |foobar - " |Second line - " |here - " |3 this is the third line - " `----------- - " instead of - " ,-------- - " |foobar - " |Second line here - " |3 this is the third line - " `----------- norm! VS Second line here call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$')) %d @@ -192,6 +159,30 @@ func! Test_normal05_formatexpr() bw! endfu +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 @@ -224,7 +215,7 @@ func! Test_normal07_internalfmt() norm! gggqG call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$')) " clean up - set formatprg= + set formatprg= tw=0 bw! endfu @@ -1695,7 +1686,7 @@ fun! Test_normal35_g_cmd4() " Test for g< " Cannot capture its output, " probably a bug, therefore, test disabled: - return + 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<)`') @@ -1853,7 +1844,7 @@ fun! Test_normal41_insert_reg() " clean up set sts=0 sw=8 ts=8 - "bw! + bw! endfu func! Test_normal42_halfpage() diff --git a/src/nvim/version.c b/src/nvim/version.c index 09fe1d029b..dd7318b697 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -108,7 +108,7 @@ static int included_patches[] = { // 2336, 2335, // 2334, - // 2333, + 2333, // 2332 NA 2331, // 2330, @@ -118,7 +118,7 @@ static int included_patches[] = { 2326, // 2325 NA // 2324, - // 2323, + 2323, 2322, 2321, // 2320, -- cgit From 4500b16f15510f6091ca98b78aa4ee13e1acf2c7 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 10:44:35 +0100 Subject: vim-patch:7.4.2336 Problem: Running normal mode tests leave a couple of files behind. (Yegappan Lakshmanan) Solution: Delete the files. (Christian Brabandt) https://github.com/vim/vim/commit/df0db16cf74281a83a9ea3388a2ef9aedccd013c --- src/nvim/testdir/test_normal.vim | 2 ++ src/nvim/version.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 9a8f8f83be..b894a633c4 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -1125,6 +1125,8 @@ func! Test_normal19_z_spell() 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 diff --git a/src/nvim/version.c b/src/nvim/version.c index dd7318b697..487685ea2e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -105,7 +105,7 @@ static int included_patches[] = { // 2339, // 2338 NA 2337, - // 2336, + 2336, 2335, // 2334, 2333, -- cgit From ae828982ceb9dc4c5bde58a276e6e10df6f35051 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 10:46:50 +0100 Subject: vim-patch:7.4.2347 Problem: Crash when closing a buffer while Visual mode is active. (Dominique Pelle) Solution: Adjust the position before computing the number of lines. When closing the current buffer stop Visual mode. https://github.com/vim/vim/commit/c4a908e83690844b0d3a46124ba6af7d23485d69 --- src/nvim/buffer.c | 12 ++++++++++++ src/nvim/normal.c | 3 ++- src/nvim/testdir/test_normal.vim | 14 ++++++++++++++ src/nvim/version.c | 2 +- 4 files changed, 29 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f52989c74d..0a95cc9020 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -438,6 +438,13 @@ 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) { + end_visual_mode(); + } + buf->b_nwindows = nwindows; buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0)); @@ -1075,6 +1082,11 @@ do_buffer ( } } + // When closing the current buffer stop Visual mode. + if (buf == curbuf) { + end_visual_mode(); + } + /* * If deleting the last (listed) buffer, make it empty. * The last (listed) buffer cannot be unloaded. diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 1fd03257ec..ce286042df 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1596,6 +1596,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. */ @@ -7831,7 +7833,6 @@ static void get_op_vcol( // prevent from moving onto a trail byte if (has_mbyte) { - check_pos(curwin->w_buffer, &oap->end); mb_adjustpos(curwin->w_buffer, &oap->end); } diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index b894a633c4..79af7b2587 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -1998,3 +1998,17 @@ func! Test_normal46_ignore() " clean up bw! endfu + +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 \$" + bw! + norm yp + set nomodified +endfu diff --git a/src/nvim/version.c b/src/nvim/version.c index 487685ea2e..b652f5fee5 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -94,7 +94,7 @@ static int included_patches[] = { // 2350, // 2349, // 2348, - // 2347, + 2347, // 2346, // 2345 NA // 2344 NA -- cgit From 707aea86bbae6ff819deb64ca977cc701d39d569 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 11:45:44 +0100 Subject: vim-patch:7.4.2353 Problem: Not enough test coverage for Normal mode commands. Solution: Add more tests. (Christian Brabandt) https://github.com/vim/vim/commit/2931f2a5df0d962032d41060af84d9fd2cb35c9f --- src/nvim/testdir/test_normal.vim | 311 +++++++++++++++++++++++++++++++-------- src/nvim/version.c | 2 +- 2 files changed, 254 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 79af7b2587..f896046d4b 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -13,9 +13,9 @@ func! MyFormatExpr() call setline(ln, substitute(line, '\s\+$', '', '') . '->$') endif endfor -endfu +endfunc -function! CountSpaces(type, ...) +func! CountSpaces(type, ...) " for testing operatorfunc " will count the number of spaces " and return the result in g:a @@ -33,7 +33,11 @@ function! CountSpaces(type, ...) let g:a=strlen(substitute(@@, '[^ ]', '', 'g')) let &selection = sel_save let @@ = reg_save -endfunction +endfunc + +func! IsWindows() + return has("win32") || has("win64") || has("win95") +endfunc fun! Test_normal00_optrans() new @@ -60,27 +64,37 @@ fun! Test_normal00_optrans() " clean up set cpo-=# bw! -endfu +endfunc func! Test_normal01_keymodel() call Setup_NewWindow() " Test 1: depending on 'keymodel' does something different - :50 + 50 call feedkeys("V\y", 'tx') call assert_equal(['47', '48', '49', '50'], getline("'<", "'>")) - :set keymodel=startsel - :50 + set keymodel=startsel + 50 call feedkeys("V\y", 'tx') call assert_equal(['49', '50'], getline("'<", "'>")) " Start visual mode when keymodel = startsel - :50 + 50 call feedkeys("\y", 'tx') call assert_equal(['49', '5'], getreg(0, 0, 1)) " Do not start visual mode when keymodel= - :set keymodel= - :50 + set keymodel= + 50 call feedkeys("\y$", 'tx') call assert_equal(['42'], getreg(0, 0, 1)) + " Stop visual mode when keymodel=stopsel + set keymodel=stopsel + 50 + call feedkeys("Vkk\yy", 'tx') + call assert_equal(['47'], getreg(0, 0, 1)) + + set keymodel= + 50 + call feedkeys("Vkk\yy", 'tx') + call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1)) " clean up bw! @@ -98,7 +112,17 @@ func! Test_normal02_selectmode() call assert_equal('y60', getline('.')) " clean up bw! -endfu +endfunc + +func! Test_normal02_selectmode2() + " some basic select mode tests + call Setup_NewWindow() + 50 + call feedkeys(":set im\n\gHc\:set noim\n", 'tx') + call assert_equal('c51', getline('.')) + " clean up + bw! +endfunc func! Test_normal03_join() " basic join test @@ -118,12 +142,12 @@ func! Test_normal03_join() call assert_equal('100', getline('.')) " clean up bw! -endfu +endfunc func! Test_normal04_filter() " basic filter test " only test on non windows platform - if has("win32") || has("win64") || has("win95") + if IsWindows() return endif call Setup_NewWindow() @@ -144,7 +168,7 @@ func! Test_normal04_filter() call assert_equal('one', getline('.')) set cpo-=! bw! -endfu +endfunc func! Test_normal05_formatexpr() " basic formatexpr test @@ -157,7 +181,7 @@ func! Test_normal05_formatexpr() call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$')) set formatexpr= bw! -endfu +endfunc func Test_normal05_formatexpr_newbuf() " Edit another buffer in the 'formatexpr' function @@ -186,7 +210,7 @@ endfunc func! Test_normal06_formatprg() " basic test for formatprg " only test on non windows platform - if has("win32") || has("win64") || has("win95") + if IsWindows() return else " uses sed to number non-empty lines @@ -203,7 +227,7 @@ func! Test_normal06_formatprg() set formatprg= call delete('Xsed_format.sh') bw! -endfu +endfunc func! Test_normal07_internalfmt() " basic test for internal formmatter to textwidth of 12 @@ -217,7 +241,7 @@ func! Test_normal07_internalfmt() " clean up set formatprg= tw=0 bw! -endfu +endfunc func! Test_normal08_fold() " basic tests for foldopen/folddelete @@ -276,7 +300,7 @@ func! Test_normal08_fold() " clean up setl nofoldenable fdm=marker bw! -endfu +endfunc func! Test_normal09_operatorfunc() " Test operatorfunc @@ -305,7 +329,7 @@ func! Test_normal09_operatorfunc() unmap ,, set opfunc= bw! -endfu +endfunc func! Test_normal10_expand() " Test for expand() @@ -319,7 +343,7 @@ func! Test_normal10_expand() call assert_equal('ifooar,,cbar', b) " clean up bw! -endfu +endfunc func! Test_normal11_showcmd() " test for 'showcmd' @@ -334,7 +358,7 @@ func! Test_normal11_showcmd() exe "norm! 0d3\2l" call assert_equal('obar2foobar3', getline('.')) bw! -endfu +endfunc func! Test_normal12_nv_error() " Test for nv_error @@ -344,7 +368,7 @@ func! Test_normal12_nv_error() exe "norm! " call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$')) bw! -endfu +endfunc func! Test_normal13_help() " Test for F1 @@ -353,7 +377,7 @@ func! Test_normal13_help() call assert_match('help\.txt', bufname('%')) call assert_equal(2, winnr('$')) bw! -endfu +endfunc func! Test_normal14_page() " basic test for Ctrl-F and Ctrl-B @@ -387,7 +411,7 @@ func! Test_normal14_page() " cleanup set startofline bw! -endfu +endfunc func! Test_normal14_page_eol() 10new @@ -485,7 +509,7 @@ func! Test_normal15_z_scroll_vert() " cleanup bw! -endfu +endfunc func! Test_normal16_z_scroll_hor() " basic test for z commands that scroll the window @@ -551,7 +575,7 @@ func! Test_normal16_z_scroll_hor() " cleanup set wrap listchars=eol:$ bw! -endfu +endfunc func! Test_normal17_z_scroll_hor2() " basic test for z commands that scroll the window @@ -618,7 +642,7 @@ func! Test_normal17_z_scroll_hor2() " cleanup set wrap listchars=eol:$ sidescrolloff=0 bw! -endfu +endfunc func! Test_normal18_z_fold() " basic tests for foldopen/folddelete @@ -989,7 +1013,7 @@ func! Test_normal18_z_fold() " clean up setl nofoldenable fdm=marker foldlevel=0 bw! -endfu +endfunc func! Test_normal19_z_spell() if !has("spell") || !has('syntax') @@ -1136,7 +1160,7 @@ func! Test_normal19_z_spell() set spellfile= bw! -endfu +endfunc func! Test_normal20_exmode() if !has("unix") @@ -1154,10 +1178,14 @@ func! Test_normal20_exmode() call delete(file) endfor bw! -endfu +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("\", 't') @@ -1167,7 +1195,7 @@ func! Test_normal21_nv_hat() " clean up set nohidden bw! -endfu +endfunc func! Test_normal22_zet() " Test for ZZ @@ -1189,7 +1217,7 @@ func! Test_normal22_zet() call delete(file) endfor " let &shell = shell -endfu +endfunc func! Test_normal23_K() " Test for K command @@ -1224,7 +1252,7 @@ func! Test_normal23_K() " clean up let &keywordprg = k bw! -endfu +endfunc func! Test_normal24_rot13() " This test uses multi byte characters @@ -1242,7 +1270,7 @@ func! Test_normal24_rot13() " clean up bw! -endfu +endfunc func! Test_normal25_tag() " Testing for CTRL-] g CTRL-] g] @@ -1309,7 +1337,7 @@ func! Test_normal25_tag() " clean up helpclose -endfu +endfunc func! Test_normal26_put() " Test for ]p ]P [p and [P @@ -1328,7 +1356,7 @@ func! Test_normal26_put() " clean up bw! -endfu +endfunc func! Test_normal27_bracket() " Test for [' [` ]' ]` @@ -1379,7 +1407,7 @@ func! Test_normal27_bracket() " clean up bw! -endfu +endfunc func! Test_normal28_parenthesis() " basic testing for ( and ) @@ -1402,7 +1430,7 @@ func! Test_normal28_parenthesis() " clean up bw! -endfu +endfunc fun! Test_normal29_brace() " basic test for { and } movements @@ -1477,7 +1505,7 @@ fun! Test_normal29_brace() " clean up set cpo-={ bw! -endfu +endfunc fun! Test_normal30_changecase() " This test uses multi byte characters @@ -1505,7 +1533,7 @@ fun! Test_normal30_changecase() " clean up bw! -endfu +endfunc fun! Test_normal31_r_cmd() " Test for r command @@ -1530,7 +1558,7 @@ fun! Test_normal31_r_cmd() " clean up set noautoindent bw! -endfu +endfunc func! Test_normal32_g_cmd1() " Test for g*, g# @@ -1546,7 +1574,7 @@ func! Test_normal32_g_cmd1() " clean up bw! -endfu +endfunc fun! Test_normal33_g_cmd2() if !has("jumplist") @@ -1666,7 +1694,7 @@ fun! Test_normal33_g_cmd2() " clean up bw! -endfu +endfunc fun! Test_normal34_g_cmd3() if !has("multi_byte") @@ -1682,7 +1710,7 @@ fun! Test_normal34_g_cmd3() call append(1, range(1,10)) " clean up bw! -endfu +endfunc fun! Test_normal35_g_cmd4() " Test for g< @@ -1692,7 +1720,7 @@ fun! Test_normal35_g_cmd4() echo "a\nb\nc\nd" let b=execute(':norm! g<') call assert_true(!empty(b), 'failed `execute(g<)`') -endfu +endfunc fun! Test_normal36_g_cmd5() new @@ -1730,7 +1758,7 @@ fun! Test_normal36_g_cmd5() call assert_equal([0, 14, 1, 0, 2147483647], getcurpos()) " clean up bw! -endfu +endfunc fun! Test_normal37_g_cmd6() " basic test for gt and gT @@ -1757,7 +1785,7 @@ fun! Test_normal37_g_cmd6() endfor " clean up call assert_fails(':tabclose', 'E784') -endfu +endfunc fun! Test_normal38_nvhome() " Test for and key @@ -1778,7 +1806,7 @@ fun! Test_normal38_nvhome() " clean up bw! -endfu +endfunc fun! Test_normal39_cw() " Test for cw and cW on whitespace @@ -1802,7 +1830,7 @@ fun! Test_normal39_cw() " clean up bw! -endfu +endfunc fun! Test_normal40_ctrl_bsl() " Basic test for CTRL-\ commands @@ -1827,7 +1855,7 @@ fun! Test_normal40_ctrl_bsl() " clean up bw! -endfu +endfunc fun! Test_normal41_insert_reg() " Test for =, = and = @@ -1847,7 +1875,7 @@ fun! Test_normal41_insert_reg() " clean up set sts=0 sw=8 ts=8 bw! -endfu +endfunc func! Test_normal42_halfpage() " basic test for Ctrl-D and Ctrl-U @@ -1884,7 +1912,7 @@ func! Test_normal42_halfpage() " cleanup set startofline bw! -endfu +endfunc fun! Test_normal43_textobject1() " basic tests for text object aw @@ -1915,7 +1943,7 @@ fun! Test_normal43_textobject1() " clean up bw! -endfu +endfunc func! Test_normal44_textobjects2() " basic testing for is and as text objects @@ -1970,7 +1998,7 @@ func! Test_normal44_textobjects2() " clean up bw! -endfu +endfunc func! Test_normal45_drop() if !has("dnd") @@ -1985,9 +2013,14 @@ func! Test_normal45_drop() " the ~ register is read only call assert_fails(':let @~="1"', 'E354') bw! -endfu +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 @@ -1995,9 +2028,16 @@ func! Test_normal46_ignore() call feedkeys("\", 't') call assert_equal([''], getline(1,'$')) + " no valid commands + exe "norm! \" + call assert_equal([''], getline(1,'$')) + + exe "norm! ä" + call assert_equal([''], getline(1,'$')) + " clean up bw! -endfu +endfunc func! Test_normal47_visual_buf_wipe() " This was causing a crash or ml_get error. @@ -2011,4 +2051,159 @@ func! Test_normal47_visual_buf_wipe() bw! norm yp set nomodified -endfu +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" + call assert_equal(1, winnr('$')) + call assert_fails(":norm! \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("\", 'tm') + + " should also fail with E11 + call assert_fails(":wincmd p", 'E11') + " return from commandline window + call feedkeys("\") + 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 :call feedkeys("\", '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("\", 'tx') + call assert_equal(18, col('.')) + call feedkeys("\", 'tx') + call assert_equal(13, col('.')) + call feedkeys("\", 'tx') + call assert_equal(7, col('.')) + call feedkeys("\", 'tx') + call assert_equal(13, col('.')) + call feedkeys("\", '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\!!" + call assert_equal(9, col('.')) + set cpo+=D + exe "norm! 1gg0f\!!" + call assert_equal(1, col('.')) + + set cpo-=D + bw! +endfunc + +func! Test_normal54_Ctrl_bsl() + new + call setline(1, 'abcdefghijklmn') + exe "norm! df\\" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + exe "norm! df\\" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + exe "norm! df\m" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + if !has("multi_byte") + return + endif + call setline(2, 'abcdefghijklmnāf') + norm! 2gg0 + exe "norm! df\" + call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) + norm! 1gg0 + exe "norm! df\" + call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) + + " clean up + bw! +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index b652f5fee5..e79d7a0faa 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -88,7 +88,7 @@ static int included_patches[] = { // 2356, // 2355, // 2354, - // 2353, + 2353, // 2352 NA // 2351 NA // 2350, -- cgit From 151605cacc5939299e0a2ac44477396a56a6e083 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 11:53:56 +0100 Subject: vim-patch:8.0.0060 Problem: When using an Ex command for 'keywordprg' it is escaped as with a shell command. (Romain Lafourcade) Solution: Escape for an Ex command. (closes vim/vim#1175) https://github.com/vim/vim/commit/426f3754223c8ff8a1bc51d6ba1eba11e8982ebc --- src/nvim/normal.c | 9 +++++++-- src/nvim/testdir/test_normal.vim | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index ce286042df..49085a27a0 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4763,9 +4763,14 @@ 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 */ ptr = vim_strnsave(ptr, n); - p = vim_strsave_shellescape(ptr, true, true); + if (kp_ex) { + // Escape the argument properly for an Ex command + p = vim_strsave_fnameescape(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; diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index f896046d4b..20cbaa00f0 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -1222,7 +1222,7 @@ endfunc func! Test_normal23_K() " Test for K command new - call append(0, ['version8.txt', 'man']) + call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd']) let k = &keywordprg set keywordprg=:help 1 @@ -1237,6 +1237,24 @@ func! Test_normal23_K() call assert_match('\*version8\.0\*', 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! + 4 + norm! K + call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t')) + bwipe! + set iskeyword-=% + set iskeyword-=\| + " Only expect "man" to work on Unix if !has("unix") let &keywordprg = k -- cgit From 88dd2e8a085f88bb8b3c7ded86d5d0ac1ebaf58b Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 11:58:57 +0100 Subject: vim-patch:8.0.0064 Problem: Normal test fails on MS-Windows. Solution: Don't try using an illegal file name. https://github.com/vim/vim/commit/eb828d01d9c91791fa1fe217ba651cdc25746d1b --- src/nvim/testdir/test_normal.vim | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 20cbaa00f0..4dafe3c105 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -1248,10 +1248,12 @@ func! Test_normal23_K() norm! K call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t')) bwipe! - 4 - norm! K - call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t')) - bwipe! + if !has('win32') + 4 + norm! K + call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t')) + bwipe! + endif set iskeyword-=% set iskeyword-=\| -- cgit From a4f20db08ce2824d3a63b5ae50aabbea14830ac2 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 12:00:36 +0100 Subject: vim-patch:8.0.0066 Problem: when calling an operator function when 'linebreak' is set, it is internally reset before calling the operator function. Solution: Restore 'linebreak' before calling op_function(). (Christian Brabandt) https://github.com/vim/vim/commit/4a08b0dc4dd70334056fc1bf069b5e938f2ed7d5 --- src/nvim/normal.c | 3 +++ src/nvim/testdir/test_normal.vim | 47 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 49085a27a0..489eec8474 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1914,6 +1914,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) break; case OP_FUNCTION: + // Restore linebreak, so that when the user edits it looks as + // before. + curwin->w_p_lbr = lbr_saved; op_function(oap); /* call 'operatorfunc' */ break; diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 4dafe3c105..29bd783ebc 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -35,8 +35,20 @@ func! CountSpaces(type, ...) let @@ = reg_save endfunc -func! IsWindows() - return has("win32") || has("win64") || has("win95") +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() @@ -147,7 +159,7 @@ endfunc func! Test_normal04_filter() " basic filter test " only test on non windows platform - if IsWindows() + if has('win32') return endif call Setup_NewWindow() @@ -210,7 +222,7 @@ endfunc func! Test_normal06_formatprg() " basic test for formatprg " only test on non windows platform - if IsWindows() + if has('win32') return else " uses sed to number non-empty lines @@ -325,10 +337,37 @@ func! Test_normal09_operatorfunc() norm V10j,, call assert_equal(22, g:a) + " clean up + unmap ,, + 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 ,, :set opfunc=OpfuncDummyg@ + 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 ,, set opfunc= bw! + unlet! g:opt endfunc func! Test_normal10_expand() -- cgit From 86b1e7f5834d58eebc87735c9a531040fea1a0f7 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 13:42:06 +0100 Subject: vim-patch:7.4.2362 Problem: Illegal memory access with ":1@". (Dominique Pelle) Solution: Correct cursor column after setting the line number. Also avoid calling end_visual_mode() when not in Visual mode. https://github.com/vim/vim/commit/4930a76a0357f76a829eafe4985d04cf3ce0e9e0 --- src/nvim/buffer.c | 4 ++-- src/nvim/ex_docmd.c | 1 + src/nvim/version.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0a95cc9020..f97f05e697 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -441,7 +441,7 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) // When closing the current buffer stop Visual mode before freeing // anything. - if (is_curbuf) { + if (is_curbuf && VIsual_active) { end_visual_mode(); } @@ -1083,7 +1083,7 @@ do_buffer ( } // When closing the current buffer stop Visual mode. - if (buf == curbuf) { + if (buf == curbuf && VIsual_active) { end_visual_mode(); } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 1234f8e888..bd3b8c204a 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7325,6 +7325,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; diff --git a/src/nvim/version.c b/src/nvim/version.c index e79d7a0faa..7d44efb401 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -79,7 +79,7 @@ static int included_patches[] = { // 2365 NA // 2364, // 2363 NA - // 2362, + 2362, // 2361 NA // 2360, // 2359 NA -- cgit From 2ad25c04663da7d08da94db84dc6ded7df11ea87 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 14:41:34 +0100 Subject: linter: make changes pass the linter --- src/nvim/cursor.c | 8 +++++--- src/nvim/move.c | 3 ++- src/nvim/normal.c | 6 +++--- src/nvim/ops.c | 14 +++++++------- 4 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 01476627de..544bcf6ede 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -296,7 +296,8 @@ linenr_T get_cursor_rel_lnum(win_T *wp, linenr_T lnum) // 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) { +void check_pos(buf_T *buf, pos_T *pos) +{ char_u *line; colnr_T len; @@ -305,10 +306,11 @@ void check_pos(buf_T *buf, pos_T *pos) { } if (pos->col > 0) { - line = ml_get_buf(buf, pos->lnum, FALSE); + line = ml_get_buf(buf, pos->lnum, false); len = (colnr_T)STRLEN(line); - if (pos->col > len) + if (pos->col > len) { pos->col = len; + } } } diff --git a/src/nvim/move.c b/src/nvim/move.c index 9ba515f209..4c3f82bc16 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1878,8 +1878,9 @@ int onepage(int dir, long count) } foldAdjustCursor(); check_cursor_col(); - if (retval == OK) + if (retval == OK) { beginline(BL_SOL | BL_FIX); + } curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL); /* diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 489eec8474..5a89fed207 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1917,7 +1917,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) // Restore linebreak, so that when the user edits it looks as // before. curwin->w_p_lbr = lbr_saved; - op_function(oap); /* call 'operatorfunc' */ + op_function(oap); // call 'operatorfunc' break; case OP_INSERT: @@ -4769,10 +4769,10 @@ static void nv_ident(cmdarg_T *cap) ptr = vim_strnsave(ptr, n); if (kp_ex) { // Escape the argument properly for an Ex command - p = vim_strsave_fnameescape(ptr, FALSE); + p = vim_strsave_fnameescape(ptr, false); } else { // Escape the argument properly for a shell command - p = vim_strsave_shellescape(ptr, TRUE, TRUE); + p = vim_strsave_shellescape(ptr, true, true); } xfree(ptr); char *newbuf = xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 3a682b6f96..c13b6f736a 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3862,14 +3862,14 @@ fex_format ( if (fex == NULL) { return 0; } - /* - * Evaluate the function. - */ - if (use_sandbox) - ++sandbox; + // Evaluate the function. + if (use_sandbox) { + sandbox++; + } r = (int)eval_to_number(fex); - if (use_sandbox) - --sandbox; + if (use_sandbox) { + sandbox--; + } set_vim_var_string(VV_CHAR, NULL, -1); xfree(fex); -- cgit From 0f5c3f111ab130f5cbb5943082ea5e877c1c2f4c Mon Sep 17 00:00:00 2001 From: raichoo Date: Thu, 9 Mar 2017 17:33:51 +0100 Subject: vim-patch:8.0.0179 Problem: 'formatprg' is a global option but the value may depend on the type of buffer. (Sung Pae) Solution: Make 'formatprg' global-local. (closes vim/vim#1380) https://github.com/vim/vim/commit/9be7c04e6cd5b0facedcb56b09a5bcfc339efe03 --- src/nvim/buffer_defs.h | 1 + src/nvim/normal.c | 22 +++++++++++++--------- src/nvim/option.c | 8 ++++++++ src/nvim/option_defs.h | 1 + src/nvim/options.lua | 2 +- src/nvim/testdir/test_normal.vim | 32 ++++++++++++++++++++++---------- 6 files changed, 46 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 3e9767adde..fdd7d945c9 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -640,6 +640,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' diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 5a89fed207..82fa9f5f97 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1901,12 +1901,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: @@ -2064,10 +2065,13 @@ static void op_colon(oparg_T *oap) stuffReadbuff(get_equalprg()); stuffReadbuff((char_u *)"\n"); } else if (oap->op_type == OP_FORMAT) { - if (*p_fp == NUL) - stuffReadbuff((char_u *)"fmt"); - else + if (*curbuf->b_p_fp != NUL) { + stuffReadbuff(curbuf->b_p_fp); + } else if (*p_fp != NUL) { stuffReadbuff(p_fp); + } else { + stuffReadbuff((char_u *)"fmt"); + } stuffReadbuff((char_u *)"\n']"); } diff --git a/src/nvim/option.c b/src/nvim/option.c index 2fae4aa848..2a17ca69d1 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2150,6 +2150,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); @@ -5255,6 +5256,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; @@ -5288,6 +5292,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); @@ -5346,6 +5351,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 @@ -5694,6 +5701,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); diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 1fd6dc9c91..b171b23edb 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -713,6 +713,7 @@ enum { , BV_EP , BV_ET , BV_FENC + , BV_FP , BV_BEXPR , BV_FEX , BV_FF diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 1476fdda2c..853c2b52d7 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -948,7 +948,7 @@ return { }, { full_name='formatprg', abbreviation='fp', - type='string', scope={'global'}, + type='string', scope={'global', 'buffer'}, secure=true, vi_def=true, expand=true, diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 29bd783ebc..98177851ab 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -224,21 +224,33 @@ func! Test_normal06_formatprg() " only test on non windows platform if has('win32') return - else - " 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') endif - call Setup_NewWindow() - %d - call setline(1, ['a', '', 'c', '', ' ', 'd', 'e']) + + " 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(['1 a', '', '3 c', '', '5 ', '6 d', '7 e'], getline(1, '$')) + 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') - bw! endfunc func! Test_normal07_internalfmt() @@ -251,7 +263,7 @@ func! Test_normal07_internalfmt() norm! gggqG call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$')) " clean up - set formatprg= tw=0 + set tw=0 bw! endfunc -- cgit From 99f2dc1341c8501290e3a0b297e1700f74fd17a3 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sat, 11 Mar 2017 16:43:15 +0100 Subject: vim-patch:8.0.0229 Problem: When freeing a buffer the local value of the 'formatprg' option is not cleared. Solution: Add missing change. https://github.com/vim/vim/commit/24a2d416ec261829ff7fd29f7b66739c96dd6513 --- src/nvim/buffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f97f05e697..ab45008962 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1679,6 +1679,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); -- cgit From db128974fcbd5702ca724610590a5dafa2e87712 Mon Sep 17 00:00:00 2001 From: raichoo Date: Thu, 16 Mar 2017 07:40:31 +0100 Subject: vim-patch:7.4.2348 Problem: Crash on exit when EXITFREE is defined. (Dominique Pelle) Solution: Don't access curwin when exiting. https://github.com/vim/vim/commit/9a27c7fde6d453d9892b6f6baa756bce4d6d419d --- src/nvim/buffer.c | 6 +++++- src/nvim/version.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ab45008962..9e781f5dff 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -441,7 +441,11 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) // When closing the current buffer stop Visual mode before freeing // anything. - if (is_curbuf && VIsual_active) { + if (is_curbuf && VIsual_active +#if defined(EXITFREE) + && !entered_free_all_mem +#endif + ) { end_visual_mode(); } diff --git a/src/nvim/version.c b/src/nvim/version.c index 7d44efb401..8fd0fce329 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -93,7 +93,7 @@ static int included_patches[] = { // 2351 NA // 2350, // 2349, - // 2348, + 2348, 2347, // 2346, // 2345 NA -- cgit From 2f54d6927cc02484b528a5e8b25b64c8d6580ddd Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 19 Mar 2017 23:45:11 +0100 Subject: test/legacy: fix test_normal.vim --- src/nvim/normal.c | 6 ++-- src/nvim/testdir/runtest.vim | 4 +-- src/nvim/testdir/test_normal.vim | 72 ++++++++++++++++++++++------------------ 3 files changed, 43 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 82fa9f5f97..7188e13436 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4766,10 +4766,8 @@ static void nv_ident(cmdarg_T *cap) } } - /* - * Now grab the chars in the identifier - */ - if (cmdchar == 'K' && !kp_ex) { + // Now grab the chars in the identifier + if (cmdchar == 'K') { ptr = vim_strnsave(ptr, n); if (kp_ex) { // Escape the argument properly for an Ex command diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index 0403a53f9c..b4eb9de506 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -68,10 +68,10 @@ let $HOME = '/does/not/exist' " Prepare for calling garbagecollect_for_testing(). let v:testing = 1 -" Align with vim defaults. +" Align Nvim defaults to Vim. set directory^=. -set nohidden set backspace= +set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd function RunTheTest(test) echo 'Executing ' . a:test diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 98177851ab..29a7c1edd8 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -69,9 +69,10 @@ fun! Test_normal00_optrans() 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,'$')) - 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,'$')) + " 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-=# @@ -79,6 +80,7 @@ fun! Test_normal00_optrans() endfunc func! Test_normal01_keymodel() + throw "skipped: Nvim regression: 'keymodel'" call Setup_NewWindow() " Test 1: depending on 'keymodel' does something different 50 @@ -431,6 +433,7 @@ func! Test_normal13_help() endfunc func! Test_normal14_page() + throw "skipped: Nvim regression: CTRL-F with 'scrolloff'" " basic test for Ctrl-F and Ctrl-B call Setup_NewWindow() exe "norm! \" @@ -1067,6 +1070,7 @@ func! Test_normal18_z_fold() endfunc func! Test_normal19_z_spell() + throw "skipped: Nvim 'spell' requires download" if !has("spell") || !has('syntax') return endif @@ -1253,7 +1257,7 @@ func! Test_normal22_zet() " let shell = &shell " let &shell = 'sh' call writefile(['1', '2'], 'Xfile') - let args = ' -u NONE -N -U NONE -i NONE --noplugins -X --not-a-term' + let args = ' --headless -u NONE -N -U NONE -i NONE --noplugins' call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile') let a = readfile('Xfile') call assert_equal([], a) @@ -1273,19 +1277,19 @@ endfunc func! Test_normal23_K() " Test for K command new - call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd']) + call append(0, ['helphelp.txt', 'man', 'aa%bb', 'cc|dd']) let k = &keywordprg set keywordprg=:help 1 norm! VK - call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t')) + call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t')) call assert_equal('help', &ft) - call assert_match('\*version8.txt\*', getline('.')) + call assert_match('\*helphelp.txt\*', getline('.')) helpclose norm! 0K - call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t')) + call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t')) call assert_equal('help', &ft) - call assert_match('\*version8\.0\*', getline('.')) + call assert_match('Help on help files', getline('.')) helpclose set keywordprg=:new @@ -1554,24 +1558,25 @@ fun! Test_normal29_brace() " Test with { in cpooptions %d call append(0, text) - 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,'$')) + " 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-={ @@ -1889,12 +1894,13 @@ fun! Test_normal39_cw() call assert_equal('hereZZZare some words', getline('.')) norm! 1gg0elcWYYY call assert_equal('hereZZZareYYYsome words', getline('.')) - 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('.')) + " 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('.')) -- cgit From 058516aaf9c29b41bf27c8d4adfa2773c3896205 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 19 Mar 2017 13:24:45 -0400 Subject: vim-patch:8.0.0190 Problem: Detecting duplicate tags uses a slow linear search. Solution: Use a much faster hash table solution. (James McCoy, closes vim/vim#1046) But don't add hi_keylen, it makes hash tables 50% bigger. https://github.com/vim/vim/commit/810f9c361c83afb36b9f1cdadca2b93f1201d039 --- src/nvim/tag.c | 243 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 118 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 9c9f24b9c0..c3c2634598 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -73,9 +73,9 @@ typedef struct { } 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 + * The matching tags are first stored in one of the ht_match[] hash tables. In + * which one depends on the priority of the match. + * At the end, the matches from ht_match[] are concatenated, to make a list * sorted on priority. */ #define MT_ST_CUR 0 /* static match in current file */ @@ -1122,11 +1122,9 @@ 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]; + char_u *mfp; + hashtab_T ht_match[MT_COUNT]; + hash_T hash = 0; int match_count = 0; /* number of matches found */ char_u **matches; int mtt; @@ -1186,7 +1184,7 @@ 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); + hash_init(&ht_match[mtt]); STRCPY(tag_fname, "from cscope"); /* for error messages */ @@ -1752,9 +1750,11 @@ parse_line: } /* - * If a match is found, add it to ga_match[]. + * If a match is found, add it to ht_match[]. */ if (match) { + int len = 0; + if (use_cscope) { /* Don't change the ordering, always use the same table. */ mtt = MT_GL_OTH; @@ -1790,116 +1790,102 @@ parse_line: } /* - * Add the found match in ga_match[mtt], avoiding duplicates. + * Add the found match in ht_match[mtt]. * 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) { + 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; - } 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; - } + // 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); + 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(char_u) + len + 1); + STRLCPY(mfp, tagp.command + 2, len + 1); + } else + mfp = NULL; + get_it_again = FALSE; } else { - /* Save the tag in a buffer. - * Emacs tag: - * other tag: - * without Emacs tags: - */ - 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 0x01 + size_t tag_fname_len = STRLEN(tag_fname); + /* Save the tag in a buffer. + * Use 0x01 to separate fields (Can't use NUL, because the + * hash key is terminated by NUL). + * Emacs tag: + * other tag: + * without Emacs tags: + */ + len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3; + mfp = xmalloc(sizeof(char_u) + len + 1); + p = mfp; + p[0] = mtt; + STRCPY(p + 1, tag_fname); #ifdef BACKSLASH_IN_FILENAME - /* Ignore differences in slashes, avoid adding - * both path/file and path\file. */ - slash_adjust(p + 1); + /* 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)) - [ga_match[mtt].ga_len++] = mfp; - ++match_count; - } else - xfree(mfp); - } + 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); + ++match_count; + } else + // duplicate tag, drop it + xfree(mfp); } } if (use_cscope && eof) @@ -1962,7 +1948,7 @@ findtag_end: xfree(tag_fname); /* - * Move the matches from the ga_match[] arrays into one list of + * Move the matches from the ht_match[] arrays into one list of * matches. When retval == FAIL, free the matches. */ if (retval == FAIL) @@ -1974,20 +1960,27 @@ findtag_end: 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) - 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))); - matches[match_count++] = (char_u *)mfp; + hashitem_T *hi; + long todo = (long)ht_match[mtt].ht_used; + + for (hi = ht_match[mtt].ht_array; todo > 0; hi++) { + if (!HASHITEM_EMPTY(hi)) { + mfp = hi->hi_key; + if (matches == NULL) { + xfree(mfp); + } else { + // now change the TAG_SEP back to NUL + for (p = mfp; *p != NUL; p++) { + if (*p == TAG_SEP) { + *p = NUL; + } + } + matches[match_count++] = (char_u *)mfp; + } + todo--; } } - ga_clear(&ga_match[mtt]); + hash_clear(&ht_match[mtt]); } *matchesp = matches; -- cgit From e1af49b425f25024a3e6361ed576cf69296a1da4 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 19 Mar 2017 14:50:00 -0400 Subject: vim-patch:8.0.0195 Problem: Jumping to a tag that is a static item in the current file fails. (Kazunobu Kuriyama) Solution: Make sure the first byte of the tag key is not NUL. (Suggested by James McCoy, closes vim/vim#1387) https://github.com/vim/vim/commit/a9d23c20879d0dcb289a4db54b3c7df060f87c3c --- src/nvim/tag.c | 22 ++++++++++++---------- src/nvim/testdir/test_tagjump.vim | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index c3c2634598..92a535ab91 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -82,10 +82,6 @@ typedef struct { #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 */ @@ -1826,7 +1822,7 @@ parse_line: if (tagp.command + 2 < temp_end) { len = (int)(temp_end - tagp.command - 2); - mfp = xmalloc(sizeof(char_u) + len + 1); + mfp = xmalloc(len + 2); STRLCPY(mfp, tagp.command + 2, len + 1); } else mfp = NULL; @@ -1849,11 +1845,12 @@ parse_line: * Emacs tag: * other tag: * without Emacs tags: + * Here 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; + p[0] = mtt + 1; STRCPY(p + 1, tag_fname); #ifdef BACKSLASH_IN_FILENAME /* Ignore differences in slashes, avoid adding @@ -1969,10 +1966,15 @@ findtag_end: if (matches == NULL) { xfree(mfp); } else { - // now change the TAG_SEP back to NUL - for (p = mfp; *p != NUL; p++) { - if (*p == TAG_SEP) { - *p = NUL; + 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; diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 678ad0ada8..54b5f4afd6 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -23,4 +23,22 @@ func Test_cancel_ptjump() 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('.')) + + set tags& + call delete('Xtags') + call delete('Xfile1') + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab -- cgit From d3f15f1e6d299796bd552896c0ba01a7cca58618 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 19 Mar 2017 15:08:26 -0400 Subject: vim-patch:8.0.0223 Problem: Coverity gets confused by the flags passed to find_tags() and warnts for an uninitialized variable. Solution: Disallow using cscope and help tags at the same time. https://github.com/vim/vim/commit/fffbf308dd98d1129ba4914d921ab47dc6a6c9b1 --- src/nvim/tag.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 92a535ab91..1cbf789270 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1057,6 +1057,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 ( @@ -1189,6 +1190,11 @@ find_tags ( */ 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) { -- cgit From 097d04ac71499f5ba0126ab6f731d4f4af0a4e84 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 19 Mar 2017 15:10:27 -0400 Subject: vim-patch:8.0.0393 Problem: When the same tag appears more than once, the order is unpredictable. (Charles Campbell) Solution: Besides using a dict for finding duplicates, use a grow array for keeping the tags in sequence. https://github.com/vim/vim/commit/98e83b295628bc29bc67bcc1adb8ae75d01b8e07 --- src/nvim/tag.c | 57 ++++++++++++++++++++------------------- src/nvim/testdir/test_tagjump.vim | 24 +++++++++++++++++ 2 files changed, 54 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 1cbf789270..0d5008b4ce 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -73,9 +73,10 @@ typedef struct { } pat_T; /* - * The matching tags are first stored in one of the ht_match[] hash tables. In + * The matching tags are first stored in one of the hash tables. In * which one depends on the priority of the match. - * At the end, the matches from ht_match[] are concatenated, to make a list + * 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 */ @@ -1120,7 +1121,8 @@ find_tags ( char_u *mfp; - hashtab_T ht_match[MT_COUNT]; + 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; @@ -1180,8 +1182,10 @@ find_tags ( */ lbuf = xmalloc(lbuf_size); tag_fname = xmalloc(MAXPATHL + 1); - for (mtt = 0; mtt < MT_COUNT; ++mtt) + 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 */ @@ -1752,7 +1756,7 @@ parse_line: } /* - * If a match is found, add it to ht_match[]. + * If a match is found, add it to ht_match[] and ga_match[]. */ if (match) { int len = 0; @@ -1792,7 +1796,7 @@ parse_line: } /* - * Add the found match in ht_match[mtt]. + * 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. */ @@ -1885,6 +1889,9 @@ parse_line: 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 // duplicate tag, drop it @@ -1951,7 +1958,7 @@ findtag_end: xfree(tag_fname); /* - * Move the matches from the ht_match[] arrays into one list of + * Move the matches from the ga_match[] arrays into one list of * matches. When retval == FAIL, free the matches. */ if (retval == FAIL) @@ -1963,31 +1970,27 @@ findtag_end: matches = NULL; match_count = 0; for (mtt = 0; mtt < MT_COUNT; ++mtt) { - hashitem_T *hi; - long todo = (long)ht_match[mtt].ht_used; - - for (hi = ht_match[mtt].ht_array; todo > 0; hi++) { - if (!HASHITEM_EMPTY(hi)) { - mfp = hi->hi_key; - if (matches == NULL) { - xfree(mfp); - } 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; - } + 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 { + 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; } - todo--; + matches[match_count++] = (char_u *)mfp; } } + + ga_clear(&ga_match[mtt]); hash_clear(&ht_match[mtt]); } diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 54b5f4afd6..2044c23f79 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -35,10 +35,34 @@ func Test_static_tagjump() 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 " vim: shiftwidth=2 sts=2 expandtab -- cgit From a56615214dbbc4b2f9cf38f65f95172a2ef06289 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 19 Mar 2017 21:00:45 -0400 Subject: lint --- src/nvim/tag.c | 118 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 0d5008b4ce..7bcaff662c 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -72,20 +72,18 @@ typedef struct { regmatch_T regmatch; /* regexp program, may be NULL */ } pat_T; -/* - * 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 */ +// 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] = @@ -1124,14 +1122,14 @@ find_tags ( 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 */ + 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 */ @@ -1182,7 +1180,7 @@ find_tags ( */ lbuf = xmalloc(lbuf_size); tag_fname = xmalloc(MAXPATHL + 1); - for (mtt = 0; mtt < MT_COUNT; ++mtt) { + for (mtt = 0; mtt < MT_COUNT; mtt++) { ga_init(&ga_match[mtt], sizeof(char_u *), 100); hash_init(&ht_match[mtt]); } @@ -1192,9 +1190,9 @@ find_tags ( /* * Initialize a few variables */ - if (help_only) /* want tags from help file */ - curbuf->b_help = true; /* will be restored later */ - else if (use_cscope) { + 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; @@ -1264,13 +1262,14 @@ find_tags ( if (is_txt) { STRCPY(help_lang, "en"); } else { - /* Prefer help tags according to 'helplang'. Put the - * two-letter language name in help_lang[]. */ + // 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] == '-') + if (i > 3 && tag_fname[i - 3] == '-') { STRCPY(help_lang, tag_fname + i - 2); - else + } else { STRCPY(help_lang, "en"); + } } /* When searching for a specific language skip tags files @@ -1755,9 +1754,7 @@ parse_line: match_re = TRUE; } - /* - * If a match is found, add it to ht_match[] and ga_match[]. - */ + // If a match is found, add it to ht_match[] and ga_match[]. if (match) { int len = 0; @@ -1795,11 +1792,9 @@ parse_line: mtt += MT_RE_OFF; } - /* - * Add the found match in ht_match[mtt] and ga_match[mtt]. - * Store the info we need later, which depends on the kind of - * tags we are dealing with. - */ + // 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 @@ -1814,57 +1809,60 @@ parse_line: 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); + 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 == '/') + if (*temp_end == '/') { while (*temp_end && *temp_end != '\r' && *temp_end != '\n' - && *temp_end != '$') + && *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 + } else { mfp = NULL; - get_it_again = FALSE; + } + get_it_again = false; } else { 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) + // if wanted, re-read line to get long form too + if (State & INSERT) { get_it_again = p_sft; + } } } else { #define TAG_SEP 0x01 size_t tag_fname_len = STRLEN(tag_fname); - /* Save the tag in a buffer. - * Use 0x01 to separate fields (Can't use NUL, because the - * hash key is terminated by NUL). - * Emacs tag: - * other tag: - * without Emacs tags: - * Here is the "mtt" value plus 1 to avoid NUL. - */ + // Save the tag in a buffer. + // Use 0x01 to separate fields (Can't use NUL, because the + // hash key is terminated by NUL). + // Emacs tag: + // other tag: + // without Emacs tags: + // Here 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. */ + // Ignore differences in slashes, avoid adding + // both path/file and path\file. slash_adjust(p + 1); #endif p[tag_fname_len + 1] = TAG_SEP; @@ -1881,10 +1879,11 @@ parse_line: // the part matters for comparing, more bytes may follow // after it. E.g. help tags store the priority after the // NUL. - if (use_cscope) + if (use_cscope) { hash++; - else + } else { hash = hash_hash(mfp); + } hi = hash_lookup(&ht_match[mtt], (const char *)mfp, STRLEN(mfp), hash); if (HASHITEM_EMPTY(hi)) { @@ -1892,10 +1891,11 @@ parse_line: ga_grow(&ga_match[mtt], 1); ((char_u **)(ga_match[mtt].ga_data)) [ga_match[mtt].ga_len++] = mfp; - ++match_count; - } else + match_count++; + } else { // duplicate tag, drop it xfree(mfp); + } } } if (use_cscope && eof) @@ -1969,7 +1969,7 @@ findtag_end: else matches = NULL; match_count = 0; - for (mtt = 0; mtt < MT_COUNT; ++mtt) { + 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) { -- cgit From 8924e75f3477b20f0ef4e3df64b56bf496b197ae Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Thu, 2 Mar 2017 23:04:57 +0100 Subject: vim-patch:7.4.2170 Problem: Cannot get information about timers. Solution: Add timer_info(). https://github.com/vim/vim/commit/8e97bd74b5377753597e3d98e7123d8985c7fffd --- src/nvim/eval.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nvim/eval.lua | 1 + src/nvim/version.c | 2 +- 3 files changed, 57 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d4daffb469..537e9e696f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17931,6 +17931,61 @@ 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 = dict_alloc(); + + list_append_dict(list, dict); + dict_add_nr_str(dict, "id", (long)timer->timer_id, NULL); + dict_add_nr_str(dict, "time", timer->timeout, NULL); + + dict_add_nr_str(dict, "repeat", + (long)(timer->repeat_count < 0 ? -1 : timer->repeat_count), + NULL); + + dictitem_T *di = dictitem_alloc((char_u *)"callback"); + if (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, { + add_timer_info(rettv, timer); + }) +} + +/// "timer_info([timer])" function +static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + rettv_list_alloc(rettv); + if (argvars[0].v_type != VAR_UNKNOWN) { + if (argvars[0].v_type != VAR_NUMBER) { + EMSG(_(e_number_exp)); + } else { + timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0])); + if (timer != NULL) { + add_timer_info(rettv, timer); + } + } + } else { + add_timer_info_all(rettv); + } +} /// "timer_start(timeout, callback, opts)" function static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e3c5981b32..e923fee316 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -306,6 +306,7 @@ return { tempname={}, termopen={args={1, 2}}, test_garbagecollect_now={}, + timer_info={args={0,1}}, timer_start={args={2,3}}, timer_stop={args=1}, tolower={args=1}, diff --git a/src/nvim/version.c b/src/nvim/version.c index 8fd0fce329..b283059c7a 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -271,7 +271,7 @@ static int included_patches[] = { // 2173, // 2172, // 2171, - // 2170, + 2170, // 2169, // 2168 NA // 2167 NA -- cgit From 5b8ce2feed6b528bae4bceba6f234be000949971 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Sun, 5 Mar 2017 16:25:40 +0100 Subject: vim-patch:7.4.2180 Problem: There is no easy way to stop all timers. There is no way to temporary pause a timer. Solution: Add timer_stopall() and timer_pause(). https://github.com/vim/vim/commit/b73598e2f022a22fec512ea681c70d2775e8fd87 --- src/nvim/eval.c | 34 +++++++++++++--- src/nvim/eval.lua | 2 + src/nvim/testdir/shared.vim | 17 ++++++++ src/nvim/testdir/test_timers.vim | 86 +++++++++++++++++++++++++++++++++------- src/nvim/version.c | 2 +- 5 files changed, 120 insertions(+), 21 deletions(-) create mode 100644 src/nvim/testdir/shared.vim (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 537e9e696f..062999e73b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -446,6 +446,7 @@ typedef struct { int refcount; long timeout; bool stopped; + bool paused; Callback callback; } timer_T; @@ -17939,6 +17940,7 @@ static void add_timer_info(typval_T *rettv, timer_T *timer) list_append_dict(list, dict); dict_add_nr_str(dict, "id", (long)timer->timer_id, NULL); dict_add_nr_str(dict, "time", timer->timeout, NULL); + dict_add_nr_str(dict, "paused", (long)timer->paused, NULL); dict_add_nr_str(dict, "repeat", (long)(timer->repeat_count < 0 ? -1 : timer->repeat_count), @@ -17965,7 +17967,9 @@ static void add_timer_info_all(typval_T *rettv) { timer_T *timer; map_foreach_value(timers, timer, { - add_timer_info(rettv, timer); + if (!timer->stopped) { + add_timer_info(rettv, timer); + } }) } @@ -17978,7 +17982,7 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_number_exp)); } else { timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0])); - if (timer != NULL) { + if (timer != NULL && !timer->stopped) { add_timer_info(rettv, timer); } } @@ -17987,6 +17991,20 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } +/// "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)); + } else { + int paused = (bool)get_tv_number(&argvars[1]); + timer_T *timer = pmap_get(uint64_t)(timers, get_tv_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) { @@ -18019,6 +18037,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++; @@ -18028,8 +18047,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; @@ -18053,13 +18071,19 @@ 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_teardown(); +} + // 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) { diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e923fee316..d30d34135b 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -307,8 +307,10 @@ return { 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/testdir/shared.vim b/src/nvim/testdir/shared.vim new file mode 100644 index 0000000000..9573f5a9c3 --- /dev/null +++ b/src/nvim/testdir/shared.vim @@ -0,0 +1,17 @@ +" Functions shared by several tests. + +" Wait for up to a second for "expr" to become true. +" Return time slept in milliseconds. +func WaitFor(expr) + let slept = 0 + for i in range(100) + try + if eval(a:expr) + return slept + endif + catch + endtry + let slept += 10 + sleep 10m + endfor +endfunc diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 56f9feef66..b03295bd01 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,44 +15,98 @@ 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) + call assert_inrange(30, 100, slept) 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) + call assert_inrange(100, 250, slept) 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 g:val = 0 let s:meow = {} function s:meow.bite(...) - let s:val += 1 + let g:val += 1 endfunction call timer_start(50, s:meow.bite) - sleep 200m - call assert_equal(1, s:val) + let slept = WaitFor('g:val == 1') + call assert_equal(1, g:val) + call assert_inrange(30, 100, slept) 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) + call assert_inrange(0, 10, slept) endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index b283059c7a..4da970d43b 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -261,7 +261,7 @@ static int included_patches[] = { 2183, // 2182 NA // 2181, - // 2180, + 2180, // 2179, // 2178, // 2177, -- cgit From 420a9955fa969ee0460f41798c60c1374476fd08 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Mon, 6 Mar 2017 07:15:19 +0100 Subject: version.c: Mark 7.4.2171 and 7.4.2181 as NA. --- src/nvim/version.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index 4da970d43b..0bf0f10b56 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -260,7 +260,7 @@ static int included_patches[] = { // 2184, 2183, // 2182 NA - // 2181, + // 2181 NA 2180, // 2179, // 2178, @@ -270,7 +270,7 @@ static int included_patches[] = { 2174, // 2173, // 2172, - // 2171, + // 2171 NA 2170, // 2169, // 2168 NA -- cgit From 5c2f1e29e3dfdfab8c2a9b31962d9cc12c171e46 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Mon, 20 Mar 2017 20:52:54 +0100 Subject: vim-patch:7.4.2240 Problem: Tests using the sleep time can be flaky. Solution: Use reltime() if available. (Partly by Shane Harper) https://github.com/vim/vim/commit/f267f8bdf777073e392ada5b31d837c7b6090eb4 --- src/nvim/testdir/shared.vim | 21 ++++++++++++++++----- src/nvim/testdir/test_timers.vim | 24 ++++++++++++++++++++---- src/nvim/version.c | 2 +- 3 files changed, 37 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim index 9573f5a9c3..1138ceba4d 100644 --- a/src/nvim/testdir/shared.vim +++ b/src/nvim/testdir/shared.vim @@ -1,17 +1,28 @@ " Functions shared by several tests. -" Wait for up to a second for "expr" to become true. -" Return time slept in milliseconds. +" Return time slept in milliseconds. With the +reltime feature this can be +" more than the actual waiting time. Without +reltime it can also be less. func WaitFor(expr) - let slept = 0 + " 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) - return slept + if has('reltime') + return float2nr(reltimefloat(reltime(start)) * 1000) + endif + return slept endif catch endtry - let slept += 10 + if !has('reltime') + let slept += 10 + endif sleep 10m endfor + return 1000 endfunc diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index b03295bd01..2a5fa5c662 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -19,7 +19,11 @@ func Test_oneshot() let timer = timer_start(50, 'MyHandler') let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) - call assert_inrange(30, 100, slept) + if has('reltime') + call assert_inrange(50, 100, slept) + else + call assert_inrange(20, 100, slept) + endif endfunc func Test_repeat_three() @@ -27,7 +31,11 @@ func Test_repeat_three() let timer = timer_start(50, 'MyHandler', {'repeat': 3}) let slept = WaitFor('g:val == 3') call assert_equal(3, g:val) - call assert_inrange(100, 250, slept) + if has('reltime') + call assert_inrange(150, 200, slept) + else + call assert_inrange(80, 200, slept) + endif endfunc func Test_repeat_many() @@ -48,7 +56,11 @@ func Test_with_partial_callback() call timer_start(50, s:meow.bite) let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) - call assert_inrange(30, 100, slept) + if has('reltime') + call assert_inrange(50, 100, slept) + else + call assert_inrange(20, 100, slept) + endif endfunc func Test_retain_partial() @@ -106,7 +118,11 @@ func Test_paused() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) - call assert_inrange(0, 10, slept) + if has('reltime') + call assert_inrange(0, 30, slept) + else + call assert_inrange(0, 10, slept) + endif endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index 0bf0f10b56..ef6c9d1454 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -201,7 +201,7 @@ static int included_patches[] = { // 2243 NA // 2242, // 2241, - // 2240, + 2240, // 2239, // 2238 NA 2237, -- cgit From 3558f89d22faad613e0049592d2187ad35f5bec8 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Mon, 20 Mar 2017 21:11:24 +0100 Subject: vim-patch:7.4.2241 Problem: Timer test sometimes fails. Solution: Increase the maximum time for repeating timer. https://github.com/vim/vim/commit/973365dcc40a41e6b72ece56f15cebfee69b1329 --- src/nvim/testdir/test_timers.vim | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 2a5fa5c662..8829b5de59 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -32,7 +32,7 @@ func Test_repeat_three() let slept = WaitFor('g:val == 3') call assert_equal(3, g:val) if has('reltime') - call assert_inrange(150, 200, slept) + call assert_inrange(150, 250, slept) else call assert_inrange(80, 200, slept) endif diff --git a/src/nvim/version.c b/src/nvim/version.c index ef6c9d1454..b7516e443a 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -200,7 +200,7 @@ static int included_patches[] = { // 2244, // 2243 NA // 2242, - // 2241, + 2241, 2240, // 2239, // 2238 NA -- cgit From 4f69a8fb8854698adb2de8956ad0d86ff35a6f68 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Mon, 20 Mar 2017 21:12:31 +0100 Subject: vim-patch:7.4.2242 Problem: Timer test sometimes fails. Solution: Increase the maximum time for callback timer test. https://github.com/vim/vim/commit/17f1347b867cbcc0ce380bf9a2466b4c31896f04 --- src/nvim/testdir/test_timers.vim | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 8829b5de59..db10f351ae 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -57,7 +57,7 @@ func Test_with_partial_callback() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') - call assert_inrange(50, 100, slept) + call assert_inrange(50, 130, slept) else call assert_inrange(20, 100, slept) endif diff --git a/src/nvim/version.c b/src/nvim/version.c index b7516e443a..91c37658aa 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -199,7 +199,7 @@ static int included_patches[] = { // 2245, // 2244, // 2243 NA - // 2242, + 2242, 2241, 2240, // 2239, -- cgit From b4cb5fa610903492f89a70d0ae2d4565ddcd1228 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Tue, 7 Mar 2017 19:20:07 +0100 Subject: vim-patch:7.4.2266 Problem: printf() test fails on Windows. "-inf" is not used. Solution: Check for Windows-specific values for "nan". Add sign to "inf" when appropriate. https://github.com/vim/vim/commit/9992237a3e791fbc0c1ebf743ece1b75e1488410 --- src/nvim/strings.c | 22 ++++++++++++++++++++-- src/nvim/testdir/test_expr.vim | 8 +++----- src/nvim/version.c | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/strings.c b/src/nvim/strings.c index d03970108b..47ee311bd4 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1209,9 +1209,10 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, } if (fmt_spec == 'f' && abs_f > 1.0e307) { + const char inf_str[] = f < 0 ? "-inf" : "inf"; // avoid a buffer overflow - memmove(tmp, "inf", sizeof("inf")); - str_arg_l = sizeof("inf") - 1; + memmove(tmp, inf_str, sizeof(inf_str) - 1); + str_arg_l = sizeof(inf_str) - 1; } else { format[0] = '%'; int l = 1; @@ -1234,6 +1235,23 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); assert(str_arg_l < sizeof(tmp)); + // Be consistent: Change "1.#IND" to "nan" and + // "1.#INF" to "inf". + char *s = *tmp == '-' ? tmp + 1 : tmp; + if (STRNCMP(s, "1.#INF", 6) == 0) { + STRCPY(s, "inf"); + } else if (STRNCMP(s, "1.#IND", 6) == 0) { + STRCPY(s, "nan"); + } + // Remove sign before "nan" + if (STRNCMP(tmp, "-nan", 4) == 0) { + STRCPY(tmp, "nan"); + } + // Add sign before "inf" if needed. + if (isinf(f) == -1 && STRNCMP(tmp, "inf", 3) == 0) { + STRCPY(tmp, "-inf"); + } + if (remove_trailing_zeroes) { int i; char *tp; diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index 7f7811dc7a..fc804f3a15 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -201,12 +201,10 @@ function Test_printf_float() call assert_equal('inf', printf('%f', 1.0/0.0)) - " This prints inf but shouldn't it print -inf instead? - call assert_match('^-\?inf$', printf('%f', -1.0/0.0)) + call assert_match('^-inf$', printf('%f', -1.0/0.0)) - " This prints -nan but shouldn't it print nan instead? - call assert_match('^-\?nan$', printf('%f', sqrt(-1.0))) - call assert_match('^-\?nan$', printf('%f', 0.0/0.0)) + call assert_match('^nan$', printf('%f', sqrt(-1.0))) + call assert_match('^nan$', printf('%f', 0.0/0.0)) call assert_fails('echo printf("%f", "a")', 'E807:') endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index 8fd0fce329..5479e9f91f 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -175,7 +175,7 @@ static int included_patches[] = { // 2269, // 2268, // 2267 NA - // 2266, + 2266, 2265, 2264, // 2263, -- cgit From 6ca580be9bffcccc513bfce383a6e1f9f026614c Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Tue, 7 Mar 2017 08:47:31 +0100 Subject: vim-patch:7.4.2280 Problem: printf() doesn't handle infinity float values correctly. Solution: Add a table with possible infinity values. (Dominique Pelle) https://github.com/vim/vim/commit/e999782e369999539a1783a7ebe4eadcc6da28a8 --- src/nvim/strings.c | 57 +++++++++++++++---------- src/nvim/testdir/test_expr.vim | 96 ++++++++++++++++++++++++++++++++++++------ src/nvim/version.c | 2 +- 3 files changed, 119 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 47ee311bd4..e8d70f2676 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -753,6 +753,22 @@ int vim_snprintf(char *str, size_t str_m, const char *fmt, ...) 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 /// @@ -1209,10 +1225,10 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, } if (fmt_spec == 'f' && abs_f > 1.0e307) { - const char inf_str[] = f < 0 ? "-inf" : "inf"; - // avoid a buffer overflow - memmove(tmp, inf_str, sizeof(inf_str) - 1); - str_arg_l = sizeof(inf_str) - 1; + STRCPY(tmp, infinity_str(f > 0.0, fmt_spec, + force_sign, space_for_positive)); + str_arg_l = STRLEN(tmp); + zero_padding = 0; } else { format[0] = '%'; int l = 1; @@ -1231,25 +1247,22 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, } format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec); format[l + 1] = NUL; - assert(l + 1 < (int)sizeof(format)); - str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); - assert(str_arg_l < sizeof(tmp)); - // Be consistent: Change "1.#IND" to "nan" and - // "1.#INF" to "inf". - char *s = *tmp == '-' ? tmp + 1 : tmp; - if (STRNCMP(s, "1.#INF", 6) == 0) { - STRCPY(s, "inf"); - } else if (STRNCMP(s, "1.#IND", 6) == 0) { - STRCPY(s, "nan"); - } - // Remove sign before "nan" - if (STRNCMP(tmp, "-nan", 4) == 0) { - STRCPY(tmp, "nan"); - } - // Add sign before "inf" if needed. - if (isinf(f) == -1 && STRNCMP(tmp, "inf", 3) == 0) { - STRCPY(tmp, "-inf"); + if (isnan(f)) { + // Not a number: nan or NAN + STRCPY(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan"); + str_arg_l = 3; + zero_padding = 0; + } else if (isinf(f)) { + STRCPY(tmp, infinity_str(f > 0.0, fmt_spec, + force_sign, space_for_positive)); + str_arg_l = STRLEN(tmp); + zero_padding = 0; + } else { + // Regular float number + assert(l + 1 < (int)sizeof(format)); + str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); + assert(str_arg_l < sizeof(tmp)); } if (remove_trailing_zeroes) { diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index fc804f3a15..b7eeb6d48c 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -141,7 +141,7 @@ function Test_printf_misc() 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('#', printf('%c', 123)) call assert_equal('abc', printf('%s', 'abc')) call assert_equal('abc', printf('%S', 'abc')) @@ -152,13 +152,22 @@ function Test_printf_misc() 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)) + 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('%.*d', 5, 123)) call assert_equal(' 123', printf('% *d', 5, 123)) call assert_equal(' +123', printf('%+ *d', 5, 123)) - call assert_equal('123', printf('%2d', 123)) - call assert_equal(' 123', printf('%5d', 123)) - call assert_equal('00123', printf('%05d', 123)) call assert_equal('123 ', printf('%-5d', 123)) call assert_equal('0x7b', printf('%#x', 123)) call assert_equal('0X7B', printf('%#X', 123)) @@ -191,20 +200,81 @@ endfunc function Test_printf_float() call assert_equal('1.230000', printf('%f', 1.23)) call assert_equal('1.230000', printf('%F', 1.23)) - call assert_equal('1.23', printf('%g', 1.23)) - call assert_equal('1.23', printf('%G', 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('1.2', printf('%.1f', 1.23)) - + 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)) + " FIXME: call assert_equal('-00.33', printf('%06.2f', -1.0/3.0)) + " FIXME: call assert_equal('-00.33', printf('%+06.2f', -1.0/3.0)) + " FIXME: call assert_equal('+00.33', printf('%+06.2f', 1.0/3.0)) + " FIXME: call assert_equal(' 00.33', printf('% 06.2f', 1.0/3.0)) + + " Float infinity can be signed. call assert_equal('inf', printf('%f', 1.0/0.0)) - - call assert_match('^-inf$', printf('%f', -1.0/0.0)) - - call assert_match('^nan$', printf('%f', sqrt(-1.0))) - call assert_match('^nan$', printf('%f', 0.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('%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('%-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 zero can be signed. + 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 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('%G', 0.0/0.0)) + call assert_equal('NAN', printf('%E', 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 diff --git a/src/nvim/version.c b/src/nvim/version.c index 5479e9f91f..09e27d210b 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -161,7 +161,7 @@ static int included_patches[] = { // 2283, // 2282 NA // 2281 NA - // 2280, + 2280, 2279, // 2278 NA 2277, -- cgit From cad9a76be28f2ee3bd2c48ae959243aa7cfdb02a Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Tue, 7 Mar 2017 21:05:02 +0100 Subject: vim-patch:7.4.2291 Problem: printf() handles floats wrong when there is a sign. Solution: Fix placing the sign. Add tests. (Dominique Pelle) https://github.com/vim/vim/commit/04186095346daa60e82e981dad114de2b641d672 --- src/nvim/strings.c | 53 ++++++++++++++++++------------- src/nvim/testdir/test_expr.vim | 72 ++++++++++++++++++++++++++++++++++-------- src/nvim/version.c | 2 +- 3 files changed, 90 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/nvim/strings.c b/src/nvim/strings.c index e8d70f2676..a2052423e2 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -925,7 +925,6 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, 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; } @@ -1202,6 +1201,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, } case 'f': + case 'F': case 'e': case 'E': case 'g': @@ -1217,37 +1217,19 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, 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'; + fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f'; } else { fmt_spec = fmt_spec == 'g' ? 'e' : 'E'; } remove_trailing_zeroes = true; } - if (fmt_spec == 'f' && abs_f > 1.0e307) { + if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0e307) { STRCPY(tmp, infinity_str(f > 0.0, fmt_spec, force_sign, space_for_positive)); str_arg_l = STRLEN(tmp); zero_padding = 0; } else { - format[0] = '%'; - int 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 += snprintf(format + 1, sizeof(format) - 1, ".%d", - (int)precision); - } - format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec); - format[l + 1] = NUL; - if (isnan(f)) { // Not a number: nan or NAN STRCPY(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan"); @@ -1259,6 +1241,27 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, str_arg_l = STRLEN(tmp); zero_padding = 0; } else { + format[0] = '%'; + int 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 += snprintf(format + l, sizeof(format) - 1, ".%d", + (int)precision); + } + format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec); + format[l + 1] = NUL; + // Regular float number assert(l + 1 < (int)sizeof(format)); str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); @@ -1270,7 +1273,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, char *tp; // using %g or %G: remove superfluous zeroes - if (fmt_spec == 'f') { + if (fmt_spec == 'f' || fmt_spec == 'F') { tp = tmp + str_arg_l - 1; } else { tp = (char *)vim_strchr((char_u *)tmp, @@ -1312,6 +1315,12 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, } } } + 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; } diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index b7eeb6d48c..ccbdde8244 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -141,7 +141,7 @@ function Test_printf_misc() 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('{', printf('%c', 123)) call assert_equal('abc', printf('%s', 'abc')) call assert_equal('abc', printf('%S', 'abc')) @@ -160,21 +160,44 @@ function Test_printf_misc() call assert_equal(' +123', printf('%+6d', 123)) call assert_equal(' 123', printf('% 6d', 123)) call assert_equal(' -123', printf('% 6d', -123)) + + " Test left adjusted. + call assert_equal('123 ', printf('%-6d', 123)) call assert_equal('+123 ', printf('%-+6d', 123)) call assert_equal(' 123 ', printf('%- 6d', 123)) call assert_equal('-123 ', printf('%- 6d', -123)) + call assert_equal(' 00123', printf('%7.5d', 123)) + call assert_equal(' -00123', printf('%7.5d', -123)) + call assert_equal(' +00123', printf('%+7.5d', 123)) + " Precision field should not be used when combined with %0 + call assert_equal(' 00123', printf('%07.5d', 123)) + call assert_equal(' -00123', printf('%07.5d', -123)) + + call assert_equal(' 123', printf('%*d', 5, 123)) + call assert_equal('123 ', printf('%*d', -5, 123)) call assert_equal('00123', printf('%.*d', 5, 123)) call assert_equal(' 123', printf('% *d', 5, 123)) call assert_equal(' +123', printf('%+ *d', 5, 123)) - call assert_equal('123 ', printf('%-5d', 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)) @@ -198,6 +221,7 @@ function Test_printf_misc() 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)) @@ -212,10 +236,31 @@ function Test_printf_float() 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)) - " FIXME: call assert_equal('-00.33', printf('%06.2f', -1.0/3.0)) - " FIXME: call assert_equal('-00.33', printf('%+06.2f', -1.0/3.0)) - " FIXME: call assert_equal('+00.33', printf('%+06.2f', 1.0/3.0)) - " FIXME: 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(' 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)) @@ -224,6 +269,8 @@ function Test_printf_float() 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)) @@ -242,6 +289,9 @@ function Test_printf_float() 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)) @@ -249,22 +299,16 @@ function Test_printf_float() call assert_equal("str2float('inf')", printf('%s', 1.0/0.0)) call assert_equal("-str2float('inf')", printf('%s', -1.0/0.0)) - " Float zero can be signed. - 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 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)) diff --git a/src/nvim/version.c b/src/nvim/version.c index 09e27d210b..dd4adae213 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -150,7 +150,7 @@ static int included_patches[] = { 2294, // 2293, 2292, - // 2291, + 2291, // 2290 NA // 2289 NA // 2288 NA -- cgit From c6c8e1e8cc4ea6fc98187c0bce8875cf82278ba5 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Tue, 21 Mar 2017 07:34:08 +0100 Subject: version: Mark patch 2221 as applied. It was implemented as a part of #3916. --- src/nvim/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index dd4adae213..4bc108dd2d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -220,7 +220,7 @@ static int included_patches[] = { // 2224, 2223, 2222, - // 2221, + 2221, 2220, 2219, // 2218 NA -- cgit From 66259e4c498dd3b5278aeea16cc3a71ed83f1b76 Mon Sep 17 00:00:00 2001 From: Jack Bracewell Date: Tue, 21 Mar 2017 10:11:32 +0000 Subject: vim-patch:7.4.2293 (#6307) The original patch makes all the modeline comments consistent, but these have been removed in the neovim source. However there as a correction of a comment included in the patch that we can use. https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47 --- src/nvim/eval.c | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d4daffb469..7eb149476f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -4196,7 +4196,7 @@ static int eval7( // 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); diff --git a/src/nvim/version.c b/src/nvim/version.c index 8fd0fce329..bf13e52be4 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -148,7 +148,7 @@ static int included_patches[] = { // 2296, 2295, 2294, - // 2293, + 2293, 2292, // 2291, // 2290 NA -- cgit From 26d7757ccbc57125a3dfe3b2cad0f07a2e567df1 Mon Sep 17 00:00:00 2001 From: lonerover Date: Fri, 17 Mar 2017 23:09:15 +0800 Subject: vim-patch:7.4.2256 Problem: Coverity complains about null pointer check. Solution: Remove wrong and superfluous error check. https://github.com/vim/vim/commit/db249f26edf7a5f88d1f4468d08ec5b84f5ab7ad --- src/nvim/eval.c | 5 ++++- src/nvim/version.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d4daffb469..5de999f175 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -4860,7 +4860,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; } diff --git a/src/nvim/version.c b/src/nvim/version.c index b9286c2a4e..5cdd0d96fe 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -185,7 +185,7 @@ static int included_patches[] = { // 2259, // 2258 NA // 2257 NA - // 2256, + 2256, 2255, // 2254 NA // 2253 NA -- cgit From 7418adc14375161b504e78c77c5c4e532016902c Mon Sep 17 00:00:00 2001 From: lonerover Date: Tue, 21 Mar 2017 21:36:31 +0800 Subject: move.c: add cursor adjustment for scrolloff (#6319) --- src/nvim/move.c | 1 + src/nvim/testdir/test_normal.vim | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/move.c b/src/nvim/move.c index 4c3f82bc16..4feabf624b 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1877,6 +1877,7 @@ int onepage(int dir, long count) } } foldAdjustCursor(); + cursor_correct(); check_cursor_col(); if (retval == OK) { beginline(BL_SOL | BL_FIX); diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 29a7c1edd8..a22dca35cc 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -433,7 +433,6 @@ func! Test_normal13_help() endfunc func! Test_normal14_page() - throw "skipped: Nvim regression: CTRL-F with 'scrolloff'" " basic test for Ctrl-F and Ctrl-B call Setup_NewWindow() exe "norm! \" -- cgit From 6baa669c10518b8751904a31899feb897fb7c995 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 17:07:00 +0100 Subject: vim-patch:7.4.2164 (#6326) Problem: It is not possible to use plugins in an "after" directory to tune the behavior of a package. Solution: First load plugins from non-after directories, then packages and finally plugins in after directories. Reset 'loadplugins' before executing --cmd arguments. https://github.com/vim/vim/commit/66459b7c98c67f8a9d39de8f08e8e8f1fca0e359 vim-patch:7.4.2172 vim-patch:7.4.2169 vim-patch:7.4.2177 vim-patch:7.4.2178 vim-patch:7.4.2184 vim-patch:8.0.0050 vim-patch:8.0.0105 vim-patch:8.0.0400 vim-patch:8.0.0405 Closes #6034 --- src/nvim/ex_cmds2.c | 16 ++- src/nvim/main.c | 13 ++- src/nvim/testdir/setup.vim | 3 +- src/nvim/testdir/shared.vim | 214 ++++++++++++++++++++++++++++++++++++++ src/nvim/testdir/test_startup.vim | 200 +++++++++++++++++++++++++++++++++++ src/nvim/version.c | 12 +-- src/nvim/vim.h | 2 + 7 files changed, 449 insertions(+), 11 deletions(-) create mode 100644 src/nvim/testdir/shared.vim create mode 100644 src/nvim/testdir/test_startup.vim (limited to 'src') diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 36f50ae7a2..9fc4ef2a02 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2361,12 +2361,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); @@ -2597,6 +2610,7 @@ static bool did_source_packages = false; // ":packloadall" // Find plugins in the package directories and source them. +// "eap" is NULL when invoked during startup. void ex_packloadall(exarg_T *eap) { if (!did_source_packages || (eap != NULL && eap->forceit)) { diff --git a/src/nvim/main.c b/src/nvim/main.c index 4416bd067c..7b1c912f4b 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -326,6 +326,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(¶ms); @@ -1268,11 +1274,14 @@ 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 + source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_NOAFTER); // NOLINT TIME_MSG("loading plugins"); ex_packloadall(NULL); TIME_MSG("loading packages"); + + source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER); + TIME_MSG("loading after plugins"); } } @@ -1708,8 +1717,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); diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim index 05257d566d..06f2199214 100644 --- a/src/nvim/testdir/setup.vim +++ b/src/nvim/testdir/setup.vim @@ -4,8 +4,9 @@ set noruler set noshowcmd set belloff= -" Make sure 'runtimepath' does not include $HOME. +" 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..784e4a0a02 --- /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='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/test_startup.vim b/src/nvim/testdir/test_startup.vim new file mode 100644 index 0000000000..f78d92f3ff --- /dev/null +++ b/src/nvim/testdir/test_startup.vim @@ -0,0 +1,200 @@ +" 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', + \ 'set packpath=Xhere,Xafter', + \ 'set nomore', + \ ] + let after = [ + \ 'redir! > Xtestout', + \ 'scriptnames', + \ 'redir END', + \ 'quit', + \ ] + call mkdir('Xhere/plugin', 'p') + call writefile(['let done = 1'], 'Xhere/plugin/here.vim') + call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p') + call writefile(['let done = 1'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') + + call mkdir('Xafter/plugin', 'p') + call writefile(['let done = 1'], 'Xafter/plugin/later.vim') + + if RunVim(before, after, '') + + let lines = readfile('Xtestout') + let expected = ['Xbefore.vim', 'here.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 delete('Xtestout') + call delete('Xhere', 'rf') + call delete('Xafter', '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.*Readonly mode' + call add(found, 'Readonly mode') + endif + " Watch out for a second --version line in the Gnome version. + if line =~ '--version.*Print version information and exit' + call add(found, "--version") + endif + endfor + call assert_equal(['--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/version.c b/src/nvim/version.c index bf13e52be4..1d4239b215 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -257,27 +257,27 @@ static int included_patches[] = { 2187, // 2186 NA 2185, - // 2184, + 2184, 2183, // 2182 NA // 2181, // 2180, // 2179, - // 2178, - // 2177, + 2178, + 2177, // 2176 NA 2175, 2174, // 2173, - // 2172, + 2172, // 2171, // 2170, - // 2169, + 2169, // 2168 NA // 2167 NA // 2166 NA // 2165, - // 2164, + 2164, 2163, 2162, // 2161, diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 458d23fcad..87e9889465 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -325,6 +325,8 @@ 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 -- cgit From 3e33025133e1e77c7ad3b8670e06175b9757cf30 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Tue, 21 Mar 2017 22:48:01 +0100 Subject: strings: Fix problems found during code review --- src/nvim/strings.c | 71 +++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/nvim/strings.c b/src/nvim/strings.c index a2052423e2..7ec2ea13f7 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1224,49 +1224,44 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, remove_trailing_zeroes = true; } - if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0e307) { - STRCPY(tmp, infinity_str(f > 0.0, fmt_spec, - force_sign, space_for_positive)); - str_arg_l = STRLEN(tmp); + 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 { - if (isnan(f)) { - // Not a number: nan or NAN - STRCPY(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan"); - str_arg_l = 3; - zero_padding = 0; - } else if (isinf(f)) { - STRCPY(tmp, infinity_str(f > 0.0, fmt_spec, - force_sign, space_for_positive)); - str_arg_l = STRLEN(tmp); - zero_padding = 0; - } else { - format[0] = '%'; - int l = 1; - if (force_sign) { - format[l++] = space_for_positive ? ' ' : '+'; - } - if (precision_specified) { - size_t max_prec = TMP_LEN - 10; + 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 += snprintf(format + l, sizeof(format) - 1, ".%d", - (int)precision); + // 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); } - format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec); - format[l + 1] = NUL; - - // Regular float number - assert(l + 1 < (int)sizeof(format)); - str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); - assert(str_arg_l < sizeof(tmp)); + if (precision > max_prec) { + precision = max_prec; + } + l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d", + (int)precision); } + format[l] = 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; -- cgit From ab16c07584ab4a5bc48784dde3b9b46d30e5e4a0 Mon Sep 17 00:00:00 2001 From: lonerover Date: Wed, 22 Mar 2017 08:28:03 +0800 Subject: vim-patch:7.4.2283 Problem: Part of ":oldfiles" command isn't cleared. (Lifepillar) Solution: Clear the rest of the line. (closes 1018) https://github.com/vim/vim/commit/885c00eabe6d1fd757d4f0eb531ad3a15a35ec04 --- src/nvim/eval.c | 1 + src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7eb149476f..e11b460edf 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -23628,6 +23628,7 @@ void ex_oldfiles(exarg_T *eap) msg_outnum(++nr); MSG_PUTS(": "); msg_outtrans(get_tv_string(&li->li_tv)); + msg_clr_eos(); msg_putchar('\n'); ui_flush(); /* output one line at a time */ os_breakcheck(); diff --git a/src/nvim/version.c b/src/nvim/version.c index 39886aa9d9..e060724d81 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -158,7 +158,7 @@ static int included_patches[] = { // 2286 NA // 2285 NA 2284, - // 2283, + 2283, // 2282 NA // 2281 NA 2280, -- cgit From 56e400d800b9eb6c89ea8336c50d2a61cc8fd18b Mon Sep 17 00:00:00 2001 From: John Szakmeister Date: Wed, 22 Mar 2017 03:49:45 -0400 Subject: vim_vsnprintf: fix conversion warning #6333 Re-apply fix from #6311 which was accidentally regressed in #6231. --- src/nvim/strings.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 7ec2ea13f7..267832ed2d 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1255,7 +1255,9 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d", (int)precision); } - format[l] = fmt_spec == 'F' ? 'f' : fmt_spec; + + // 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 -- cgit From c554b53040e9fea2dce343eb11178a3352d5e8da Mon Sep 17 00:00:00 2001 From: lonerover Date: Wed, 22 Mar 2017 08:34:04 +0800 Subject: vim-patch:7.4.2296 Problem: No tests for :undolist and "U" command. Solution: Add tests. (Dominique Pelle) https://github.com/vim/vim/commit/c628fdcd46e93c308f742efdf54248695960e290 --- src/nvim/testdir/test_undo.vim | 33 +++++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim index fc61d1f223..9ff73fd870 100644 --- a/src/nvim/testdir/test_undo.vim +++ b/src/nvim/testdir/test_undo.vim @@ -131,6 +131,39 @@ func Test_undo_del_chars() 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\', '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\", 'xt') + call feedkeys("achange2\", '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\", 'xt') diff --git a/src/nvim/version.c b/src/nvim/version.c index e060724d81..1f2c8d12f5 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -145,7 +145,7 @@ static int included_patches[] = { 2299, // 2298 NA // 2297 NA - // 2296, + 2296, 2295, 2294, 2293, -- cgit From 114a18b93588c7d5238fe66a77dc0f94a2ba5500 Mon Sep 17 00:00:00 2001 From: lonerover Date: Wed, 22 Mar 2017 08:37:02 +0800 Subject: vim-patch:7.4.2303 Problem: When using "is" the mode isn't always updated. Solution: Redraw the command line. (Christian Brabandt) https://github.com/vim/vim/commit/779f2fc3a7468e273897d2fd0672315812a2e3da --- src/nvim/search.c | 3 ++- src/nvim/version.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/search.c b/src/nvim/search.c index ba6c4e6548..75862e1136 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3028,7 +3028,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) diff --git a/src/nvim/version.c b/src/nvim/version.c index 1f2c8d12f5..ccd7fd21d9 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -138,7 +138,7 @@ static int included_patches[] = { // 2306, 2305, // 2304 NA - // 2303, + 2303, // 2302 NA // 2301 NA 2300, -- cgit From a1732b46abe48541f380d6a605fa7529c9a05da1 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 14:49:37 +0100 Subject: terminal: Avoid invalid cursor col (#6265) Patch-by: oni-link Closes #6203 https://s3.amazonaws.com/archive.travis-ci.org/jobs/206794197/log.txt References #3161 [ RUN ] ...d/neovim/neovim/test/functional/terminal/buffer_spec.lua @ 199: terminal buffer term_close() use-after-free #4393 ./test/functional/helpers.lua:187: attempt to perform arithmetic on local 'written' (a nil value) stack traceback: ./test/functional/helpers.lua:187: in function 'nvim_feed' ./test/functional/helpers.lua:329: in function 'execute' ...d/neovim/neovim/test/functional/terminal/buffer_spec.lua:206: in function <...d/neovim/neovim/test/functional/terminal/buffer_spec.lua:199> [ ERROR ] ...d/neovim/neovim/test/functional/terminal/buffer_spec.lua @ 199: terminal buffer term_close() use-after-free #4393 (199.47 ms) ==================== File /home/travis/build/neovim/neovim/build/log/ubsan.15466 ==================== = ================================================================= = ==15466==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x621000029101 at pc 0x000000ea7ba0 bp 0x7ffd5bb628c0 sp 0x7ffd5bb628b8 = READ of size 1 at 0x621000029101 thread T0 = #0 0xea7b9f in utf_head_off /home/travis/build/neovim/neovim/src/nvim/mbyte.c:1637:7 = #1 0xeaaf53 in mb_adjustpos /home/travis/build/neovim/neovim/src/nvim/mbyte.c:1840:16 = #2 0xeaab48 in mb_adjust_cursor /home/travis/build/neovim/neovim/src/nvim/mbyte.c:1825:3 = #3 0x11000d0 in normal_finish_command /home/travis/build/neovim/neovim/src/nvim/normal.c:928:5 = #4 0x1077df1 in normal_execute /home/travis/build/neovim/neovim/src/nvim/normal.c:1147:3 = #5 0x16ff943 in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:58:26 = #6 0x102d8db in normal_enter /home/travis/build/neovim/neovim/src/nvim/normal.c:463:3 = #7 0xdf3398 in main /home/travis/build/neovim/neovim/src/nvim/main.c:540:3 = #8 0x2b973e8b4f44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287 = #9 0x447445 in _start (/home/travis/build/neovim/neovim/build/bin/nvim+0x447445) = = 0x621000029101 is located 1 bytes to the right of 4096-byte region [0x621000028100,0x621000029100) = allocated by thread T0 here: = #0 0x4f17b8 in malloc (/home/travis/build/neovim/neovim/build/bin/nvim+0x4f17b8) = #1 0xf1f374 in try_malloc /home/travis/build/neovim/neovim/src/nvim/memory.c:84:15 = #2 0xf1f534 in xmalloc /home/travis/build/neovim/neovim/src/nvim/memory.c:118:15 = #3 0xebe6a8 in mf_alloc_bhdr /home/travis/build/neovim/neovim/src/nvim/memfile.c:646:17 = #4 0xebc394 in mf_new /home/travis/build/neovim/neovim/src/nvim/memfile.c:297:12 = #5 0xed1368 in ml_new_data /home/travis/build/neovim/neovim/src/nvim/memline.c:2704:16 = #6 0xece6ab in ml_open /home/travis/build/neovim/neovim/src/nvim/memline.c:349:8 = #7 0x6438ad in open_buffer /home/travis/build/neovim/neovim/src/nvim/buffer.c:109:7 = #8 0xa6ec8d in do_ecmd /home/travis/build/neovim/neovim/src/nvim/ex_cmds.c:2489:24 = #9 0xb5a0f9 in do_exedit /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:6723:9 = #10 0xb791f8 in ex_edit /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:6651:3 = #11 0xb28b43 in do_one_cmd /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:2198:5 = #12 0xb077a7 in do_cmdline /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:601:20 = #13 0x10905db in nv_colon /home/travis/build/neovim/neovim/src/nvim/normal.c:4495:18 = #14 0x1077de8 in normal_execute /home/travis/build/neovim/neovim/src/nvim/normal.c:1144:3 = #15 0x16ff943 in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:58:26 = #16 0x102d8db in normal_enter /home/travis/build/neovim/neovim/src/nvim/normal.c:463:3 = #17 0xdf3398 in main /home/travis/build/neovim/neovim/src/nvim/main.c:540:3 = #18 0x2b973e8b4f44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287 = = SUMMARY: AddressSanitizer: heap-buffer-overflow /home/travis/build/neovim/neovim/src/nvim/mbyte.c:1637:7 in utf_head_off stack traceback: ./test/helpers.lua:80: in function 'check_logs' ./test/functional/helpers.lua:639: in function <./test/functional/helpers.lua:638> [----------] 9 tests from /home/travis/build/neovim/neovim/test/functional/terminal/buffer_spec.lua (2263.12 ms total) --- src/nvim/cursor.c | 5 ++--- src/nvim/mbyte.c | 35 +++++++++++++++++++++++++++++++++++ src/nvim/normal.c | 4 +--- src/nvim/terminal.c | 1 + 4 files changed, 39 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 544bcf6ede..82f1bf0a16 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -338,9 +338,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; diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 6a87a63b8c..7a54b0c64f 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1848,6 +1848,41 @@ 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(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); + + // 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; + } + } +} + /* * Return a pointer to the character before "*p", if there is one. */ diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 7188e13436..85dc509ee6 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -925,9 +925,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 diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index bd925a8106..87ee8f410f 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -1197,6 +1197,7 @@ static void adjust_topline(Terminal *term, buf_T *buf, long added) // 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); } } } -- cgit From 1d8356a807e306eb82f2c1a7e2d2802407c7fa6e Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Wed, 22 Mar 2017 17:16:49 +0100 Subject: mbyte: remove dead code --- src/nvim/mbyte.c | 249 +++++++----------------------------------------------- src/nvim/search.c | 30 ++----- src/nvim/spell.c | 9 +- 3 files changed, 41 insertions(+), 247 deletions(-) (limited to 'src') diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 7a54b0c64f..0ab133a545 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -355,14 +355,13 @@ int bomb_size(void) */ void remove_bom(char_u *s) { - if (enc_utf8) { - char_u *p = s; - - while ((p = vim_strbyte(p, 0xef)) != NULL) { - if (p[1] == 0xbb && p[2] == 0xbf) - STRMOVE(p, p + 3); - else - ++p; + char_u *p = s; + + while ((p = vim_strbyte(p, 0xef)) != NULL) { + if (p[1] == 0xbb && p[2] == 0xbf) { + STRMOVE(p, p + 3); + } else { + p++; } } } @@ -388,154 +387,7 @@ int mb_get_class_buf(const char_u *p, buf_T *buf) return 2; return 1; } - if (enc_dbcs != 0 && p[0] != NUL && p[1] != NUL) - return dbcs_class(p[0], p[1]); - if (enc_utf8) - return utf_class(utf_ptr2char(p)); - return 0; -} - -/* - * Get class of a double-byte character. This always returns 3 or bigger. - * TODO: Should return 1 for punctuation. - */ -int dbcs_class(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)); } /* @@ -788,10 +640,7 @@ int mb_cptr2char_adv(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; } @@ -1542,36 +1391,7 @@ int utf16_to_utf8(const WCHAR *strw, char **str) */ 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; + return utf_strnicmp(s1, s2, nn, nn); } /* We need to call mb_stricmp() even when we aren't dealing with a multi-byte @@ -1699,27 +1519,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; } /* @@ -1762,10 +1579,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); } @@ -2279,13 +2096,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) { diff --git a/src/nvim/search.c b/src/nvim/search.c index 75862e1136..8c56eda7cf 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2417,32 +2417,20 @@ static int cls(void) int c; c = gchar_cursor(); - if (p_altkeymap && c == F_BLANK) + if (p_altkeymap && c == F_BLANK) { return 0; - if (c == ' ' || c == '\t' || c == NUL) - return 0; - if (enc_dbcs != 0 && c > 0xFF) { - /* If cls_bigword, report multi-byte chars as class 1. */ - if (enc_dbcs == DBCS_KOR && cls_bigword) - return 1; - - /* process code leading/trailing bytes */ - return dbcs_class(((unsigned)c >> 8), (c & 0xFF)); } - if (enc_utf8) { - c = utf_class(c); - if (c != 0 && cls_bigword) - return 1; - return c; + if (c == ' ' || c == '\t' || c == NUL) { + return 0; } - /* If cls_bigword is TRUE, report all non-blanks as class 1. */ - if (cls_bigword) - return 1; + c = utf_class(c); - if (vim_iswordc(c)) - return 2; - return 1; + // If cls_bigword is TRUE, report all non-blanks as class 1. + if (c != 0 && cls_bigword) { + return 1; + } + return c; } /* diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 12f982106a..3b891d998f 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2623,7 +2623,7 @@ 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) @@ -2646,12 +2646,7 @@ 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]; } -- cgit From b9e1289819183f94afb43330a7e0d953869e2af7 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 20 Mar 2017 02:48:28 +0100 Subject: vim-patch:8.0.0486 Problem: Crash and endless loop when closing windows in a SessionLoadPost autocommand. Solution: Check for valid tabpage. (partly neovim/neovim#6308) https://github.com/vim/vim/commit/8c752bd6c4af54c0b7bac35a39acc2bf16015f85 Closes #6308 --- src/nvim/fileio.c | 6 ++++ src/nvim/testdir/test_autocmd.vim | 68 +++++++++++++++++++++++++++++++++++++++ src/nvim/window.c | 58 ++++++++++++++++++++++++++------- 3 files changed, 121 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 873c15ff4a..d948e20b32 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -6464,6 +6464,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(); diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index f05a55f1aa..fe9a3dd451 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -196,3 +196,71 @@ func Test_augroup_deleted() au! VimEnter endfunc +" Closing a window might cause an endless loop +" E814 for older Vims +function Test_autocmd_bufwipe_in_SessLoadPost() + if has('win32') + throw 'Skipped: test hangs on MS-Windows' + endif + tabnew + set noswapfile + let g:bufnr=bufnr('%') + mksession! + + let content=['set nocp noswapfile', + \ 'let v:swapchoice="e"', + \ 'augroup test_autocmd_sessionload', + \ 'autocmd!', + \ 'autocmd SessionLoadPost * 4bw!', + \ 'augroup END' + \ ] + call writefile(content, 'Xvimrc') + let a=system(v:progpath. ' --headless -u Xvimrc --noplugins -S Session.vim') + call assert_match('E814', a) + + unlet! g:bufnr + set swapfile + for file in ['Session.vim', 'Xvimrc'] + call delete(file) + endfor +endfunc + +" SEGV occurs in older versions. +function Test_autocmd_bufwipe_in_SessLoadPost2() + if has('win32') + throw 'Skipped: test hangs on MS-Windows' + endif + tabnew + set noswapfile + let g:bufnr=bufnr('%') + 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', + \ 'call append("1", "SessionLoadPost DONE")', + \ 'endfunction', + \ 'au SessionLoadPost * call DeleteInactiveBufs()'] + call writefile(content, 'Xvimrc') + let a=system(v:progpath. ' --headless -u Xvimrc --noplugins -S Session.vim') + " this probably only matches on unix + if has("unix") + call assert_notmatch('Caught deadly signal SEGV', a) + endif + call assert_match('SessionLoadPost DONE', a) + + unlet! g:bufnr + set swapfile + for file in ['Session.vim', 'Xvimrc'] + call delete(file) + endfor +endfunc diff --git a/src/nvim/window.c b/src/nvim/window.c index 6c9d3554f1..eda3cd7810 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1714,14 +1714,10 @@ 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(); @@ -1731,9 +1727,11 @@ close_windows ( for (win_T *wp = firstwin; wp != NULL && lastwin != firstwin; ) { if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) - && !(wp->w_closing || wp->w_buffer->b_closing) - ) { - win_close(wp, FALSE); + && !(wp->w_closing || wp->w_buffer->b_closing)) { + 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; @@ -3134,6 +3132,44 @@ 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 + } + 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. */ -- cgit From ca853edb6f9ffe1d2e5d4a63bf88e4c3a059f5fb Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 20 Mar 2017 13:59:11 +0100 Subject: vim-patch:8.0.0177 Problem: When opening a buffer on a directory and inside a try/catch then the BufEnter event is not triggered. Solution: Return NOTDONE from readfile() for a directory and deal with the three possible return values. (Justin M. Keyes, closes vim/vim#1375, closes vim/vim#1353) https://github.com/vim/vim/commit/e13b9afe1283f5ae43232b5992372a0eb570666c --- src/nvim/testdir/test_autocmd.vim | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src') diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index fe9a3dd451..395c4a8596 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -196,6 +196,25 @@ func Test_augroup_deleted() au! VimEnter 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) + bwipe! + + 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() -- cgit From 165ba3e636769c38d67285e1b8ea2966ccb00b30 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 20 Mar 2017 14:01:22 +0100 Subject: vim-patch:7.4.2324 Problem: Crash when editing a new buffer and BufUnload autocommand wipes out the new buffer. (Norio Takagi) Solution: Don't allow wiping out this buffer. (partly by Hirohito Higashi) Move old style test13 into test_autocmd. Avoid ml_get error when editing a file. https://github.com/vim/vim/commit/e0ab94e7123ca7855f45919114d948ef2bc1e8c3 --- src/nvim/buffer.c | 23 +++++---- src/nvim/buffer_defs.h | 6 +-- src/nvim/ex_cmds.c | 11 ++--- src/nvim/ex_docmd.c | 6 +-- src/nvim/testdir/test13.in | 63 ------------------------- src/nvim/testdir/test13.ok | 31 ------------ src/nvim/testdir/test_autocmd.vim | 99 +++++++++++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- src/nvim/window.c | 13 ++--- 9 files changed, 133 insertions(+), 121 deletions(-) delete mode 100644 src/nvim/testdir/test13.in delete mode 100644 src/nvim/testdir/test13.ok (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 9e781f5dff..5edc87eab1 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -360,6 +360,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. @@ -378,14 +385,14 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) /* When the buffer is no longer in a window, trigger BufWinLeave */ if (buf->b_nwindows == 1) { - buf->b_closing = true; + 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)); @@ -395,14 +402,14 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) /* When the buffer becomes hidden, but is not unloaded, trigger * BufHidden */ if (!unload_buf) { - buf->b_closing = true; + 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)); @@ -559,7 +566,7 @@ 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; + buf->b_locked++; bufref_T bufref; set_bufref(&bufref, buf); @@ -584,7 +591,7 @@ void buf_freeall(buf_T *buf, int flags) // 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 @@ -1111,7 +1118,7 @@ do_buffer ( * a window with this buffer. */ while (buf == curbuf - && !(curwin->w_closing || curwin->w_buffer->b_closing) + && !(curwin->w_closing || curwin->w_buffer->b_locked > 0) && (firstwin != lastwin || first_tabpage->tp_next != NULL)) { if (win_close(curwin, FALSE) == FAIL) break; @@ -4499,7 +4506,7 @@ void ex_buffer_all(exarg_T *eap) : wp->w_width != Columns) || (had_tab > 0 && wp != firstwin) ) && firstwin != lastwin - && !(wp->w_closing || wp->w_buffer->b_closing) + && !(wp->w_closing || wp->w_buffer->b_locked > 0) ) { win_close(wp, FALSE); wpnext = firstwin; /* just in case an autocommand does diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index fdd7d945c9..9d350c763e 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -470,9 +470,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). diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 1b83677807..41f97b0cef 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2284,8 +2284,11 @@ 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; + buf->b_locked++; + if (curbuf == old_curbuf.br_buf) { buf_copy_options(buf, BCO_ENTER); } @@ -2298,6 +2301,7 @@ int do_ecmd( false); the_curwin->w_closing = false; + buf->b_locked--; // autocmds may abort script processing if (aborting() && curwin->w_buffer != NULL) { @@ -2444,11 +2448,6 @@ int do_ecmd( /* Assume success now */ retval = OK; - /* - * Reset cursor position, could be used by autocommands. - */ - check_cursor(); - /* * Check if we are editing the w_arg_idx file in the argument list. */ diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index bd3b8c204a..ebfbf2bf09 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5775,7 +5775,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; } @@ -5836,7 +5836,7 @@ static void ex_quit_all(exarg_T *eap) apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf); /* Refuse to quit when locked or when the buffer in the last window is * being closed (can only happen in autocommands). */ - if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing)) + if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) return; exiting = true; @@ -6131,7 +6131,7 @@ static void ex_exit(exarg_T *eap) apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf); /* Refuse to quit when locked or when the buffer in the last window is * being closed (can only happen in autocommands). */ - if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing)) + if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) return; // if more files or windows we won't exit 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/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 395c4a8596..39cd92440e 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -77,11 +77,49 @@ function Test_autocmd_bufunload_with_tabnext() quit call assert_equal(2, tabpagenr('$')) + autocmd! test_autocmd_bufunload_with_tabnext_group augroup! test_autocmd_bufunload_with_tabnext_group tablast quit 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 ' . (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 ' . (lastbuf + 1) . 'bwipeout!' + augroup END + + normal! i1 + call assert_fails('edit a.txt', 'E517:') + call feedkeys("\") + + autocmd! test_autocmd_bufunload + augroup! test_autocmd_bufunload + bwipe! a.txt +endfunc + func Test_win_tab_autocmd() let g:record = [] @@ -196,6 +234,67 @@ func Test_augroup_deleted() au! VimEnter endfunc +" Tests for autocommands on :close command. +" This used to be in test13. +func Test_three_windows() + " 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 + help + wincmd w + 1quit + call assert_equal('Xanother', expand('%')) + + au! + call delete('Xtestje1') + call delete('Xtestje2') + call delete('Xtestje3') +endfunc + func Test_BufEnter() au! BufEnter au Bufenter * let val = val . '+' diff --git a/src/nvim/version.c b/src/nvim/version.c index 32ef2c2fdb..8ae5e4057e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -117,7 +117,7 @@ static int included_patches[] = { // 2327 NA 2326, // 2325 NA - // 2324, + 2324, 2323, 2322, 2321, diff --git a/src/nvim/window.c b/src/nvim/window.c index eda3cd7810..a737ffb33c 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1727,7 +1727,7 @@ void close_windows(buf_T *buf, int keep_curwin) for (win_T *wp = firstwin; wp != NULL && lastwin != firstwin; ) { if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) - && !(wp->w_closing || wp->w_buffer->b_closing)) { + && !(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; @@ -1745,8 +1745,7 @@ void close_windows(buf_T *buf, int keep_curwin) if (tp != curtab) { FOR_ALL_WINDOWS_IN_TAB(wp, tp) { if (wp->w_buffer == buf - && !(wp->w_closing || wp->w_buffer->b_closing) - ) { + && !(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 @@ -1882,8 +1881,9 @@ int win_close(win_T *win, int free_buf) 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; @@ -2064,7 +2064,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 } -- cgit From 6a8bad03084c58d531e48b3d7f7f87f305f150d8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 10:15:22 +0100 Subject: vim-patch:8.0.0019 Problem: Test_command_count is old style. Solution: Turn it into a new style test. (Naruhiko Nishino) Use more assert functions. --- src/nvim/testdir/Makefile | 3 +- src/nvim/testdir/test_alot.vim | 1 + src/nvim/testdir/test_autocmd.vim | 13 +++ src/nvim/testdir/test_command_count.vim | 191 ++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 src/nvim/testdir/test_command_count.vim (limited to 'src') diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index d090ace432..0337ab13dd 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -1,4 +1,4 @@ -# +# vim: noet ts=8 # Makefile to run all tests for Vim # @@ -30,6 +30,7 @@ SCRIPTS ?= \ NEW_TESTS ?= \ test_bufwintabinfo.res \ test_cmdline.res \ + test_command_count.res \ test_cscope.res \ test_digraph.res \ test_diffmode.res \ diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 8aa0f417d1..241300f688 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -3,6 +3,7 @@ source test_assign.vim source test_autocmd.vim +source test_command_count.vim source test_cursor_func.vim source test_execute_func.vim source test_ex_undo.vim diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 39cd92440e..ace9e457bb 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) @@ -237,6 +247,9 @@ 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. 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 = [, ] + command! -range=% -addr=loaded_buffers RangeLoadedBuffersAll :let lines = [, ] + command! -range -addr=buffers RangeBuffers :let lines = [, ] + command! -range=% -addr=buffers RangeBuffersAll :let lines = [, ] + + .,$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 = [, ] + command! -range=% -addr=arguments RangeArgumentsAll :let lines = [, ] + .-,$-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 = [, ] + .,$RangeWindows + call assert_equal([3, 5], lines) + %RangeWindows + call assert_equal([1, 5], lines) + delcommand RangeWindows + + command! -range=% -addr=windows RangeWindowsAll :let lines = [, ] + 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 = [, ] + .,$RangeTabs + call assert_equal([2, 5], lines) + %RangeTabs + call assert_equal([1, 5], lines) + delcommand RangeTabs + + command! -range=% -addr=tabs RangeTabsAll :let lines = [, ] + RangeTabsAll + call assert_equal([1, 5], lines) + delcommand RangeTabsAll + 1tabonly + + s/\n/\r\r\r\r\r/ + 2ma< + $-ma> + command! -range=% RangeLines :let lines = [, ] + '<,'>RangeLines + call assert_equal([2, 5], lines) + delcommand RangeLines + + command! -range=% -buffer LocalRangeLines :let lines = [, ] + '<,'>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 -- cgit From 4c18670e91e22ab4fe566aa181aa6f28166e8aad Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 10:19:01 +0100 Subject: vim-patch:7.4.2346 Problem: Autocommand test fails when run directly, passes when run as part of test_alot. Solution: Add command to make the cursor move. Close a tab page. --- src/nvim/testdir/test_autocmd.vim | 3 +++ src/nvim/version.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index ace9e457bb..34cca5f612 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -23,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 diff --git a/src/nvim/version.c b/src/nvim/version.c index 8ae5e4057e..21f3a493c3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -95,7 +95,7 @@ static int included_patches[] = { // 2349, 2348, 2347, - // 2346, + 2346, // 2345 NA // 2344 NA // 2343, -- cgit From 4a2e6f460d02762d211c0f92af305ef5290a667b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 10:24:40 +0100 Subject: vim-patch:7.4.2341 Problem: Tiny things. Test doesn't clean up properly. Solution: Adjust comment and white space. Restore option value. --- src/nvim/ex_cmds.c | 2 +- src/nvim/testdir/test_autocmd.vim | 3 +++ src/nvim/version.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 41f97b0cef..e368838df7 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2294,7 +2294,7 @@ int do_ecmd( } // 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, diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 34cca5f612..b5d78c183f 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -33,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() @@ -44,6 +45,7 @@ if has('timers') call feedkeys("a\", 'x!') call assert_equal(0, g:triggered) au! CursorHoldI + set updatetime& endfunc endif @@ -223,6 +225,7 @@ func Test_augroup_warning() augroup Another augroup END call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0) + augroup! Another " no warning for postpone aucmd delete augroup StartOK diff --git a/src/nvim/version.c b/src/nvim/version.c index 21f3a493c3..84cb8fea9b 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -100,7 +100,7 @@ static int included_patches[] = { // 2344 NA // 2343, // 2342 NA - // 2341, + 2341, // 2340 NA // 2339, // 2338 NA -- cgit From 10f6624f65edbc8af84c9775e6712484be9c81a5 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 10:39:24 +0100 Subject: vim-patch:7.4.2328 Problem: Crash when BufWinLeave autocmd goes to another tab page. (Hirohito Higashi) Solution: Make close_buffer() go back to the right window. --- src/nvim/buffer.c | 14 ++++++++++++++ src/nvim/testdir/test_autocmd.vim | 11 +++++++++++ src/nvim/version.c | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5edc87eab1..7429e8628e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -337,6 +337,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 @@ -419,6 +423,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) */ diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index b5d78c183f..a122a62561 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -98,6 +98,17 @@ function Test_autocmd_bufunload_with_tabnext() quit endfunc +function Test_autocmd_bufwinleave_with_tabfirst() + tabedit + augroup sample + autocmd! + autocmd BufWinLeave 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 diff --git a/src/nvim/version.c b/src/nvim/version.c index 84cb8fea9b..d1d3e5a3c9 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -113,7 +113,7 @@ static int included_patches[] = { 2331, // 2330, 2329, - // 2328, + 2328, // 2327 NA 2326, // 2325 NA -- cgit From 2e9c1a9c4a6e2aaaef87c1c37b9cd14965b6d7b8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 12:09:11 +0100 Subject: vim-patch:8.0.0178 Problem: test_command_count may fail when a previous test interferes, seen on MS-Windows. Solution: Run it separately. https://github.com/vim/vim/commit/9b73c4a215cb5f0f7df1e7f0663aea2bce1914ab --- src/nvim/testdir/test_alot.vim | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 241300f688..8aa0f417d1 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -3,7 +3,6 @@ source test_assign.vim source test_autocmd.vim -source test_command_count.vim source test_cursor_func.vim source test_execute_func.vim source test_ex_undo.vim -- cgit From b0e34497b357462024c07d506a16426d58475497 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 10:47:46 +0100 Subject: test/legacy: fix test_autocmd.vim vim-patch:8.0.0487 --- src/nvim/testdir/runtest.vim | 2 ++ src/nvim/testdir/test_autocmd.vim | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index b4eb9de506..1cf7ab475c 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -72,6 +72,8 @@ let v:testing = 1 set directory^=. set backspace= set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd +" Prevent Nvim log from writing to stderr. +let $NVIM_LOG_FILE='Xnvim.log' function RunTheTest(test) echo 'Executing ' . a:test diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index a122a62561..5b5232f06e 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -359,11 +359,11 @@ function Test_autocmd_bufwipe_in_SessLoadPost() \ 'let v:swapchoice="e"', \ 'augroup test_autocmd_sessionload', \ 'autocmd!', - \ 'autocmd SessionLoadPost * 4bw!', - \ 'augroup END' + \ 'autocmd SessionLoadPost * 4bw!|qall!', + \ 'augroup END', \ ] call writefile(content, 'Xvimrc') - let a=system(v:progpath. ' --headless -u Xvimrc --noplugins -S Session.vim') + let a=system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim') call assert_match('E814', a) unlet! g:bufnr @@ -395,11 +395,13 @@ function Test_autocmd_bufwipe_in_SessLoadPost2() \ ' exec ''bwipeout '' . b', \ ' endif', \ ' endfor', - \ 'call append("1", "SessionLoadPost DONE")', + \ 'redraw!', + \ 'echon "SessionLoadPost DONE"', + \ 'qall!', \ 'endfunction', \ 'au SessionLoadPost * call DeleteInactiveBufs()'] call writefile(content, 'Xvimrc') - let a=system(v:progpath. ' --headless -u Xvimrc --noplugins -S Session.vim') + let a=system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim') " this probably only matches on unix if has("unix") call assert_notmatch('Caught deadly signal SEGV', a) -- cgit From 53ccd07fa1c0bfcb79ca11bd873ea12f4dc12f4a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 11:02:29 +0100 Subject: lint --- src/nvim/buffer.c | 4 ++-- src/nvim/ex_docmd.c | 18 ++++++++++-------- src/nvim/window.c | 5 +++-- 3 files changed, 15 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7429e8628e..3c416c157f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4518,8 +4518,8 @@ 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 + || (had_tab > 0 && wp != firstwin)) + && firstwin != lastwin && !(wp->w_closing || wp->w_buffer->b_locked > 0) ) { win_close(wp, FALSE); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index ebfbf2bf09..abf4371455 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5833,11 +5833,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_locked > 0)) + 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)) { @@ -6128,11 +6129,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_locked > 0)) + 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()) { diff --git a/src/nvim/window.c b/src/nvim/window.c index a737ffb33c..15482d9061 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1746,7 +1746,7 @@ void close_windows(buf_T *buf, int keep_curwin) FOR_ALL_WINDOWS_IN_TAB(wp, tp) { if (wp->w_buffer == buf && !(wp->w_closing || wp->w_buffer->b_locked > 0)) { - win_close_othertab(wp, FALSE, tp); + win_close_othertab(wp, false, tp); /* Start all over, the tab page may be closed and * autocommands may change the window layout. */ @@ -1881,7 +1881,8 @@ int win_close(win_T *win, int free_buf) return FAIL; } - if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) { + 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) { -- cgit From 929859ed8156a45f5acb491d82f8c06ef5f57902 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 13:11:10 +0100 Subject: vim-patch:7.4.2355 Problem: Regexp fails to match when using "\>\)\?". (Ramel) Solution: When a state is already in the list, but addstate_here() is used and the existing state comes later, add the new state anyway. https://github.com/vim/vim/commit/16b3578f355282846f2600ce77fb344950f0b9ce --- src/nvim/regexp_nfa.c | 61 +++++++++++++++++++++++++---------- src/nvim/testdir/test_regexp_utf8.vim | 9 ++++++ src/nvim/version.c | 2 +- 3 files changed, 54 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 474f3df32a..3f4e12af4a 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -3893,21 +3893,25 @@ 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; int save_in_use; @@ -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: @@ -4145,7 +4170,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; @@ -4168,7 +4193,7 @@ 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; } case NFA_MCLOSE1: @@ -4228,7 +4253,7 @@ skip_add: save_lpos.col = 0; } - 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; @@ -4266,8 +4291,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) diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim index 9e9a3de500..7f3b31575d 100644 --- a/src/nvim/testdir/test_regexp_utf8.vim +++ b/src/nvim/testdir/test_regexp_utf8.vim @@ -97,3 +97,12 @@ func Test_recursive_substitute() call setwinvar(1, 'myvar', 1) bwipe! 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/version.c b/src/nvim/version.c index d1d3e5a3c9..1b6e513c49 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -86,7 +86,7 @@ static int included_patches[] = { // 2358 NA // 2357, // 2356, - // 2355, + 2355, // 2354, 2353, // 2352 NA -- cgit From 5ee211770d9c7999a01413f368e82588f3d0426d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 13:22:14 +0100 Subject: vim-patch:8.0.0033 Problem: Cannot use overlapping positions with matchaddpos(). Solution: Check end of match. (Ozaki Kiichi) Add a test (Hirohito Higashi) https://github.com/vim/vim/commit/a6c27ee6db2c328e0ab0e6d143e2a295a0bb9c9a --- src/nvim/testdir/test_match.vim | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim index 9398ef2f27..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 -- cgit From cd9fc4627ecf4d675e2c221b614cc2eb40aabf9c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 13:26:02 +0100 Subject: vim-patch:8.0.0049 Problem: When a match ends in part of concealed text highlighting, it might mess up concealing by resetting prev_syntax_id. Solution: Do not reset prev_syntax_id and add a test to verify. (Christian Brabandt, closes vim/vim#1092) https://github.com/vim/vim/commit/2f97912800e86a296c001832bbbf2fc425f1e533 --- src/nvim/screen.c | 1 - src/nvim/testdir/test_matchadd_conceal.vim | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index b98e59ed06..280b8c65fe 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2922,7 +2922,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); diff --git a/src/nvim/testdir/test_matchadd_conceal.vim b/src/nvim/testdir/test_matchadd_conceal.vim index bc1c28d6e9..c788689e33 100644 --- a/src/nvim/testdir/test_matchadd_conceal.vim +++ b/src/nvim/testdir/test_matchadd_conceal.vim @@ -260,3 +260,25 @@ 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') + 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 -- cgit From 89abed7d852518528051c1c0fdf84d34d3d8c2d5 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 13:56:10 +0100 Subject: vim-patch:8.0.0032 Problem: Tests may change the input file when something goes wrong. Solution: Avoid writing the input file. https://github.com/vim/vim/commit/3e8474dd50f64c998bb665ce852f584a58dede6b --- src/nvim/testdir/test_tabpage.vim | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index 7c3039ba24..c2aadcea6e 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 -- cgit From 78a4c73cf06aaf8cd496d39bbbeaef821906fc25 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 14:11:27 +0100 Subject: vim-patch:7.4.2339 Problem: Tab page test fails when run as fake root. Solution: Check 'buftype' instead of 'filetype'. (James McCoy, closes vim/vim#1042) https://github.com/vim/vim/commit/100f5c90f4d4fb40bc3aeabc35192db371f5988f --- src/nvim/testdir/test_tabpage.vim | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index c2aadcea6e..870cb4da13 100644 --- a/src/nvim/testdir/test_tabpage.vim +++ b/src/nvim/testdir/test_tabpage.vim @@ -205,7 +205,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 diff --git a/src/nvim/version.c b/src/nvim/version.c index 1b6e513c49..db3b9b51b2 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -102,7 +102,7 @@ static int included_patches[] = { // 2342 NA 2341, // 2340 NA - // 2339, + 2339, // 2338 NA 2337, 2336, -- cgit From c99514c2a4ebfc35413daa57d017be16bd179e90 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 13:42:33 +0100 Subject: test/legacy: Run test_match, test_tabpage isolated These are failing when run as a batch. Most likely some Vim runtime patch fixed something, but we don't have it yet. Just isolate them for now. Also test_matchadd_conceal_utf8 (it's not there in Vim tree, either). --- src/nvim/testdir/test_alot.vim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 8aa0f417d1..9d1f07fc0b 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -13,8 +13,6 @@ source test_filter_map.vim source test_goto.vim source test_jumps.vim source test_lambda.vim -source test_match.vim -source test_matchadd_conceal_utf8.vim source test_menu.vim source test_mapping.vim source test_messages.vim @@ -26,7 +24,7 @@ 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_true_false.vim -- cgit From 386a5f379b059060808d9772cd1f150f507a5577 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 14:35:21 +0100 Subject: test/legacy: Makefile Add missing tests These tests aren't in test_alot.vim, so they need to be added to the Makefile or they won't be run. --- src/nvim/testdir/Makefile | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 0337ab13dd..d948cd0f93 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -36,6 +36,8 @@ NEW_TESTS ?= \ test_diffmode.res \ test_farsi.res \ test_filter_map.res \ + test_fold.res \ + test_glob2regpat.res \ test_gn.res \ test_hardcopy.res \ test_help_tagjump.res \ @@ -47,13 +49,16 @@ NEW_TESTS ?= \ 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_signs.res \ test_syntax.res \ + test_tabpage.res \ test_textobjects.res \ test_timers.res \ + test_undo.res \ test_usercommands.res \ test_viml.res \ test_visual.res \ -- cgit From 0f3afdaa1b5a75a5ed54a69dc43e32ddbb6a32ea Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 16:22:04 +0100 Subject: vim-patch:8.0.0259 Problem: Tab commands do not handle count correctly. (Ken Hamada) Solution: Add ADDR_TABS_RELATIVE. (Hirohito Higashi) https://github.com/vim/vim/commit/2f72c70657129c16e6b0e413752a775c804f02f8 --- src/nvim/ex_cmds.lua | 29 ++-- src/nvim/ex_cmds_defs.h | 3 +- src/nvim/ex_docmd.c | 282 ++++++++++++++++++++++++++------------ src/nvim/testdir/test_tabpage.vim | 242 ++++++++++++++++++++++++++++++-- 4 files changed, 444 insertions(+), 112 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 5f81306fc1..92f0669422 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -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. @@ -2650,12 +2651,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', }, @@ -2680,7 +2681,7 @@ return { { command='tabfirst', flags=bit.bor(TRLBAR), - addr_type=ADDR_LINES, + addr_type=ADDR_TABS, func='ex_tabnext', }, { @@ -2692,13 +2693,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', }, { @@ -2709,32 +2710,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_cmds_defs.h b/src/nvim/ex_cmds_defs.h index c6389a0c8b..133c37cef4 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -72,7 +72,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; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index abf4371455..4f34312562 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1522,8 +1522,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; @@ -1536,8 +1535,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); @@ -1587,6 +1588,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; @@ -1973,6 +1978,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; @@ -2028,11 +2036,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; + } } } @@ -3459,6 +3467,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; @@ -3493,6 +3506,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) { @@ -3641,6 +3659,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; @@ -3655,7 +3676,12 @@ 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 { @@ -3777,6 +3803,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)) { @@ -4285,6 +4314,104 @@ 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; + 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; + 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. */ @@ -5938,8 +6065,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; @@ -5947,44 +6075,43 @@ 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_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; - } } } } @@ -6473,6 +6600,8 @@ void tabpage_new(void) */ static void ex_tabnext(exarg_T *eap) { + int tab_number; + switch (eap->cmdidx) { case CMD_tabfirst: case CMD_tabrewind: @@ -6483,66 +6612,47 @@ static void ex_tabnext(exarg_T *eap) break; case CMD_tabprevious: case CMD_tabNext: - goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2); - break; - default: /* CMD_tabnext */ - goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2); - break; - } -} - -/* - * :tabmove command - */ -static void ex_tabmove(exarg_T *eap) -{ - int tab_number; + if (eap->arg && *eap->arg != NUL) { + char_u *p = eap->arg; + char_u *p_save = p; - if (eap->arg && *eap->arg != NUL) { - char_u *p = eap->arg; - int relative = 0; /* argument +N/-N means: move N places to the - * right/left relative to the current position. */ - - if (*eap->arg == '-') { - relative = -1; - p = eap->arg + 1; - } else if (*eap->arg == '+') { - relative = 1; - p = eap->arg + 1; - } else - p = eap->arg; - - if (relative == 0) { - if (STRCMP(p, "$") == 0) { - tab_number = LAST_TAB_NR; - } else if (p == skipdigits(p)) { + tab_number = getdigits(&p); + if (p == p_save || *p_save == '-' || *p != 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); + } } /* diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index 870cb4da13..33139fcda0 100644 --- a/src/nvim/testdir/test_tabpage.vim +++ b/src/nvim/testdir/test_tabpage.vim @@ -94,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 @@ -110,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 @@ -118,7 +123,6 @@ function Test_tabpage_with_autocmd() if !has('autocmd') return endif - tabonly! command -nargs=1 -bar C :call add(s:li, '=== ' . . ' ===')| augroup TestTabpageGroup au! @@ -183,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 @@ -192,8 +198,7 @@ function Test_tabpage_with_autocmd() augroup! TabDestructive autocmd! TestTabpageGroup augroup! TestTabpageGroup - tabonly! - bw! + 1tabonly! endfunction function Test_tabpage_with_tab_modifier() @@ -224,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() -- cgit From 7e23ce6b4fa843c12e44464a20154d92e95355c6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 17:34:25 +0100 Subject: lint --- src/nvim/ex_docmd.c | 168 ++++++++++++++++++++++++---------------------------- 1 file changed, 76 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4f34312562..2bd5158b33 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4314,102 +4314,86 @@ 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; - 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; - else - { - tab_number = eap->line2; - if (!unaccept_arg0 && **eap->cmdlinep == '-') - { - --tab_number; - if (tab_number < unaccept_arg0) - eap->errmsg = e_invarg; - } - } +/// 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; + 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++; } - 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); - } + + 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; + } 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; + return tab_number; } /* -- cgit From a24c6cc6a8e180d201c5887935d6dfdc95ac1abf Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 17:38:30 +0100 Subject: get_tabpage_arg: satisfy clang warning vim-patch:8.0.0266 --- src/nvim/ex_docmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 2bd5158b33..a06c6a89c8 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4319,7 +4319,7 @@ static int getargopt(exarg_T *eap) /// When an error is encountered then eap->errmsg is set. static int get_tabpage_arg(exarg_T *eap) { - int tab_number; + int tab_number = 0; int unaccept_arg0 = (eap->cmdidx == CMD_tabmove) ? 0 : 1; if (eap->arg && *eap->arg != NUL) { @@ -4368,6 +4368,7 @@ static int get_tabpage_arg(exarg_T *eap) } 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 == '-') { -- cgit From f06a6913260a320ec6b8ede5860edb1829c4f8ba Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 19:14:18 +0100 Subject: vim-patch:8.0.0037 Problem: Get E924 when switching tabs. () Solution: Use win_valid_any_tab() instead of win_valid(). (Martin Vuille, closes vim/vim#1167, closes vim/vim#1171) https://github.com/vim/vim/commit/0a9046fbcb33770517ab0220b8100c4494bddab2 --- src/nvim/quickfix.c | 2 +- src/nvim/testdir/test_quickfix.vim | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 3f7975051f..8d8c20c1d0 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1975,7 +1975,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; diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 640918b343..75ab01f013 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -599,6 +599,22 @@ function Test_locationlist_curwin_was_closed() augroup! testgroup endfunction +function 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') +endfunction + " More tests for 'errorformat' function! Test_efm1() if !has('unix') -- cgit From 9c8540edfd52c77678eac84e48beb56171487b3f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 19:16:26 +0100 Subject: vim-patch:8.0.0159 References #5406 Problem: Using a NULL pointer when using feedkeys() to trigger drawing a tabline. Solution: Skip drawing a tabline if TabPageIdxs is NULL. (Dominique Pelle) Also fix recursing into getcmdline() from the cmd window. https://github.com/vim/vim/commit/c695cec4698b41d7b9555efdd47dda9b1945d3ae --- src/nvim/ex_getln.c | 2 ++ src/nvim/screen.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index d99c8d02f7..d6e003a82f 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -698,7 +698,9 @@ static int command_line_execute(VimState *state, int key) if (s->c == cedit_key || s->c == K_CMDWIN) { if (ex_normal_busy == 0 && got_int == false) { // Open a window to edit the command line (and history). + save_cmdline(&s->save_ccline); s->c = ex_window(); + restore_cmdline(&s->save_ccline); s->some_key_typed = true; } } else { diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 280b8c65fe..baec18dd6f 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -6884,7 +6884,10 @@ static void draw_tabline(void) int use_sep_chars = (t_colors < 8 ); - redraw_tabline = FALSE; + if (ScreenLines == NULL) { + return; + } + redraw_tabline = false; if (tabline_height() < 1) -- cgit From b82e3358e006264187f104bb0321104621bcc811 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 19:23:12 +0100 Subject: vim-patch:8.0.0083 Problem: Using freed memory with win_getid(). (Domenique Pelle) Solution: For the current tab use curwin. https://github.com/vim/vim/commit/8e639052638a9bb8c7dd6e3e10776b1218cec1a3 --- src/nvim/testdir/test_window_id.vim | 9 +++++++++ src/nvim/window.c | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src') 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/window.c b/src/nvim/window.c index 15482d9061..ce322e1185 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5821,7 +5821,11 @@ int win_getid(typval_T *argvars) 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) { -- cgit From 01bf78971cea43938e01439ae6d4687bc97196ea Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 23:17:10 +0100 Subject: vim-patch:8.0.0172 Problem: The command selected in the command line window is not executed. (Andrey Starodubtsev) Solution: Save and restore the command line at a lower level. (closes vim/vim#1370) https://github.com/vim/vim/commit/1d669c233c97486555a34f7d3f069068d9ebdb63 --- src/nvim/ex_getln.c | 12 ++++-------- src/nvim/testdir/test_history.vim | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index d6e003a82f..2600f484dc 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -698,9 +698,7 @@ static int command_line_execute(VimState *state, int key) if (s->c == cedit_key || s->c == K_CMDWIN) { if (ex_normal_busy == 0 && got_int == false) { // Open a window to edit the command line (and history). - save_cmdline(&s->save_ccline); s->c = ex_window(); - restore_cmdline(&s->save_ccline); s->some_key_typed = true; } } else { @@ -5229,10 +5227,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; @@ -5266,8 +5262,8 @@ 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; diff --git a/src/nvim/testdir/test_history.vim b/src/nvim/testdir/test_history.vim index ee6acfffc3..3163b344d3 100644 --- a/src/nvim/testdir/test_history.vim +++ b/src/nvim/testdir/test_history.vim @@ -63,3 +63,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\", 'xt') + call assert_equal('a', getline('.')) + 1 + call feedkeys("/b\", 'xt') + call assert_equal('b', getline('.')) + 1 + " select the previous /a command + call feedkeys("q/kk\", 'x!') + call assert_equal('a', getline('.')) + call assert_equal('a', @/) + bwipe! +endfunc -- cgit From 33858ccb9b53d79f3dafbffef8ca7273be7de119 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 21 Mar 2017 23:36:27 +0100 Subject: vim-patch:8.0.0485 Problem: Not all windows commands are tested. Solution: Add more tests for windows commands. (Dominique Pelle, closes vim/vim#1575) Run test_autocmd separately, it interferes with other tests. Fix tests that depended on side effects. https://github.com/vim/vim/commit/4520d440c59034452d1450b27fcd56825c090687 --- src/nvim/testdir/Makefile | 1 + src/nvim/testdir/test_alot.vim | 1 - src/nvim/testdir/test_autocmd.vim | 2 + src/nvim/testdir/test_window_cmd.vim | 300 +++++++++++++++++++++++++++++++++++ 4 files changed, 303 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index d948cd0f93..531a07912f 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -28,6 +28,7 @@ SCRIPTS ?= \ # Tests using runtest.vim. # Keep test_alot*.res as the last one, sort the others. NEW_TESTS ?= \ + test_autocmd.res \ test_bufwintabinfo.res \ test_cmdline.res \ test_command_count.res \ diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 9d1f07fc0b..9c7db9e397 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -2,7 +2,6 @@ " 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 diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 5b5232f06e..e8e563d8ad 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -320,6 +320,8 @@ func Test_three_windows() call assert_equal('Xanother', expand('%')) au! + enew + bwipe! Xtestje1 call delete('Xtestje1') call delete('Xtestje2') call delete('Xtestje3') diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index 569a78a0ed..a5f27fba8a 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -67,4 +67,304 @@ function Test_window_cmd_wincmd_gf() augroup! test_window_cmd_wincmd_gf 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_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 -- cgit From 51bc9f243a0b60205985b42bb47f174379a463c6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 00:22:45 +0100 Subject: ex_tabnext: Disallow "+NN" arg. Need to do this explicitly because our implementation of getdigits() is slightly different. --- src/nvim/ex_docmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index a06c6a89c8..d815d57a60 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6602,7 +6602,8 @@ static void ex_tabnext(exarg_T *eap) char_u *p_save = p; tab_number = getdigits(&p); - if (p == p_save || *p_save == '-' || *p != NUL || tab_number == 0) { + if (p == p_save || *p_save == '-' || *p_save == '+' || *p != NUL + || tab_number == 0) { // No numbers as argument. eap->errmsg = e_invarg; return; -- cgit From 2b32053559669580f51da3cad2258f65c3adf9c4 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 01:19:13 +0100 Subject: test/legacy: Test_three_windows: rtp for :help --- src/nvim/testdir/test_autocmd.vim | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index e8e563d8ad..c4110eba94 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -314,6 +314,8 @@ func Test_three_windows() call assert_equal('Xanother', expand('%')) only + + helptags ALL help wincmd w 1quit -- cgit From f58a593cea3872c7b8b862375b6982436ee88ef2 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 01:26:32 +0100 Subject: vim-patch:8.0.0483 Problem: Illegal memory access when using :all. (Dominique Pelle) Solution: Adjust the cursor position right after setting "curwin". https://github.com/vim/vim/commit/f79225ed4f81bc579bb3360ad2eb06adc8058153 --- src/nvim/testdir/test_window_cmd.vim | 12 ++++++++++++ src/nvim/window.c | 8 +++++--- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index a5f27fba8a..188a7ed0f3 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -67,6 +67,18 @@ function Test_window_cmd_wincmd_gf() augroup! test_window_cmd_wincmd_gf endfunc +func Test_next_split_all() + " This was causing an illegal memory access. + n x + norm axxx + split + split + s/x + s/x + all + bwipe! +endfunc + func Test_window_quit() e Xa split Xb diff --git a/src/nvim/window.c b/src/nvim/window.c index ce322e1185..82e97ea00d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2018,10 +2018,12 @@ 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) - ) { + if (p_ea && (*p_ead == 'b' || *p_ead == dir)) { win_equal(curwin, true, dir); } else { win_comp_pos(); -- cgit From 54f31187ba006049ba455a1eeea4781750a3958d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 02:13:54 +0100 Subject: vim-patch:8.0.0482 Problem: The setbufvar() function may mess up the window layout. (Kay Z.) Solution: Do not check the window to be valid if it is NULL. https://github.com/vim/vim/commit/2c90d51123fba44a90e09aa4a4f2b7d972dadb94 --- src/nvim/testdir/test_functions.vim | 31 +++++++++++++++++++++++++++++++ src/nvim/window.c | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/nvim/testdir/test_functions.vim (limited to 'src') diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim new file mode 100644 index 0000000000..81cb6314ce --- /dev/null +++ b/src/nvim/testdir/test_functions.vim @@ -0,0 +1,31 @@ +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 + diff --git a/src/nvim/window.c b/src/nvim/window.c index 82e97ea00d..ebb998e3af 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5377,7 +5377,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; } -- cgit From 41bffeacff885b4904a1f456c6d56e016ad6f88c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 02:20:06 +0100 Subject: vim-patch:8.0.0331 Problem: Restoring help snapshot accesses freed memory. (Dominique Pelle) Solution: Don't restore a snapshot when the window closes. https://github.com/vim/vim/commit/343b8c042967da82f2f022afa31f2c97a264c1c8 --- src/nvim/testdir/test_help.vim | 16 ++++++++++++++++ src/nvim/window.c | 6 ++---- 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 src/nvim/testdir/test_help.vim (limited to 'src') 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/window.c b/src/nvim/window.c index ebb998e3af..a34daccb89 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5365,10 +5365,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 -- cgit From 830b31683e9958130a64b9dec990f42b58efc0a7 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 13:06:29 +0100 Subject: vim-patch:8.0.0502 Problem: Coverity complains about possible NULL pointer. Solution: Add an assert(), let's see if this works on all systems. https://github.com/vim/vim/commit/a37ffaa5e0a47e2db27bc0cc23f49e7094f47f3b --- src/nvim/window.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/window.c b/src/nvim/window.c index a34daccb89..db6c0f9048 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3167,6 +3167,7 @@ void close_tabpage(tabpage_T *tab) ptp = ptp->tp_next) { // do nothing } + assert(ptp != NULL); ptp->tp_next = tab->tp_next; } -- cgit From c398402f1225e8050856260cbc6ae929ff2f5c31 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 22 Mar 2017 15:02:19 +0100 Subject: vim-patch:8.0.0307 Problem: Asan detects a memory error when EXITFREE is defined. (Dominique Pelle) Solution: In getvcol() check for ml_get_buf() returning an empty string. Also skip adjusting the scroll position. Set "exiting" in mch_exit() for all systems. https://github.com/vim/vim/commit/955f198fc546cc30a34361932d3f454a61df0efa --- src/nvim/charset.c | 5 +++++ src/nvim/window.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 9e240fd38b..f31cef5886 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1160,6 +1160,11 @@ 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; } diff --git a/src/nvim/window.c b/src/nvim/window.c index db6c0f9048..dc0ce03794 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4803,7 +4803,11 @@ void win_new_height(win_T *wp, int height) wp->w_height = height; wp->w_skipcol = 0; - scroll_to_fraction(wp, prev_height); + // 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) -- cgit From 44e75eba30682007dd17f9a80805a9925a921976 Mon Sep 17 00:00:00 2001 From: raichoo Date: Wed, 22 Mar 2017 21:57:20 +0100 Subject: vim-patch:7.4.2161 (#6340) Problem: Expression test fails without conceal feature. Solution: Only check "conceal" with the conceal feature. https://github.com/vim/vim/commit/7ab6defcafe017a3ad58580a3e56dab705b1ed8b --- src/nvim/testdir/test_expr.vim | 8 ++++++-- src/nvim/version.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index ccbdde8244..2541d38d12 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -101,8 +101,12 @@ endfunc func Test_setmatches() hi def link 1 Comment hi def link 2 PreProc - let set = [{"group": 1, "pattern": 2, "id": 3, "priority": 4, "conceal": 5}] - let exp = [{"group": '1', "pattern": '2', "id": 3, "priority": 4, "conceal": '5'}] + 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 diff --git a/src/nvim/version.c b/src/nvim/version.c index 398a3e6542..cbb7902985 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -280,7 +280,7 @@ static int included_patches[] = { 2164, 2163, 2162, - // 2161, + 2161, 2160, 2159, 2158, -- cgit From 06ed7a189b2c1dca88f307538b9739b989776068 Mon Sep 17 00:00:00 2001 From: Jurica Bradarić Date: Thu, 23 Mar 2017 08:54:01 +0100 Subject: vim-patch:7.4.2329 (#6341) Problem: Error for min() and max() contains %s. (Nikolay Pavlov) Solution: Pass the function name. (closes vim/vim#1040) https://github.com/vim/vim/commit/26b84339fd8766898bcf6a259cbc2e0c38689726 --- src/nvim/eval.c | 5 +++-- src/nvim/testdir/test_expr.vim | 7 +++++++ src/nvim/version.c | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0872ed37ad..8f52717252 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13804,8 +13804,9 @@ static void max_min(typval_T *argvars, typval_T *rettv, int domax) } } } - } else - EMSG(_(e_listdictarg)); + } else { + EMSG2(_(e_listdictarg), domax ? "max()" : "min()"); + } rettv->vval.v_number = error ? 0 : n; } diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index 2541d38d12..03a9155512 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -335,6 +335,13 @@ function Test_printf_errors() 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', '')) diff --git a/src/nvim/version.c b/src/nvim/version.c index cbb7902985..32ef2c2fdb 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -112,7 +112,7 @@ static int included_patches[] = { // 2332 NA 2331, // 2330, - // 2329, + 2329, // 2328, // 2327 NA 2326, -- cgit From b2b88423aa0087e5d4aaa122e63dffb97f85222f Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Mon, 27 Feb 2017 09:46:50 +0000 Subject: Robustly handle folds during a :move command In order to re-order marks according to the :move command, do_move() uses mark_adjust() in a non-standard manner. The non-standard action is that it moves some marks *past* other marks. This doesn't matter for marks, but mark_adjust() calls foldMarkAdjust() which simply changes fold starts and lengths and doesn't have enough information to know that other folds have to be checked and reordered. The array of folds for each window are assumed to be in order of increasing line number, and if this gets broken some folds can get "lost". There has been a previous patch to avoid this problem by deleting and recalculating all folds in the window, but this comes at the cost of closing all folds when executing :move, and doesn't cover the case of manual folds. This patch adds a new function foldMoveRange() specifically for the :move command that handles reordering folds as well as simply moving them. Additionally, we allow calling mark_adjust_nofold() that does the same as mark_adjust() but doesn't affect any fold array. Calling mark_adjust_nofold() should be done in the same manner as calling mark_adjust(), but according changes to the fold arrays must be done seperately by the calling function. vim-patch:8.0.0457 vim-patch:8.0.0459 vim-patch:8.0.0461 vim-patch:8.0.0465 --- src/nvim/ex_cmds.c | 35 +++++----- src/nvim/fold.c | 148 +++++++++++++++++++++++++++++++++++++++++ src/nvim/mark.c | 22 +++++- src/nvim/testdir/test_fold.vim | 141 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 324 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 1b83677807..c560ff9210 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -756,14 +756,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 +793,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); if (dest >= line2) { - mark_adjust(line2 + 1, dest, -num_lines, 0L); + mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L); + 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); + 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); /* * Now we delete the original text -- webb @@ -851,11 +851,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; } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 7c0283971e..e2d1b017b6 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -2597,6 +2597,154 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot) } } +// 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 they are not necessarily in the correct + // order. + // We have to swap folds in the range [move_end, dest_index) with those in + // the range [move_start, move_end). + 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 */ /* * Merge two adjacent folds (and the nested ones in them). diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 4e05845eb5..de2fdd7f13 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -886,6 +886,23 @@ void ex_changes(exarg_T *eap) * or: mark_adjust(56, 55, MAXLNUM, 2); */ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) +{ + mark_adjust_internal(line1, line2, amount, amount_after, true); +} + +// 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) +{ + mark_adjust_internal(line1, line2, amount, amount_after, false); +} + +static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, + long amount_after, bool adjust_folds) { int i; int fnum = curbuf->b_fnum; @@ -1011,8 +1028,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); + } } } diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 7cb9faa75f..de07a05a2c 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -1,5 +1,9 @@ " 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, '}/*}}}*/', @@ -128,3 +132,140 @@ func Test_manual_fold_with_filter() call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$')) bwipe! 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 -- cgit From 308a953e0b892a0d59467e55227e972dbe51983c Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Wed, 22 Mar 2017 16:41:00 +0000 Subject: Fix wrap-around in 32 bit --- src/nvim/fold.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/nvim/fold.c b/src/nvim/fold.c index e2d1b017b6..5835da2e94 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -2507,6 +2507,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; @@ -2555,34 +2557,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)); @@ -2591,8 +2594,8 @@ 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); } } } -- cgit From a6c9c91841a9c3a63196ec5b82c09308c8e5b78d Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Thu, 23 Mar 2017 14:16:21 +0000 Subject: vim-patch:8.0.0407 : filtering folds with marker method not tested Problem: Filtering folds with marker method not tested. Solution: Also set 'foldmethod' to "marker". --- src/nvim/testdir/test_fold.vim | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index de07a05a2c..976c6b5cd1 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -120,17 +120,22 @@ func Test_manual_fold_with_filter() if !executable('cat') return endif - 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! + 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_move_folds_around_manual() -- cgit From 7214d0bc846179a862e8d3061d00270a6caa0d7b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 23 Mar 2017 14:07:51 +0100 Subject: XXX: ex_tabonly(): aucmd_win is not part of the window list. During free_all_mem, somehow ex_tabonly() may free aucmd_win. But it isn't fully destroyed (maybe autocmd_busy?). When win_free_all() tries to free aucmd_win directly, it double-frees the sub-fields. Tried unnsuccessfully to work around this by invoking `:tabonly!` with autocmds disabled: diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 58c01fbe7a12..91c845e94d22 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -565,9 +565,9 @@ void free_all_mem(void) /* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */ p_ea = false; if (first_tabpage->tp_next != NULL) - do_cmdline_cmd("tabonly!"); + do_cmdline_cmd("noautocmd tabonly!"); if (firstwin != lastwin) - do_cmdline_cmd("only!"); + do_cmdline_cmd("noautocmd only!"); /* Free all spell info. */ spell_free_all(); --- src/nvim/ex_docmd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index d815d57a60..486baaad47 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6081,6 +6081,9 @@ static void ex_tabonly(exarg_T *eap) // 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); -- cgit From 2a6d44ca5232d5fbfa0401451b3ebce60e93ed4d Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 24 Mar 2017 09:36:09 -0400 Subject: vim-patch:8.0.0250 Problem: When virtcol() gets a column that is not the first byte of a multi-byte character the result is unpredictable. (Christian Ludwig) Solution: Correct the column to the first byte of a multi-byte character. Change the utf-8 test to new style. https://github.com/vim/vim/commit/0c0590d9827cb07a33c1552cb3558b94bddcb4dc Closes #6269 --- src/nvim/charset.c | 1 + src/nvim/testdir/test_alot.vim | 1 + src/nvim/testdir/test_utf8.vim | 65 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/nvim/testdir/test_utf8.vim (limited to 'src') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index f31cef5886..efe32b915f 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1166,6 +1166,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, pos->col = 0; } posptr = ptr + pos->col; + posptr -= utf_head_off(line, posptr); } // This function is used very often, do some speed optimizations. diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 9c7db9e397..baf49b7ff7 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -28,4 +28,5 @@ source test_tagcase.vim source test_tagjump.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_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\jjIx\" + 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 \\\"\", 'itx') + call assert_equal('"Test1 ', getreg(':')) + + command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo + call feedkeys(":Test2 \\\"\", 'itx') + call assert_equal('"Test2 あた', getreg(':')) + + command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo + call feedkeys(":Test3 \\\"\", '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 -- cgit From 90ac8b09f56bf5a53ca9e1ddba0a5f92e4df7fa9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 25 Mar 2017 00:15:31 +0100 Subject: fold.c: uppercase macros --- src/nvim/fold.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 5835da2e94..36a5b0efd7 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -2649,9 +2649,9 @@ static void truncate_fold(fold_T *fp, linenr_T end) 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))) +#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) { @@ -2661,13 +2661,13 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2, const bool at_start = foldFind(gap, line1 - 1, &fp); if (at_start) { - if (fold_end(fp) > dest) { + 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) { + } 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. @@ -2684,22 +2684,22 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2, fp = fp + 1; } - if (!valid_fold(fp, gap) || fp->fd_top > dest) { + 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++) { + 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) { + 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) { + } 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); @@ -2710,12 +2710,12 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2, // 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_start = FOLD_INDEX(fp, gap); size_t move_end = 0, dest_index = 0; - for (; valid_fold(fp, gap) && fp->fd_top <= dest; fp++) { + for (; VALID_FOLD(fp, gap) && fp->fd_top <= dest; fp++) { if (fp->fd_top <= line2) { // 5, or 6 - if (fold_end(fp) > line2) { + if (FOLD_END(fp) > line2) { // 6, truncate before moving truncate_fold(fp, line2); } @@ -2725,16 +2725,16 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2, // Record index of the first fold after the moved range. if (move_end == 0) { - move_end = fold_index(fp, gap); + move_end = FOLD_INDEX(fp, gap); } - if (fold_end(fp) > dest) { + if (FOLD_END(fp) > dest) { truncate_fold(fp, dest); } fp->fd_top -= range_len; } - dest_index = fold_index(fp, gap); + dest_index = FOLD_INDEX(fp, gap); // All folds are now correct, but they are not necessarily in the correct // order. @@ -2744,9 +2744,9 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2, 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 +#undef FOLD_END +#undef VALID_FOLD +#undef FOLD_INDEX /* foldMerge() {{{2 */ /* -- cgit From 098e91400eb06d29c31264ba973ea8a563703059 Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Sat, 25 Mar 2017 14:43:19 +0000 Subject: refactor: Remove allow_keys global (#6346) * The allow_keys global is unused in nvim, remove it * clint --- src/nvim/digraph.c | 4 ---- src/nvim/edit.c | 36 ++++++++++++++++-------------------- src/nvim/eval.c | 6 ++---- src/nvim/ex_cmds.c | 6 ++---- src/nvim/ex_getln.c | 12 ++++-------- src/nvim/getchar.c | 27 ++++++++++----------------- src/nvim/globals.h | 12 +++++------- src/nvim/message.c | 23 +++++++++++------------ src/nvim/misc1.c | 18 +++++++----------- src/nvim/normal.c | 38 +++++++++++++------------------------- src/nvim/window.c | 11 +++++------ 11 files changed, 75 insertions(+), 118 deletions(-) (limited to 'src') diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 6ba6e659a6..560205fe7d 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1448,10 +1448,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 +1466,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 diff --git a/src/nvim/edit.c b/src/nvim/edit.c index aa029c38a2..5544f0b163 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -689,11 +689,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); @@ -8303,17 +8301,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(); @@ -8333,15 +8330,14 @@ 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); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8f52717252..d49fcbf17e 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -10596,8 +10596,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) varnumber_T n; int 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. @@ -10630,8 +10629,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) continue; break; } - --no_mapping; - --allow_keys; + no_mapping--; vimvars[VV_MOUSE_WIN].vv_nr = 0; vimvars[VV_MOUSE_WINID].vv_nr = 0; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 852d930b0a..678102daf6 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3577,11 +3577,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 */ diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 2600f484dc..58979c0e43 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -621,11 +621,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' @@ -1887,8 +1885,7 @@ getexmodeline ( msg_putchar(' '); } } - ++no_mapping; - ++allow_keys; + no_mapping++; /* * Get the line, one character at a time. @@ -2078,8 +2075,7 @@ redraw: } } - --no_mapping; - --allow_keys; + no_mapping--; /* make following messages go to the next line */ msg_didout = FALSE; diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index bae8ae6d91..0c131d7b33 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1389,27 +1389,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; @@ -1487,7 +1480,7 @@ int vgetc(void) buf[i] = CSI; } } - --no_mapping; + no_mapping--; c = (*mb_ptr2char)(buf); } @@ -1570,7 +1563,7 @@ int char_avail(void) no_mapping++; retval = vpeekc(); - --no_mapping; + no_mapping--; return retval != NUL; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index f8c7c9d330..ad14ec4f8c 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -832,13 +832,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 diff --git a/src/nvim/message.c b/src/nvim/message.c index 4cd0db21e8..cc9ef15f13 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -847,23 +847,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; - - /* Temporarily disable Recording. If Recording is active, the - * character will be recorded later, since it will be added to the - * typebuf after the loop */ + // 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 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; diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 0bb5a8468d..d751f13644 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2225,11 +2225,10 @@ int ask_yesno(const char *str, bool direct) int r = ' '; 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(); // disables mouse for xterm + no_mapping++; while (r != 'y' && r != 'n') { /* same highlighting as for wait_return */ @@ -2247,8 +2246,7 @@ int ask_yesno(const char *str, bool direct) --no_wait_return; State = save_State; setmouse(); - --no_mapping; - --allow_keys; + no_mapping--; return r; } @@ -2398,8 +2396,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(); @@ -2427,8 +2424,7 @@ get_number ( } else if (c == CAR || c == NL || c == Ctrl_C || c == ESC) break; } - --no_mapping; - --allow_keys; + no_mapping--; return n; } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 85dc509ee6..2ade9cb87d 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -642,8 +642,7 @@ static void normal_get_additional_char(NormalState *s) bool langmap_active = false; // using :lmap mappings int lang; // getting a text character - ++no_mapping; - ++allow_keys; // no mapping for nchar, but allow key codes + no_mapping++; // Don't generate a CursorHold event here, most commands can't handle // it, e.g., nv_replace(), nv_csearch(). did_cursorhold = true; @@ -681,8 +680,7 @@ static void normal_get_additional_char(NormalState *s) } if (lang && curbuf->b_p_iminsert == B_IMODE_LMAP) { // Allow mappings defined with ":lmap". - --no_mapping; - --allow_keys; + no_mapping--; if (repl) { State = LREPLACE; } else { @@ -695,8 +693,7 @@ static void normal_get_additional_char(NormalState *s) if (langmap_active) { // Undo the decrement done above - ++no_mapping; - ++allow_keys; + no_mapping++; State = NORMAL_BUSY; } State = NORMAL_BUSY; @@ -781,8 +778,7 @@ static void normal_get_additional_char(NormalState *s) } no_mapping++; } - --no_mapping; - --allow_keys; + no_mapping--; } static void normal_invert_horizontal(NormalState *s) @@ -832,8 +828,7 @@ static bool normal_get_command_count(NormalState *s) } if (s->ctrl_w) { - ++no_mapping; - ++allow_keys; // no mapping for nchar, but keys + no_mapping++; } ++no_zero_mapping; // don't map zero here @@ -841,8 +836,7 @@ static bool normal_get_command_count(NormalState *s) LANGMAP_ADJUST(s->c, true); --no_zero_mapping; if (s->ctrl_w) { - --no_mapping; - --allow_keys; + no_mapping--; } s->need_flushbuf |= add_to_showcmd(s->c); } @@ -852,12 +846,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; } @@ -4043,12 +4035,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; @@ -4376,13 +4366,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); diff --git a/src/nvim/window.c b/src/nvim/window.c index dc0ce03794..4fac730f02 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -447,13 +447,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 '}': -- cgit From 43a99f77a82e3de980798383ae8a4134953ece06 Mon Sep 17 00:00:00 2001 From: Yichao Zhou Date: Sun, 26 Mar 2017 04:04:20 -0700 Subject: highlight: :match should override 'list' (#6343) Closes #4946 --- src/nvim/screen.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index baec18dd6f..505d04ed56 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2193,7 +2193,8 @@ 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 @@ -2625,6 +2626,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; } @@ -2962,6 +2964,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; @@ -2974,8 +2977,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; } @@ -3711,7 +3716,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); } -- cgit From f9a31e98505c0f5e83dd3ba957fbd0f4b150d30c Mon Sep 17 00:00:00 2001 From: lonerover Date: Mon, 27 Mar 2017 01:04:57 +0800 Subject: vim-patch:7.4.2349 (#6368) Problem: Valgrind reports using uninitialzed memory. (Dominique Pelle) Solution: Check the length before checking for a NUL. https://github.com/vim/vim/commit/2321ca2a78286bc026fa7f407281ddbeb04114bb --- src/nvim/message.c | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index cc9ef15f13..bf54284881 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1986,7 +1986,7 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) char buf[4]; char *p; - while (*s != NUL && (maxlen < 0 || 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]; diff --git a/src/nvim/version.c b/src/nvim/version.c index db3b9b51b2..a354634218 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -92,7 +92,7 @@ static int included_patches[] = { // 2352 NA // 2351 NA // 2350, - // 2349, + 2349, 2348, 2347, 2346, -- cgit From e7bbd8256b8c701205389be431bbafd8743c72a9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 4 Mar 2016 21:55:28 +0300 Subject: eval: Add luaeval function No tests yet, no documentation update, no :lua* stuff, no vim module. converter.c should also work with typval_T, not Object. Known problem: luaeval("1", {}) results in PANIC: unprotected error in call to Lua API (attempt to index a nil value) Ref #3823 --- src/nvim/CMakeLists.txt | 40 ++- src/nvim/eval.c | 43 +++ src/nvim/eval.lua | 1 + src/nvim/viml/executor/converter.c | 537 +++++++++++++++++++++++++++++++++++++ src/nvim/viml/executor/converter.h | 12 + src/nvim/viml/executor/executor.c | 270 +++++++++++++++++++ src/nvim/viml/executor/executor.h | 23 ++ src/nvim/viml/executor/vim.lua | 2 + 8 files changed, 919 insertions(+), 9 deletions(-) create mode 100644 src/nvim/viml/executor/converter.c create mode 100644 src/nvim/viml/executor/converter.h create mode 100644 src/nvim/viml/executor/executor.c create mode 100644 src/nvim/viml/executor/executor.h create mode 100644 src/nvim/viml/executor/vim.lua (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 22cf1f3a3d..a47a8e49c7 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -11,11 +11,10 @@ endif() endif() 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(MSGPACK_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genmsgpack.lua) set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack) set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack) +set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c) set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua) set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include) set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h) @@ -37,8 +36,14 @@ 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(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}/viml/executor/vim_module.generated.h) +set(VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/viml/executor/vim.lua) +set(VIM_MODULE_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/generate_vim_module.lua) + +file(GLOB API_HEADERS api/*.h) +file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h) +file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt) include_directories(${GENERATED_DIR}) include_directories(${CACHED_GENERATED_DIR}) @@ -57,6 +62,8 @@ foreach(subdir tui event eval + viml + viml/executor ) if(${subdir} MATCHES "tui" AND NOT FEAT_TUI) continue() @@ -198,18 +205,30 @@ 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} ${MSGPACK_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} + ${MSGPACK_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua ) +add_custom_command( + OUTPUT ${VIM_MODULE_FILE} + COMMAND ${LUA_PRG} ${VIM_MODULE_GENERATOR} ${VIM_MODULE_SOURCE} + ${VIM_MODULE_FILE} + DEPENDS + ${VIM_MODULE_GENERATOR} + ${VIM_MODULE_SOURCE} +) + list(APPEND NEOVIM_GENERATED_SOURCES "${PROJECT_BINARY_DIR}/config/auto/pathdef.c" "${GENERATED_API_DISPATCH}" @@ -219,6 +238,8 @@ list(APPEND NEOVIM_GENERATED_SOURCES "${GENERATED_EVENTS_NAMES_MAP}" "${GENERATED_OPTIONS}" "${GENERATED_UNICODE_TABLES}" + "${MSGPACK_LUA_C_BINDINGS}" + "${VIM_MODULE_FILE}" ) add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS} @@ -270,6 +291,7 @@ list(APPEND NVIM_LINK_LIBRARIES ${LIBTERMKEY_LIBRARIES} ${UNIBILIUM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} + ${LUAJIT_LIBRARIES} ) if(UNIX) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d49fcbf17e..c9141fbcbf 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -95,6 +95,7 @@ #include "nvim/lib/khash.h" #include "nvim/lib/queue.h" #include "nvim/eval/typval_encode.h" +#include "nvim/viml/executor/executor.h" #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ @@ -13376,6 +13377,48 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) } } +/// luaeval() function implementation +static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) + FUNC_ATTR_NONNULL_ALL +{ + char *const str = (char *) get_tv_string(&argvars[0]); + if (str == NULL) { + return; + } + + Object arg; + if (argvars[1].v_type == VAR_UNKNOWN) { + arg = NIL; + } else { + arg = vim_to_object(&argvars[1]); + } + + // TODO(ZyX-I): Create function which converts lua objects directly to VimL + // objects, not to API objects. + Error err; + String err_str; + Object ret = executor_eval_lua(cstr_as_string(str), arg, &err, &err_str); + if (err.set) { + if (err_str.size) { + EMSG3(_("E971: Failed to eval lua string: %s (%s)"), err.msg, + err_str.data); + } else { + EMSG2(_("E971: Failed to eval lua string: %s"), err.msg); + } + } + + api_free_string(err_str); + + if (!err.set) { + if (!object_to_vim(ret, rettv, &err)) { + EMSG2(_("E972: Failed to convert resulting API object to VimL: %s"), + err.msg); + } + } + + api_free_object(ret); +} + /* * "map()" function */ diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e3c5981b32..9db90ce05d 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -193,6 +193,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}}, diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c new file mode 100644 index 0000000000..2105beb08a --- /dev/null +++ b/src/nvim/viml/executor/converter.c @@ -0,0 +1,537 @@ +#include +#include +#include +#include + +#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" + +#include "nvim/viml/executor/converter.h" +#include "nvim/viml/executor/executor.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "viml/executor/converter.c.generated.h" +#endif + +#define NLUA_PUSH_IDX(lstate, type, idx) \ + do { \ + STATIC_ASSERT(sizeof(type) <= sizeof(lua_Number), \ + "Number sizes do not match"); \ + const type src = idx; \ + lua_Number tgt; \ + memset(&tgt, 0, sizeof(tgt)); \ + memcpy(&tgt, &src, sizeof(src)); \ + lua_pushnumber(lstate, tgt); \ + } while (0) + +#define NLUA_POP_IDX(lstate, type, stack_idx, idx) \ + do { \ + STATIC_ASSERT(sizeof(type) <= sizeof(lua_Number), \ + "Number sizes do not match"); \ + const lua_Number src = lua_tonumber(lstate, stack_idx); \ + type tgt; \ + memcpy(&tgt, &src, sizeof(tgt)); \ + idx = tgt; \ + } while (0) + +/// 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, true); +} + +/// Push value which is a locks index +/// +/// Used for containers tables. +static inline void nlua_push_locks_idx(lua_State *lstate) + FUNC_ATTR_NONNULL_ALL +{ + lua_pushboolean(lstate, false); +} + +/// 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_pushnumber(lstate, (lua_Number) 0); +} + +/// Push type +/// +/// Type is a value in vim.types table. +/// +/// @param[out] lstate Lua state. +/// @param[in] type Type to push (key in vim.types table). +static inline void nlua_push_type(lua_State *lstate, const char *const type) +{ + lua_getglobal(lstate, "vim"); + lua_getfield(lstate, -1, "types"); + lua_remove(lstate, -2); + lua_getfield(lstate, -1, type); + lua_remove(lstate, -2); +} + +/// 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 char *const 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, "float"); + 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); +} + +static inline void nlua_add_locks_table(lua_State *lstate) +{ + nlua_push_locks_idx(lstate); + lua_newtable(lstate); + lua_rawset(lstate, -3); +} + +/// 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 +{ + nlua_create_typed_table(lstate, 0, 1 + dict.size, "dict"); + nlua_add_locks_table(lstate); + 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 +{ + nlua_create_typed_table(lstate, array.size, 1, "float"); + nlua_add_locks_table(lstate); + for (size_t i = 0; i < array.size; i++) { + nlua_push_Object(lstate, array.items[i]); + lua_rawseti(lstate, -3, (int) i + 1); + } +} + +#define GENERATE_INDEX_FUNCTION(type) \ +void nlua_push_##type(lua_State *lstate, const type item) \ + FUNC_ATTR_NONNULL_ALL \ +{ \ + NLUA_PUSH_IDX(lstate, type, 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 +{ + String ret; + + ret.data = (char *) lua_tolstring(lstate, -1, &(ret.size)); + + if (ret.data == NULL) { + lua_pop(lstate, 1); + set_api_error("Expected lua string", err); + return (String) { .size = 0, .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 +{ + Integer ret = 0; + + if (!lua_isnumber(lstate, -1)) { + lua_pop(lstate, 1); + set_api_error("Expected lua integer", err); + return ret; + } + ret = (Integer) lua_tonumber(lstate, -1); + lua_pop(lstate, 1); + + return ret; +} + +/// 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 +{ + Boolean ret = lua_toboolean(lstate, -1); + lua_pop(lstate, 1); + return ret; +} + +static inline bool nlua_check_type(lua_State *lstate, Error *err, + const char *const type) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (lua_type(lstate, -1) != LUA_TTABLE) { + set_api_error("Expected lua table", err); + return true; + } + + nlua_push_type_idx(lstate); + lua_rawget(lstate, -2); + nlua_push_type(lstate, type); + if (!lua_rawequal(lstate, -2, -1)) { + lua_pop(lstate, 2); + set_api_error("Expected lua table with float type", err); + return true; + } + lua_pop(lstate, 2); + + return false; +} + +/// 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 +{ + Float ret = 0; + + if (nlua_check_type(lstate, err, "float")) { + lua_pop(lstate, 1); + return 0; + } + + nlua_push_val_idx(lstate); + lua_rawget(lstate, -2); + + if (!lua_isnumber(lstate, -1)) { + lua_pop(lstate, 2); + set_api_error("Value field should be lua number", err); + return ret; + } + ret = lua_tonumber(lstate, -1); + lua_pop(lstate, 2); + + 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 +{ + Array ret = { .size = 0, .items = NULL }; + + if (nlua_check_type(lstate, err, "list")) { + lua_pop(lstate, 1); + return ret; + } + + for (int i = 1; ; i++, ret.size++) { + lua_rawgeti(lstate, -1, i); + + if (lua_isnil(lstate, -1)) { + lua_pop(lstate, 1); + break; + } + lua_pop(lstate, 1); + } + + 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 (err->set) { + ret.size = i; + 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 dictionary +/// +/// Always pops one value from the stack. Does not check whether +/// `vim.is_dict(table[type_idx])` or whether topmost value on the stack is +/// a table. +Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate, Error *err) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + Dictionary ret = { .size = 0, .items = NULL }; + + lua_pushnil(lstate); + + while (lua_next(lstate, -2)) { + if (lua_type(lstate, -2) == LUA_TSTRING) { + ret.size++; + } + lua_pop(lstate, 1); + } + + 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);) { + // 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 (!err->set) { + ret.items[i].value = nlua_pop_Object(lstate, err); + // stack: dict, key + } else { + lua_pop(lstate, 1); + // stack: dict, key + } + + if (err->set) { + 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 +{ + if (nlua_check_type(lstate, err, "dict")) { + lua_pop(lstate, 1); + return (Dictionary) { .size = 0, .items = NULL }; + } + + return nlua_pop_Dictionary_unchecked(lstate, err); +} + +/// Convert lua table to object +/// +/// Always pops one value from the stack. +Object nlua_pop_Object(lua_State *lstate, Error *err) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + Object ret = { .type = kObjectTypeNil }; + + switch (lua_type(lstate, -1)) { + case LUA_TNIL: { + ret.type = kObjectTypeNil; + lua_pop(lstate, 1); + break; + } + case LUA_TSTRING: { + ret.type = kObjectTypeString; + ret.data.string = nlua_pop_String(lstate, err); + break; + } + case LUA_TNUMBER: { + ret.type = kObjectTypeInteger; + ret.data.integer = nlua_pop_Integer(lstate, err); + break; + } + case LUA_TBOOLEAN: { + ret.type = kObjectTypeBoolean; + ret.data.boolean = nlua_pop_Boolean(lstate, err); + break; + } + case LUA_TTABLE: { + lua_getglobal(lstate, "vim"); + // stack: obj, vim +#define CHECK_TYPE(Type, key, vim_type) \ + lua_getfield(lstate, -1, "is_" #vim_type); \ + /* stack: obj, vim, checker */ \ + lua_pushvalue(lstate, -3); \ + /* stack: obj, vim, checker, obj */ \ + lua_call(lstate, 1, 1); \ + /* stack: obj, vim, result */ \ + if (lua_toboolean(lstate, -1)) { \ + lua_pop(lstate, 2); \ + /* stack: obj */ \ + ret.type = kObjectType##Type; \ + ret.data.key = nlua_pop_##Type(lstate, err); \ + /* stack: */ \ + break; \ + } \ + lua_pop(lstate, 1); \ + // stack: obj, vim + CHECK_TYPE(Float, floating, float) + CHECK_TYPE(Array, array, list) + CHECK_TYPE(Dictionary, dictionary, dict) +#undef CHECK_TYPE + lua_pop(lstate, 1); + // stack: obj + ret.type = kObjectTypeDictionary; + ret.data.dictionary = nlua_pop_Dictionary_unchecked(lstate, err); + break; + } + default: { + lua_pop(lstate, 1); + set_api_error("Cannot convert given lua type", err); + break; + } + } + if (err->set) { + ret.type = kObjectTypeNil; + } + + 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; \ + NLUA_POP_IDX(lstate, type, -1, ret); \ + lua_pop(lstate, 1); \ + return ret; \ +} + +GENERATE_INDEX_FUNCTION(Buffer) +GENERATE_INDEX_FUNCTION(Window) +GENERATE_INDEX_FUNCTION(Tabpage) + +#undef GENERATE_INDEX_FUNCTION diff --git a/src/nvim/viml/executor/converter.h b/src/nvim/viml/executor/converter.h new file mode 100644 index 0000000000..e11d0cef19 --- /dev/null +++ b/src/nvim/viml/executor/converter.h @@ -0,0 +1,12 @@ +#ifndef NVIM_VIML_EXECUTOR_CONVERTER_H +#define NVIM_VIML_EXECUTOR_CONVERTER_H + +#include +#include +#include "nvim/api/private/defs.h" +#include "nvim/func_attr.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "viml/executor/converter.h.generated.h" +#endif +#endif // NVIM_VIML_EXECUTOR_CONVERTER_H diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c new file mode 100644 index 0000000000..6f1e847649 --- /dev/null +++ b/src/nvim/viml/executor/executor.c @@ -0,0 +1,270 @@ +#include +#include +#include + +#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/vim.h" +#include "nvim/vim.h" +#include "nvim/message.h" + +#include "nvim/viml/executor/executor.h" +#include "nvim/viml/executor/converter.h" + +typedef struct { + Error err; + String lua_err_str; +} LuaError; + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "viml/executor/vim_module.generated.h" +# include "viml/executor/executor.c.generated.h" +#endif + +/// Name of the run code for use in messages +#define NLUA_EVAL_NAME "" + +/// 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 four 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) + +static void set_lua_error(lua_State *lstate, LuaError *lerr) + FUNC_ATTR_NONNULL_ALL +{ + const char *const str = lua_tolstring(lstate, -1, &lerr->lua_err_str.size); + lerr->lua_err_str.data = xmemdupz(str, lerr->lua_err_str.size); + lua_pop(lstate, 1); + + // FIXME? More specific error? + set_api_error("Error while executing lua code", &lerr->err); +} + +/// 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 *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 three values on the stack: string to evaluate, pointer to the +/// location where result is saved, pointer to the location where error is +/// saved. Always returns nothing (from the lua point of view). +static int nlua_exec_lua_string(lua_State *lstate) FUNC_ATTR_NONNULL_ALL +{ + String *str = (String *) lua_touserdata(lstate, 1); + Object *obj = (Object *) lua_touserdata(lstate, 2); + LuaError *lerr = (LuaError *) lua_touserdata(lstate, 3); + lua_pop(lstate, 3); + + if (luaL_loadbuffer(lstate, str->data, str->size, NLUA_EVAL_NAME)) { + set_lua_error(lstate, lerr); + return 0; + } + if (lua_pcall(lstate, 0, 1, 0)) { + set_lua_error(lstate, lerr); + return 0; + } + *obj = nlua_pop_Object(lstate, &lerr->err); + return 0; +} + +/// Initialize lua interpreter state +/// +/// Called by lua interpreter itself to initialize state. +static int nlua_state_init(lua_State *lstate) FUNC_ATTR_NONNULL_ALL +{ + lua_pushcfunction(lstate, &nlua_stricmp); + lua_setglobal(lstate, "stricmp"); + if (luaL_dostring(lstate, (char *) &vim_module[0])) { + LuaError lerr; + set_lua_error(lstate, &lerr); + return 1; + } + nlua_add_api_functions(lstate); + lua_setglobal(lstate, "vim"); + return 0; +} + +/// Initialize lua interpreter +/// +/// Crashes NeoVim if initialization fails. Should be called once per lua +/// interpreter instance. +static lua_State *init_lua(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; +} + +static Object exec_lua_string(lua_State *lstate, String str, LuaError *lerr) + FUNC_ATTR_NONNULL_ALL +{ + Object ret = { kObjectTypeNil, { false } }; + NLUA_CALL_C_FUNCTION_3(lstate, nlua_exec_lua_string, 0, &str, &ret, lerr); + return ret; +} + +static lua_State *global_lstate = NULL; + +/// Execute lua string +/// +/// Used for :lua. +/// +/// @param[in] str String to execute. +/// @param[out] err Location where error will be saved. +/// @param[out] err_str Location where lua error string will be saved, if any. +/// +/// @return Result of the execution. +Object executor_exec_lua(String str, Error *err, String *err_str) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (global_lstate == NULL) { + global_lstate = init_lua(); + } + + LuaError lerr = { + .err = { .set = false }, + .lua_err_str = STRING_INIT, + }; + + Object ret = exec_lua_string(global_lstate, str, &lerr); + + *err = lerr.err; + *err_str = lerr.lua_err_str; + + return ret; +} + +/// 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. +/// 4. Pointer to location where error will be saved. +/// +/// @param[in,out] lstate Lua interpreter state. +static int nlua_eval_lua_string(lua_State *lstate) + FUNC_ATTR_NONNULL_ALL +{ + String *str = (String *) lua_touserdata(lstate, 1); + Object *arg = (Object *) lua_touserdata(lstate, 2); + Object *ret = (Object *) lua_touserdata(lstate, 3); + LuaError *lerr = (LuaError *) lua_touserdata(lstate, 4); + + garray_T str_ga; + ga_init(&str_ga, 1, 80); +#define EVALHEADER "local _A=select(1,...) return " + ga_concat_len(&str_ga, EVALHEADER, sizeof(EVALHEADER) - 1); +#undef EVALHEADER + ga_concat_len(&str_ga, str->data, str->size); + if (luaL_loadbuffer(lstate, str_ga.ga_data, (size_t) str_ga.ga_len, + NLUA_EVAL_NAME)) { + set_lua_error(lstate, lerr); + return 0; + } + ga_clear(&str_ga); + + nlua_push_Object(lstate, *arg); + if (lua_pcall(lstate, 1, 1, 0)) { + set_lua_error(lstate, lerr); + return 0; + } + *ret = nlua_pop_Object(lstate, &lerr->err); + + return 0; +} + +static Object eval_lua_string(lua_State *lstate, String str, Object arg, + LuaError *lerr) + FUNC_ATTR_NONNULL_ALL +{ + Object ret = { kObjectTypeNil, { false } }; + NLUA_CALL_C_FUNCTION_4(lstate, nlua_eval_lua_string, 0, + &str, &arg, &ret, lerr); + return ret; +} + +/// Evaluate lua string +/// +/// Used for luaeval(). +/// +/// @param[in] str String to execute. +/// @param[out] err Location where error will be saved. +/// @param[out] err_str Location where lua error string will be saved, if any. +/// +/// @return Result of the execution. +Object executor_eval_lua(String str, Object arg, Error *err, String *err_str) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (global_lstate == NULL) { + global_lstate = init_lua(); + } + + LuaError lerr = { + .err = { .set = false }, + .lua_err_str = STRING_INIT, + }; + + Object ret = eval_lua_string(global_lstate, str, arg, &lerr); + + *err = lerr.err; + *err_str = lerr.lua_err_str; + + return ret; +} diff --git a/src/nvim/viml/executor/executor.h b/src/nvim/viml/executor/executor.h new file mode 100644 index 0000000000..85cb3550e7 --- /dev/null +++ b/src/nvim/viml/executor/executor.h @@ -0,0 +1,23 @@ +#ifndef NVIM_VIML_EXECUTOR_EXECUTOR_H +#define NVIM_VIML_EXECUTOR_EXECUTOR_H + +#include + +#include "nvim/api/private/defs.h" +#include "nvim/func_attr.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 "viml/executor/executor.h.generated.h" +#endif +#endif // NVIM_VIML_EXECUTOR_EXECUTOR_H diff --git a/src/nvim/viml/executor/vim.lua b/src/nvim/viml/executor/vim.lua new file mode 100644 index 0000000000..8d1c5bdf4f --- /dev/null +++ b/src/nvim/viml/executor/vim.lua @@ -0,0 +1,2 @@ +-- TODO(ZyX-I): Create compatibility layer. +return {} -- cgit From f551df17f33e7f38b7e5693eb923118ca1542d27 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 10 Jul 2016 08:03:14 +0300 Subject: viml/executor: Directly generate typval_T values Note: this will *still* crash when using API in cases similar to the one described in first commit. Just it needs different code to reproduce. --- src/nvim/eval.c | 70 +++---- src/nvim/eval/decode.c | 138 +++++++------ src/nvim/viml/executor/converter.c | 388 +++++++++++++++++++++++++++++++++++++ src/nvim/viml/executor/converter.h | 3 + src/nvim/viml/executor/executor.c | 159 ++++++++------- 5 files changed, 572 insertions(+), 186 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c9141fbcbf..248383d2e1 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6480,28 +6480,44 @@ static void dict_free_dict(dict_T *d) { xfree(d); } -void dict_free(dict_T *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 +/// Allocate a dictionary item +/// +/// @note that the value of the item di_tv still needs to be initialized. +/// +/// @param[in] key Item key. +/// @param[in] len Key length. +/// +/// @return [allocated] New dictionary item. +dictitem_T *dictitem_alloc_len(const char *const key, const size_t len) + FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT { - dictitem_T *di = xmalloc(offsetof(dictitem_T, di_key) + STRLEN(key) + 1); -#ifndef __clang_analyzer__ - STRCPY(di->di_key, key); -#endif + dictitem_T *const di = xmallocz(offsetof(dictitem_T, di_key) + len); + memcpy(di->di_key, key, len); 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 Item key, NUL-terminated string. +/// +/// @return [allocated] New dictionary item. +dictitem_T *dictitem_alloc(const char_u *const key) + FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT +{ + return dictitem_alloc_len((const char *)key, STRLEN(key)); +} + /* * Make a copy of a Dictionary item. */ @@ -13386,37 +13402,7 @@ static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - Object arg; - if (argvars[1].v_type == VAR_UNKNOWN) { - arg = NIL; - } else { - arg = vim_to_object(&argvars[1]); - } - - // TODO(ZyX-I): Create function which converts lua objects directly to VimL - // objects, not to API objects. - Error err; - String err_str; - Object ret = executor_eval_lua(cstr_as_string(str), arg, &err, &err_str); - if (err.set) { - if (err_str.size) { - EMSG3(_("E971: Failed to eval lua string: %s (%s)"), err.msg, - err_str.data); - } else { - EMSG2(_("E971: Failed to eval lua string: %s"), err.msg); - } - } - - api_free_string(err_str); - - if (!err.set) { - if (!object_to_vim(ret, rettv, &err)) { - EMSG2(_("E972: Failed to convert resulting API object to VimL: %s"), - err.msg); - } - } - - api_free_object(ret); + executor_eval_lua(cstr_as_string(str), &argvars[1], rettv); } /* diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 43e9f76c0f..cb5a624f7b 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -7,6 +7,7 @@ #include "nvim/eval/encode.h" #include "nvim/ascii.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 @@ -218,6 +219,69 @@ 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 = 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. +/// +/// @return Decoded string. +typval_T decode_string(const char *const s, const size_t len, + const TriState hasnul, const bool binary) + 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 = 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 }, + })); + if (encode_list_write((void *)list, s, len) == -1) { + clear_tv(&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 = xmemdupz(s, len) }, + }; + } +} + /// Parse JSON double-quoted string /// /// @param[in] conv Defines conversion necessary to convert UTF-8 string to @@ -428,29 +492,13 @@ static inline int parse_json_string(vimconv_T *const conv, 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); + typval_T obj; + obj = decode_string(str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, + false); + 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; @@ -827,13 +875,7 @@ 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->dv_refcount++; @@ -980,37 +1022,15 @@ 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); + 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); + if (rettv->v_type == VAR_UNKNOWN) { return FAIL; } break; @@ -1067,13 +1087,7 @@ 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); diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index 2105beb08a..123659aa5c 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -2,12 +2,24 @@ #include #include #include +#include +#include #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_defs.h" +#include "nvim/ascii.h" + +#include "nvim/lib/kvec.h" +#include "nvim/eval/decode.h" #include "nvim/viml/executor/converter.h" #include "nvim/viml/executor/executor.h" @@ -16,6 +28,382 @@ # include "viml/executor/converter.c.generated.h" #endif +/// 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. +} PopStackItem; + +/// 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; +#ifndef NDEBUG + const int initial_size = lua_gettop(lstate); +#endif + kvec_t(PopStackItem) stack = KV_INITIAL_VALUE; + kv_push(stack, ((PopStackItem) { ret_tv, false, false })); + 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; + } + PopStackItem 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)); + if (lua_next(lstate, -2)) { + assert(lua_type(lstate, -2) == LUA_TSTRING); + size_t len; + const char *s = lua_tolstring(lstate, -2, &len); + if (cur.special) { + list_T *const kv_pair = list_alloc(); + list_append_list(cur.tv->vval.v_list, kv_pair); + listitem_T *const key = listitem_alloc(); + key->li_tv = decode_string(s, len, kTrue, false); + list_append(kv_pair, key); + if (key->li_tv.v_type == VAR_UNKNOWN) { + ret = false; + list_unref(kv_pair); + continue; + } + listitem_T *const val = listitem_alloc(); + list_append(kv_pair, val); + kv_push(stack, cur); + cur = (PopStackItem) { &val->li_tv, false, false }; + } else { + dictitem_T *const di = dictitem_alloc_len(s, len); + if (dict_add(cur.tv->vval.v_dict, di) == FAIL) { + assert(false); + } + kv_push(stack, cur); + cur = (PopStackItem) { &di->di_tv, false, false }; + } + } 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, 1); + lua_pop(lstate, 1); + continue; + } + listitem_T *li = listitem_alloc(); + list_append(cur.tv->vval.v_list, li); + kv_push(stack, cur); + cur = (PopStackItem) { &li->li_tv, false, false }; + } + } + assert(!cur.container); + memset(cur.tv, 0, sizeof(*cur.tv)); + 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); + 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: { + bool has_string = false; + bool has_string_with_nul = false; + bool has_other = false; + size_t maxidx = 0; + size_t tsize = 0; + 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) { + has_string_with_nul = true; + } + has_string = true; + 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) { + has_other = true; + } else { + const size_t idx = (size_t)n; + if (idx > maxidx) { + maxidx = idx; + } + } + break; + } + default: { + has_other = true; + break; + } + } + tsize++; + lua_pop(lstate, 1); + } + + if (tsize == 0) { + // Assuming empty list + cur.tv->v_type = VAR_LIST; + cur.tv->vval.v_list = list_alloc(); + cur.tv->vval.v_list->lv_refcount++; + } else if (tsize == maxidx && !has_other && !has_string) { + // Assuming array + cur.tv->v_type = VAR_LIST; + cur.tv->vval.v_list = list_alloc(); + cur.tv->vval.v_list->lv_refcount++; + cur.container = true; + kv_push(stack, cur); + } else if (has_string && !has_other && maxidx == 0) { + // Assuming dictionary + cur.special = has_string_with_nul; + if (has_string_with_nul) { + decode_create_map_special_dict(cur.tv); + assert(cur.tv->v_type = VAR_DICT); + dictitem_T *const val_di = dict_find(cur.tv->vval.v_dict, + (char_u *)"_VAL", 4); + 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 = dict_alloc(); + cur.tv->vval.v_dict->dv_refcount++; + } + cur.container = true; + kv_push(stack, cur); + lua_pushnil(lstate); + } else { + 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: { + EMSG(_("E5101: Cannot convert given lua type")); + ret = false; + break; + } + } + if (!cur.container) { + lua_pop(lstate, 1); + } + } + kv_destroy(stack); + if (!ret) { + clear_tv(ret_tv); + memset(ret_tv, 0, sizeof(*ret_tv)); + 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) \ + TYPVAL_ENCODE_CONV_EMPTY_LIST() + +#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, \ + 1 - ((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 + 1)) { + 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; +} + #define NLUA_PUSH_IDX(lstate, type, idx) \ do { \ STATIC_ASSERT(sizeof(type) <= sizeof(lua_Number), \ diff --git a/src/nvim/viml/executor/converter.h b/src/nvim/viml/executor/converter.h index e11d0cef19..dbbaaebf6b 100644 --- a/src/nvim/viml/executor/converter.h +++ b/src/nvim/viml/executor/converter.h @@ -3,8 +3,11 @@ #include #include +#include + #include "nvim/api/private/defs.h" #include "nvim/func_attr.h" +#include "nvim/eval.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "viml/executor/converter.h.generated.h" diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 6f1e847649..a9d05bcd31 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -36,7 +36,19 @@ typedef struct { lua_pushcfunction(lstate, &function); \ lua_call(lstate, 0, numret); \ } while (0) -/// Call C function which expects four arguments +/// 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 @@ -64,15 +76,19 @@ typedef struct { lua_call(lstate, 4, numret); \ } while (0) -static void set_lua_error(lua_State *lstate, LuaError *lerr) +/// 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 { - const char *const str = lua_tolstring(lstate, -1, &lerr->lua_err_str.size); - lerr->lua_err_str.data = xmemdupz(str, lerr->lua_err_str.size); - lua_pop(lstate, 1); + size_t len; + const char *const str = lua_tolstring(lstate, -1, &len); + + EMSG2(msg, str); - // FIXME? More specific error? - set_api_error("Error while executing lua code", &lerr->err); + lua_pop(lstate, 1); } /// Compare two strings, ignoring case @@ -94,25 +110,26 @@ static int nlua_stricmp(lua_State *lstate) FUNC_ATTR_NONNULL_ALL /// Evaluate lua string /// -/// Expects three values on the stack: string to evaluate, pointer to the -/// location where result is saved, pointer to the location where error is -/// saved. Always returns nothing (from the lua point of view). +/// 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 *lstate) FUNC_ATTR_NONNULL_ALL { - String *str = (String *) lua_touserdata(lstate, 1); - Object *obj = (Object *) lua_touserdata(lstate, 2); - LuaError *lerr = (LuaError *) lua_touserdata(lstate, 3); - lua_pop(lstate, 3); + String *str = (String *)lua_touserdata(lstate, 1); + typval_T *ret_tv = (typval_T *)lua_touserdata(lstate, 2); + lua_pop(lstate, 2); if (luaL_loadbuffer(lstate, str->data, str->size, NLUA_EVAL_NAME)) { - set_lua_error(lstate, lerr); + nlua_error(lstate, _("E5104: Error while creating lua chunk: %s")); return 0; } if (lua_pcall(lstate, 0, 1, 0)) { - set_lua_error(lstate, lerr); + nlua_error(lstate, _("E5105: Error while calling lua chunk: %s")); + return 0; + } + if (!nlua_pop_typval(lstate, ret_tv)) { return 0; } - *obj = nlua_pop_Object(lstate, &lerr->err); return 0; } @@ -124,8 +141,7 @@ static int nlua_state_init(lua_State *lstate) FUNC_ATTR_NONNULL_ALL lua_pushcfunction(lstate, &nlua_stricmp); lua_setglobal(lstate, "stricmp"); if (luaL_dostring(lstate, (char *) &vim_module[0])) { - LuaError lerr; - set_lua_error(lstate, &lerr); + nlua_error(lstate, _("E5106: Error while creating vim module: %s")); return 1; } nlua_add_api_functions(lstate); @@ -150,14 +166,6 @@ static lua_State *init_lua(void) return lstate; } -static Object exec_lua_string(lua_State *lstate, String str, LuaError *lerr) - FUNC_ATTR_NONNULL_ALL -{ - Object ret = { kObjectTypeNil, { false } }; - NLUA_CALL_C_FUNCTION_3(lstate, nlua_exec_lua_string, 0, &str, &ret, lerr); - return ret; -} - static lua_State *global_lstate = NULL; /// Execute lua string @@ -165,28 +173,17 @@ static lua_State *global_lstate = NULL; /// Used for :lua. /// /// @param[in] str String to execute. -/// @param[out] err Location where error will be saved. -/// @param[out] err_str Location where lua error string will be saved, if any. +/// @param[out] ret_tv Location where result will be saved. /// /// @return Result of the execution. -Object executor_exec_lua(String str, Error *err, String *err_str) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +void executor_exec_lua(String str, typval_T *ret_tv) + FUNC_ATTR_NONNULL_ALL { if (global_lstate == NULL) { global_lstate = init_lua(); } - LuaError lerr = { - .err = { .set = false }, - .lua_err_str = STRING_INIT, - }; - - Object ret = exec_lua_string(global_lstate, str, &lerr); - - *err = lerr.err; - *err_str = lerr.lua_err_str; - - return ret; + NLUA_CALL_C_FUNCTION_2(global_lstate, nlua_exec_lua_string, 0, &str, ret_tv); } /// Evaluate lua string @@ -196,75 +193,73 @@ Object executor_exec_lua(String str, Error *err, String *err_str) /// 1. String to evaluate. /// 2. _A value. /// 3. Pointer to location where result is saved. -/// 4. Pointer to location where error will be saved. /// /// @param[in,out] lstate Lua interpreter state. static int nlua_eval_lua_string(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { - String *str = (String *) lua_touserdata(lstate, 1); - Object *arg = (Object *) lua_touserdata(lstate, 2); - Object *ret = (Object *) lua_touserdata(lstate, 3); - LuaError *lerr = (LuaError *) lua_touserdata(lstate, 4); + String *str = (String *)lua_touserdata(lstate, 1); + typval_T *arg = (typval_T *)lua_touserdata(lstate, 2); + typval_T *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 " - ga_concat_len(&str_ga, EVALHEADER, sizeof(EVALHEADER) - 1); +#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 - ga_concat_len(&str_ga, str->data, str->size); - if (luaL_loadbuffer(lstate, str_ga.ga_data, (size_t) str_ga.ga_len, - NLUA_EVAL_NAME)) { - set_lua_error(lstate, lerr); + if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) { + nlua_error(lstate, + _("E5107: Error while creating lua chunk for luaeval(): %s")); return 0; } - ga_clear(&str_ga); + if (lcmd != (char *)IObuff) { + xfree(lcmd); + } - nlua_push_Object(lstate, *arg); + if (arg == NULL || arg->v_type == VAR_UNKNOWN) { + lua_pushnil(lstate); + } else { + nlua_push_typval(lstate, arg); + } if (lua_pcall(lstate, 1, 1, 0)) { - set_lua_error(lstate, lerr); + nlua_error(lstate, + _("E5108: Error while calling lua chunk for luaeval(): %s")); + return 0; + } + if (!nlua_pop_typval(lstate, ret_tv)) { return 0; } - *ret = nlua_pop_Object(lstate, &lerr->err); return 0; } -static Object eval_lua_string(lua_State *lstate, String str, Object arg, - LuaError *lerr) - FUNC_ATTR_NONNULL_ALL -{ - Object ret = { kObjectTypeNil, { false } }; - NLUA_CALL_C_FUNCTION_4(lstate, nlua_eval_lua_string, 0, - &str, &arg, &ret, lerr); - return ret; -} - /// Evaluate lua string /// /// Used for luaeval(). /// /// @param[in] str String to execute. -/// @param[out] err Location where error will be saved. -/// @param[out] err_str Location where lua error string will be saved, if any. +/// @param[in] arg Second argument to `luaeval()`. +/// @param[out] ret_tv Location where result will be saved. /// /// @return Result of the execution. -Object executor_eval_lua(String str, Object arg, Error *err, String *err_str) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +void executor_eval_lua(const String str, typval_T *const arg, + typval_T *const ret_tv) + FUNC_ATTR_NONNULL_ALL { if (global_lstate == NULL) { global_lstate = init_lua(); } - LuaError lerr = { - .err = { .set = false }, - .lua_err_str = STRING_INIT, - }; - - Object ret = eval_lua_string(global_lstate, str, arg, &lerr); - - *err = lerr.err; - *err_str = lerr.lua_err_str; - - return ret; + NLUA_CALL_C_FUNCTION_3(global_lstate, nlua_eval_lua_string, 0, + (void *)&str, arg, ret_tv); } -- cgit From a4dc8de0739d8e9e910d786a9b6fbfbc162aee9c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 10 Jul 2016 21:49:59 +0300 Subject: *: Silence linter --- src/nvim/eval.c | 2 +- src/nvim/viml/executor/converter.c | 20 ++++++++++---------- src/nvim/viml/executor/executor.c | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 248383d2e1..c349a601c6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13397,7 +13397,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) FUNC_ATTR_NONNULL_ALL { - char *const str = (char *) get_tv_string(&argvars[0]); + const char *const str = (const char *)get_tv_string(&argvars[0]); if (str == NULL) { return; } diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index 123659aa5c..fb7bbd51eb 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -334,8 +334,8 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) 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)) { \ + ? (void *)mpval.data.d.dict == (void *)(val) \ + : (void *)mpval.data.l.list == (void *)(val)) { \ lua_pushvalue(lstate, \ 1 - ((int)((kv_size(*mpstack) - backref + 1) * 2))); \ break; \ @@ -450,7 +450,7 @@ static inline void nlua_push_locks_idx(lua_State *lstate) static inline void nlua_push_val_idx(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { - lua_pushnumber(lstate, (lua_Number) 0); + lua_pushnumber(lstate, (lua_Number)0); } /// Push type @@ -480,7 +480,7 @@ static inline void nlua_create_typed_table(lua_State *lstate, const char *const type) FUNC_ATTR_NONNULL_ALL { - lua_createtable(lstate, (int) narr, (int) (1 + nrec)); + lua_createtable(lstate, (int)narr, (int)(1 + nrec)); nlua_push_type_idx(lstate); nlua_push_type(lstate, type); lua_rawset(lstate, -3); @@ -502,7 +502,7 @@ void nlua_push_String(lua_State *lstate, const String s) void nlua_push_Integer(lua_State *lstate, const Integer n) FUNC_ATTR_NONNULL_ALL { - lua_pushnumber(lstate, (lua_Number) n); + lua_pushnumber(lstate, (lua_Number)n); } /// Convert given Float to lua table @@ -513,7 +513,7 @@ void nlua_push_Float(lua_State *lstate, const Float f) { nlua_create_typed_table(lstate, 0, 1, "float"); nlua_push_val_idx(lstate); - lua_pushnumber(lstate, (lua_Number) f); + lua_pushnumber(lstate, (lua_Number)f); lua_rawset(lstate, -3); } @@ -558,7 +558,7 @@ void nlua_push_Array(lua_State *lstate, const Array array) nlua_add_locks_table(lstate); for (size_t i = 0; i < array.size; i++) { nlua_push_Object(lstate, array.items[i]); - lua_rawseti(lstate, -3, (int) i + 1); + lua_rawseti(lstate, -3, (int)i + 1); } } @@ -619,7 +619,7 @@ String nlua_pop_String(lua_State *lstate, Error *err) { String ret; - ret.data = (char *) lua_tolstring(lstate, -1, &(ret.size)); + ret.data = (char *)lua_tolstring(lstate, -1, &(ret.size)); if (ret.data == NULL) { lua_pop(lstate, 1); @@ -646,7 +646,7 @@ Integer nlua_pop_Integer(lua_State *lstate, Error *err) set_api_error("Expected lua integer", err); return ret; } - ret = (Integer) lua_tonumber(lstate, -1); + ret = (Integer)lua_tonumber(lstate, -1); lua_pop(lstate, 1); return ret; @@ -744,7 +744,7 @@ Array nlua_pop_Array(lua_State *lstate, Error *err) for (size_t i = 1; i <= ret.size; i++) { Object val; - lua_rawgeti(lstate, -1, (int) i); + lua_rawgeti(lstate, -1, (int)i); val = nlua_pop_Object(lstate, err); if (err->set) { diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index a9d05bcd31..1a7b5f8915 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -104,7 +104,7 @@ static int nlua_stricmp(lua_State *lstate) FUNC_ATTR_NONNULL_ALL 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))); + lua_pushnumber(lstate, (lua_Number)((ret > 0) - (ret < 0))); return 1; } @@ -140,7 +140,7 @@ static int nlua_state_init(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { lua_pushcfunction(lstate, &nlua_stricmp); lua_setglobal(lstate, "stricmp"); - if (luaL_dostring(lstate, (char *) &vim_module[0])) { + if (luaL_dostring(lstate, (char *)&vim_module[0])) { nlua_error(lstate, _("E5106: Error while creating vim module: %s")); return 1; } -- cgit From ed3115bd26047c9b125798d9cb56d09b155a243b Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 11 Jul 2016 20:42:27 +0300 Subject: executor: Make sure it works with API values --- src/nvim/api/vim.c | 16 +- src/nvim/eval.c | 2 +- src/nvim/viml/executor/converter.c | 547 +++++++++++++++++++++++-------------- src/nvim/viml/executor/executor.c | 1 + 4 files changed, 362 insertions(+), 204 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 413456c615..24959e9a59 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -197,7 +197,21 @@ Object nvim_eval(String expr, Error *err) return rv; } -/// Calls a VimL function with the given arguments. +/// 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 _vim_id(Object obj) +{ + return obj; +} + +/// 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 diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c349a601c6..de82f8a145 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13402,7 +13402,7 @@ static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - executor_eval_lua(cstr_as_string(str), &argvars[1], rettv); + executor_eval_lua(cstr_as_string((char *)str), &argvars[1], rettv); } /* diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index fb7bbd51eb..c127b87738 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -24,10 +24,121 @@ #include "nvim/viml/executor/converter.h" #include "nvim/viml/executor/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. +} LuaTableProps; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "viml/executor/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 +{ + bool has_type_key = false; // True if type key was found, + // @see nlua_push_type_idx(). + 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(). + bool has_other = false; // True if there are keys that are not strings + // or positive integral values. + LuaTableProps ret; + memset(&ret, 0, sizeof(ret)); + if (!lua_checkstack(lstate, lua_gettop(lstate) + 2)) { + 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) { + has_other = true; + } 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) { + has_type_key = true; + ret.type = (ObjectType)n; + } else { + has_other = true; + } + } else { + has_other = true; + } + } else { + has_val_key = true; + val_type = lua_type(lstate, -1); + if (val_type == LUA_TNUMBER) { + ret.val = lua_tonumber(lstate, -1); + } + } + break; + } + default: { + has_other = true; + break; + } + } + tsize++; + lua_pop(lstate, 1); + } + if (has_type_key) { + if (ret.type == kObjectTypeFloat + && (!has_val_key || val_type != LUA_TNUMBER)) { + ret.type = kObjectTypeNil; + } + } else { + if (tsize == 0 + || (tsize == ret.maxidx && !has_other && 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. @@ -63,8 +174,15 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) if (cur.container) { if (cur.special || cur.tv->v_type == VAR_DICT) { assert(cur.tv->v_type == (cur.special ? VAR_LIST : VAR_DICT)); - if (lua_next(lstate, -2)) { - assert(lua_type(lstate, -2) == LUA_TSTRING); + 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) { @@ -109,7 +227,11 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) } } assert(!cur.container); - memset(cur.tv, 0, sizeof(*cur.tv)); + *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; @@ -145,81 +267,64 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) break; } case LUA_TTABLE: { - bool has_string = false; - bool has_string_with_nul = false; - bool has_other = false; - size_t maxidx = 0; - size_t tsize = 0; - 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) { - has_string_with_nul = true; - } - has_string = true; - break; + const LuaTableProps table_props = nlua_traverse_table(lstate); + + switch (table_props.type) { + case kObjectTypeArray: { + if (table_props.maxidx == 0) { + cur.tv->v_type = VAR_LIST; + cur.tv->vval.v_list = list_alloc(); + cur.tv->vval.v_list->lv_refcount++; + } else { + cur.tv->v_type = VAR_LIST; + cur.tv->vval.v_list = list_alloc(); + cur.tv->vval.v_list->lv_refcount++; + cur.container = true; + kv_push(stack, cur); } - 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) { - has_other = true; + break; + } + case kObjectTypeDictionary: { + if (table_props.string_keys_num == 0) { + cur.tv->v_type = VAR_DICT; + cur.tv->vval.v_dict = 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 = dict_find(cur.tv->vval.v_dict, + (char_u *)"_VAL", 4); + assert(val_di != NULL); + cur.tv = &val_di->di_tv; + assert(cur.tv->v_type == VAR_LIST); } else { - const size_t idx = (size_t)n; - if (idx > maxidx) { - maxidx = idx; - } + cur.tv->v_type = VAR_DICT; + cur.tv->vval.v_dict = dict_alloc(); + cur.tv->vval.v_dict->dv_refcount++; } - break; - } - default: { - has_other = true; - break; + cur.container = true; + kv_push(stack, cur); + lua_pushnil(lstate); } + break; } - tsize++; - lua_pop(lstate, 1); - } - - if (tsize == 0) { - // Assuming empty list - cur.tv->v_type = VAR_LIST; - cur.tv->vval.v_list = list_alloc(); - cur.tv->vval.v_list->lv_refcount++; - } else if (tsize == maxidx && !has_other && !has_string) { - // Assuming array - cur.tv->v_type = VAR_LIST; - cur.tv->vval.v_list = list_alloc(); - cur.tv->vval.v_list->lv_refcount++; - cur.container = true; - kv_push(stack, cur); - } else if (has_string && !has_other && maxidx == 0) { - // Assuming dictionary - cur.special = has_string_with_nul; - if (has_string_with_nul) { - decode_create_map_special_dict(cur.tv); - assert(cur.tv->v_type = VAR_DICT); - dictitem_T *const val_di = dict_find(cur.tv->vval.v_dict, - (char_u *)"_VAL", 4); - 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 = dict_alloc(); - cur.tv->vval.v_dict->dv_refcount++; + 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); } - cur.container = true; - kv_push(stack, cur); - lua_pushnil(lstate); - } else { - 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; } @@ -236,7 +341,11 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) kv_destroy(stack); if (!ret) { clear_tv(ret_tv); - memset(ret_tv, 0, sizeof(*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); @@ -281,7 +390,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) lua_createtable(lstate, 0, 0) #define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ - TYPVAL_ENCODE_CONV_EMPTY_LIST() + nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary) #define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ do { \ @@ -432,16 +541,7 @@ bool nlua_push_typval(lua_State *lstate, typval_T *const tv) static inline void nlua_push_type_idx(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { - lua_pushboolean(lstate, true); -} - -/// Push value which is a locks index -/// -/// Used for containers tables. -static inline void nlua_push_locks_idx(lua_State *lstate) - FUNC_ATTR_NONNULL_ALL -{ - lua_pushboolean(lstate, false); + lua_pushboolean(lstate, TYPE_IDX_VALUE); } /// Push value which is a value index @@ -450,7 +550,7 @@ static inline void nlua_push_locks_idx(lua_State *lstate) static inline void nlua_push_val_idx(lua_State *lstate) FUNC_ATTR_NONNULL_ALL { - lua_pushnumber(lstate, (lua_Number)0); + lua_pushboolean(lstate, VAL_IDX_VALUE); } /// Push type @@ -458,14 +558,11 @@ static inline void nlua_push_val_idx(lua_State *lstate) /// Type is a value in vim.types table. /// /// @param[out] lstate Lua state. -/// @param[in] type Type to push (key in vim.types table). -static inline void nlua_push_type(lua_State *lstate, const char *const type) +/// @param[in] type Type to push. +static inline void nlua_push_type(lua_State *lstate, ObjectType type) + FUNC_ATTR_NONNULL_ALL { - lua_getglobal(lstate, "vim"); - lua_getfield(lstate, -1, "types"); - lua_remove(lstate, -2); - lua_getfield(lstate, -1, type); - lua_remove(lstate, -2); + lua_pushnumber(lstate, (lua_Number)type); } /// Create lua table which has an entry that determines its VimL type @@ -477,7 +574,7 @@ static inline void nlua_push_type(lua_State *lstate, const char *const type) static inline void nlua_create_typed_table(lua_State *lstate, const size_t narr, const size_t nrec, - const char *const type) + const ObjectType type) FUNC_ATTR_NONNULL_ALL { lua_createtable(lstate, (int)narr, (int)(1 + nrec)); @@ -511,7 +608,7 @@ void nlua_push_Integer(lua_State *lstate, const Integer n) void nlua_push_Float(lua_State *lstate, const Float f) FUNC_ATTR_NONNULL_ALL { - nlua_create_typed_table(lstate, 0, 1, "float"); + nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat); nlua_push_val_idx(lstate); lua_pushnumber(lstate, (lua_Number)f); lua_rawset(lstate, -3); @@ -526,21 +623,17 @@ void nlua_push_Boolean(lua_State *lstate, const Boolean b) lua_pushboolean(lstate, b); } -static inline void nlua_add_locks_table(lua_State *lstate) -{ - nlua_push_locks_idx(lstate); - lua_newtable(lstate); - lua_rawset(lstate, -3); -} - /// 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 { - nlua_create_typed_table(lstate, 0, 1 + dict.size, "dict"); - nlua_add_locks_table(lstate); + 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); @@ -554,11 +647,10 @@ void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict) void nlua_push_Array(lua_State *lstate, const Array array) FUNC_ATTR_NONNULL_ALL { - nlua_create_typed_table(lstate, array.size, 1, "float"); - nlua_add_locks_table(lstate); + 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, -3, (int)i + 1); + lua_rawseti(lstate, -2, (int)i + 1); } } @@ -663,26 +755,33 @@ Boolean nlua_pop_Boolean(lua_State *lstate, Error *err) return ret; } -static inline bool nlua_check_type(lua_State *lstate, Error *err, - const char *const type) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +/// 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) { - set_api_error("Expected lua table", err); - return true; + if (err) { + set_api_error("Expected lua table", err); + } + return (LuaTableProps) { .type = kObjectTypeNil }; } + const LuaTableProps table_props = nlua_traverse_table(lstate); - nlua_push_type_idx(lstate); - lua_rawget(lstate, -2); - nlua_push_type(lstate, type); - if (!lua_rawequal(lstate, -2, -1)) { - lua_pop(lstate, 2); - set_api_error("Expected lua table with float type", err); - return true; + if (table_props.type != type) { + if (err) { + set_api_error("Unexpected type", err); + } } - lua_pop(lstate, 2); - return false; + return table_props; } /// Convert lua table to float @@ -691,49 +790,32 @@ static inline bool nlua_check_type(lua_State *lstate, Error *err, Float nlua_pop_Float(lua_State *lstate, Error *err) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - Float ret = 0; - - if (nlua_check_type(lstate, err, "float")) { + if (lua_type(lstate, -1) == LUA_TNUMBER) { + const Float ret = (Float)lua_tonumber(lstate, -1); lua_pop(lstate, 1); - return 0; - } - - nlua_push_val_idx(lstate); - lua_rawget(lstate, -2); - - if (!lua_isnumber(lstate, -1)) { - lua_pop(lstate, 2); - set_api_error("Value field should be lua number", err); return ret; } - ret = lua_tonumber(lstate, -1); - lua_pop(lstate, 2); - 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 +/// Convert lua table to array without determining whether it is 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 +/// @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 = 0, .items = NULL }; - - if (nlua_check_type(lstate, err, "list")) { - lua_pop(lstate, 1); - return ret; - } - - for (int i = 1; ; i++, ret.size++) { - lua_rawgeti(lstate, -1, i); - - if (lua_isnil(lstate, -1)) { - lua_pop(lstate, 1); - break; - } - lua_pop(lstate, 1); - } + Array ret = { .size = table_props.maxidx, .items = NULL }; if (ret.size == 0) { lua_pop(lstate, 1); @@ -748,7 +830,7 @@ Array nlua_pop_Array(lua_State *lstate, Error *err) val = nlua_pop_Object(lstate, err); if (err->set) { - ret.size = i; + ret.size = i - 1; lua_pop(lstate, 1); api_free_array(ret); return (Array) { .size = 0, .items = NULL }; @@ -760,24 +842,35 @@ Array nlua_pop_Array(lua_State *lstate, Error *err) return ret; } -/// Convert lua table to dictionary +/// Convert lua table to array /// -/// Always pops one value from the stack. Does not check whether -/// `vim.is_dict(table[type_idx])` or whether topmost value on the stack is -/// a table. -Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate, Error *err) +/// 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 { - Dictionary ret = { .size = 0, .items = NULL }; - - lua_pushnil(lstate); - - while (lua_next(lstate, -2)) { - if (lua_type(lstate, -2) == LUA_TSTRING) { - ret.size++; - } - lua_pop(lstate, 1); + const LuaTableProps table_props = nlua_check_type(lstate, err, + kObjectTypeArray); + lua_pop(lstate, 1); + 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); @@ -786,7 +879,7 @@ Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate, Error *err) ret.items = xcalloc(ret.size, sizeof(*ret.items)); lua_pushnil(lstate); - for (size_t i = 0; lua_next(lstate, -2);) { + for (size_t i = 0; lua_next(lstate, -2) && i < ret.size;) { // stack: dict, key, value if (lua_type(lstate, -2) == LUA_TSTRING) { @@ -828,12 +921,14 @@ Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate, Error *err) Dictionary nlua_pop_Dictionary(lua_State *lstate, Error *err) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - if (nlua_check_type(lstate, err, "dict")) { + 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, err); + return nlua_pop_Dictionary_unchecked(lstate, table_props, err); } /// Convert lua table to object @@ -856,8 +951,16 @@ Object nlua_pop_Object(lua_State *lstate, Error *err) break; } case LUA_TNUMBER: { - ret.type = kObjectTypeInteger; - ret.data.integer = nlua_pop_Integer(lstate, err); + 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) { + ret.type = kObjectTypeFloat; + ret.data.floating = (Float)n; + } else { + ret.type = kObjectTypeInteger; + ret.data.integer = (Integer)n; + } + lua_pop(lstate, 1); break; } case LUA_TBOOLEAN: { @@ -866,33 +969,26 @@ Object nlua_pop_Object(lua_State *lstate, Error *err) break; } case LUA_TTABLE: { - lua_getglobal(lstate, "vim"); - // stack: obj, vim -#define CHECK_TYPE(Type, key, vim_type) \ - lua_getfield(lstate, -1, "is_" #vim_type); \ - /* stack: obj, vim, checker */ \ - lua_pushvalue(lstate, -3); \ - /* stack: obj, vim, checker, obj */ \ - lua_call(lstate, 1, 1); \ - /* stack: obj, vim, result */ \ - if (lua_toboolean(lstate, -1)) { \ - lua_pop(lstate, 2); \ - /* stack: obj */ \ - ret.type = kObjectType##Type; \ - ret.data.key = nlua_pop_##Type(lstate, err); \ - /* stack: */ \ - break; \ - } \ - lua_pop(lstate, 1); \ - // stack: obj, vim - CHECK_TYPE(Float, floating, float) - CHECK_TYPE(Array, array, list) - CHECK_TYPE(Dictionary, dictionary, dict) -#undef CHECK_TYPE - lua_pop(lstate, 1); - // stack: obj - ret.type = kObjectTypeDictionary; - ret.data.dictionary = nlua_pop_Dictionary_unchecked(lstate, err); + const LuaTableProps table_props = nlua_traverse_table(lstate); + ret.type = table_props.type; + switch (table_props.type) { + case kObjectTypeArray: { + ret.data.array = nlua_pop_Array_unchecked(lstate, table_props, err); + break; + } + case kObjectTypeDictionary: { + ret.data.dictionary = nlua_pop_Dictionary_unchecked(lstate, + table_props, err); + break; + } + case kObjectTypeFloat: { + ret.data.floating = (Float)table_props.val; + break; + } + default: { + assert(false); + } + } break; } default: { @@ -923,3 +1019,50 @@ 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/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 1a7b5f8915..33b6870ea0 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -145,6 +145,7 @@ static int nlua_state_init(lua_State *lstate) FUNC_ATTR_NONNULL_ALL return 1; } nlua_add_api_functions(lstate); + nlua_init_types(lstate); lua_setglobal(lstate, "vim"); return 0; } -- cgit From 3fa4ca81880bc5113c32a89de965ce593e9b001f Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 12 Jul 2016 19:04:12 +0300 Subject: executor/converter: Fix conversion of self-containing containers --- src/nvim/viml/executor/converter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index c127b87738..319e07bdbc 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -446,7 +446,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) ? (void *)mpval.data.d.dict == (void *)(val) \ : (void *)mpval.data.l.list == (void *)(val)) { \ lua_pushvalue(lstate, \ - 1 - ((int)((kv_size(*mpstack) - backref + 1) * 2))); \ + -((int)((kv_size(*mpstack) - backref + 1) * 2))); \ break; \ } \ } \ -- cgit From 9297d941e2f1576006d77bfd6391cecc3bea37b0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 12 Jul 2016 19:20:57 +0300 Subject: executor/converter: Fix how maxidx is determined --- src/nvim/viml/executor/converter.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index 319e07bdbc..c8d6848006 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -54,8 +54,8 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) 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(). - bool has_other = false; // True if there are keys that are not strings - // or positive integral values. + 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) + 2)) { @@ -79,7 +79,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) const lua_Number n = lua_tonumber(lstate, -2); if (n > (lua_Number)SIZE_MAX || n <= 0 || ((lua_Number)((size_t)n)) != n) { - has_other = true; + other_keys_num++; } else { const size_t idx = (size_t)n; if (idx > ret.maxidx) { @@ -99,10 +99,10 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) has_type_key = true; ret.type = (ObjectType)n; } else { - has_other = true; + other_keys_num++; } } else { - has_other = true; + other_keys_num++; } } else { has_val_key = true; @@ -114,7 +114,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) break; } default: { - has_other = true; + other_keys_num++; break; } } @@ -125,10 +125,33 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) 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 + - 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 && !has_other && ret.string_keys_num == 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; -- cgit From 425d348f0f9f680a44af31fc3cecd20a07374bb5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 16 Jul 2016 00:34:24 +0300 Subject: executor/converter: Make nlua_pop_Object not recursive --- src/nvim/api/private/defs.h | 2 +- src/nvim/api/vim.c | 54 +++++++-- src/nvim/viml/executor/converter.c | 243 ++++++++++++++++++++++++++----------- 3 files changed, 211 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 223aab09dc..86b549cb44 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -76,10 +76,10 @@ typedef struct { } Dictionary; typedef enum { + kObjectTypeNil = 0, kObjectTypeBuffer, kObjectTypeWindow, kObjectTypeTabpage, - kObjectTypeNil, kObjectTypeBoolean, kObjectTypeInteger, kObjectTypeFloat, diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 24959e9a59..5d862628cb 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -197,19 +197,6 @@ Object nvim_eval(String expr, Error *err) return rv; } -/// 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 _vim_id(Object obj) -{ - return obj; -} - /// Calls a VimL function with the given arguments /// /// On VimL error: Returns a generic error; v:errmsg is not updated. @@ -843,3 +830,44 @@ 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 _vim_id(Object obj) +{ + return 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 _vim_id_array(Array arr) +{ + return arr; +} + +/// 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 _vim_id_dictionary(Dictionary dct) +{ + return dct; +} diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index c8d6848006..6c9b42b38c 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -58,7 +58,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) // or type keys. LuaTableProps ret; memset(&ret, 0, sizeof(ret)); - if (!lua_checkstack(lstate, lua_gettop(lstate) + 2)) { + 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; @@ -168,7 +168,7 @@ typedef struct { bool container; ///< True if tv is a container. bool special; ///< If true then tv is a _VAL part of special dictionary ///< that represents mapping. -} PopStackItem; +} TVPopStackItem; /// Convert lua object to VimL typval_T /// @@ -182,18 +182,16 @@ typedef struct { bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) { bool ret = true; -#ifndef NDEBUG const int initial_size = lua_gettop(lstate); -#endif - kvec_t(PopStackItem) stack = KV_INITIAL_VALUE; - kv_push(stack, ((PopStackItem) { ret_tv, false, false })); + kvec_t(TVPopStackItem) stack = KV_INITIAL_VALUE; + kv_push(stack, ((TVPopStackItem) { ret_tv, false, false })); 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; } - PopStackItem cur = kv_pop(stack); + 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)); @@ -222,14 +220,14 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) listitem_T *const val = listitem_alloc(); list_append(kv_pair, val); kv_push(stack, cur); - cur = (PopStackItem) { &val->li_tv, false, false }; + cur = (TVPopStackItem) { &val->li_tv, false, false }; } else { dictitem_T *const di = dictitem_alloc_len(s, len); if (dict_add(cur.tv->vval.v_dict, di) == FAIL) { assert(false); } kv_push(stack, cur); - cur = (PopStackItem) { &di->di_tv, false, false }; + cur = (TVPopStackItem) { &di->di_tv, false, false }; } } else { lua_pop(lstate, 1); @@ -239,14 +237,13 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) 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, 1); - lua_pop(lstate, 1); + lua_pop(lstate, 2); continue; } listitem_T *li = listitem_alloc(); list_append(cur.tv->vval.v_list, li); kv_push(stack, cur); - cur = (PopStackItem) { &li->li_tv, false, false }; + cur = (TVPopStackItem) { &li->li_tv, false, false }; } } assert(!cur.container); @@ -294,14 +291,10 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) switch (table_props.type) { case kObjectTypeArray: { - if (table_props.maxidx == 0) { - cur.tv->v_type = VAR_LIST; - cur.tv->vval.v_list = list_alloc(); - cur.tv->vval.v_list->lv_refcount++; - } else { - cur.tv->v_type = VAR_LIST; - cur.tv->vval.v_list = list_alloc(); - cur.tv->vval.v_list->lv_refcount++; + cur.tv->v_type = VAR_LIST; + cur.tv->vval.v_list = list_alloc(); + cur.tv->vval.v_list->lv_refcount++; + if (table_props.maxidx != 0) { cur.container = true; kv_push(stack, cur); } @@ -525,7 +518,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) bool nlua_push_typval(lua_State *lstate, typval_T *const tv) { const int initial_size = lua_gettop(lstate); - if (!lua_checkstack(lstate, initial_size + 1)) { + if (!lua_checkstack(lstate, initial_size + 2)) { emsgf(_("E1502: Lua failed to grow stack to %i"), initial_size + 4); return false; } @@ -873,7 +866,6 @@ Array nlua_pop_Array(lua_State *lstate, Error *err) { const LuaTableProps table_props = nlua_check_type(lstate, err, kObjectTypeArray); - lua_pop(lstate, 1); if (table_props.type != kObjectTypeArray) { return (Array) { .size = 0, .items = NULL }; } @@ -954,76 +946,179 @@ Dictionary nlua_pop_Dictionary(lua_State *lstate, Error *err) 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 *lstate, Error *err) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +Object nlua_pop_Object(lua_State *const lstate, Error *const err) { - Object ret = { .type = kObjectTypeNil }; - - switch (lua_type(lstate, -1)) { - case LUA_TNIL: { - ret.type = kObjectTypeNil; - lua_pop(lstate, 1); - break; - } - case LUA_TSTRING: { - ret.type = kObjectTypeString; - ret.data.string = nlua_pop_String(lstate, 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 (!err->set && kv_size(stack)) { + if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { + api_set_error(err, Exception, "Lua failed to grow stack"); 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) { - ret.type = kObjectTypeFloat; - ret.data.floating = (Float)n; + 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 { - ret.type = kObjectTypeInteger; - ret.data.integer = (Integer)n; - } - lua_pop(lstate, 1); - break; - } - case LUA_TBOOLEAN: { - ret.type = kObjectTypeBoolean; - ret.data.boolean = nlua_pop_Boolean(lstate, err); - break; - } - case LUA_TTABLE: { - const LuaTableProps table_props = nlua_traverse_table(lstate); - ret.type = table_props.type; - switch (table_props.type) { - case kObjectTypeArray: { - ret.data.array = nlua_pop_Array_unchecked(lstate, table_props, err); - break; + if (cur.obj->data.array.size == cur.obj->data.array.capacity) { + lua_pop(lstate, 1); + continue; } - case kObjectTypeDictionary: { - ret.data.dictionary = nlua_pop_Dictionary_unchecked(lstate, - table_props, err); - break; + 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; } - case kObjectTypeFloat: { - ret.data.floating = (Float)table_props.val; - break; + 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 = FLOATING_OBJ((Float)n); + } else { + *cur.obj = INTEGER_OBJ((Integer)n); } - default: { - assert(false); + 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 = FLOATING_OBJ((Float)table_props.val); + break; + } + case kObjectTypeNil: { + api_set_error(err, Validation, "Cannot convert given lua table"); + break; + } + default: { + assert(false); + } } + break; + } + default: { + api_set_error(err, Validation, "Cannot convert given lua type"); + break; } - break; } - default: { + if (!cur.container) { lua_pop(lstate, 1); - set_api_error("Cannot convert given lua type", err); - break; } } + kv_destroy(stack); if (err->set) { - ret.type = kObjectTypeNil; + api_free_object(ret); + ret = NIL; + lua_pop(lstate, lua_gettop(lstate) - initial_size + 1); } - + assert(lua_gettop(lstate) == initial_size - 1); return ret; } -- cgit From 7a013e93e0364f78a2bc04eadaaeeaa689d0258a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 16 Jul 2016 00:48:25 +0300 Subject: executor/converter: Make it possible to supply `{}` to Dictionary arg --- src/nvim/viml/executor/converter.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index 6c9b42b38c..a6399500f2 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -33,6 +33,7 @@ typedef struct { ///< 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 @@ -48,8 +49,6 @@ typedef struct { static LuaTableProps nlua_traverse_table(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - bool has_type_key = false; // True if type key was found, - // @see nlua_push_type_idx(). 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, @@ -96,7 +95,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) if (n == (lua_Number)kObjectTypeFloat || n == (lua_Number)kObjectTypeArray || n == (lua_Number)kObjectTypeDictionary) { - has_type_key = true; + ret.has_type_key = true; ret.type = (ObjectType)n; } else { other_keys_num++; @@ -121,7 +120,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) tsize++; lua_pop(lstate, 1); } - if (has_type_key) { + if (ret.has_type_key) { if (ret.type == kObjectTypeFloat && (!has_val_key || val_type != LUA_TNUMBER)) { ret.type = kObjectTypeNil; @@ -133,7 +132,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) // should be ignored. if (ret.maxidx != 0 && ret.maxidx != (tsize - - has_type_key + - ret.has_type_key - other_keys_num - has_val_key - ret.string_keys_num)) { @@ -789,7 +788,12 @@ static inline LuaTableProps nlua_check_type(lua_State *const lstate, } return (LuaTableProps) { .type = kObjectTypeNil }; } - const LuaTableProps table_props = nlua_traverse_table(lstate); + 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) { -- cgit From ba2f615cd40d5d809d1a141c7b098e3bd22ff7bb Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 16 Jul 2016 02:26:04 +0300 Subject: functests: Test for error conditions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During testing found the following bugs: 1. msgpack-gen.lua script is completely unprepared for Float values either in return type or in arguments. Specifically: 1. At the time of writing relevant code FLOAT_OBJ did not exist as well as FLOATING_OBJ, but it would be used by msgpack-gen.lua should return type be Float. I added FLOATING_OBJ macros later because did not know that msgpack-gen.lua uses these _OBJ macros, otherwise it would be FLOAT_OBJ. 2. msgpack-gen.lua should use .data.floating in place of .data.float. But it did not expect that .data subattribute may have name different from lowercased type name. 2. vim_replace_termcodes returned its argument as-is if it receives an empty string (as well as _vim_id*() functions did). But if something in returned argument lives in an allocated memory such action will cause double free: once when freeing arguments, then when freeing return value. It did not cause problems yet because msgpack bindings return empty string as {NULL, 0} and nothing was actually allocated. 3. New code in msgpack-gen.lua popped arguments in reversed order, making lua bindings’ signatures be different from API ones. --- src/nvim/api/private/helpers.c | 2 +- src/nvim/api/private/helpers.h | 2 +- src/nvim/api/vim.c | 21 ++++++++++++++++---- src/nvim/msgpack_rpc/helpers.c | 2 +- src/nvim/viml/executor/converter.c | 39 +++++++++++++++++++------------------- 5 files changed, 40 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 7efa086af2..23d1540e2f 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -351,7 +351,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 { \ diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 9fe8c351cf..640e901fa1 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -27,7 +27,7 @@ .type = kObjectTypeInteger, \ .data.integer = i }) -#define FLOATING_OBJ(f) ((Object) { \ +#define FLOAT_OBJ(f) ((Object) { \ .type = kObjectTypeFloat, \ .data.floating = f }) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 5d862628cb..3fd1f57ace 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -139,7 +139,7 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, { if (str.size == 0) { // Empty string - return str; + return (String) { .data = NULL, .size = 0 }; } char *ptr = NULL; @@ -843,7 +843,7 @@ static void write_msg(String message, bool to_err) /// @return its argument. Object _vim_id(Object obj) { - return obj; + return copy_object(obj); } /// Returns array given as argument @@ -856,7 +856,7 @@ Object _vim_id(Object obj) /// @return its argument. Array _vim_id_array(Array arr) { - return arr; + return copy_object(ARRAY_OBJ(arr)).data.array; } /// Returns dictionary given as argument @@ -869,5 +869,18 @@ Array _vim_id_array(Array arr) /// @return its argument. Dictionary _vim_id_dictionary(Dictionary dct) { - return 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 _vim_id_float(Float flt) +{ + return flt; } diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 5137b375f0..64a018f5c3 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -117,7 +117,7 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg) case MSGPACK_OBJECT_FLOAT: { 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) \ diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index a6399500f2..a741d3a752 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -724,16 +724,15 @@ void nlua_push_Object(lua_State *lstate, const Object obj) String nlua_pop_String(lua_State *lstate, Error *err) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - String ret; - - ret.data = (char *)lua_tolstring(lstate, -1, &(ret.size)); - - if (ret.data == NULL) { + if (lua_type(lstate, -1) != LUA_TSTRING) { lua_pop(lstate, 1); - set_api_error("Expected lua string", err); + api_set_error(err, Validation, "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); @@ -746,17 +745,19 @@ String nlua_pop_String(lua_State *lstate, Error *err) Integer nlua_pop_Integer(lua_State *lstate, Error *err) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - Integer ret = 0; - - if (!lua_isnumber(lstate, -1)) { + if (lua_type(lstate, -1) != LUA_TNUMBER) { lua_pop(lstate, 1); - set_api_error("Expected lua integer", err); - return ret; + api_set_error(err, Validation, "Expected lua number"); + return 0; } - ret = (Integer)lua_tonumber(lstate, -1); + const lua_Number n = lua_tonumber(lstate, -1); lua_pop(lstate, 1); - - return ret; + if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN + || ((lua_Number)((Integer)n)) != n) { + api_set_error(err, Exception, "Number is not integral"); + return 0; + } + return (Integer)n; } /// Convert lua value to boolean @@ -765,7 +766,7 @@ Integer nlua_pop_Integer(lua_State *lstate, Error *err) Boolean nlua_pop_Boolean(lua_State *lstate, Error *err) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - Boolean ret = lua_toboolean(lstate, -1); + const Boolean ret = lua_toboolean(lstate, -1); lua_pop(lstate, 1); return ret; } @@ -784,7 +785,7 @@ static inline LuaTableProps nlua_check_type(lua_State *const lstate, { if (lua_type(lstate, -1) != LUA_TTABLE) { if (err) { - set_api_error("Expected lua table", err); + api_set_error(err, Validation, "Expected lua table"); } return (LuaTableProps) { .type = kObjectTypeNil }; } @@ -797,7 +798,7 @@ static inline LuaTableProps nlua_check_type(lua_State *const lstate, if (table_props.type != type) { if (err) { - set_api_error("Unexpected type", err); + api_set_error(err, Validation, "Unexpected type"); } } @@ -1050,7 +1051,7 @@ Object nlua_pop_Object(lua_State *const lstate, Error *const err) 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 = FLOATING_OBJ((Float)n); + *cur.obj = FLOAT_OBJ((Float)n); } else { *cur.obj = INTEGER_OBJ((Integer)n); } @@ -1094,7 +1095,7 @@ Object nlua_pop_Object(lua_State *const lstate, Error *const err) break; } case kObjectTypeFloat: { - *cur.obj = FLOATING_OBJ((Float)table_props.val); + *cur.obj = FLOAT_OBJ((Float)table_props.val); break; } case kObjectTypeNil: { -- cgit From d932693d5147ac12d181e0810a20bdcbffab2818 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 20 Jan 2017 23:00:36 +0300 Subject: executor/converter: Allow converting self-referencing lua objects --- src/nvim/viml/executor/converter.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index a741d3a752..b7bacc8ed9 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -167,6 +167,7 @@ typedef struct { 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 @@ -183,7 +184,7 @@ 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 })); + 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); @@ -219,14 +220,14 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) listitem_T *const val = listitem_alloc(); list_append(kv_pair, val); kv_push(stack, cur); - cur = (TVPopStackItem) { &val->li_tv, false, false }; + cur = (TVPopStackItem) { &val->li_tv, false, false, 0 }; } else { dictitem_T *const di = dictitem_alloc_len(s, len); if (dict_add(cur.tv->vval.v_dict, di) == FAIL) { assert(false); } kv_push(stack, cur); - cur = (TVPopStackItem) { &di->di_tv, false, false }; + cur = (TVPopStackItem) { &di->di_tv, false, false, 0 }; } } else { lua_pop(lstate, 1); @@ -242,7 +243,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) listitem_T *li = listitem_alloc(); list_append(cur.tv->vval.v_list, li); kv_push(stack, cur); - cur = (TVPopStackItem) { &li->li_tv, false, false }; + cur = (TVPopStackItem) { &li->li_tv, false, false, 0 }; } } assert(!cur.container); @@ -288,6 +289,14 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) 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)) { + copy_tv(item.tv, cur.tv); + goto nlua_pop_typval_table_processing_end; + } + } + switch (table_props.type) { case kObjectTypeArray: { cur.tv->v_type = VAR_LIST; @@ -295,6 +304,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) 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; @@ -320,6 +330,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) cur.tv->vval.v_dict->dv_refcount++; } cur.container = true; + cur.idx = lua_gettop(lstate); kv_push(stack, cur); lua_pushnil(lstate); } @@ -341,6 +352,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) assert(false); } } +nlua_pop_typval_table_processing_end: break; } default: { -- cgit From 5c1b9a0d2af86461f56f0d27ed275456921f6187 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 20 Jan 2017 23:06:22 +0300 Subject: api: Reserve more numbers for internal calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reasoning; currently INTERNAL_CALL is mostly used to determine whether it is needed to deal with NL-used-as-NUL problem. This code is useful for nvim_… API calls done from VimL, but not for API calls done from lua, yet lua needs to supply something as channel_id. --- src/nvim/api/buffer.c | 4 ++-- src/nvim/api/private/defs.h | 27 +++++++++++++++++++++++++-- src/nvim/eval.c | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index b75a2c7211..5eda88025f 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -192,7 +192,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'); } @@ -313,7 +313,7 @@ void nvim_buf_set_lines(uint64_t channel_id, // 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) { + if (l.data[j] == '\n' && channel_id != VIML_INTERNAL_CALL) { api_set_error(err, Exception, _("string cannot contain newlines")); new_len = i + 1; goto end; diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 86b549cb44..cb7ee8eb4c 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -5,6 +5,8 @@ #include #include +#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 } @@ -33,8 +35,29 @@ 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_MAX ^ (UINT64_MAX >> 1)) +// (1 << 63) in all forms produces “warning: shift count >= width of type +// [-Wshift-count-overflow]” + +/// 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; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index de82f8a145..8b6638f1d7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7796,7 +7796,7 @@ 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) { nvim_err_writeln(cstr_as_string(err.msg)); -- cgit From 8679feb3cbffd6b175be6a2868e980ca971125f7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 21 Jan 2017 00:00:09 +0300 Subject: executor/converter: Use readable lua numbers for handles --- src/nvim/viml/executor/converter.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index b7bacc8ed9..316a5aa93f 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -217,7 +217,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) list_unref(kv_pair); continue; } - listitem_T *const val = listitem_alloc(); + listitem_T *const val = listitem_alloc(); list_append(kv_pair, val); kv_push(stack, cur); cur = (TVPopStackItem) { &val->li_tv, false, false, 0 }; @@ -240,7 +240,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) lua_pop(lstate, 2); continue; } - listitem_T *li = listitem_alloc(); + listitem_T *const li = listitem_alloc(); list_append(cur.tv->vval.v_list, li); kv_push(stack, cur); cur = (TVPopStackItem) { &li->li_tv, false, false, 0 }; @@ -293,6 +293,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) const TVPopStackItem item = kv_A(stack, i); if (item.container && lua_rawequal(lstate, -1, item.idx)) { copy_tv(item.tv, cur.tv); + cur.container = false; goto nlua_pop_typval_table_processing_end; } } @@ -540,25 +541,14 @@ bool nlua_push_typval(lua_State *lstate, typval_T *const tv) return true; } -#define NLUA_PUSH_IDX(lstate, type, idx) \ +#define NLUA_PUSH_HANDLE(lstate, type, idx) \ do { \ - STATIC_ASSERT(sizeof(type) <= sizeof(lua_Number), \ - "Number sizes do not match"); \ - const type src = idx; \ - lua_Number tgt; \ - memset(&tgt, 0, sizeof(tgt)); \ - memcpy(&tgt, &src, sizeof(src)); \ - lua_pushnumber(lstate, tgt); \ + lua_pushnumber(lstate, (lua_Number)(idx)); \ } while (0) -#define NLUA_POP_IDX(lstate, type, stack_idx, idx) \ +#define NLUA_POP_HANDLE(lstate, type, stack_idx, idx) \ do { \ - STATIC_ASSERT(sizeof(type) <= sizeof(lua_Number), \ - "Number sizes do not match"); \ - const lua_Number src = lua_tonumber(lstate, stack_idx); \ - type tgt; \ - memcpy(&tgt, &src, sizeof(tgt)); \ - idx = tgt; \ + idx = (type)lua_tonumber(lstate, stack_idx); \ } while (0) /// Push value which is a type index @@ -685,7 +675,7 @@ void nlua_push_Array(lua_State *lstate, const Array array) void nlua_push_##type(lua_State *lstate, const type item) \ FUNC_ATTR_NONNULL_ALL \ { \ - NLUA_PUSH_IDX(lstate, type, item); \ + NLUA_PUSH_HANDLE(lstate, type, item); \ } GENERATE_INDEX_FUNCTION(Buffer) @@ -1144,7 +1134,7 @@ type nlua_pop_##type(lua_State *lstate, Error *err) \ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \ { \ type ret; \ - NLUA_POP_IDX(lstate, type, -1, ret); \ + NLUA_POP_HANDLE(lstate, type, -1, ret); \ lua_pop(lstate, 1); \ return ret; \ } -- cgit From 45feaa73d0759858a9a4454037fe4a41ea97e5b9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 21 Jan 2017 00:16:25 +0300 Subject: eval/decode: Fix memory leak in JSON functions --- src/nvim/eval/decode.c | 24 ++++++++++++++++++------ src/nvim/viml/executor/converter.c | 4 ++-- 2 files changed, 20 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index cb5a624f7b..d95e75170a 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -249,10 +249,14 @@ list_T *decode_create_map_special_dict(typval_T *const ret_tv) /// 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 TriState hasnul, const bool binary, + const bool s_allocated) FUNC_ATTR_WARN_UNUSED_RESULT { assert(s != NULL || len == 0); @@ -268,7 +272,11 @@ typval_T decode_string(const char *const s, const size_t len, .v_lock = VAR_UNLOCKED, .vval = { .v_list = list }, })); - if (encode_list_write((void *)list, s, len) == -1) { + const int elw_ret = encode_list_write((void *)list, s, len); + if (s_allocated) { + xfree((void *)s); + } + if (elw_ret == -1) { clear_tv(&tv); return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED }; } @@ -277,7 +285,8 @@ typval_T decode_string(const char *const s, const size_t len, return (typval_T) { .v_type = VAR_STRING, .v_lock = VAR_UNLOCKED, - .vval = { .v_string = xmemdupz(s, len) }, + .vval = { .v_string = (char_u *)( + s_allocated ? (char *)s : xmemdupz(s, len)) }, }; } } @@ -492,9 +501,10 @@ static inline int parse_json_string(vimconv_T *const conv, str = new_str; str_end = new_str + str_len; } + *str_end = NUL; typval_T obj; obj = decode_string(str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, - false); + false, true); if (obj.v_type == VAR_UNKNOWN) { goto parse_json_string_fail; } @@ -1022,14 +1032,16 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) break; } case MSGPACK_OBJECT_STR: { - *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false); + *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: { - *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true); + *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true, + false); if (rettv->v_type == VAR_UNKNOWN) { return FAIL; } diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index 316a5aa93f..a39f573036 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -210,7 +210,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) list_T *const kv_pair = list_alloc(); list_append_list(cur.tv->vval.v_list, kv_pair); listitem_T *const key = listitem_alloc(); - key->li_tv = decode_string(s, len, kTrue, false); + key->li_tv = decode_string(s, len, kTrue, false, false); list_append(kv_pair, key); if (key->li_tv.v_type == VAR_UNKNOWN) { ret = false; @@ -268,7 +268,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) case LUA_TSTRING: { size_t len; const char *s = lua_tolstring(lstate, -1, &len); - *cur.tv = decode_string(s, len, kNone, true); + *cur.tv = decode_string(s, len, kNone, true, false); if (cur.tv->v_type == VAR_UNKNOWN) { ret = false; } -- cgit From f8d55266e461a0a85e17e5adfd33e8429e45d9a5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 21 Jan 2017 01:02:15 +0300 Subject: executor/executor: When reporting errors use lua string length --- src/nvim/viml/executor/executor.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 33b6870ea0..29ec8dc927 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -86,7 +86,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg) size_t len; const char *const str = lua_tolstring(lstate, -1, &len); - EMSG2(msg, str); + emsgf(msg, (int)len, str); lua_pop(lstate, 1); } @@ -120,11 +120,11 @@ static int nlua_exec_lua_string(lua_State *lstate) FUNC_ATTR_NONNULL_ALL 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")); + 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")); + nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s")); return 0; } if (!nlua_pop_typval(lstate, ret_tv)) { @@ -141,7 +141,7 @@ static int nlua_state_init(lua_State *lstate) FUNC_ATTR_NONNULL_ALL lua_pushcfunction(lstate, &nlua_stricmp); lua_setglobal(lstate, "stricmp"); if (luaL_dostring(lstate, (char *)&vim_module[0])) { - nlua_error(lstate, _("E5106: Error while creating vim module: %s")); + nlua_error(lstate, _("E5106: Error while creating vim module: %.*s")); return 1; } nlua_add_api_functions(lstate); @@ -220,7 +220,7 @@ static int nlua_eval_lua_string(lua_State *lstate) #undef EVALHEADER if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) { nlua_error(lstate, - _("E5107: Error while creating lua chunk for luaeval(): %s")); + _("E5107: Error while creating lua chunk for luaeval(): %.*s")); return 0; } if (lcmd != (char *)IObuff) { @@ -234,7 +234,7 @@ static int nlua_eval_lua_string(lua_State *lstate) } if (lua_pcall(lstate, 1, 1, 0)) { nlua_error(lstate, - _("E5108: Error while calling lua chunk for luaeval(): %s")); + _("E5108: Error while calling lua chunk for luaeval(): %.*s")); return 0; } if (!nlua_pop_typval(lstate, ret_tv)) { -- cgit From 53b89c1dcf44c95827cc85a9657faee451c573c5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 21 Jan 2017 01:42:50 +0300 Subject: executor/executor: Free lcmd on error --- src/nvim/viml/executor/executor.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 29ec8dc927..acc375881c 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -221,6 +221,9 @@ static int nlua_eval_lua_string(lua_State *lstate) 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) { -- cgit From 1646a28173d1b7c8309188ebe7b6fb38a6ca8315 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 21 Jan 2017 02:33:09 +0300 Subject: cmake: Allow switching from luajit to lua --- src/nvim/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index a47a8e49c7..7a7dbbcce6 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -291,8 +291,12 @@ list(APPEND NVIM_LINK_LIBRARIES ${LIBTERMKEY_LIBRARIES} ${UNIBILIUM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - ${LUAJIT_LIBRARIES} ) +if(PREFER_LUAJIT) + list(APPEND NVIM_LINK_LIBRARIES ${LUAJIT_LIBRARIES}) +else() + list(APPEND NVIM_LINK_LIBRARIES ${LUA_LIBRARIES}) +endif() if(UNIX) list(APPEND NVIM_LINK_LIBRARIES -- cgit From 6b4a51f7ea49a6ef8305831e8d96b2a7cc4ba5f3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 22 Jan 2017 04:34:26 +0300 Subject: scripts: Make generate_vim_module more generic --- src/nvim/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 7a7dbbcce6..21a39b950f 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -39,7 +39,7 @@ set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode) set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h) set(VIM_MODULE_FILE ${GENERATED_DIR}/viml/executor/vim_module.generated.h) set(VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/viml/executor/vim.lua) -set(VIM_MODULE_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/generate_vim_module.lua) +set(CHAR_BLOB_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gencharblob.lua) file(GLOB API_HEADERS api/*.h) file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h) @@ -222,10 +222,10 @@ add_custom_command( add_custom_command( OUTPUT ${VIM_MODULE_FILE} - COMMAND ${LUA_PRG} ${VIM_MODULE_GENERATOR} ${VIM_MODULE_SOURCE} - ${VIM_MODULE_FILE} + COMMAND ${LUA_PRG} ${CHAR_BLOB_GENERATOR} ${VIM_MODULE_SOURCE} + ${VIM_MODULE_FILE} vim_module DEPENDS - ${VIM_MODULE_GENERATOR} + ${CHAR_BLOB_GENERATOR} ${VIM_MODULE_SOURCE} ) -- cgit From ca4c8b7f8a7b9543ef01157cb5ab94783f624ac6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 22 Jan 2017 04:55:26 +0300 Subject: api: Allow kObjectTypeNil to be zero without breaking compatibility --- src/nvim/api/private/defs.h | 7 ++++--- src/nvim/msgpack_rpc/helpers.c | 26 +++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index cb7ee8eb4c..432ab347bc 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -100,15 +100,16 @@ typedef struct { typedef enum { kObjectTypeNil = 0, - kObjectTypeBuffer, - kObjectTypeWindow, - kObjectTypeTabpage, 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/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 64a018f5c3..972d5b3441 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -20,13 +20,20 @@ static msgpack_zone zone; static msgpack_sbuffer sbuffer; +/// 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 + #define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \ bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \ Integer *const arg) \ FUNC_ATTR_NONNULL_ALL \ { \ if (obj->type != MSGPACK_OBJECT_EXT \ - || obj->via.ext.type != kObjectType##t) { \ + || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \ return false; \ } \ \ @@ -51,7 +58,8 @@ static msgpack_sbuffer sbuffer; 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); \ } @@ -211,7 +219,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 +235,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; } @@ -350,6 +367,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); -- cgit From 927e6efc3d93ff9d34c532180591dc3ca326edf5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 22 Jan 2017 05:16:05 +0300 Subject: clint: Allow omitting include guards in .c.h file and func_attr.h file --- src/clint.py | 5 +++++ src/nvim/eval/typval_encode.c.h | 5 ----- src/nvim/func_attr.h | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index ce31822ada..ca4dbdb1bc 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', @@ -1224,6 +1225,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) diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index 4ff5589887..812340b9c3 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -233,10 +233,6 @@ /// /// 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 #include #include @@ -816,4 +812,3 @@ encode_vim_to__error_ret: // Prevent “unused label” warnings. goto typval_encode_stop_converting_one_item; } -#endif // NVIM_EVAL_TYPVAL_ENCODE_C_H diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h index 18410445e1..7b8fcc4343 100644 --- a/src/nvim/func_attr.h +++ b/src/nvim/func_attr.h @@ -41,10 +41,6 @@ // $ gcc -E -dM - Date: Sun, 22 Jan 2017 05:35:48 +0300 Subject: msgpack_rpc: Fix #HANDLE_TYPE_CONVERSION_IMPL Function declarations generator is able to handle properly only the *first* function definition that is in macros, and only if it is the first entity in the macros. So msgpack_rpc_from_* was already really a static function, additionally its attributes were useless. This commit switches to explicit declarations and makes generated functions static. --- src/nvim/msgpack_rpc/helpers.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 972d5b3441..94a4f5ce3e 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -28,9 +28,11 @@ static msgpack_sbuffer sbuffer; #define EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer #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) \ + REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT; \ + static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \ + Integer *const arg) \ { \ if (obj->type != MSGPACK_OBJECT_EXT \ || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \ @@ -52,8 +54,9 @@ static msgpack_sbuffer sbuffer; return true; \ } \ \ - void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \ - FUNC_ATTR_NONNULL_ARG(2) \ + static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \ + REAL_FATTR_NONNULL_ARG(2); \ + static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \ { \ msgpack_packer pac; \ msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \ -- cgit From d33b13dd6ba5fddbb0903c28fd78a69b5f0a11bd Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 22 Jan 2017 22:02:39 +0300 Subject: cmake: Try fixing ASAN nvim-test compilation --- src/nvim/CMakeLists.txt | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 21a39b950f..918a64c2b4 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -363,6 +363,23 @@ if(WIN32) add_dependencies(nvim_runtime_deps external_blobs) 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_target_properties(nvim-test PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_property(TARGET nvim-test + APPEND_STRING PROPERTY COMPILE_FLAGS " -DUNIT_TESTING ") + if(CLANG_ASAN_UBSAN) message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.") check_c_compiler_flag(-fno-sanitize-recover=all SANITIZE_RECOVER_ALL) @@ -374,6 +391,9 @@ if(CLANG_ASAN_UBSAN) set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ") set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "${SANITIZE_RECOVER} -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address -fsanitize=undefined -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/src/.asan-blacklist") set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=address -fsanitize=undefined ") + + set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS "${SANITIZE_RECOVER} -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/src/.asan-blacklist") + set_property(TARGET nvim-test APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=address ") elseif(CLANG_MSAN) message(STATUS "Enabling Clang memory sanitizer for nvim.") set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ") @@ -387,17 +407,4 @@ 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) - add_subdirectory(po) -- cgit From d60302d5177e2ba99e84588c8ddd70dad0cbc64a Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 27 Jan 2017 02:55:34 +0300 Subject: cmake: Link libnvim-test with luajit in place of lua, disable ASAN Reasoning: luajit is not being compiled with sanitizers, lua is. Given that linking with sanitized libraries requires sanitizers enabled, it is needed to either compile libnvim-test with sanitizers or link it with lua compiled without sanitizers. Most easy way to do the latter is just use luajit which is compiled without sanitizers (as they do not work well with luajit). --- src/nvim/CMakeLists.txt | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 918a64c2b4..467af5bc00 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -292,11 +292,6 @@ list(APPEND NVIM_LINK_LIBRARIES ${UNIBILIUM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) -if(PREFER_LUAJIT) - list(APPEND NVIM_LINK_LIBRARIES ${LUAJIT_LIBRARIES}) -else() - list(APPEND NVIM_LINK_LIBRARIES ${LUA_LIBRARIES}) -endif() if(UNIX) list(APPEND NVIM_LINK_LIBRARIES @@ -306,6 +301,14 @@ if(UNIX) endif() set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES}) +set(NVIM_TEST_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES}) + +if(PREFER_LUAJIT) + list(APPEND NVIM_EXEC_LINK_LIBRARIES ${LUAJIT_LIBRARIES}) +else() + list(APPEND NVIM_EXEC_LINK_LIBRARIES ${LUA_LIBRARIES}) +endif() +list(APPEND NVIM_TEST_LINK_LIBRARIES ${LUAJIT_LIBRARIES}) # Don't use jemalloc in the unit test library. if(JEMALLOC_FOUND) @@ -317,6 +320,12 @@ add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) install_helper(TARGETS nvim) +if(PREFER_LUAJIT) + target_include_directories(nvim SYSTEM PRIVATE ${LUAJIT_INCLUDE_DIRS}) +else() + target_include_directories(nvim SYSTEM PRIVATE ${LUA_INCLUDE_DIRS}) +endif() + if(WIN32) # Copy DLLs and third-party tools to bin/ and install them along with nvim add_custom_target(nvim_runtime_deps ALL @@ -365,7 +374,7 @@ endif() add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) -target_link_libraries(libnvim ${NVIM_LINK_LIBRARIES}) +target_link_libraries(libnvim ${NVIM_TEST_LINK_LIBRARIES}) set_target_properties(libnvim PROPERTIES POSITION_INDEPENDENT_CODE ON OUTPUT_NAME nvim) @@ -374,7 +383,8 @@ set_property(TARGET libnvim 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}) +target_link_libraries(nvim-test ${NVIM_TEST_LINK_LIBRARIES}) +target_include_directories(nvim-test SYSTEM PRIVATE ${LUAJIT_INCLUDE_DIRS}) set_target_properties(nvim-test PROPERTIES POSITION_INDEPENDENT_CODE ON) set_property(TARGET nvim-test @@ -391,9 +401,6 @@ if(CLANG_ASAN_UBSAN) set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ") set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "${SANITIZE_RECOVER} -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address -fsanitize=undefined -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/src/.asan-blacklist") set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=address -fsanitize=undefined ") - - set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS "${SANITIZE_RECOVER} -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/src/.asan-blacklist") - set_property(TARGET nvim-test APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=address ") elseif(CLANG_MSAN) message(STATUS "Enabling Clang memory sanitizer for nvim.") set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ") -- cgit From 9c743df2d532b3adc04b532fa6fc9c7838b31353 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 27 Jan 2017 03:12:53 +0300 Subject: cmake: Use LuaJIT include directory for declarations generator --- src/nvim/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 467af5bc00..be3c8d1b07 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -151,7 +151,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} ${LUAJIT_INCLUDE_DIRS}) list(APPEND gen_cflags "-I${gen_include}") endforeach() string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) -- cgit From ae4adcc70735a89bffb110bcf9d5a993b0786c4d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 28 Jan 2017 03:47:15 +0300 Subject: gendeclarations: Make declarations generator work with macros funcs Now it checks functions also after every semicolon and closing figure brace, possibly preceded by whitespaces (tabs and spaces). This should make messing with declarations in macros not needed. --- src/nvim/msgpack_rpc/helpers.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 94a4f5ce3e..ec35d56978 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -30,9 +30,7 @@ static msgpack_sbuffer sbuffer; #define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \ static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \ Integer *const arg) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT; \ - 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 + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \ @@ -55,8 +53,7 @@ static msgpack_sbuffer sbuffer; } \ \ static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \ - REAL_FATTR_NONNULL_ARG(2); \ - 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); \ -- cgit From d836464cd2a6cdb4f4b797677794a376d5a12a45 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 28 Jan 2017 22:16:24 +0300 Subject: cmake: Also include luajit directories for libnvim target --- src/nvim/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index be3c8d1b07..0cf331206e 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -374,6 +374,7 @@ endif() add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) +target_include_directories(libnvim SYSTEM PRIVATE ${LUAJIT_INCLUDE_DIRS}) target_link_libraries(libnvim ${NVIM_TEST_LINK_LIBRARIES}) set_target_properties(libnvim PROPERTIES POSITION_INDEPENDENT_CODE ON -- cgit From 62fde319360e27a86c0deba0053ff230f80ca772 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 01:29:51 +0300 Subject: api: Also shift numbers in api_metadata output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes problem introduced by “api: Allow kObjectTypeNil to be zero without breaking compatibility”: apparently there are clients which use metadata and there are which aren’t. For the first that commit would not be needed, for the second that commit misses this critical piece. --- src/nvim/api/private/helpers.c | 9 ++++++--- src/nvim/msgpack_rpc/helpers.c | 7 ------- src/nvim/msgpack_rpc/helpers.h | 7 +++++++ 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 23d1540e2f..373e509120 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -851,15 +851,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)); diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index ec35d56978..21acd6a394 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -20,13 +20,6 @@ static msgpack_zone zone; static msgpack_sbuffer sbuffer; -/// 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 - #define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \ static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \ Integer *const arg) \ 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 -- cgit From 872a909150506828f72a63636e1cfd6b72f1b306 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 02:41:37 +0300 Subject: executor: Add :lua command Does not work currently. --- src/nvim/ex_cmds.lua | 2 +- src/nvim/ex_docmd.c | 1 + src/nvim/viml/executor/executor.c | 19 +++++++++++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 92f0669422..b34975f00e 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1542,7 +1542,7 @@ return { command='lua', flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), addr_type=ADDR_LINES, - func='ex_script_ni', + func='ex_lua', }, { command='luado', diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 486baaad47..aa43b71a0d 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -67,6 +67,7 @@ #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" #include "nvim/shada.h" +#include "nvim/viml/executor/executor.h" static int quitmore = 0; static int ex_pressedreturn = FALSE; diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index acc375881c..8da218270a 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -7,8 +7,10 @@ #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/message.h" #include "nvim/viml/executor/executor.h" @@ -171,8 +173,6 @@ static lua_State *global_lstate = NULL; /// Execute lua string /// -/// Used for :lua. -/// /// @param[in] str String to execute. /// @param[out] ret_tv Location where result will be saved. /// @@ -267,3 +267,18 @@ void executor_eval_lua(const String str, typval_T *const arg, NLUA_CALL_C_FUNCTION_3(global_lstate, nlua_eval_lua_string, 0, (void *)&str, arg, ret_tv); } + +/// Run lua string +/// +/// Used for :lua. +/// +/// @param eap VimL command being run. +void ex_lua(exarg_T *const eap) + FUNC_ATTR_NONNULL_ALL +{ + char *const code = (char *)script_get(eap, eap->arg); + typval_T tv = { .v_type = VAR_UNKNOWN }; + executor_exec_lua(cstr_as_string(code), &tv); + clear_tv(&tv); + xfree(code); +} -- cgit From 3531d8c8eaa6783637f510dbc5dbd58c9d435b61 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 03:08:56 +0300 Subject: executor: Add some const qualifiers --- src/nvim/viml/executor/executor.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 8da218270a..38e3cf1c6d 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -100,7 +100,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg) /// /// Does no error handling: never call it with non-string or with some arguments /// omitted. -static int nlua_stricmp(lua_State *lstate) FUNC_ATTR_NONNULL_ALL +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); @@ -115,10 +115,10 @@ static int nlua_stricmp(lua_State *lstate) FUNC_ATTR_NONNULL_ALL /// 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 *lstate) FUNC_ATTR_NONNULL_ALL +static int nlua_exec_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { - String *str = (String *)lua_touserdata(lstate, 1); - typval_T *ret_tv = (typval_T *)lua_touserdata(lstate, 2); + const String *const str = (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)) { @@ -138,7 +138,7 @@ static int nlua_exec_lua_string(lua_State *lstate) FUNC_ATTR_NONNULL_ALL /// Initialize lua interpreter state /// /// Called by lua interpreter itself to initialize state. -static int nlua_state_init(lua_State *lstate) FUNC_ATTR_NONNULL_ALL +static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { lua_pushcfunction(lstate, &nlua_stricmp); lua_setglobal(lstate, "stricmp"); @@ -177,14 +177,15 @@ static lua_State *global_lstate = NULL; /// @param[out] ret_tv Location where result will be saved. /// /// @return Result of the execution. -void executor_exec_lua(String str, typval_T *ret_tv) +void executor_exec_lua(const String str, typval_T *const ret_tv) FUNC_ATTR_NONNULL_ALL { if (global_lstate == NULL) { global_lstate = init_lua(); } - NLUA_CALL_C_FUNCTION_2(global_lstate, nlua_exec_lua_string, 0, &str, ret_tv); + NLUA_CALL_C_FUNCTION_2(global_lstate, nlua_exec_lua_string, 0, + (void *)&str, ret_tv); } /// Evaluate lua string @@ -196,12 +197,12 @@ void executor_exec_lua(String str, typval_T *ret_tv) /// 3. Pointer to location where result is saved. /// /// @param[in,out] lstate Lua interpreter state. -static int nlua_eval_lua_string(lua_State *lstate) +static int nlua_eval_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { - String *str = (String *)lua_touserdata(lstate, 1); - typval_T *arg = (typval_T *)lua_touserdata(lstate, 2); - typval_T *ret_tv = (typval_T *)lua_touserdata(lstate, 3); + const String *const str = (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; -- cgit From 3d48c35d6bfa83ba3ae621fa9ec3f512da199f59 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 03:36:47 +0300 Subject: ex_getln: Refactor script_get() 1. Use `char *` for strings. 2. Add `const` qualifiers. 3. Add attributes and documentation. 4. Handle skipping *inside*. 5. Handle non-heredoc argument also inside: deferring this to the caller is pointless because all callers need the same thing. Though new ex_lua caller may live without allocations in this case, allocating nevertheless produces cleaner code. 6. Note that all callers call script_get with `eap` and `eap->arg`. Thus second argument is useless in practice: it is one and the same always and can be reached through the first argument. --- src/nvim/ex_cmds2.c | 11 +++---- src/nvim/ex_docmd.c | 8 +++-- src/nvim/ex_getln.c | 68 +++++++++++++++++++++++---------------- src/nvim/viml/executor/executor.c | 9 ++++-- 4 files changed, 58 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 9fc4ef2a02..092bb38dd0 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -3695,19 +3695,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 = list_alloc(); // script - list_append_string(args, script ? script : eap->arg, -1); + list_append_allocated_string(args, script); // current range list_append_number(args, (int)eap->line1); 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) diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index aa43b71a0d..74bb6177c6 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -3734,10 +3734,12 @@ void ex_ni(exarg_T *eap) /// Skips over ":perl <skip) + if (!eap->skip) { ex_ni(eap); - else - xfree(script_get(eap, eap->arg)); + } else { + size_t len; + xfree(script_get(eap, &len)); + } } /* diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 58979c0e43..f7e10f3787 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -5343,47 +5343,61 @@ static int ex_window(void) return cmdwin_result; } -/* - * Used for commands that either take a simple command string argument, or: - * cmd << endmarker - * {script} - * endmarker - * Returns a pointer to allocated memory with {script} or NULL. - */ -char_u *script_get(exarg_T *eap, char_u *cmd) +/// Get script string +/// +/// Used for commands which accept either `:command script` or +/// +/// :command << endmarker +/// script +/// endmarker +/// +/// @param eap Command being run. +/// @param[out] lenp Location where length of resulting string is saved. Will +/// be set to zero when skipping. +/// +/// @return [allocated] NULL or script. Does not show any error messages. +/// NULL is returned when skipping and on error. +char *script_get(exarg_T *const eap, size_t *const lenp) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC { - char_u *theline; - char *end_pattern = NULL; - char dot[] = "."; - garray_T ga; + const char *const cmd = (const char *)eap->arg; - if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) - return NULL; - - ga_init(&ga, 1, 0x400); + if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) { + *lenp = STRLEN(eap->arg); + return 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 diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 38e3cf1c6d..fb39716f5c 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -277,9 +277,14 @@ void executor_eval_lua(const String str, typval_T *const arg, void ex_lua(exarg_T *const eap) FUNC_ATTR_NONNULL_ALL { - char *const code = (char *)script_get(eap, eap->arg); + 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(cstr_as_string(code), &tv); + executor_exec_lua((String) { .data = code, .size = len }, &tv); clear_tv(&tv); xfree(code); } -- cgit From 9114d9be778b07f4a49edc078f1c159aa51320d8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 18:40:39 +0300 Subject: executor: Add :luado command --- src/nvim/ex_cmds.lua | 2 +- src/nvim/macros.h | 9 +++ src/nvim/viml/executor/executor.c | 121 +++++++++++++++++++++++++++++++++++++- 3 files changed, 128 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index b34975f00e..25e74ebf9b 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1548,7 +1548,7 @@ return { command='luado', flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), addr_type=ADDR_LINES, - func='ex_ni', + func='ex_luado', }, { command='luafile', diff --git a/src/nvim/macros.h b/src/nvim/macros.h index 650bf76156..5042663041 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -19,6 +19,15 @@ # define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) #endif +/// 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) + /* * Position comparisons */ diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index fb39716f5c..80f2651afc 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -12,6 +12,13 @@ #include "nvim/vim.h" #include "nvim/ex_getln.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/viml/executor/executor.h" #include "nvim/viml/executor/converter.h" @@ -38,6 +45,17 @@ typedef struct { 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 @@ -117,7 +135,7 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL /// of view). static int nlua_exec_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { - const String *const str = (String *)lua_touserdata(lstate, 1); + 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); @@ -135,6 +153,79 @@ static int nlua_exec_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL 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, 1); + lua_pop(lstate, 1); + +#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); + } + memcpy(lcmd, S_LEN(DOSTART)); + memcpy(lcmd + sizeof(DOSTART) - 1, str->data, str->size); + memcpy(lcmd + sizeof(DOSTART) - 1 + str->size, S_LEN(DOEND)); +#undef DOSTART +#undef DOEND + + if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) { + nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s")); + return 0; + } + 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)) { + if (sandbox) { + EMSG(_("E5112: Not allowed in sandbox")); + lua_pop(lstate, 1); + break; + } + size_t new_line_len; + const char *new_line = lua_tolstring(lstate, -1, &new_line_len); + char *const new_line_transformed = ( + new_line_len < IOSIZE + ? memcpy(IObuff, new_line, new_line_len) + : xmemdupz(new_line, new_line_len)); + new_line_transformed[new_line_len] = NUL; + for (size_t i = 0; i < new_line_len; i++) { + if (new_line_transformed[new_line_len] == NUL) { + new_line_transformed[new_line_len] = '\n'; + } + } + ml_replace(l, (char_u *)new_line_transformed, true); + changed_bytes(l, 0); + } + lua_pop(lstate, 1); + } + lua_pop(lstate, 1); + check_cursor(); + update_screen(NOT_VALID); + return 0; +} + /// Initialize lua interpreter state /// /// Called by lua interpreter itself to initialize state. @@ -200,7 +291,7 @@ void executor_exec_lua(const String str, typval_T *const ret_tv) static int nlua_eval_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { - const String *const str = (String *)lua_touserdata(lstate, 1); + 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); @@ -215,7 +306,7 @@ static int nlua_eval_lua_string(lua_State *const lstate) } else { lcmd = xmalloc(lcmd_len); } - memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1); + memcpy(lcmd, S_LEN(EVALHEADER)); memcpy(lcmd + sizeof(EVALHEADER) - 1, str->data, str->size); lcmd[lcmd_len - 1] = ')'; #undef EVALHEADER @@ -288,3 +379,27 @@ void ex_lua(exarg_T *const eap) clear_tv(&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 (global_lstate == NULL) { + global_lstate = init_lua(); + } + 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(global_lstate, nlua_exec_luado_string, 0, + (void *)&cmd, (void *)range); +} -- cgit From e1bbaca7acf7fc498da49081d069b00aa05506df Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 19:26:22 +0300 Subject: executor,functests: Add tests for :luado, also some fixes Fixes: 1. Allocate space for the NUL byte. 2. Do not exclude last line from range. 3. Remove code for sandbox: it is handled earlier. 4. Fix index in new_line_transformed when converting NULs to NLs. 5. Always allocate new_line_transformed, but save allocated value. --- src/nvim/viml/executor/executor.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 80f2651afc..c426806b6f 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -160,17 +160,19 @@ static int nlua_exec_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL 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, 1); + const linenr_T *const range = (const linenr_T *)lua_touserdata(lstate, 2); lua_pop(lstate, 1); #define DOSTART "return function(line, linenr) " #define DOEND " end" - const size_t lcmd_len = str->size + (sizeof(DOSTART) - 1) + (sizeof(DOEND) - 1); + 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); + lcmd = xmalloc(lcmd_len + 1); } memcpy(lcmd, S_LEN(DOSTART)); memcpy(lcmd + sizeof(DOSTART) - 1, str->data, str->size); @@ -186,7 +188,7 @@ static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL nlua_error(lstate, _("E5110: Error while creating lua function: %.*s")); return 0; } - for (linenr_T l = range[0]; l < range[1]; l++) { + for (linenr_T l = range[0]; l <= range[1]; l++) { if (l > curbuf->b_ml.ml_line_count) { break; } @@ -198,24 +200,15 @@ static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL break; } if (lua_isstring(lstate, -1)) { - if (sandbox) { - EMSG(_("E5112: Not allowed in sandbox")); - lua_pop(lstate, 1); - break; - } size_t new_line_len; - const char *new_line = lua_tolstring(lstate, -1, &new_line_len); - char *const new_line_transformed = ( - new_line_len < IOSIZE - ? memcpy(IObuff, new_line, new_line_len) - : xmemdupz(new_line, new_line_len)); - new_line_transformed[new_line_len] = NUL; + 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[new_line_len] == NUL) { - new_line_transformed[new_line_len] = '\n'; + if (new_line_transformed[i] == NUL) { + new_line_transformed[i] = '\n'; } } - ml_replace(l, (char_u *)new_line_transformed, true); + ml_replace(l, (char_u *)new_line_transformed, false); changed_bytes(l, 0); } lua_pop(lstate, 1); -- cgit From 295e7607c472b49e8c0762977e38c4527b746b6f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 19:32:01 +0300 Subject: executor: Fix some memory leaks --- src/nvim/viml/executor/executor.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index c426806b6f..df63667102 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -182,8 +182,14 @@ static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL 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; -- cgit From dcb992ab3759b604c1824913002714a018be0532 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 19:51:55 +0300 Subject: executor: Add :luafile command --- src/nvim/ex_cmds.lua | 2 +- src/nvim/viml/executor/executor.c | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 25e74ebf9b..ad2fb642d4 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1554,7 +1554,7 @@ return { command='luafile', flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), addr_type=ADDR_LINES, - func='ex_ni', + func='ex_luafile', }, { command='lvimgrep', diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index df63667102..a01bf9966d 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -161,7 +161,7 @@ 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, 1); + lua_pop(lstate, 2); #define DOSTART "return function(line, linenr) " #define DOEND " end" @@ -225,6 +225,26 @@ static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL 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. @@ -402,3 +422,18 @@ void ex_luado(exarg_T *const eap) NLUA_CALL_C_FUNCTION_2(global_lstate, 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 +{ + if (global_lstate == NULL) { + global_lstate = init_lua(); + } + NLUA_CALL_C_FUNCTION_1(global_lstate, nlua_exec_lua_file, 0, + (void *)eap->arg); +} -- cgit From 1801d44f53e4340f5483902e6f0a2aa0ab4f551a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 20:20:41 +0300 Subject: executor: Do not use S_LEN for memcpy Sometimes it is implemented as a macro and `S_LEN` is treated as a single argument in this case. --- src/nvim/viml/executor/executor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index a01bf9966d..ad92b52f3e 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -174,9 +174,9 @@ static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL } else { lcmd = xmalloc(lcmd_len + 1); } - memcpy(lcmd, S_LEN(DOSTART)); + memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1); memcpy(lcmd + sizeof(DOSTART) - 1, str->data, str->size); - memcpy(lcmd + sizeof(DOSTART) - 1 + str->size, S_LEN(DOEND)); + memcpy(lcmd + sizeof(DOSTART) - 1 + str->size, DOEND, sizeof(DOEND) - 1); #undef DOSTART #undef DOEND @@ -325,7 +325,7 @@ static int nlua_eval_lua_string(lua_State *const lstate) } else { lcmd = xmalloc(lcmd_len); } - memcpy(lcmd, S_LEN(EVALHEADER)); + memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1); memcpy(lcmd + sizeof(EVALHEADER) - 1, str->data, str->size); lcmd[lcmd_len - 1] = ')'; #undef EVALHEADER -- cgit From f2ad6201d94fec1e0c98550e55f3b069fa24a68b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 21:03:36 +0300 Subject: api: Use a form of `1 << 63` for INTERNAL_CALL_MASK --- src/nvim/api/private/defs.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 432ab347bc..8bd1dd5085 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -36,9 +36,7 @@ typedef enum { #define NO_RESPONSE UINT64_MAX /// Mask for all internal calls -#define INTERNAL_CALL_MASK (UINT64_MAX ^ (UINT64_MAX >> 1)) -// (1 << 63) in all forms produces “warning: shift count >= width of type -// [-Wshift-count-overflow]” +#define INTERNAL_CALL_MASK (((uint64_t)1) << (sizeof(uint64_t) * 8 - 1)) /// Internal call from VimL code #define VIML_INTERNAL_CALL INTERNAL_CALL_MASK -- cgit From 90e2a043e3394f83eb5d5e32e13cda00d752f212 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 21:58:55 +0300 Subject: executor: Add print() function --- src/nvim/viml/executor/executor.c | 74 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index ad92b52f3e..48149c4420 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -252,6 +252,8 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { lua_pushcfunction(lstate, &nlua_stricmp); lua_setglobal(lstate, "stricmp"); + lua_pushcfunction(lstate, &nlua_print); + lua_setglobal(lstate, "print"); if (luaL_dostring(lstate, (char *)&vim_module[0])) { nlua_error(lstate, _("E5106: Error while creating vim module: %.*s")); return 1; @@ -358,6 +360,78 @@ static int nlua_eval_lua_string(lua_State *const lstate) 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); + if (!errmsg) { + PRINT_ERROR(""); + } + goto nlua_print_error; + } + size_t len; + const char *const s = lua_tolstring(lstate, -1, &len); + if (s == NULL) { + PRINT_ERROR( + ""); + } + 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 - 1;) { + const size_t start = i; + while (str[i] != NL && i < len - 1) { + if (str[i] == NUL) { + str[i] = NL; + } + i++; + } + if (str[i] == NL) { + str[i] = NUL; + } + msg((char_u *)str + start); + } + } + 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; +} + /// Evaluate lua string /// /// Used for luaeval(). -- cgit From 9fd2bf67aa1db66e3465753d5aaaec342f4ce193 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Jan 2017 23:22:50 +0300 Subject: executor,functests: Add print() tests, some fixes --- src/nvim/viml/executor/executor.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 48149c4420..4eb63f38ad 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -384,9 +384,6 @@ static int nlua_print(lua_State *const lstate) lua_pushvalue(lstate, curargidx); // arg if (lua_pcall(lstate, 1, 1, 0)) { errmsg = lua_tolstring(lstate, -1, &errmsg_len); - if (!errmsg) { - PRINT_ERROR(""); - } goto nlua_print_error; } size_t len; @@ -408,19 +405,32 @@ static int nlua_print(lua_State *const lstate) 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 - 1;) { + for (size_t i = 0; i < len;) { const size_t start = i; - while (str[i] != NL && i < len - 1) { - if (str[i] == NUL) { - str[i] = NL; + while (i < len) { + switch (str[i]) { + case NUL: { + str[i] = NL; + i++; + continue; + } + case NL: { + str[i] = NUL; + i++; + break; + } + default: { + i++; + continue; + } } - i++; - } - if (str[i] == NL) { - str[i] = NUL; + break; } msg((char_u *)str + start); } + if (str[len - 1] == NUL) { // Last was newline + msg((char_u *)""); + } } ga_clear(&msg_ga); return 0; -- cgit From edc80f6b46f51ea1137289301914c0f90db19295 Mon Sep 17 00:00:00 2001 From: raichoo Date: Sun, 26 Mar 2017 23:15:53 +0200 Subject: vim-patch:7.4.2357 (#6354) Problem: Attempt to read history entry while not initialized. Solution: Skip when the index is negative. https://github.com/vim/vim/commit/46643713dc6bb04b4e84986b1763ef309e960161 --- src/nvim/ex_getln.c | 4 ++-- src/nvim/version.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 58979c0e43..8758a63bce 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -4677,8 +4677,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]; diff --git a/src/nvim/version.c b/src/nvim/version.c index a354634218..a911e8ebc3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -84,7 +84,7 @@ static int included_patches[] = { // 2360, // 2359 NA // 2358 NA - // 2357, + 2357, // 2356, 2355, // 2354, -- cgit From 73d37f8b6e9eba0d2f2c59694ae5a13777a7f1cd Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 30 Jan 2017 00:34:33 +0300 Subject: executor: Add :lua debug.debug mock --- src/nvim/eval.c | 177 ++++++++++++++++++++------------------ src/nvim/ex_docmd.c | 4 +- src/nvim/message.c | 3 +- src/nvim/viml/executor/executor.c | 38 ++++++++ 4 files changed, 136 insertions(+), 86 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8b6638f1d7..fa817bb705 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12280,93 +12280,70 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr) static int inputsecret_flag = 0; +/// Get user input +/// +/// Used for f_input and f_inputdialog functions. +/// +/// @param[in] prompt Input prompt. +/// @param[in] initval Initial value, may be NULL. +/// @param[in] xp_name Completion, for input(). +/// @param[in] cancelval Value returned when user cancelled dialog, for +/// inputdialog(). +/// +/// @return [allocated] User input or NULL. +char *get_user_input(const char *const prompt, + const char *const initval, + const char *const xp_name, + const char *const cancelval) + FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC +{ + char *ret = NULL; + const int saved_cmd_silent = cmd_silent; + 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, NL); + if (p == NULL) { + p = prompt; + } else { + p++; + msg_start(); + msg_clr_eos(); + msg_puts_attr_len(prompt, (int)(p - prompt) + 1, echo_attr); + msg_didout = false; + msg_starthere(); + } + cmdline_row = msg_row; -/* - * This function is used by f_input() and f_inputdialog() functions. The third - * argument to f_input() specifies the type of completion to use at the - * prompt. The third argument to f_inputdialog() specifies the value to return - * when the user cancels the prompt. - */ -static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) -{ - char_u *prompt = get_tv_string_chk(&argvars[0]); - char_u *p = NULL; - int c; - char_u buf[NUMBUFLEN]; - int cmd_silent_save = cmd_silent; - char_u *defstr = (char_u *)""; - int xp_type = EXPAND_NOTHING; - char_u *xp_arg = NULL; - - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; + stuffReadbuffSpec((char_u *)initval); - 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((const char *)prompt, echo_attr); - msg_didout = false; - msg_starthere(); - *p = c; + char *xp_arg = NULL; + int xp_type = EXPAND_NOTHING; + if (xp_name != NULL) { + uint32_t argt; + if (parse_compl_arg((const char_u *)xp_name, (int)strlen(xp_name), + &xp_type, &argt, (char_u **)&xp_arg) == FAIL) { + return NULL; } - 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); + const int saved_ex_normal_busy = ex_normal_busy; + ex_normal_busy = 0; + ret = (char *)getcmdline_prompt(inputsecret_flag ? NUL : '@', (char_u *)p, + echo_attr, xp_type, (char_u *)xp_arg); + ex_normal_busy = saved_ex_normal_busy; - if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, - &xp_arg) == FAIL) - return; - } - } - - if (defstr != NULL) { - int save_ex_normal_busy = ex_normal_busy; - ex_normal_busy = 0; - rettv->vval.v_string = - getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, - xp_type, xp_arg); - ex_normal_busy = save_ex_normal_busy; - } - if (inputdialog && rettv->vval.v_string == NULL - && argvars[1].v_type != VAR_UNKNOWN - && argvars[2].v_type != VAR_UNKNOWN) - rettv->vval.v_string = vim_strsave(get_tv_string_buf( - &argvars[2], buf)); + if (ret == NULL && cancelval != NULL) { + ret = xstrdup(cancelval); + } - xfree(xp_arg); + 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; + // Since the user typed this, no need to wait for return. + need_wait_return = false; + msg_didout = false; + cmd_silent = saved_cmd_silent; + return ret; } /* @@ -12375,7 +12352,25 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) */ static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - get_user_input(argvars, rettv, FALSE); + char initval_buf[NUMBUFLEN]; + char xp_name_buf[NUMBUFLEN]; + const char *const prompt = (const char *)get_tv_string_chk(&argvars[0]); + const char *const initval = ( + argvars[1].v_type != VAR_UNKNOWN + ? (const char *)get_tv_string_buf(&argvars[1], (char_u *)initval_buf) + : ""); + const char *const xp_name = ( + argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN + ? (const char *)get_tv_string_buf(&argvars[2], (char_u *)xp_name_buf) + : NULL); + if (prompt == NULL || initval == NULL || ( + argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN + && xp_name == NULL)) { + return; + } + rettv->v_type = VAR_STRING; + rettv->vval.v_string = (char_u *)get_user_input(prompt, initval, xp_name, + NULL); } /* @@ -12383,7 +12378,25 @@ static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - get_user_input(argvars, rettv, TRUE); + char initval_buf[NUMBUFLEN]; + char cancelval_buf[NUMBUFLEN]; + const char *const prompt = (const char *)get_tv_string_chk(&argvars[0]); + const char *const initval = ( + argvars[1].v_type != VAR_UNKNOWN + ? (const char *)get_tv_string_buf(&argvars[1], (char_u *)initval_buf) + : ""); + const char *const cancelval = ( + argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN + ? (const char *)get_tv_string_buf(&argvars[2], (char_u *)cancelval_buf) + : NULL); + if (prompt == NULL || initval == NULL || ( + argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN + && cancelval == NULL)) { + return; + } + rettv->v_type = VAR_STRING; + rettv->vval.v_string = (char_u *)get_user_input(prompt, initval, NULL, + cancelval); } /* diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 74bb6177c6..69dab9c18f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5757,10 +5757,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; diff --git a/src/nvim/message.c b/src/nvim/message.c index bf54284881..4b786c11dd 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1564,7 +1564,6 @@ void msg_puts_attr(const char *const s, const int 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. void msg_puts_attr_len(const char *str, const ptrdiff_t maxlen, int attr) { // If redirection is on, also write to the redirection file. @@ -1576,7 +1575,7 @@ void msg_puts_attr_len(const char *str, const ptrdiff_t maxlen, int attr) } // if MSG_HIST flag set, add message to history - if ((attr & MSG_HIST) && maxlen < 0) { + if (attr & MSG_HIST) { add_msg_hist(str, -1, attr); attr &= ~MSG_HIST; } diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c index 4eb63f38ad..d0e269bf6a 100644 --- a/src/nvim/viml/executor/executor.c +++ b/src/nvim/viml/executor/executor.c @@ -250,15 +250,28 @@ static int nlua_exec_lua_file(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL /// 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; @@ -442,6 +455,31 @@ nlua_print_error: 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 +{ + for (;;) { + lua_settop(lstate, 0); + char *const input = get_user_input("lua_debug> ", "", NULL, NULL); + msg_putchar('\n'); // Avoid outputting on input line. + if (input == NULL || *input == NUL || strcmp(input, "cont") == 0) { + xfree(input); + return 0; + } + if (luaL_loadbuffer(lstate, input, strlen(input), "=(debug command)")) { + nlua_error(lstate, _("E5115: Error while loading debug string: %.*s")); + } + xfree(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(). -- cgit From a24e94215ed0a4bfe55b6741ab2e9477b278dbb7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 30 Jan 2017 03:35:45 +0300 Subject: eval,functests: Fix linter errors --- src/nvim/eval.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index fa817bb705..67b755f053 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12363,8 +12363,8 @@ static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr) argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN ? (const char *)get_tv_string_buf(&argvars[2], (char_u *)xp_name_buf) : NULL); - if (prompt == NULL || initval == NULL || ( - argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN + if (prompt == NULL || initval == NULL + || (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN && xp_name == NULL)) { return; } @@ -12389,8 +12389,8 @@ static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr) argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN ? (const char *)get_tv_string_buf(&argvars[2], (char_u *)cancelval_buf) : NULL); - if (prompt == NULL || initval == NULL || ( - argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN + if (prompt == NULL || initval == NULL + || (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN && cancelval == NULL)) { return; } -- cgit From 5992cdf3c27ee9c73cea22e288c6ea6d54867394 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 30 Jan 2017 23:13:06 +0300 Subject: cmake: Use set_property in place of target_include_dirs Should work with cmake-2.8.7. --- src/nvim/CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 0cf331206e..a6ae758a8e 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -321,9 +321,11 @@ target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) install_helper(TARGETS nvim) if(PREFER_LUAJIT) - target_include_directories(nvim SYSTEM PRIVATE ${LUAJIT_INCLUDE_DIRS}) + set_property(TARGET nvim APPEND PROPERTY + INCLUDE_DIRECTORIES ${LUAJIT_INCLUDE_DIRS}) else() - target_include_directories(nvim SYSTEM PRIVATE ${LUA_INCLUDE_DIRS}) + set_property(TARGET nvim APPEND PROPERTY + INCLUDE_DIRECTORIES ${LUA_INCLUDE_DIRS}) endif() if(WIN32) @@ -374,7 +376,8 @@ endif() add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) -target_include_directories(libnvim SYSTEM PRIVATE ${LUAJIT_INCLUDE_DIRS}) +set_property(TARGET libnvim APPEND PROPERTY + INCLUDE_DIRECTORIES ${LUAJIT_INCLUDE_DIRS}) target_link_libraries(libnvim ${NVIM_TEST_LINK_LIBRARIES}) set_target_properties(libnvim PROPERTIES POSITION_INDEPENDENT_CODE ON @@ -385,7 +388,8 @@ set_property(TARGET libnvim add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${UNIT_TEST_FIXTURES} ${NEOVIM_HEADERS}) target_link_libraries(nvim-test ${NVIM_TEST_LINK_LIBRARIES}) -target_include_directories(nvim-test SYSTEM PRIVATE ${LUAJIT_INCLUDE_DIRS}) +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 -- cgit From 20e7652b6980e0efed5db65e0f80c0d72ef8c68d Mon Sep 17 00:00:00 2001 From: lonerover Date: Thu, 23 Mar 2017 22:42:26 +0800 Subject: vim-patch:7.4.2307 Problem: Several tests are old style. Solution: Turn them into new style tests. (Yegappan Lakshmanan) https://github.com/vim/vim/commit/cd055da370114f66c960be9c8b1eb0f33a9e0a85 --- src/nvim/testdir/Makefile | 3 ++ src/nvim/testdir/test_charsearch.vim | 62 +++++++++++++++++++++++++++++++++++ src/nvim/testdir/test_fnameescape.vim | 21 ++++++++++++ src/nvim/testdir/test_substitute.vim | 41 +++++++++++++++++++++++ src/nvim/version.c | 2 +- 5 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/nvim/testdir/test_charsearch.vim create mode 100644 src/nvim/testdir/test_fnameescape.vim create mode 100644 src/nvim/testdir/test_substitute.vim (limited to 'src') diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 531a07912f..fd557cca51 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -30,6 +30,7 @@ SCRIPTS ?= \ NEW_TESTS ?= \ test_autocmd.res \ test_bufwintabinfo.res \ + test_charsearch.res \ test_cmdline.res \ test_command_count.res \ test_cscope.res \ @@ -37,6 +38,7 @@ NEW_TESTS ?= \ test_diffmode.res \ test_farsi.res \ test_filter_map.res \ + test_fnameescape.res \ test_fold.res \ test_glob2regpat.res \ test_gn.res \ @@ -55,6 +57,7 @@ NEW_TESTS ?= \ test_normal.res \ test_quickfix.res \ test_signs.res \ + test_substitute.res \ test_syntax.res \ test_tabpage.res \ test_textobjects.res \ diff --git a/src/nvim/testdir/test_charsearch.vim b/src/nvim/testdir/test_charsearch.vim new file mode 100644 index 0000000000..115659a013 --- /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_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim new file mode 100644 index 0000000000..ce2cd3f7a6 --- /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_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/version.c b/src/nvim/version.c index a911e8ebc3..ee66b00b4e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -134,7 +134,7 @@ static int included_patches[] = { // 2310 NA 2309, // 2308 NA - // 2307, + 2307, // 2306, 2305, // 2304 NA -- cgit From 85ba14af6ad19fa3c4ba1ade3819014254635b2f Mon Sep 17 00:00:00 2001 From: lonerover Date: Thu, 23 Mar 2017 22:54:30 +0800 Subject: vim-patch:7.4.2330 Problem: Coverity complains about not checking curwin to be NULL. Solution: Use firstwin to avoid the warning. https://github.com/vim/vim/commit/030cddc7ec0c3d2fe3969140cd1b92b2f18633c0 --- src/nvim/buffer.c | 7 ++++--- src/nvim/version.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 3c416c157f..4a07884f98 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -627,10 +627,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) { diff --git a/src/nvim/version.c b/src/nvim/version.c index ee66b00b4e..c18439c279 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -111,7 +111,7 @@ static int included_patches[] = { 2333, // 2332 NA 2331, - // 2330, + 2330, 2329, 2328, // 2327 NA -- cgit From 9cd7e199048161c5224aca885af8b7945236392d Mon Sep 17 00:00:00 2001 From: lonerover Date: Fri, 24 Mar 2017 12:24:25 +0800 Subject: vim-patch:7.4.2334 Problem: On MS-Windows test_getcwd leaves Xtopdir behind. Solution: Set 'noswapfile'. (Michael Soyka) https://github.com/vim/vim/commit/1b0c2fcf6e85c9b85c24757ba970061e1f3e4e80 --- src/nvim/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index c18439c279..500e8984c0 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -107,7 +107,7 @@ static int included_patches[] = { 2337, 2336, 2335, - // 2334, + 2334, 2333, // 2332 NA 2331, -- cgit From 7bc37ffb22a84668bba5b2e3589c4c05ad43f7d0 Mon Sep 17 00:00:00 2001 From: Jakob Schnitzer Date: Fri, 24 Mar 2017 20:21:05 +0100 Subject: terminal: global 'scrollback' #6352 Make the 'scrollback' option work like most other buffer-local options: - `:set scrollback=x` sets the global and local value - `:setglobal scrollback=x` sets only the global default - new terminal buffers inherit the global Normal buffers are still always -1, and :setlocal there is an error. Closes #6337 --- src/nvim/globals.h | 2 +- src/nvim/option.c | 21 +++++++++++---------- src/nvim/option_defs.h | 3 +++ src/nvim/options.lua | 2 +- src/nvim/terminal.c | 13 ++++++------- 5 files changed, 22 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/globals.h b/src/nvim/globals.h index ad14ec4f8c..de79ee2469 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1255,7 +1255,7 @@ typedef enum { kCdScopeInvalid = -1, kCdScopeWindow, ///< Affects one window. kCdScopeTab, ///< Affects one tab page. - kCdScopeGlobal, ///< Affects the entire instance of Neovim. + kCdScopeGlobal, ///< Affects the entire Nvim instance. } CdScope; #define MIN_CD_SCOPE kCdScopeWindow diff --git a/src/nvim/option.c b/src/nvim/option.c index 2a17ca69d1..b037b0ae35 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -156,7 +156,6 @@ static long p_ts; static long p_tw; static int p_udf; static long p_wm; -static long p_scbk; static char_u *p_keymap; /* Saved values for when 'bin' is set. */ @@ -4199,16 +4198,13 @@ set_num_option ( FOR_ALL_TAB_WINDOWS(tp, wp) { check_colorcolumn(wp); } - } else if (pp == &curbuf->b_p_scbk) { + } else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) { // 'scrollback' - if (!curbuf->terminal) { + if (*pp < -1 || *pp > SB_MAX + || (opt_flags == OPT_LOCAL && !curbuf->terminal)) { errmsg = e_invarg; - curbuf->b_p_scbk = -1; - } else { - if (curbuf->b_p_scbk < -1 || curbuf->b_p_scbk > 100000) { - errmsg = e_invarg; - curbuf->b_p_scbk = 1000; - } + *pp = old_value; + } else if (curbuf->terminal) { // Force the scrollback to take effect. terminal_resize(curbuf->terminal, UINT16_MAX, UINT16_MAX); } @@ -4331,6 +4327,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) { @@ -4586,7 +4587,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 diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index b171b23edb..94c6361236 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -524,6 +524,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' @@ -811,4 +812,6 @@ enum { /* 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 853c2b52d7..ee2b8a563d 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1918,7 +1918,7 @@ return { vi_def=true, varname='p_scbk', redraw={'current_buffer'}, - defaults={if_true={vi=-1}} + defaults={if_true={vi=1000}} }, { full_name='scrollbind', abbreviation='scb', diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 87ee8f410f..dc418e25fa 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -85,8 +85,6 @@ typedef struct terminal_state { # include "terminal.c.generated.h" #endif -#define SB_MAX 100000 // Maximum 'scrollback' value. - // Delay for refreshing the terminal buffer after receiving updates from // libvterm. Improves performance when receiving large bursts of data. #define REFRESH_DELAY 10 @@ -231,10 +229,10 @@ Terminal *terminal_open(TerminalOptions opts) set_option_value((uint8_t *)"buftype", 0, (uint8_t *)"terminal", OPT_LOCAL); // Default settings for terminal buffers - curbuf->b_p_ma = false; // 'nomodifiable' - curbuf->b_p_ul = -1; // 'undolevels' - curbuf->b_p_scbk = 1000; // 'scrollback' - curbuf->b_p_tw = 0; // 'textwidth' + 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((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); @@ -248,7 +246,8 @@ Terminal *terminal_open(TerminalOptions opts) apply_autocmds(EVENT_TERMOPEN, NULL, NULL, false, curbuf); // Configure the scrollback buffer. - rv->sb_size = curbuf->b_p_scbk < 0 ? SB_MAX : (size_t)curbuf->b_p_scbk;; + 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) { -- cgit From 62774e43564b166d6907c7abc2e3431a65bd5596 Mon Sep 17 00:00:00 2001 From: Eiichi NISHINA Date: Sun, 12 Feb 2017 02:10:53 +0900 Subject: ci: Check that `#include "*.h"` works as a single include Lesser form of include-what-you-use: at least guarantees that header file did not forget to include something through some other included file. Activate run_single_includes_tests on CI. Fix some IWYU violations. References #5321 --- src/nvim/CMakeLists.txt | 156 ++++++++++++++++++++++++++++++++++++++++-------- src/nvim/eval_defs.h | 1 + src/nvim/ex_docmd.c | 1 + src/nvim/ex_docmd.h | 1 + src/nvim/mark.h | 2 +- src/nvim/os/fs_defs.h | 2 +- src/nvim/os/os_defs.h | 4 +- src/nvim/os/unix_defs.h | 2 +- src/nvim/os/win_defs.h | 6 +- src/nvim/strings.h | 3 +- 10 files changed, 145 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 22cf1f3a3d..8af2dcf5f6 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -48,6 +48,7 @@ file(MAKE_DIRECTORY ${GENERATED_DIR}) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}) file(GLOB NEOVIM_SOURCES *.c) +file(GLOB NEOVIM_HEADERS *.h) foreach(subdir os @@ -65,10 +66,11 @@ foreach(subdir file(MAKE_DIRECTORY ${GENERATED_DIR}/${subdir}) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/${subdir}) file(GLOB sources ${subdir}/*.c) + file(GLOB headers ${subdir}/*.h) list(APPEND NEOVIM_SOURCES ${sources}) + list(APPEND NEOVIM_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 @@ -152,6 +154,19 @@ 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}) +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() + +# NEOVIM_GENERATED_FOR_HEADERS: header files generated to be included in headers +# NEOVIM_GENERATED_FOR_SOURCES: header files generated to be included in sources +# NEOVIM_GENERATED_SOURCES: generated source files +# These lists should be mutually exclusive + foreach(sfile ${NEOVIM_SOURCES} "${PROJECT_SOURCE_DIR}/src/nvim/regexp_nfa.c" ${GENERATED_API_DISPATCH}) @@ -166,26 +181,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 NEOVIM_GENERATED_FOR_SOURCES "${gf_c_h}") + list(APPEND NEOVIM_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() @@ -210,17 +221,23 @@ add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA} ${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua ) -list(APPEND NEOVIM_GENERATED_SOURCES - "${PROJECT_BINARY_DIR}/config/auto/pathdef.c" - "${GENERATED_API_DISPATCH}" +list(APPEND NEOVIM_GENERATED_FOR_HEADERS "${GENERATED_EX_CMDS_ENUM}" - "${GENERATED_EX_CMDS_DEFS}" "${GENERATED_EVENTS_ENUM}" +) + +list(APPEND NEOVIM_GENERATED_FOR_SOURCES + "${GENERATED_API_DISPATCH}" + "${GENERATED_EX_CMDS_DEFS}" "${GENERATED_EVENTS_NAMES_MAP}" "${GENERATED_OPTIONS}" "${GENERATED_UNICODE_TABLES}" ) +list(APPEND NEOVIM_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} @@ -237,7 +254,7 @@ add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA} ${GENERATED_FUNCS_HASH_INPUT} --output-file=${GENERATED_FUNCS} DEPENDS ${FUNCS_GENERATOR} ${EVAL_DEFS_FILE} ${API_METADATA} ) -list(APPEND NEOVIM_GENERATED_SOURCES +list(APPEND NEOVIM_GENERATED_FOR_SOURCES "${GENERATED_FUNCS}") add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} @@ -252,6 +269,15 @@ add_custom_command(OUTPUT ${GENERATED_OPTIONS} DEPENDS ${OPTIONS_GENERATOR} ${OPTIONS_LIST_FILE} ) +# Check that NEOVIM_GENERATED_FOR_SOURCES and NEOVIM_GENERATED_FOR_HEADERS are mutually exclusive + +foreach(hfile ${NEOVIM_GENERATED_FOR_HEADERS}) + list(FIND NEOVIM_GENERATED_FOR_SOURCES ${hfile} hfile_idx) + if(NOT ${hfile_idx} EQUAL -1) + message(FATAL_ERROR "File included in both NEOVIM_GENERATED_FOR_HEADERS and NEOVIM_GENERATED_FOR_SOURCES") + endif() +endforeach() + # Our dependencies come first. if (LibIntl_FOUND) @@ -286,8 +312,8 @@ 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 ${NEOVIM_GENERATED_FOR_SOURCES} ${NEOVIM_GENERATED_FOR_HEADERS} + ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) install_helper(TARGETS nvim) @@ -361,17 +387,97 @@ 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}) +add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_FOR_SOURCES} ${NEOVIM_GENERATED_FOR_HEADERS} + ${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}) +add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_FOR_SOURCES} ${NEOVIM_GENERATED_FOR_HEADERS} + ${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) +set(NO_SINGLE_CHECK_HEADERS + buffer + charset + cursor_shape + diff + digraph + ex_cmds + ex_getln + file_search + fold + getchar + hardcopy + if_cscope + if_cscope_defs + mark + mbyte + memfile_defs + memline + memline_defs + menu + misc2 + move + msgpack_rpc/server + ops + option + os/shell + os_unix + os/win_defs + popupmnu + quickfix + regexp + regexp_defs + screen + search + sha256 + sign_defs + spell + syntax + syntax_defs + tag + terminal + tui/tui + ugrid + ui + ui_bridge + undo + undo_defs + version + window +) +foreach(hfile ${NEOVIM_HEADERS}) + get_filename_component(full_d ${hfile} 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 ${hfile} NAME_WE) + if(NOT ${d} EQUAL ".") + set(r "${d}/${r}") + endif() + + if(NOT ${hfile} MATCHES "[.]c[.]h$") + set(tsource "${GENERATED_DIR}/${r}.test-include.c") + set(tresult "${GENERATED_DIR}/${r}.test-include.i") + string(REPLACE "/" "-" texe "${r}-test") + write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }") + get_preproc_output(PREPROC_OUTPUT ${tresult}) + add_executable( + ${texe} + EXCLUDE_FROM_ALL + ${tsource} ${NEOVIM_HEADERS} ${NEOVIM_GENERATED_FOR_HEADERS}) + + list(FIND NO_SINGLE_CHECK_HEADERS "${r}" 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}) + add_subdirectory(po) diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h index 39028fdb11..8f5e1a897d 100644 --- a/src/nvim/eval_defs.h +++ b/src/nvim/eval_defs.h @@ -3,6 +3,7 @@ #include #include +#include #include "nvim/hashtab.h" #include "nvim/lib/queue.h" diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 486baaad47..d1557f9c82 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -67,6 +67,7 @@ #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" #include "nvim/shada.h" +#include "nvim/globals.h" static int quitmore = 0; static int ex_pressedreturn = FALSE; diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index 4def4cbbae..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 diff --git a/src/nvim/mark.h b/src/nvim/mark.h index aff6e7273a..efba9708db 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -29,7 +29,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_) \ 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/os_defs.h b/src/nvim/os/os_defs.h index 14c210c69c..f81785675e 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -27,11 +27,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/unix_defs.h b/src/nvim/os/unix_defs.h index c98aa88bfa..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 -#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) diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 8de896c490..827fb2f247 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 @@ -15,7 +19,7 @@ #define NAME_MAX _MAX_PATH -#define TEMP_DIR_NAMES {"$TMP", "$TEMP", "$USERPROFILE", ""} +#define TEMP_DIR_NAMES { "$TMP", "$TEMP", "$USERPROFILE", "" } #define TEMP_FILE_PATH_MAXLEN _MAX_PATH #define FNAME_ILLEGAL "\"*?><|" diff --git a/src/nvim/strings.h b/src/nvim/strings.h index eb8b83c7d0..8aea374b96 100644 --- a/src/nvim/strings.h +++ b/src/nvim/strings.h @@ -1,9 +1,8 @@ #ifndef NVIM_STRINGS_H #define NVIM_STRINGS_H -#include #include -#include +#include #include "nvim/types.h" #include "nvim/eval_defs.h" -- cgit From e20e9645b2c74b8cf6e1ba90961c08b079bbee3c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 27 Mar 2017 14:12:23 +0200 Subject: build: Rename NEOVIM_* to NVIM_* --- src/nvim/CMakeLists.txt | 64 ++++++++++++++++++++++------------------------ src/nvim/po/CMakeLists.txt | 10 ++++---- 2 files changed, 36 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 8af2dcf5f6..877b403463 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -47,8 +47,8 @@ include_directories(${GENERATED_INCLUDES_DIR}) file(MAKE_DIRECTORY ${GENERATED_DIR}) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}) -file(GLOB NEOVIM_SOURCES *.c) -file(GLOB NEOVIM_HEADERS *.h) +file(GLOB NVIM_SOURCES *.c) +file(GLOB NVIM_HEADERS *.h) foreach(subdir os @@ -67,18 +67,18 @@ foreach(subdir file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/${subdir}) file(GLOB sources ${subdir}/*.c) file(GLOB headers ${subdir}/*.h) - list(APPEND NEOVIM_SOURCES ${sources}) - list(APPEND NEOVIM_HEADERS ${headers}) + list(APPEND NVIM_SOURCES ${sources}) + list(APPEND NVIM_HEADERS ${headers}) endforeach() file(GLOB UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c) # Sort file lists to ensure generated files are created in the same order from # build to build. -list(SORT NEOVIM_SOURCES) -list(SORT NEOVIM_HEADERS) +list(SORT NVIM_SOURCES) +list(SORT NVIM_HEADERS) -foreach(sfile ${NEOVIM_SOURCES}) +foreach(sfile ${NVIM_SOURCES}) get_filename_component(f ${sfile} NAME) if(${f} MATCHES "^(regexp_nfa.c)$") list(APPEND to_remove ${sfile}) @@ -88,7 +88,7 @@ foreach(sfile ${NEOVIM_SOURCES}) 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 @@ -162,12 +162,11 @@ function(get_preproc_output varname iname) endif() endfunction() -# NEOVIM_GENERATED_FOR_HEADERS: header files generated to be included in headers -# NEOVIM_GENERATED_FOR_SOURCES: header files generated to be included in sources -# NEOVIM_GENERATED_SOURCES: generated source files -# These lists should be mutually exclusive - -foreach(sfile ${NEOVIM_SOURCES} +# 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} "${PROJECT_SOURCE_DIR}/src/nvim/regexp_nfa.c" ${GENERATED_API_DISPATCH}) get_filename_component(full_d ${sfile} PATH) @@ -193,8 +192,8 @@ foreach(sfile ${NEOVIM_SOURCES} COMMAND "${LUA_PRG}" "${HEADER_GENERATOR}" "${sfile}" "${gf_c_h}" "${gf_h_h}" "${gf_i}" DEPENDS "${HEADER_GENERATOR}" "${sfile}" ) - list(APPEND NEOVIM_GENERATED_FOR_SOURCES "${gf_c_h}") - list(APPEND NEOVIM_GENERATED_FOR_HEADERS "${gf_h_h}") + 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 ${gf_h_h}) endif() @@ -221,12 +220,12 @@ add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA} ${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua ) -list(APPEND NEOVIM_GENERATED_FOR_HEADERS +list(APPEND NVIM_GENERATED_FOR_HEADERS "${GENERATED_EX_CMDS_ENUM}" "${GENERATED_EVENTS_ENUM}" ) -list(APPEND NEOVIM_GENERATED_FOR_SOURCES +list(APPEND NVIM_GENERATED_FOR_SOURCES "${GENERATED_API_DISPATCH}" "${GENERATED_EX_CMDS_DEFS}" "${GENERATED_EVENTS_NAMES_MAP}" @@ -234,7 +233,7 @@ list(APPEND NEOVIM_GENERATED_FOR_SOURCES "${GENERATED_UNICODE_TABLES}" ) -list(APPEND NEOVIM_GENERATED_SOURCES +list(APPEND NVIM_GENERATED_SOURCES "${PROJECT_BINARY_DIR}/config/auto/pathdef.c" ) @@ -254,7 +253,7 @@ add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA} ${GENERATED_FUNCS_HASH_INPUT} --output-file=${GENERATED_FUNCS} DEPENDS ${FUNCS_GENERATOR} ${EVAL_DEFS_FILE} ${API_METADATA} ) -list(APPEND NEOVIM_GENERATED_FOR_SOURCES +list(APPEND NVIM_GENERATED_FOR_SOURCES "${GENERATED_FUNCS}") add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} @@ -269,12 +268,11 @@ add_custom_command(OUTPUT ${GENERATED_OPTIONS} DEPENDS ${OPTIONS_GENERATOR} ${OPTIONS_LIST_FILE} ) -# Check that NEOVIM_GENERATED_FOR_SOURCES and NEOVIM_GENERATED_FOR_HEADERS are mutually exclusive - -foreach(hfile ${NEOVIM_GENERATED_FOR_HEADERS}) - list(FIND NEOVIM_GENERATED_FOR_SOURCES ${hfile} hfile_idx) +# 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 NEOVIM_GENERATED_FOR_HEADERS and NEOVIM_GENERATED_FOR_SOURCES") + message(FATAL_ERROR "File included in both NVIM_GENERATED_FOR_HEADERS and NVIM_GENERATED_FOR_SOURCES") endif() endforeach() @@ -312,8 +310,8 @@ if(JEMALLOC_FOUND) list(APPEND NVIM_EXEC_LINK_LIBRARIES ${JEMALLOC_LIBRARIES}) endif() -add_executable(nvim ${NEOVIM_GENERATED_FOR_SOURCES} ${NEOVIM_GENERATED_FOR_HEADERS} - ${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) @@ -387,16 +385,16 @@ elseif(CLANG_TSAN) set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=thread ") endif() -add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_FOR_SOURCES} ${NEOVIM_GENERATED_FOR_HEADERS} - ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) +add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS} + ${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${NVIM_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_FOR_SOURCES} ${NEOVIM_GENERATED_FOR_HEADERS} - ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${UNIT_TEST_FIXTURES} ${NEOVIM_HEADERS}) +add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS} + ${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${UNIT_TEST_FIXTURES} ${NVIM_HEADERS}) target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES}) set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTING) @@ -450,7 +448,7 @@ set(NO_SINGLE_CHECK_HEADERS version window ) -foreach(hfile ${NEOVIM_HEADERS}) +foreach(hfile ${NVIM_HEADERS}) get_filename_component(full_d ${hfile} PATH) file(RELATIVE_PATH d "${PROJECT_SOURCE_DIR}/src/nvim" "${full_d}") if(${d} MATCHES "^[.][.]") @@ -470,7 +468,7 @@ foreach(hfile ${NEOVIM_HEADERS}) add_executable( ${texe} EXCLUDE_FROM_ALL - ${tsource} ${NEOVIM_HEADERS} ${NEOVIM_GENERATED_FOR_HEADERS}) + ${tsource} ${NVIM_HEADERS} ${NVIM_GENERATED_FOR_HEADERS}) list(FIND NO_SINGLE_CHECK_HEADERS "${r}" hfile_exclude_idx) if(${hfile_exclude_idx} EQUAL -1) 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}) -- cgit From 88124dfebc1a9c7eeb149beedd52a818058f9c16 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 27 Mar 2017 14:44:14 +0200 Subject: build: Prefix check-single-includes artifacts. The previous naming scheme could conflict with the test fixture artifacts from `test/functional/fixtures/`, which also produce `foo-test` artifacts. --- src/nvim/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 877b403463..3ee4380538 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -435,6 +435,7 @@ set(NO_SINGLE_CHECK_HEADERS sha256 sign_defs spell + spellfile syntax syntax_defs tag @@ -462,7 +463,7 @@ foreach(hfile ${NVIM_HEADERS}) if(NOT ${hfile} MATCHES "[.]c[.]h$") set(tsource "${GENERATED_DIR}/${r}.test-include.c") set(tresult "${GENERATED_DIR}/${r}.test-include.i") - string(REPLACE "/" "-" texe "${r}-test") + string(REPLACE "/" "-" texe "test-incl-${r}") write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }") get_preproc_output(PREPROC_OUTPUT ${tresult}) add_executable( -- cgit From 9d200cd0a3ef749509cee3331ba1d0b5fb62e7f2 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 27 Mar 2017 21:04:52 +0200 Subject: getcompletion("cmdline") (#6376) Closes #5823 --- src/nvim/eval.c | 18 +++++++++++++----- src/nvim/testdir/test_cmdline.vim | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d49fcbf17e..927a1dcb0e 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -10765,16 +10765,23 @@ 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(get_tv_string(&argvars[1]), "cmdline") == 0) { + set_one_cmd_context(&xpc, get_tv_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 = (int)STRLEN(xpc.xp_pattern); xpc.xp_context = cmdcomplete_str_to_type(get_tv_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; } @@ -10793,6 +10800,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); if (pat != NULL) { diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 40db227d97..f56227250c 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -156,6 +156,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'] -- cgit From b9e7ab1484784903b3233309a402138dc42e7e59 Mon Sep 17 00:00:00 2001 From: Samuel Catherasoo Date: Tue, 28 Mar 2017 19:21:30 -0400 Subject: refactor/single-include: charset.h (#6385) --- src/nvim/CMakeLists.txt | 1 - src/nvim/charset.h | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 3ee4380538..e752f5d4df 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -400,7 +400,6 @@ set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTIN set(NO_SINGLE_CHECK_HEADERS buffer - charset cursor_shape diff digraph diff --git a/src/nvim/charset.h b/src/nvim/charset.h index 78d6f2a76c..8d25b828e5 100644 --- a/src/nvim/charset.h +++ b/src/nvim/charset.h @@ -1,6 +1,10 @@ #ifndef NVIM_CHARSET_H #define NVIM_CHARSET_H +#include "nvim/types.h" +#include "nvim/pos.h" +#include "nvim/buffer_defs.h" + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "charset.h.generated.h" #endif -- cgit From e86042ae178736d657b5da12adce4479633aa8d5 Mon Sep 17 00:00:00 2001 From: lonerover Date: Wed, 29 Mar 2017 07:30:54 +0800 Subject: vim-patch:7.4.2343 and mark NA patches (#6384) vim-patch:7.4.2343 Problem: Too many old file tests. Solution: Turn several into new style tests. (Yegappan Lakshmanan) https://github.com/vim/vim/commit/53f1673cd909eb1c809c6a9086e3d104a0df9bed --- src/nvim/testdir/Makefile | 3 +++ src/nvim/testdir/test_charsearch.vim | 4 ++-- src/nvim/testdir/test_fnameescape.vim | 2 +- src/nvim/testdir/test_gf.vim | 33 +++++++++++++++++++++++++++++++++ src/nvim/testdir/test_hlsearch.vim | 34 ++++++++++++++++++++++++++++++++++ src/nvim/testdir/test_smartindent.vim | 14 ++++++++++++++ src/nvim/testdir/test_tagjump.vim | 30 ++++++++++++++++++++++++++++++ src/nvim/version.c | 6 +++--- 8 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/nvim/testdir/test_gf.vim create mode 100644 src/nvim/testdir/test_hlsearch.vim create mode 100644 src/nvim/testdir/test_smartindent.vim (limited to 'src') diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index fd557cca51..70a9f2b8c4 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -41,10 +41,12 @@ NEW_TESTS ?= \ test_fnameescape.res \ test_fold.res \ test_glob2regpat.res \ + test_gf.res \ test_gn.res \ test_hardcopy.res \ test_help_tagjump.res \ test_history.res \ + test_hlsearch.res \ test_increment.res \ test_increment_dbcs.res \ test_lambda.res \ @@ -57,6 +59,7 @@ NEW_TESTS ?= \ test_normal.res \ test_quickfix.res \ test_signs.res \ + test_smartindent.res \ test_substitute.res \ test_syntax.res \ test_tabpage.res \ diff --git a/src/nvim/testdir/test_charsearch.vim b/src/nvim/testdir/test_charsearch.vim index 115659a013..8b313b5a35 100644 --- a/src/nvim/testdir/test_charsearch.vim +++ b/src/nvim/testdir/test_charsearch.vim @@ -2,8 +2,8 @@ function! Test_charsearch() enew! call append(0, ['Xabcdefghijkemnopqretuvwxyz', - \ 'Yabcdefghijkemnopqretuvwxyz', - \ 'Zabcdefghijkemnokqretkvwxyz']) + \ 'Yabcdefghijkemnopqretuvwxyz', + \ 'Zabcdefghijkemnokqretkvwxyz']) " check that "fe" and ";" work 1 normal! ylfep;;p,,p diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim index ce2cd3f7a6..cdff0dfbd9 100644 --- a/src/nvim/testdir/test_fnameescape.vim +++ b/src/nvim/testdir/test_fnameescape.vim @@ -6,7 +6,7 @@ function! Test_fnameescape() try exe "w! " . fnameescape(fname) let status = v:true - endtry + endtry call assert_true(status, "Space") call delete(fname) 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("")) + call search("^second") + call search("URL") + call assert_equal("URL://machine.name/tmp/vimtest2b", expand("")) + 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("")) + call search("^fourth") + call search("URL") + call assert_equal("URL:\\\\machine.name\\tmp\\vimtest2d", expand("")) + + set isf&vim + enew! +endfunction 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\" | 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! /\" | redraw + call assert_equal(r1, screenattr(1,1)) + set nohls + exe "normal! /\" | 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_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\" + exe "normal! 2cc#test\" + call assert_equal(" #test", getline(1)) + enew! | close +endfunction diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 2044c23f79..0d697b3f3e 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -65,4 +65,34 @@ func Test_duplicate_tagjump() 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[\" + call assert_equal(" start OK if found this line", getline('.')) + call cursor(1,1) + call search("start") + exe "normal! 5\\" + 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/version.c b/src/nvim/version.c index 500e8984c0..dd583f6ffd 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -74,10 +74,10 @@ static char *features[] = { // clang-format off static int included_patches[] = { - // 2367, + // 2367,NA // 2366 NA // 2365 NA - // 2364, + // 2364,NA // 2363 NA 2362, // 2361 NA @@ -98,7 +98,7 @@ static int included_patches[] = { 2346, // 2345 NA // 2344 NA - // 2343, + 2343, // 2342 NA 2341, // 2340 NA -- cgit From 18e7d552008b92dd3ecd42bf6855530838fd22ab Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 29 Mar 2017 02:13:50 +0200 Subject: terminal.c:redraw(): Avoid invalid cursor col (#6379) Removed the call to validate_cursor() because mb_check_adjust_col() is already called in adjust_topline(). Closes #6378 References #6203 https://s3.amazonaws.com/archive.travis-ci.org/jobs/215498258/log.txt [ ERROR ] ...ovim/neovim/test/functional/terminal/scrollback_spec.lua @ 386: 'scrollback' option set to 0 behaves as 1 (10621.17 ms) ==================== File /home/travis/build/neovim/neovim/build/log/ubsan.12836 ==================== = ================================================================= = ==12836==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62100002cd00 at pc 0x000000eafe90 bp 0x7ffc8661fe50 sp 0x7ffc8661fe48 = READ of size 1 at 0x62100002cd00 thread T0 = #0 0xeafe8f in utf_head_off /home/travis/build/neovim/neovim/src/nvim/mbyte.c:1457:7 = #1 0x6b890e in getvcol /home/travis/build/neovim/neovim/src/nvim/charset.c:1169:15 = #2 0x6bc777 in getvvcol /home/travis/build/neovim/neovim/src/nvim/charset.c:1336:5 = #3 0xfc067b in curs_columns /home/travis/build/neovim/neovim/src/nvim/move.c:730:5 = #4 0xfbc8db in validate_cursor /home/travis/build/neovim/neovim/src/nvim/move.c:510:5 = #5 0x14479ed in setcursor /home/travis/build/neovim/neovim/src/nvim/screen.c:6363:5 = #6 0x17fe054 in redraw /home/travis/build/neovim/neovim/src/nvim/terminal.c:1175:5 = #7 0x17f95e4 in terminal_enter /home/travis/build/neovim/neovim/src/nvim/terminal.c:392:3 = #8 0x70eb2b in edit /home/travis/build/neovim/neovim/src/nvim/edit.c:1300:7 = #9 0x11097d1 in normal_finish_command /home/travis/build/neovim/neovim/src/nvim/normal.c:947:13 = #10 0x1081191 in normal_execute /home/travis/build/neovim/neovim/src/nvim/normal.c:1138:3 = #11 0x170b813 in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:58:26 = #12 0x103631b in normal_enter /home/travis/build/neovim/neovim/src/nvim/normal.c:464:3 = #13 0xdfb7a8 in main /home/travis/build/neovim/neovim/src/nvim/main.c:552:3 = #14 0x2b8a3c85bf44 in __libc_start_main /build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:287 = #15 0x447b25 in _start (/home/travis/build/neovim/neovim/build/bin/nvim+0x447b25) = = 0x62100002cd00 is located 0 bytes to the right of 4096-byte region [0x62100002bd00,0x62100002cd00) = allocated by thread T0 here: = #0 0x4f1e98 in malloc (/home/travis/build/neovim/neovim/build/bin/nvim+0x4f1e98) = #1 0xf28774 in try_malloc /home/travis/build/neovim/neovim/src/nvim/memory.c:84:15 = #2 0xf28934 in xmalloc /home/travis/build/neovim/neovim/src/nvim/memory.c:118:15 = #3 0xec7be8 in mf_alloc_bhdr /home/travis/build/neovim/neovim/src/nvim/memfile.c:646:17 = #4 0xec58d4 in mf_new /home/travis/build/neovim/neovim/src/nvim/memfile.c:297:12 = #5 0xeda8a8 in ml_new_data /home/travis/build/neovim/neovim/src/nvim/memline.c:2697:16 = #6 0xed7beb in ml_open /home/travis/build/neovim/neovim/src/nvim/memline.c:349:8 = #7 0x643fcd in open_buffer /home/travis/build/neovim/neovim/src/nvim/buffer.c:109:7 = #8 0xa7038c in do_ecmd /home/travis/build/neovim/neovim/src/nvim/ex_cmds.c:2483:24 = #9 0xb5bb49 in do_exedit /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:6839:9 = #10 0xb7b6d8 in ex_edit /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:6767:3 = #11 0xb2a598 in do_one_cmd /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:2208:5 = #12 0xb08f47 in do_cmdline /home/travis/build/neovim/neovim/src/nvim/ex_docmd.c:602:20 = #13 0x109997b in nv_colon /home/travis/build/neovim/neovim/src/nvim/normal.c:4492:18 = #14 0x1081188 in normal_execute /home/travis/build/neovim/neovim/src/nvim/normal.c:1135:3 = #15 0x170b813 in state_enter /home/travis/build/neovim/neovim/src/nvim/state.c:58:26 = #16 0x103631b in normal_enter /home/travis/build/neovim/neovim/src/nvim/normal.c:464:3 = #17 0xdfb7a8 in main /home/travis/build/neovim/neovim/src/nvim/main.c:552:3 = #18 0x2b8a3c85bf44 in __libc_start_main /build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:287 = = SUMMARY: AddressSanitizer: heap-buffer-overflow /home/travis/build/neovim/neovim/src/nvim/mbyte.c:1457:7 in utf_head_off = Shadow bytes around the buggy address: = 0x0c427fffd950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 = 0x0c427fffd960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 = 0x0c427fffd970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 = 0x0c427fffd980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 = 0x0c427fffd990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 = =>0x0c427fffd9a0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa = 0x0c427fffd9b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa = 0x0c427fffd9c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa = 0x0c427fffd9d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa = 0x0c427fffd9e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa = 0x0c427fffd9f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa = Shadow byte legend (one shadow byte represents 8 application bytes): = Addressable: 00 = Partially addressable: 01 02 03 04 05 06 07 = Heap left redzone: fa = Heap right redzone: fb = Freed heap region: fd = Stack left redzone: f1 = Stack mid redzone: f2 = Stack right redzone: f3 = Stack partial redzone: f4 = Stack after return: f5 = Stack use after scope: f8 = Global redzone: f9 = Global init order: f6 = Poisoned by user: f7 = Container overflow: fc = Array cookie: ac = Intra object redzone: bb = ASan internal: fe = Left alloca redzone: ca = Right alloca redzone: cb = ==12836==ABORTING ===================================================================================================== ./test/helpers.lua:82: assertion failed! stack traceback: ./test/helpers.lua:82: in function 'check_logs' ./test/functional/helpers.lua:643: in function <./test/functional/helpers.lua:642> --- src/nvim/terminal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index dc418e25fa..c81e883fb9 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -1155,7 +1155,6 @@ static void redraw(bool restore_cursor) save_col = ui_current_col(); } block_autocmds(); - validate_cursor(); if (must_redraw) { update_screen(0); @@ -1172,7 +1171,7 @@ static void redraw(bool restore_cursor) 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; - setcursor(); + mb_check_adjust_col(curwin); } unblock_autocmds(); -- cgit From fb146e80aa1ead96518f38b9684e39249bc83485 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 26 Jul 2016 23:16:23 +0300 Subject: eval: Split eval.c into smaller files --- src/clint.py | 7 +- src/nvim/api/private/helpers.c | 17 +- src/nvim/api/vim.c | 5 +- src/nvim/buffer.c | 2 +- src/nvim/buffer_defs.h | 45 +- src/nvim/charset.c | 26 +- src/nvim/cursor.c | 15 +- src/nvim/edit.c | 13 +- src/nvim/eval.c | 2961 ++++++++++++++------------------------- src/nvim/eval/decode.c | 98 +- src/nvim/eval/decode.h | 2 +- src/nvim/eval/encode.c | 9 +- src/nvim/eval/executor.c | 114 ++ src/nvim/eval/executor.h | 9 + src/nvim/eval/gc.c | 11 + src/nvim/eval/gc.h | 12 + src/nvim/eval/typval.c | 1171 ++++++++++++++++ src/nvim/eval/typval.h | 285 ++++ src/nvim/eval/typval_encode.c.h | 2 +- src/nvim/eval/typval_encode.h | 2 +- src/nvim/eval_defs.h | 286 ---- src/nvim/ex_cmds.c | 2 +- src/nvim/ex_cmds.h | 2 +- src/nvim/ex_cmds2.c | 24 +- src/nvim/ex_docmd.c | 4 +- src/nvim/ex_eval.c | 14 +- src/nvim/ex_getln.c | 6 +- src/nvim/ex_getln.h | 2 +- src/nvim/globals.h | 16 +- src/nvim/main.c | 7 +- src/nvim/mark.c | 23 + src/nvim/mark_defs.h | 2 +- src/nvim/mbyte.c | 41 +- src/nvim/mbyte.h | 23 + src/nvim/memory.c | 13 + src/nvim/normal.c | 14 +- src/nvim/ops.c | 73 +- src/nvim/ops.h | 2 +- src/nvim/quickfix.c | 2 +- src/nvim/regexp.c | 51 +- src/nvim/regexp_nfa.c | 4 +- src/nvim/shada.c | 36 +- src/nvim/spell.c | 2 +- src/nvim/strings.c | 2 +- src/nvim/strings.h | 2 +- src/nvim/tag.c | 8 +- src/nvim/undo.c | 4 +- src/nvim/window.c | 15 +- 48 files changed, 2961 insertions(+), 2525 deletions(-) create mode 100644 src/nvim/eval/executor.c create mode 100644 src/nvim/eval/executor.h create mode 100644 src/nvim/eval/gc.c create mode 100644 src/nvim/eval/gc.h create mode 100644 src/nvim/eval/typval.c create mode 100644 src/nvim/eval/typval.h delete mode 100644 src/nvim/eval_defs.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index ce31822ada..61c53d128e 100755 --- a/src/clint.py +++ b/src/clint.py @@ -2268,11 +2268,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') @@ -3575,7 +3578,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/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 7efa086af2..ff45cad8f5 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -14,6 +14,7 @@ #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" @@ -87,7 +88,7 @@ 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); + hashitem_T *hi = hash_find(&dict->dv_hashtab, (char_u *)key.data); if (HASHITEM_EMPTY(hi)) { api_set_error(err, Validation, _("Key not found")); @@ -177,13 +178,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, 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); // Clear the temporary variable - clear_tv(&tv); + tv_clear(&tv); } return rv; @@ -682,20 +683,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++; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 413456c615..59c0200395 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -22,6 +22,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/eval.h" +#include "nvim/eval/typval.h" #include "nvim/option.h" #include "nvim/syntax.h" #include "nvim/getchar.h" @@ -237,11 +238,11 @@ Object nvim_call_function(String fname, Array args, Error *err) 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; diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4a07884f98..f7333fead4 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1472,7 +1472,7 @@ static inline void buf_init_changedtick(buf_T *const buf) { STATIC_ASSERT(sizeof("changedtick") <= sizeof(buf->changedtick_di.di_key), "buf->changedtick_di cannot hold large enough keys"); - buf->changedtick_di = (dictitem16_T) { + 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, diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 9d350c763e..20a2b931bd 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -21,8 +21,6 @@ typedef struct { #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. @@ -30,7 +28,9 @@ typedef struct { // for hashtab_T #include "nvim/hashtab.h" // for dict_T -#include "nvim/eval_defs.h" +#include "nvim/eval/typval.h" +// for proftime_T +#include "nvim/profile.h" // for String #include "nvim/api/private/defs.h" // for Map(K, V) @@ -318,25 +318,6 @@ typedef struct { String save_inputbuf; } 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. */ @@ -447,6 +428,10 @@ 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 @@ -491,7 +476,7 @@ struct file_buffer { // file has been changed and not written out. /// Change identifier incremented for each change, including undo #define b_changedtick changedtick_di.di_tv.vval.v_number - dictitem16_T changedtick_di; // b:changedtick dictionary item. + ChangedtickDictItem changedtick_di; // b:changedtick dictionary item. bool b_saving; /* Set to true if we are in the middle of saving the buffer. */ @@ -735,8 +720,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 @@ -824,9 +809,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 *tp_localdir; ///< Absolute path of local CWD 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. }; /* @@ -1118,8 +1103,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 */ diff --git a/src/nvim/charset.c b/src/nvim/charset.c index efe32b915f..cb6a9fa43c 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -41,8 +41,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]; @@ -634,7 +636,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) { @@ -776,6 +778,21 @@ 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 +{ + if (c >= 0x100) { + return utf_class(c) >= 2; + } + return c > 0 && c < 0x100 && 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). @@ -785,10 +802,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. diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 82f1bf0a16..45abd314fc 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -12,6 +12,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 +228,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; @@ -361,9 +363,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/edit.c b/src/nvim/edit.c index 5544f0b163..77d5b2c816 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -15,6 +15,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" @@ -3461,8 +3462,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; } } @@ -3484,10 +3485,12 @@ expand_by_function ( ins_compl_add_dict(matchdict); theend: - if (matchdict != NULL) + if (matchdict != NULL) { dict_unref(matchdict); - if (matchlist != NULL) - list_unref(matchlist); + } + if (matchlist != NULL) { + tv_list_unref(matchlist); + } } /* diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 927a1dcb0e..03d6eef9e3 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -94,7 +94,11 @@ #include "nvim/lib/kvec.h" #include "nvim/lib/khash.h" #include "nvim/lib/queue.h" -#include "nvim/eval/typval_encode.h" +#include "nvim/eval/typval.h" +#include "nvim/eval/executor.h" +#include "nvim/eval/gc.h" + +// TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ @@ -150,7 +154,6 @@ typedef struct lval_S { 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"); @@ -167,17 +170,21 @@ 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\""); -static char_u * const empty_string = (char_u *)""; +// TODO(ZyX-I): move to eval/executor +static char *e_letwrong = N_("E734: Wrong variable type for %s="); + 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 /* @@ -188,12 +195,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; @@ -231,17 +241,44 @@ typedef enum { // 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 - -#define FLEN_FIXED 40 - #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] +/// 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. + /// 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. */ @@ -283,8 +320,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,7 +426,10 @@ 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: +/// Variable used for v: +static ScopeDictDictItem vimvars_var; + +/// v: hashtab #define vimvarht vimvardict.dv_hashtab typedef enum { @@ -465,6 +505,17 @@ 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; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval.c.generated.h" #endif @@ -547,7 +598,7 @@ void eval_init(void) dict_T *const msgpack_types_dict = 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]); @@ -570,7 +621,7 @@ void eval_init(void) dict_T *v_event = 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); @@ -601,7 +652,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; } } @@ -832,7 +883,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); @@ -854,7 +905,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); @@ -874,7 +925,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); @@ -888,7 +939,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); @@ -907,27 +958,29 @@ 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); + tv_clear(&tv); } } - if (skip) - --emsg_skip; + if (skip) { + emsg_skip--; + } return retval; } @@ -953,7 +1006,7 @@ eval_to_string_skip ( retval = NULL; else { retval = vim_strsave(get_tv_string(&tv)); - clear_tv(&tv); + tv_clear(&tv); } if (skip) --emsg_skip; @@ -992,9 +1045,10 @@ char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert) 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; @@ -1003,7 +1057,7 @@ char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert) retval = vim_strsave(numbuf); } else retval = vim_strsave(get_tv_string(&tv)); - clear_tv(&tv); + tv_clear(&tv); } return retval; @@ -1047,7 +1101,7 @@ int eval_to_number(char_u *expr) retval = -1; else { retval = get_tv_number_chk(&rettv, NULL); - clear_tv(&rettv); + tv_clear(&rettv); } --emsg_off; @@ -1104,11 +1158,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) @@ -1207,7 +1262,7 @@ int call_vim_function( ++sandbox; } - rettv->v_type = VAR_UNKNOWN; // clear_tv() uses this + 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); @@ -1218,7 +1273,7 @@ int call_vim_function( xfree(argvars); if (ret == FAIL) { - clear_tv(rettv); + tv_clear(rettv); } return ret; @@ -1245,7 +1300,7 @@ call_func_retnr ( return -1; retval = get_tv_number_chk(&rettv, NULL); - clear_tv(&rettv); + tv_clear(&rettv); return retval; } @@ -1270,7 +1325,7 @@ call_func_retstr ( return NULL; retval = vim_strsave(get_tv_string(&rettv)); - clear_tv(&rettv); + tv_clear(&rettv); return retval; } @@ -1294,7 +1349,7 @@ call_func_retlist ( return NULL; if (rettv.v_type != VAR_LIST) { - clear_tv(&rettv); + tv_clear(&rettv); return NULL; } @@ -1392,7 +1447,7 @@ 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) @@ -1464,13 +1519,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); } } } @@ -1516,7 +1571,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; @@ -1538,9 +1593,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; } @@ -1549,11 +1604,12 @@ ex_let_vars ( ltv.vval.v_list = l; l->lv_refcount = 1; - arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, - (char_u *)"]", nextchars); - clear_tv(<v); - if (arg == NULL) + arg = ex_let_one(skipwhite(arg + 1), <v, false, + (char_u *)"]", nextchars); + tv_clear(<v); + if (arg == NULL) { return FAIL; + } break; } else if (*arg != ',' && *arg != ']') { EMSG2(_(e_intern2), "ex_let_vars()"); @@ -1774,7 +1830,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) tv.v_type, s == NULL ? "" : s, first); xfree(s); } - clear_tv(&tv); + tv_clear(&tv); } } } @@ -1788,6 +1844,8 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) return arg; } +// TODO(ZyX-I): move to eval/ex_cmds + /* * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. * Returns a pointer to the char just after the var name. @@ -1952,6 +2010,8 @@ ex_let_one ( return arg_end; } +// TODO(ZyX-I): move to eval/executor + /// Get an lvalue /// /// Lvalue may be @@ -2081,8 +2141,8 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ return NULL; if (get_tv_string_chk(&var1) == NULL) { - /* not a number or string */ - clear_tv(&var1); + // Not a number or string. + tv_clear(&var1); return NULL; } } @@ -2090,35 +2150,41 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, /* 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); + // Not a number or string. + if (!empty1) { + tv_clear(&var1); + } + tv_clear(&var2); return NULL; } } @@ -2127,12 +2193,15 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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; } @@ -2145,7 +2214,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, // "[key]": get key from "var1" key = get_tv_string_chk(&var1); // is number or string if (key == NULL) { - clear_tv(&var1); + tv_clear(&var1); return NULL; } } @@ -2184,56 +2253,63 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, /* 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; // 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) { - clear_tv(&var1); + 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) + 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 = get_tv_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; } @@ -2244,24 +2320,26 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, * 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 = get_tv_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; } } @@ -2273,6 +2351,8 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, return p; } +// TODO(ZyX-I): move to eval/executor + /* * Clear lval "lp" that was filled by get_lval(). */ @@ -2282,6 +2362,8 @@ 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. @@ -2308,10 +2390,10 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch STRLEN(lp->ll_name)) && !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name, STRLEN(lp->ll_name)))) - && tv_op(&tv, rettv, op) == OK) { + && eexe_mod_op(&tv, rettv, (const char *)op) == OK) { set_var(lp->ll_name, &tv, false); } - clear_tv(&tv); + tv_clear(&tv); } } else { set_var(lp->ll_name, rettv, copy); @@ -2344,18 +2426,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); + 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); copy_tv(&ri->li_tv, &lp->ll_li->li_tv); } ri = ri->li_next; if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) break; if (lp->ll_li->li_next == NULL) { - /* Need to add an empty item. */ - 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; @@ -2398,10 +2480,10 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch } 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); } } @@ -2421,145 +2503,13 @@ notify: } 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_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. @@ -2567,14 +2517,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(char_u *arg, bool *errp, char_u **nextcmdp, int skip) { forinfo_T *fi = xcalloc(1, sizeof(forinfo_T)); 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) @@ -2589,20 +2539,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; } } @@ -2613,6 +2563,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. @@ -2636,6 +2588,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". */ @@ -2644,8 +2598,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); } @@ -2733,6 +2687,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. @@ -2752,13 +2707,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; } @@ -2786,7 +2742,7 @@ void ex_call(exarg_T *eap) /* 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); @@ -2825,9 +2781,10 @@ void ex_call(exarg_T *eap) break; } - clear_tv(&rettv); - if (doesrange || eap->skip) + tv_clear(&rettv); + if (doesrange || eap->skip) { break; + } /* Stop when immediately aborting on error, or when an interrupt * occurred or an exception was thrown but not caught. @@ -2853,6 +2810,8 @@ end: xfree(tofree); } +// TODO(ZyX-I): move to eval/ex_cmds + /* * ":unlet[!] var1 ... " command. */ @@ -2861,6 +2820,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 */ @@ -2879,6 +2840,8 @@ 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. */ @@ -2912,8 +2875,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; + } } } @@ -2926,6 +2890,8 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep) eap->nextcmd = check_nextcmd(arg); } +// TODO(ZyX-I): move to eval/ex_cmds + static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit) { int ret = OK; @@ -2966,14 +2932,14 @@ 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; @@ -2992,7 +2958,7 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit) if (watched) { dictwatcher_notify(d, key, NULL, &oldtv); - clear_tv(&oldtv); + tv_clear(&oldtv); xfree(key); } } @@ -3001,6 +2967,8 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit) return ret; } +// TODO(ZyX-I): move to eval/ex_cmds + /* * "unlet" a variable. Return OK if it existed, FAIL if not. * When "forceit" is TRUE don't complain if the variable doesn't exist. @@ -3060,7 +3028,7 @@ int do_unlet(char_u *name, int forceit) if (watched) { dictwatcher_notify(dict, (char *)varname, NULL, &oldtv); - clear_tv(&oldtv); + tv_clear(&oldtv); } return OK; } @@ -3071,12 +3039,15 @@ 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 *name_end, const int deep, + const bool lock) { int ret = OK; @@ -3104,117 +3075,28 @@ static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock) } else { di->di_flags &= ~DI_FLAGS_LOCK; } - item_lock(&di->di_tv, deep, lock); + tv_item_lock(&di->di_tv, deep, lock); } } 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; - - if (recurse >= DICT_MAXNEST) { - EMSG(_("E743: variable nested too deep for (un)lock")); - return; - } - if (deep == 0) { - return; - } - recurse++; - - // lock/unlock the item itself -#define CHANGE_LOCK(var, lock) \ - 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(tv->v_lock, lock); - - switch (tv->v_type) { - case VAR_LIST: { - list_T *const l = tv->vval.v_list; - if (l != NULL) { - CHANGE_LOCK(l->lv_lock, 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) { - 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(d->dv_lock, lock); - if (deep < 0 || deep > 1) { - // Recursive: lock/unlock the items the List contains. - int todo = (int)d->dv_hashtab.ht_used; - for (hashitem_T *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); - } - } -#undef CHANGE_LOCK - recurse--; -} - -/* - * Return TRUE if typeval "tv" is locked: Either that value is locked itself - * or it refers to a List or Dictionary that is locked. - */ -static int tv_islocked(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. */ @@ -3343,6 +3225,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'. @@ -3379,6 +3262,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 @@ -3400,15 +3285,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) @@ -3417,6 +3302,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 @@ -3442,13 +3329,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 (get_tv_number_chk(rettv, &error) != 0) { + result = true; + } + tv_clear(rettv); + if (error) { return FAIL; + } } /* @@ -3462,9 +3351,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; } @@ -3472,9 +3362,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) @@ -3484,6 +3375,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 @@ -3498,7 +3391,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. @@ -3513,12 +3406,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 (get_tv_number_chk(rettv, &error) != 0) { + result = true; + } + tv_clear(rettv); + if (error) { return FAIL; - first = FALSE; + } + first = false; } /* @@ -3532,11 +3427,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 (get_tv_number_chk(&var2, &error) != 0) { + result = true; + } + tv_clear(&var2); + if (error) { return FAIL; + } } if (evaluate) { rettv->v_type = VAR_NUMBER; @@ -3547,6 +3444,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 @@ -3561,7 +3460,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. @@ -3576,12 +3475,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 (get_tv_number_chk(rettv, &error) == 0) { + result = false; + } + tv_clear(rettv); + if (error) { return FAIL; - first = FALSE; + } + first = false; } /* @@ -3595,11 +3496,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 (get_tv_number_chk(&var2, &error) == 0) { + result = false; + } + tv_clear(&var2); + if (error) { return FAIL; + } } if (evaluate) { rettv->v_type = VAR_NUMBER; @@ -3610,6 +3513,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 @@ -3706,7 +3611,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; } @@ -3728,15 +3633,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) { @@ -3750,8 +3655,8 @@ 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. */ @@ -3765,8 +3670,8 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) || var2.v_type == VAR_PARTIAL) { 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 @@ -3868,8 +3773,8 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) 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; } @@ -3878,6 +3783,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 @@ -3925,7 +3832,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) * 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); + tv_clear(rettv); return FAIL; } } @@ -3935,7 +3842,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; } @@ -3946,28 +3853,28 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) 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); + if (s2 == NULL) { // Type error ? + tv_clear(rettv); + tv_clear(&var2); return FAIL; } p = concat_str(s1, s2); - clear_tv(rettv); + 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; @@ -3978,7 +3885,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) /* 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) @@ -3990,14 +3897,14 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) } else { n2 = get_tv_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) { @@ -4016,12 +3923,14 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) rettv->vval.v_number = n1; } } - clear_tv(&var2); + tv_clear(&var2); } } return OK; } +// TODO(ZyX-I): move to eval/expressions + /* * Handle fifth level expression: * * number multiplication @@ -4046,7 +3955,7 @@ eval6 ( long n1, n2; int use_float = FALSE; float_T f1 = 0, f2; - int error = FALSE; + bool error = false; /* * Get the first variable. @@ -4069,11 +3978,13 @@ eval6 ( n1 = 0; } else n1 = get_tv_number_chk(rettv, &error); - clear_tv(rettv); - if (error) + tv_clear(rettv); + if (error) { return FAIL; - } else + } + } else { n1 = 0; + } /* * Get the second variable. @@ -4092,11 +4003,13 @@ eval6 ( n2 = 0; } else { n2 = get_tv_number_chk(&var2, &error); - clear_tv(&var2); - if (error) + tv_clear(&var2); + if (error) { return FAIL; - if (use_float) + } + if (use_float) { f2 = n2; + } } /* @@ -4154,6 +4067,8 @@ eval6 ( return OK; } +// TODO(ZyX-I): move to eval/expressions + // Handle sixth level expression: // number number constant // "string" string constant @@ -4192,7 +4107,7 @@ static int eval7( 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; @@ -4308,7 +4223,7 @@ static int eval7( ++*arg; } else if (ret == OK) { EMSG(_("E110: Missing ')'")); - clear_tv(rettv); + tv_clear(rettv); ret = FAIL; } break; @@ -4349,7 +4264,7 @@ static int eval7( // 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; } @@ -4358,7 +4273,7 @@ static int eval7( // an exception was thrown but not caught. if (aborting()) { if (ret == OK) { - clear_tv(rettv); + tv_clear(rettv); } ret = FAIL; } @@ -4382,7 +4297,7 @@ static int eval7( // Apply logical NOT and unary '-', from right to left, ignore '+'. if (ret == OK && evaluate && end_leader > start_leader) { - int error = false; + bool error = false; int val = 0; float_T f = 0.0; @@ -4392,7 +4307,7 @@ static int eval7( val = get_tv_number_chk(rettv, &error); } if (error) { - clear_tv(rettv); + tv_clear(rettv); ret = FAIL; } else { while (end_leader > start_leader) { @@ -4412,10 +4327,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; } @@ -4425,6 +4340,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 '.'. @@ -4499,13 +4416,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 && get_tv_string_chk(&var1) == NULL) { + // Not a number or string. + tv_clear(&var1); return FAIL; } @@ -4515,28 +4432,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); + // 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 ']' */ @@ -4546,14 +4467,14 @@ eval_index ( n1 = 0; if (!empty1 && rettv->v_type != VAR_DICT) { n1 = get_tv_number(&var1); - clear_tv(&var1); + tv_clear(&var1); } if (range) { if (empty2) n2 = -1; else { n2 = get_tv_number(&var2); - clear_tv(&var2); + tv_clear(&var2); } } @@ -4587,15 +4508,16 @@ eval_index ( else s = vim_strnsave(s + n1, 1); } - clear_tv(rettv); + tv_clear(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) + len = tv_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. */ @@ -4616,29 +4538,31 @@ eval_index ( n2 = len - 1; if (!empty2 && (n2 < 0 || n2 + 1 < n1)) n2 = -1; - l = list_alloc(); - item = list_find(rettv->vval.v_list, n1); + l = tv_list_alloc(); + item = tv_list_find(rettv->vval.v_list, n1); while (n1++ <= n2) { - list_append_tv(l, &item->li_tv); + tv_list_append_tv(l, &item->li_tv); item = item->li_next; } - clear_tv(rettv); + tv_clear(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); + copy_tv(&tv_list_find(rettv->vval.v_list, n1)->li_tv, &var1); + tv_clear(rettv); *rettv = var1; } break; case VAR_DICT: if (range) { - if (verbose) - EMSG(_(e_dictrange)); - if (len == -1) - clear_tv(&var1); + if (verbose) { + emsgf(_(e_dictrange)); + } + if (len == -1) { + tv_clear(&var1); + } return FAIL; } { @@ -4647,22 +4571,25 @@ eval_index ( if (len == -1) { key = get_tv_string_chk(&var1); if (key == NULL) { - clear_tv(&var1); + tv_clear(&var1); return FAIL; } } item = dict_find(rettv->vval.v_dict, key, (int)len); - if (item == NULL && verbose) - EMSG2(_(e_dictkey), key); - if (len == -1) - clear_tv(&var1); - if (item == NULL) + 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_clear(rettv); *rettv = var1; } break; @@ -4678,6 +4605,8 @@ eval_index ( return OK; } +// TODO(ZyX-I): move to eval/executor + /// Get an option value /// /// @param[in,out] arg Points to the '&' or '+' before the option name. Is @@ -4931,10 +4860,12 @@ char_u *partial_name(partial_T *pt) 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); @@ -4947,6 +4878,8 @@ static void partial_free(partial_T *pt) xfree(pt); } +// TODO(ZyX-I): Move to eval/typval.h + /// Unreference a closure: decrement the reference count and free it when it /// becomes zero. void partial_unref(partial_T *pt) @@ -4965,7 +4898,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); @@ -4973,10 +4906,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 == ']') @@ -4992,7 +4925,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; } @@ -5007,142 +4940,8 @@ 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; -} +// TODO(ZyX-I): move to eval/typval /* * Return the dictitem that an entry in a hashtable points to. @@ -5152,6 +4951,8 @@ dictitem_T *dict_lookup(hashitem_T *hi) return HI2DI(hi); } +// TODO(ZyX-I): move to eval/typval + /* * Return TRUE when two dictionaries have exactly the same key/values. */ @@ -5255,8 +5056,7 @@ static bool func_equal( * Compares the items just like "==" would compare them, but strings and * numbers are different. Floats and numbers are also different. */ -static int -tv_equal ( +int tv_equal( typval_T *tv1, typval_T *tv2, int ic, /* ignore case */ @@ -5298,501 +5098,41 @@ tv_equal ( switch (tv1->v_type) { case VAR_LIST: - ++recursive_cnt; - r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); - --recursive_cnt; + recursive_cnt++; + r = tv_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; - } + return r; - garray_T join_ga; - int retval; + case VAR_NUMBER: + return tv1->vval.v_number == tv2->vval.v_number; - ga_init(&join_ga, (int)sizeof(join_T), l->lv_len); - retval = list_join_inner(gap, l, sep, &join_ga); + 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; -# define FREE_JOIN_TOFREE(join) xfree((join)->tofree) - GA_DEEP_CLEAR(&join_ga, join_T, FREE_JOIN_TOFREE); + case VAR_SPECIAL: + return tv1->vval.v_special == tv2->vval.v_special; - return retval; + 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; } /// Get next (unique) copy ID @@ -6035,7 +5375,7 @@ bool garbage_collect(bool testing) /// 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. @@ -6048,14 +5388,14 @@ 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 @@ -6068,36 +5408,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); } } - 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; } @@ -6369,12 +5709,13 @@ 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; + // 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; - first_dict = d; + gc_first_dict = d; hash_init(&d->dv_hashtab); d->dv_lock = VAR_UNLOCKED; @@ -6434,21 +5775,18 @@ void dict_unref(dict_T *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. */ +static void 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); - todo = (int)d->dv_hashtab.ht_used; - for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) { + size_t todo = (int)d->dv_hashtab.ht_used; + for (hashitem_T *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); + // Remove the item before deleting it, just in case there is + // something recursive causing trouble. + dictitem_T *const di = HI2DI(hi); hash_remove(&d->dv_hashtab, hi); dictitem_free(di); todo--; @@ -6465,10 +5803,12 @@ static void dict_free_contents(dict_T *d) { hash_clear(&d->dv_hashtab); } -static void dict_free_dict(dict_T *d) { +static void dict_free_dict(dict_T *d) + FUNC_ATTR_NONNULL_ALL +{ // Remove the dict from the list of dicts for garbage collection. if (d->dv_used_prev == NULL) { - first_dict = d->dv_used_next; + gc_first_dict = d->dv_used_next; } else { d->dv_used_prev->dv_used_next = d->dv_used_next; } @@ -6479,8 +5819,10 @@ static void dict_free_dict(dict_T *d) { xfree(d); } -void dict_free(dict_T *d) { - if (!in_free_unref_items) { +void dict_free(dict_T *d) + FUNC_ATTR_NONNULL_ALL +{ + if (!tv_in_free_unref_items) { dict_free_contents(d); dict_free_dict(d); } @@ -6536,7 +5878,7 @@ static void dictitem_remove(dict_T *dict, dictitem_T *item) */ void dictitem_free(dictitem_T *item) { - clear_tv(&item->di_tv); + tv_clear(&item->di_tv); if (item->di_flags & DI_FLAGS_ALLOC) { xfree(item); } @@ -6767,7 +6109,7 @@ static bool get_dict_callback(dict_T *d, char *key, Callback *result) copy_tv(&di->di_tv, &tv); set_selfdict(&tv, d); bool res = callback_from_typval(result, &tv); - clear_tv(&tv); + tv_clear(&tv); return res; } @@ -6845,34 +6187,35 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate) goto failret; if (**arg != ':') { EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); - clear_tv(&tvkey); + tv_clear(&tvkey); goto failret; } if (evaluate) { key = get_tv_string_buf_chk(&tvkey, buf); if (key == NULL) { // "key" is NULL when get_tv_string_buf_chk() gave an errmsg - clear_tv(&tvkey); + 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); 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); + tv_clear(&tvkey); item->di_tv = tv; item->di_tv.v_lock = 0; if (dict_add(d, item) == FAIL) { @@ -7391,8 +6734,9 @@ get_func_tv ( } } - while (--argcount >= 0) - clear_tv(&argvars[argcount]); + while (--argcount >= 0) { + tv_clear(&argvars[argcount]); + } *arg = skipwhite(argp); return ret; @@ -7688,7 +7032,7 @@ call_func( } while (argv_clear > 0) { - clear_tv(&argv[--argv_clear]); + tv_clear(&argv[--argv_clear]); } xfree(tofree); xfree(name); @@ -7804,7 +7148,7 @@ 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) @@ -7829,7 +7173,7 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr) const size_t arg_errmsg_len = strlen(arg_errmsg); if ((l = argvars[0].vval.v_list) != NULL && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { - list_append_tv(l, &argvars[1]); + tv_list_append_tv(l, &argvars[1]); copy_tv(&argvars[0], rettv); } } else @@ -7950,9 +7294,10 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); } } } @@ -8024,10 +7369,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) @@ -8116,10 +7461,10 @@ static void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr) void assert_inrange(typval_T *argvars) { - int error = (int)false; - varnumber_T lower = get_tv_number_chk(&argvars[0], &error); - varnumber_T upper = get_tv_number_chk(&argvars[1], &error); - varnumber_T actual = get_tv_number_chk(&argvars[2], &error); + bool error = false; + const varnumber_T lower = get_tv_number_chk(&argvars[0], &error); + const varnumber_T upper = get_tv_number_chk(&argvars[1], &error); + const varnumber_T actual = get_tv_number_chk(&argvars[2], &error); if (error) { return; @@ -8129,8 +7474,9 @@ void assert_inrange(typval_T *argvars) prepare_assert_error(&ga); char msg[55]; - vim_snprintf(msg, sizeof(msg), "range %" PRId64 " - %" PRId64 ",", - (int64_t)lower, (int64_t)upper); + 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); @@ -8141,7 +7487,7 @@ void assert_inrange(typval_T *argvars) // 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 @@ -8363,7 +7709,7 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int error = false; + bool error = false; char_u *name; rettv->vval.v_number = -1; @@ -8512,9 +7858,10 @@ int func_call(char_u *name, typval_T *args, partial_T *partial, &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; } @@ -8707,8 +8054,8 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u buf2[NUMBUFLEN]; int def = 1; int type = VIM_GENERIC; - char_u *typestr; - int error = FALSE; + char_u *typestr; + bool error = false; message = get_tv_string_chk(&argvars[0]); if (message == NULL) @@ -8768,15 +8115,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); if (argvars[3].v_type != VAR_UNKNOWN) { idx = get_tv_number_chk(&argvars[3], &error); if (!error) { - li = list_find(l, idx); - if (li == NULL) + li = tv_list_find(l, idx); + if (li == NULL) { EMSGN(_(e_listidx), idx); + } } } if (error) @@ -8793,7 +8141,7 @@ 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); @@ -9349,7 +8697,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Handle d.key, l[idx], f(expr). n = (handle_subscript((const char **)&p, &tv, true, false) == OK); if (n) { - clear_tv(&tv); + tv_clear(&tv); } } } @@ -9372,8 +8720,8 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 @@ -9390,9 +8738,9 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) result = eval_vars(s, 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; @@ -9407,14 +8755,14 @@ static void f_expand(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, s, NULL, - options, WILD_ALL); - else { - rettv_list_alloc(rettv); + if (rettv->v_type == VAR_STRING) { + rettv->vval.v_string = ExpandOne(&xpc, s, NULL, options, WILD_ALL); + } else { + tv_list_alloc_ret(rettv); ExpandOne(&xpc, 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); } @@ -9479,12 +8827,12 @@ void dict_extend(dict_T *d1, dict_T *d2, char_u *action) copy_tv(&di1->di_tv, &oldtv); } - clear_tv(&di1->di_tv); + tv_clear(&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); + tv_clear(&oldtv); } } } @@ -9504,7 +8852,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) list_T *l1, *l2; listitem_T *item; long before; - int error = FALSE; + bool error = false; l1 = argvars[0].vval.v_list; l2 = argvars[1].vval.v_list; @@ -9515,10 +8863,10 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -9526,7 +8874,7 @@ 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); } @@ -9616,8 +8964,8 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) char_u *p; char_u pathbuf[NUMBUFLEN]; 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; @@ -9632,13 +8980,14 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) if (*p != NUL) path = p; - if (argvars[2].v_type != VAR_UNKNOWN) + if (argvars[2].v_type != VAR_UNKNOWN) { count = get_tv_number_chk(&argvars[2], &error); + } } } if (count < 0) { - rettv_list_alloc(rettv); + tv_list_alloc_ret(rettv); } if (*fname != NUL && !error) { @@ -9652,11 +9001,11 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) (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); } @@ -9736,9 +9085,10 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) 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, arg_errmsg_len) || var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len)) { @@ -9762,9 +9112,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++; } } @@ -9819,24 +9170,25 @@ static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) } } 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; + bool error = false; - /* filter(): when expr is zero remove the item */ + // 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) + tv_clear(&rettv); + // On type error, nothing has been removed; return FAIL to stop the + // loop. The error message was given by get_tv_number_chk(). + if (error) { goto theend; + } } retval = OK; theend: - clear_tv(&vimvars[VV_VAL].vv_tv); + tv_clear(&vimvars[VV_VAL].vv_tv); return retval; } @@ -10278,11 +9630,12 @@ 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, get_tv_number_chk(&argvars[1], &error)); + if (!error && li != NULL) { tv = &li->li_tv; + } } } else if (argvars[0].v_type == VAR_DICT) { if ((d = argvars[0].vval.v_dict) != NULL) { @@ -10326,11 +9679,9 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } 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 { @@ -10353,13 +9704,13 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 = 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)); - list_append_dict(l, d); + tv_list_append_dict(l, d); } } @@ -10384,17 +9735,17 @@ static dict_T *get_buffer_info(buf_T *buf) dict_add_dict(dict, "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); 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); } @@ -10410,7 +9761,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) { @@ -10452,9 +9803,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; @@ -10475,7 +9826,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) @@ -10496,8 +9847,8 @@ 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); } } } @@ -10594,7 +9945,7 @@ f_getbufvar_end: static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) { varnumber_T n; - int error = FALSE; + bool error = false; no_mapping++; for (;; ) { @@ -10802,12 +10153,13 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); @@ -11110,7 +10462,7 @@ 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) { - rettv_list_alloc(rettv); + tv_list_alloc_ret(rettv); if (is_qf || wp != NULL) { (void)get_errorlist(wp, -1, rettv->vval.v_list); } @@ -11145,7 +10497,7 @@ 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(); if (cur->match.regprog == NULL) { @@ -11158,11 +10510,11 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); @@ -11181,7 +10533,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf); } - list_append_dict(rettv->vval.v_list, dict); + tv_list_append_dict(rettv->vval.v_list, dict); cur = cur->next; } } @@ -11205,20 +10557,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)); } } @@ -11251,7 +10605,7 @@ static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) int regname; 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]); @@ -11279,7 +10633,7 @@ static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 { @@ -11328,9 +10682,9 @@ static dict_T *get_tabpage_info(tabpage_T *tp, int tp_idx) dict_add_nr_str(dict, "tabnr", tp_idx, NULL); - 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); @@ -11345,7 +10699,7 @@ 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 @@ -11362,9 +10716,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; @@ -11447,7 +10801,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); @@ -11467,9 +10821,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 @@ -11504,7 +10858,7 @@ find_win_by_nr ( tabpage_T *tp /* NULL for current tab page */ ) { - int nr = get_tv_number_chk(vp, NULL); + int nr = (int)get_tv_number_chk(vp, NULL); if (nr < 0) { return NULL; @@ -11645,7 +10999,7 @@ 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. */ @@ -11669,14 +11023,15 @@ 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); + if (rettv->v_type == VAR_STRING) { + rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), NULL, + options, WILD_ALL); + } else { + tv_list_alloc_ret(rettv); ExpandOne(&xpc, get_tv_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); } @@ -11688,7 +11043,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; @@ -11722,10 +11077,10 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); } } @@ -12249,11 +11604,11 @@ 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, get_tv_number_chk(&argvars[2], &error)); idx = l->lv_idx; if (argvars[3].v_type != VAR_UNKNOWN) ic = get_tv_number_chk(&argvars[3], &error); @@ -12456,10 +11811,8 @@ 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; const char *const arg_errmsg = _("insert() argument"); const size_t arg_errmsg_len = strlen(arg_errmsg); @@ -12467,6 +11820,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG2(_(e_listarg), "insert()"); } else if ((l = argvars[0].vval.v_list) != NULL && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { + long before = 0; if (argvars[2].v_type != VAR_UNKNOWN) { before = get_tv_number_chk(&argvars[2], &error); } @@ -12475,17 +11829,16 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); + tv_list_insert_tv(l, &argvars[1], item); copy_tv(&argvars[0], rettv); } } @@ -12574,7 +11927,7 @@ static void dict_list(typval_T *argvars, typval_T *rettv, int what) if ((d = argvars[0].vval.v_dict) == NULL) return; - rettv_list_alloc(rettv); + tv_list_alloc_ret(rettv); todo = (int)d->dv_hashtab.ht_used; for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) { @@ -12582,8 +11935,8 @@ static void dict_list(typval_T *argvars, typval_T *rettv, int what) --todo; di = HI2DI(hi); - li = listitem_alloc(); - list_append(rettv->vval.v_list, li); + li = tv_list_item_alloc(); + tv_list_append(rettv->vval.v_list, li); if (what == 0) { /* keys() */ @@ -12594,21 +11947,21 @@ static void dict_list(typval_T *argvars, typval_T *rettv, int what) /* values() */ copy_tv(&di->di_tv, &li->li_tv); } else { - /* items() */ - l2 = list_alloc(); + // items() + l2 = 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 = tv_list_item_alloc(); + tv_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); + li2 = tv_list_item_alloc(); + tv_list_append(l2, li2); copy_tv(&di->di_tv, &li2->li_tv); } } @@ -12983,7 +12336,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); @@ -12994,11 +12347,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 @@ -13097,7 +12450,7 @@ static void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (sep != NULL) { 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, (const char *)sep); ga_append(&ga, NUL); rettv->vval.v_string = (char_u *)ga.ga_data; } else @@ -13181,7 +12534,7 @@ static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr) get_tv_string(&argvars[0])); break; case VAR_LIST: - rettv->vval.v_number = list_len(argvars[0].vval.v_list); + rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list); break; case VAR_DICT: rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); @@ -13435,12 +12788,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; @@ -13461,16 +12814,17 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type) 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) 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; @@ -13552,11 +12906,11 @@ 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) { @@ -13583,7 +12937,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: @@ -13609,7 +12964,7 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ int prio = 10; /* default priority */ int id = -1; - int error = false; + bool error = false; char_u *conceal_char = NULL; rettv->vval.v_number = -1; @@ -13667,7 +13022,7 @@ 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; @@ -13708,7 +13063,7 @@ 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]); @@ -13716,11 +13071,12 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); } } } @@ -13768,7 +13124,7 @@ static void max_min(typval_T *argvars, typval_T *rettv, int domax) { long n = 0; long i; - int error = FALSE; + bool error = false; if (argvars[0].v_type == VAR_LIST) { list_T *l; @@ -13938,7 +13294,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; @@ -13966,7 +13322,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; @@ -14011,9 +13367,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; @@ -14188,11 +13544,11 @@ 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; + varnumber_T start; + varnumber_T end; + varnumber_T stride = 1; long i; - int error = FALSE; + bool error = false; start = get_tv_number_chk(&argvars[0], &error); if (argvars[1].v_type == VAR_UNKNOWN) { @@ -14204,16 +13560,17 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) stride = get_tv_number_chk(&argvars[2], &error); } - if (error) - return; /* type error; errmsg already given */ - if (stride == 0) - EMSG(_("E726: Stride is zero")); - else if (stride > 0 ? end + 1 < start : end - 1 > start) - EMSG(_("E727: Start past end")); - else { - 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); } } } @@ -14244,7 +13601,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) maxline = get_tv_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. */ @@ -14293,11 +13650,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) @@ -14372,8 +13729,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); @@ -14395,9 +13752,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; } @@ -14456,9 +13813,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} @@ -14519,27 +13876,27 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG2(_(e_listdictarg), "remove()"); } else if ((l = argvars[0].vval.v_list) != NULL && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { - int error = (int)false; + 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) + 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) + 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) { @@ -14547,11 +13904,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; @@ -14588,10 +13945,10 @@ static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr) n = get_tv_number(&argvars[1]); if (argvars[0].v_type == VAR_LIST) { - rettv_list_alloc(rettv); + tv_list_alloc_ret(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_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL); } } } else { @@ -14802,12 +14159,12 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr) l->lv_len = 0; while (li != NULL) { listitem_T *const ni = li->li_prev; - list_append(l, li); + 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; } } @@ -15243,7 +14600,7 @@ 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 */ @@ -15346,15 +14703,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); } /* @@ -15386,7 +14743,6 @@ do_searchpair ( int n; int r; int nest = 1; - int err; int options = SEARCH_KEEP; proftime_T tm; @@ -15442,7 +14798,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. */ @@ -15513,7 +14870,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) { @@ -15521,10 +14878,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 @@ -15534,13 +14892,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); } @@ -15610,7 +14968,7 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (*varname == '&') { long numval; char_u *strval; - int error = false; + bool error = false; aco_save_T aco; // set curbuf to be our buf, temporarily @@ -15915,7 +15273,7 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) d = li->li_tv.vval.v_dict; if (dict_find(d, (char_u *)"pattern", -1) == NULL) { if (s == NULL) { - s = list_alloc(); + s = tv_list_alloc(); if (s == NULL) { return; } @@ -15929,7 +15287,7 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - list_append_tv(s, &di->di_tv); + tv_list_append_tv(s, &di->di_tv); s->lv_refcount++; } else { break; @@ -15949,7 +15307,7 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) priority, id, NULL, conceal); } else { match_add(curwin, group, NULL, priority, id, s, conceal); - list_unref(s); + tv_list_unref(s); s = NULL; } xfree(group); @@ -16193,7 +15551,7 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off) if (*varname == '&') { long numval; char_u *strval; - int error = false; + bool error = false; ++varname; numval = get_tv_number_chk(varp, &error); @@ -16272,7 +15630,7 @@ typedef struct { char_u *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; @@ -16399,13 +15757,13 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) copy_tv(&si1->item->li_tv, &argv[0]); copy_tv(&si2->item->li_tv, &argv[1]); - rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this + rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this res = call_func(func_name, (int)STRLEN(func_name), &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; @@ -16415,7 +15773,7 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) 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. @@ -16470,7 +15828,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) 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 } @@ -16490,7 +15848,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } 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); if (error) { @@ -16569,7 +15927,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); } } } @@ -16605,8 +15963,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--; } } @@ -16667,7 +16025,7 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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. */ @@ -16692,14 +16050,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, (const char *)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); } /* @@ -16708,13 +16065,13 @@ 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]); @@ -16735,11 +16092,11 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr) for (int i = 0; i < ga.ga_len; ++i) { str = ((char_u **)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); + tv_list_append(rettv->vval.v_list, li); } ga_clear(&ga); } @@ -16755,8 +16112,8 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -16765,15 +16122,17 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) str = get_tv_string(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) { pat = get_tv_string_buf_chk(&argvars[1], patbuf); - if (pat == NULL) - typeerr = TRUE; - if (argvars[2].v_type != VAR_UNKNOWN) - keepempty = get_tv_number_chk(&argvars[2], &typeerr); + if (pat == NULL) { + typeerr = true; + } + if (argvars[2].v_type != VAR_UNKNOWN) { + keepempty = (bool)get_tv_number_chk(&argvars[2], &typeerr); + } } if (pat == NULL || *pat == NUL) pat = (char_u *)"[\\x01- ]\\+"; - rettv_list_alloc(rettv); + tv_list_alloc_ret(rettv); if (typeerr) return; @@ -16793,7 +16152,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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)); + tv_list_append_string(rettv->vval.v_list, (const char *)str, end - str); } if (!match) break; @@ -16917,33 +16276,29 @@ 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]); + + char_u *str = get_tv_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 = get_tv_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(str + byteidx); + break; } + charidx--; + byteidx += MB_CPTR2LEN(str + byteidx); } } @@ -16966,7 +16321,7 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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)) @@ -17048,22 +16403,17 @@ static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // "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) +{ + char_u *const p = get_tv_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 = get_tv_number_chk(&argvars[1], &error); if (!error) { if (nchar > 0) { - while (nchar > 0 && nbyte < slen) { + while (nchar > 0 && (size_t)nbyte < slen) { nbyte += MB_CPTR2LEN(p + nbyte); nchar--; } @@ -17071,9 +16421,10 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) { 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 = get_tv_number(&argvars[2]); + while (charlen > 0 && nbyte + len < (int)slen) { int off = nbyte + len; if (off < 0) { @@ -17092,12 +16443,12 @@ 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; } @@ -17114,7 +16465,7 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) int n; int len; int slen; - int error = FALSE; + bool error = false; p = get_tv_string(&argvars[0]); slen = (int)STRLEN(p); @@ -17205,7 +16556,7 @@ 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; + bool error = false; int no = (int)get_tv_number_chk(&argvars[0], &error); if (error) { return; @@ -17270,7 +16621,7 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr) long lnum; long col; int trans; - int transerr = FALSE; + bool transerr = false; lnum = get_tv_lnum(argvars); /* -1 on type error */ col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ @@ -17396,7 +16747,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); @@ -17417,10 +16768,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); } /* @@ -17441,43 +16792,24 @@ static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) && 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); + tv_list_alloc_ret(rettv); + (void)syn_get_id(curwin, lnum, (colnr_T)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); + if (!keepempty && str[len - 1] == NL) { + len--; } - - // Optionally retain final newline, if present - if (keepempty && str[len-1] == NL) { - list_append_string(list, (char_u*)"", 0); - } - + list_T *const list = tv_list_alloc(); + encode_list_write(list, str, len); return list; } @@ -17522,7 +16854,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(""); } @@ -17534,7 +16866,7 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { keepempty = get_tv_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; @@ -17588,9 +16920,9 @@ static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; } } @@ -17683,16 +17015,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); @@ -17712,7 +17044,7 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (*tag_pattern == NUL) return; - (void)get_tags(rettv_list_alloc(rettv), tag_pattern); + (void)get_tags(tv_list_alloc_ret(rettv), tag_pattern); } /* @@ -18029,7 +17361,7 @@ static void timer_due_cb(TimeWatcher *tw, void *data) 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 @@ -18295,7 +17627,7 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr) dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL); dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL); - list = list_alloc(); + list = tv_list_alloc(); u_eval_tree(curbuf->b_u_oldhead, list); dict_add_list(dict, "entries", list); } @@ -18356,7 +17688,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); } @@ -18375,7 +17707,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); } @@ -18786,40 +18118,47 @@ var2fpos ( if (varp->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) 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; } @@ -18890,32 +18229,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; @@ -19259,7 +18603,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; } @@ -19270,7 +18614,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; } @@ -19284,7 +18628,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; @@ -19301,7 +18645,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) { @@ -19316,7 +18660,7 @@ 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; @@ -19536,17 +18880,19 @@ handle_subscript( 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); @@ -19560,7 +18906,7 @@ handle_subscript( } else selfdict = NULL; if (eval_index((char_u **)arg, rettv, evaluate, verbose) == FAIL) { - clear_tv(rettv); + tv_clear(rettv); ret = FAIL; } } @@ -19667,7 +19013,7 @@ void free_tv(typval_T *varp) partial_unref(varp->vval.v_partial); break; case VAR_LIST: - list_unref(varp->vval.v_list); + tv_list_unref(varp->vval.v_list); break; case VAR_DICT: dict_unref(varp->vval.v_dict); @@ -19682,247 +19028,6 @@ void free_tv(typval_T *varp) } } -#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; - } - 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; - } - 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; -} -#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 -/// -/// @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. */ @@ -19932,69 +19037,25 @@ static void init_tv(typval_T *varp) memset(varp, 0, sizeof(typval_T)); } -/// Check that given value is a number or string +// TODO(ZyX-I): move to eval/typval + +/// Get the number value of a variable /// -/// Error messages are compatible with get_tv_number() previously used for the -/// same purpose in buf*() functions. Special values are not accepted (previous -/// behaviour: silently fail to find buffer). +/// @note Use get_tv_number_chk() if you need to determine whether there was an +/// error. /// -/// @param[in] tv Value to check. +/// @param[in] varp Variable to get value from. /// -/// @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 FUNC_ATTR_PURE -{ - switch (tv->v_type) { - case VAR_NUMBER: - case VAR_STRING: { - return true; - } - case VAR_FLOAT: { - EMSG(_("E805: Expected a Number or a String, Float found")); - return false; - } - case VAR_PARTIAL: - case VAR_FUNC: { - EMSG(_("E703: Expected a Number or a String, Funcref found")); - return false; - } - case VAR_LIST: { - EMSG(_("E745: Expected a Number or a String, List found")); - return false; - } - case VAR_DICT: { - EMSG(_("E728: Expected a Number or a String, Dictionary found")); - return false; - } - case VAR_SPECIAL: { - EMSG(_("E5300: Expected a Number or a String")); - return false; - } - case VAR_UNKNOWN: { - EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)"); - return false; - } - } - assert(false); - return false; -} - -/* - * 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) +/// @return Number value: vim_str2nr() output for VAR_STRING variables, value +/// for VAR_NUMBER variables, -1 for other types. +varnumber_T get_tv_number(const typval_T *const varp) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - int error = FALSE; - - return get_tv_number_chk(varp, &error); /* return 0L on error */ + bool error = false; + return get_tv_number_chk(varp, &error); } -long get_tv_number_chk(typval_T *varp, int *denote) +varnumber_T get_tv_number_chk(const typval_T *const varp, bool *const denote) { long n = 0L; @@ -20087,7 +19148,7 @@ static linenr_T get_tv_lnum(typval_T *argvars) rettv.v_type = VAR_NUMBER; f_line(argvars, &rettv, NULL); lnum = rettv.vval.v_number; - clear_tv(&rettv); + tv_clear(&rettv); } return lnum; } @@ -20107,35 +19168,41 @@ static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf) 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 +// TODO(ZyX-I): move to eval/typval + +/// Get the string value of a variable +/// +/// @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 +/// get_tv_string_buf() if you need to use get_tv_string() output after +/// calling it again. +/// +/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// return NULL on error. +/// +/// @param[in] varp Varible to get value of. +/// +/// @return Variable value if it is VAR_STRING variable, number converted to +/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or empty +/// string. +char_u *get_tv_string(const typval_T *const varp) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { 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 *get_tv_string_buf(const typval_T *varp, char_u *buf) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { - char_u *res = get_tv_string_buf_chk(varp, buf); + char_u *const 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 + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { static char_u mybuf[NUMBUFLEN]; @@ -20143,7 +19210,7 @@ char_u *get_tv_string_chk(const typval_T *varp) } char_u *get_tv_string_buf_chk(const typval_T *varp, char_u *buf) - FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { switch (varp->v_type) { case VAR_NUMBER: @@ -20438,7 +19505,7 @@ 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 = VAR_UNLOCKED; @@ -20494,7 +19561,7 @@ static void vars_clear_ext(hashtab_T *ht, int free_val) // later. v = HI2DI(hi); if (free_val) { - clear_tv(&v->di_tv); + tv_clear(&v->di_tv); } if (v->di_flags & DI_FLAGS_ALLOC) { xfree(v); @@ -20514,7 +19581,7 @@ static void delete_var(hashtab_T *ht, hashitem_T *hi) dictitem_T *di = HI2DI(hi); hash_remove(ht, hi); - clear_tv(&di->di_tv); + tv_clear(&di->di_tv); xfree(di); } @@ -20652,11 +19719,11 @@ set_var ( if (watched) { copy_tv(&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; } @@ -20686,7 +19753,7 @@ set_var ( dictwatcher_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_clear(&oldtv); } } } @@ -20934,7 +20001,7 @@ 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) ret = FAIL; @@ -21036,7 +20103,7 @@ void ex_echo(exarg_T *eap) } xfree(tofree); } - clear_tv(&rettv); + tv_clear(&rettv); arg = skipwhite(arg); } eap->nextcmd = check_nextcmd(arg); @@ -21111,7 +20178,7 @@ void ex_execute(exarg_T *eap) ga.ga_len += len; } - clear_tv(&rettv); + tv_clear(&rettv); arg = skipwhite(arg); } @@ -21670,9 +20737,10 @@ void ex_function(exarg_T *eap) 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); @@ -21733,7 +20801,7 @@ ret_free: /// Advances "pp" to just after the function name (if no error). /// /// @return the function name in allocated memory, or NULL for failure. -char_u * +static char_u * trans_function_name( char_u **pp, int skip, /* only find the end, don't evaluate */ @@ -22720,9 +21788,9 @@ call_user_func( // 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"); @@ -22741,11 +21809,11 @@ 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"); @@ -22762,10 +21830,10 @@ call_user_func( // 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); + 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; @@ -22782,7 +21850,7 @@ call_user_func( 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)); @@ -22805,7 +21873,7 @@ call_user_func( } 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; } @@ -22913,7 +21981,7 @@ 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; } @@ -23109,7 +22177,7 @@ free_funccal ( // 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); + tv_clear(&li->li_tv); } } @@ -23152,10 +22220,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) { @@ -23242,7 +22311,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); @@ -23652,12 +22721,12 @@ void ex_oldfiles(exarg_T *eap) nr = prompt_for_number(false); msg_starthere(); if (nr > 0 && nr <= l->lv_len) { - char_u *p = list_find_str(l, nr); + char *p = tv_list_find_str(l, nr); if (p == NULL) { return; } - p = expand_env_save(p); - eap->arg = p; + p = (char *)expand_env_save((char_u *)p); + eap->arg = (char_u *)p; eap->cmdidx = CMD_edit; do_exedit(eap, NULL); xfree(p); @@ -24148,7 +23217,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; @@ -24156,7 +23225,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; @@ -24169,7 +23238,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; } @@ -24318,7 +23387,7 @@ static void on_job_event(JobEvent *ev) typval_T rettv; init_tv(&rettv); callback_call(ev->callback, 3, argv, &rettv); - clear_tv(&rettv); + tv_clear(&rettv); } static TerminalJobData *find_job(uint64_t id) @@ -24341,8 +23410,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); } @@ -24387,7 +23456,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; @@ -24479,12 +23548,12 @@ static void dictwatcher_notify(dict_T *dict, const char *key, typval_T *newtv, watcher->busy = true; callback_call(&watcher->callback, 3, argv, &rettv); watcher->busy = false; - clear_tv(&rettv); + tv_clear(&rettv); } } for (size_t i = 1; i < ARRAY_SIZE(argv); i++) { - clear_tv(argv + i); + tv_clear(argv + i); } } diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 43e9f76c0f..1d30f51f55 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -2,7 +2,7 @@ #include -#include "nvim/eval_defs.h" +#include "nvim/eval/typval.h" #include "nvim/eval.h" #include "nvim/eval/encode.h" #include "nvim/ascii.h" @@ -118,18 +118,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); @@ -139,33 +139,33 @@ static inline int json_decoder_pop(ValuesStackItem obj, || 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); + tv_clear(&key.val); if (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 @@ -175,14 +175,14 @@ static inline int json_decoder_pop(ValuesStackItem obj, || *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_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; @@ -430,7 +430,7 @@ static inline int parse_json_string(vimconv_T *const conv, } if (hasnul) { typval_T obj; - list_T *const list = list_alloc(); + list_T *const list = tv_list_alloc(); list->lv_refcount++; create_special_dict(&obj, kMPString, ((typval_T) { .v_type = VAR_LIST, @@ -439,7 +439,7 @@ static inline int parse_json_string(vimconv_T *const conv, })); if (encode_list_write((void *) list, str, (size_t) (str_end - str)) == -1) { - clear_tv(&obj); + tv_clear(&obj); goto parse_json_string_fail; } xfree(str); @@ -806,7 +806,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,7 +827,7 @@ json_decode_string_cycle_start: list_T *val_list = NULL; if (next_map_special) { next_map_special = false; - val_list = list_alloc(); + val_list = tv_list_alloc(); val_list->lv_refcount++; create_special_dict(&tv, kMPMap, ((typval_T) { .v_type = VAR_LIST, @@ -887,7 +887,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 +933,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 +941,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,18 +956,18 @@ 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; } @@ -980,7 +980,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) break; } case MSGPACK_OBJECT_STR: { - list_T *const list = list_alloc(); + list_T *const list = tv_list_alloc(); list->lv_refcount++; create_special_dict(rettv, kMPString, ((typval_T) { .v_type = VAR_LIST, @@ -1002,7 +1002,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) }; break; } - list_T *const list = list_alloc(); + list_T *const list = tv_list_alloc(); list->lv_refcount++; create_special_dict(rettv, kMPBinary, ((typval_T) { .v_type = VAR_LIST, @@ -1016,7 +1016,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) 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 +1024,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; } @@ -1057,7 +1057,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) di->di_tv.v_type = VAR_UNKNOWN; if (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,7 +1067,7 @@ 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_T *const list = tv_list_alloc(); list->lv_refcount++; create_special_dict(rettv, kMPMap, ((typval_T) { .v_type = VAR_LIST, @@ -1075,14 +1075,14 @@ msgpack_to_vim_generic_map: {} .vval = { .v_list = list }, })); 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 +1093,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..c8e7a189e3 100644 --- a/src/nvim/eval/decode.h +++ b/src/nvim/eval/decode.h @@ -5,7 +5,7 @@ #include -#include "nvim/eval_defs.h" +#include "nvim/eval/typval.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..1416806ca6 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -13,7 +13,7 @@ #include "nvim/eval/encode.h" #include "nvim/buffer_defs.h" // vimconv_T #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" @@ -45,7 +45,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 +81,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; } diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c new file mode 100644 index 0000000000..ab48ace400 --- /dev/null +++ b/src/nvim/eval/executor.c @@ -0,0 +1,114 @@ +#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 +{ + // 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 = 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; + } + tv_clear(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); + } + tv_clear(tv1); + tv1->v_type = VAR_NUMBER; + tv1->vval.v_number = n; + } + } else { + // str .= str + if (tv2->v_type == VAR_FLOAT) { + break; + } + char *s = (char *)get_tv_string(tv1); + char numbuf[NUMBUFLEN]; + s = (char *)concat_str((char_u *)s, + get_tv_string_buf(tv2, (char_u *)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 + : 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; +} diff --git a/src/nvim/eval/executor.h b/src/nvim/eval/executor.h new file mode 100644 index 0000000000..19e2a75914 --- /dev/null +++ b/src/nvim/eval/executor.h @@ -0,0 +1,9 @@ +#ifndef NVIM_EVAL_EXECUTOR_H +#define NVIM_EVAL_EXECUTOR_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..5ce52ddd70 --- /dev/null +++ b/src/nvim/eval/gc.c @@ -0,0 +1,11 @@ +#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..7726e106a1 --- /dev/null +++ b/src/nvim/eval/typval.c @@ -0,0 +1,1171 @@ +#include +#include +#include + +#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" +// 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 Lists +//{{{3 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 FUNC_ATTR_MALLOC +{ + 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; + for (listwatch_T *lw = l->lv_watch; lw != NULL; lw = lw->lw_next) { + lw->lw_item = 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); + } +} + +//{{{3 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) +{ + // notify watchers + for (listitem_T *ip = item; ip != NULL; ip = ip->li_next) { + l->lv_len--; + tv_list_watch_fix(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; +} + +/// 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 copy_tv()) 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(); + + copy_tv(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 copy_tv()) 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(); + copy_tv(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); +} + +//{{{3 Operations on the whole list + +/// 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. +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 { + copy_tv(&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; + // 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->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 +{ + if (l1 == NULL || l2 == NULL) { + return FAIL; + } + + // make a copy of the first list. + list_T *const l = tv_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 + tv_list_extend(l, l2, NULL); + 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. +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 == NULL || l2 == NULL) { + // FIXME? compare empty list with NULL list equal + return false; + } + if (l1 == l2) { + return true; + } + 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; +} + +//{{{3 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 *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 get_tv_number_chk(&li->li_tv, ret_error); +} + +/// Get list item l[n - 1] as a string +/// +/// @param[in] l List to index. +/// @param[in] n Index in a list. +/// +/// @return [allocated] Copy of the list item string value. +char *tv_list_find_str(list_T *l, int n) + FUNC_ATTR_MALLOC +{ + const listitem_T *const li = tv_list_find(l, n - 1); + if (li == NULL) { + EMSGN(_(e_listidx), n); + return NULL; + } + return (char *)get_tv_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; + 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 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 FUNC_ATTR_MALLOC +{ + 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; +} + +//{{{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); \ + 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) { + 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 +/// +/// @param[in,out] varp Value to free. +void tv_clear(typval_T *varp) +{ + if (varp != NULL && varp->v_type != VAR_UNKNOWN) { + const int evn_ret = encode_vim_to_nothing(varp, varp, "tv_clear argument"); + (void)evn_ret; + assert(evn_ret == OK); + } +} + +//{{{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) +{ + // 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 + int todo = (int)d->dv_hashtab.ht_used; + for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) { + if (!HASHITEM_EMPTY(hi)) { + todo--; + tv_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); + } + } +#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))); +} + +//{{{2 Type checks + +/// Check that given value is a number or string +/// +/// Error messages are compatible with get_tv_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 FUNC_ATTR_PURE +{ + switch (tv->v_type) { + case VAR_NUMBER: + case VAR_STRING: { + return true; + } + case VAR_FLOAT: { + EMSG(_("E805: Expected a Number or a String, Float found")); + return false; + } + case VAR_PARTIAL: + case VAR_FUNC: { + EMSG(_("E703: Expected a Number or a String, Funcref found")); + return false; + } + case VAR_LIST: { + EMSG(_("E745: Expected a Number or a String, List found")); + return false; + } + case VAR_DICT: { + EMSG(_("E728: Expected a Number or a String, Dictionary found")); + return false; + } + case VAR_SPECIAL: { + EMSG(_("E5300: Expected a Number or a String")); + return false; + } + case VAR_UNKNOWN: { + EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)"); + return false; + } + } + assert(false); + return false; +} diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h new file mode 100644 index 0000000000..cf83904ffc --- /dev/null +++ b/src/nvim/eval/typval.h @@ -0,0 +1,285 @@ +#ifndef NVIM_EVAL_TYPVAL_H +#define NVIM_EVAL_TYPVAL_H + +#include +#include +#include + +#include "nvim/hashtab.h" +#include "nvim/garray.h" +#include "nvim/mbyte.h" +#include "nvim/lib/queue.h" +#include "nvim/profile.h" // for proftime_T +#include "nvim/pos.h" // for linenr_T + +/// Type used for VimL VAR_NUMBER values +typedef int varnumber_T; + +/// Type used for VimL VAR_FLOAT values +typedef double float_T; + +/// Maximal possible value of varnumber_T variable +#define VARNUMBER_MAX INT_MAX + +/// Mimimal possible value of varnumber_T variable +#define VARNUMBER_MIN INT_MIN + +/// %d printf format specifier for varnumber_T +#define PRIdVARNUMBER "d" + +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 = 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]; /* NUL. */ \ + } + +/// 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; + +// 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. +typedef struct ufunc ufunc_T; + +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 123_ ( 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 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) + +/// Get the number of items in a list +/// +/// @param[in] l List to check. +static inline long tv_list_len(list_T *const l) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (l == NULL) { + return 0; + } + return l->lv_len; +} + +/// 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; + +#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 4ff5589887..eb89a601ff 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -242,7 +242,7 @@ #include #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" diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h index 46145c5d03..3475f6d8b3 100644 --- a/src/nvim/eval/typval_encode.h +++ b/src/nvim/eval/typval_encode.h @@ -11,7 +11,7 @@ #include #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 diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h deleted file mode 100644 index 8f5e1a897d..0000000000 --- a/src/nvim/eval_defs.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef NVIM_EVAL_DEFS_H -#define NVIM_EVAL_DEFS_H - -#include -#include -#include - -#include "nvim/hashtab.h" -#include "nvim/lib/queue.h" -#include "nvim/garray.h" // for garray_T -#include "nvim/profile.h" // for proftime_T -#include "nvim/pos.h" // for linenr_T - -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 = 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 "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; ///< 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!) -}; - -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. -}; - -typedef int scid_T; // script ID -typedef struct funccall_S funccall_T; - -// 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 - 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 123_ ( is K_SPECIAL - // KS_EXTRA KE_SNR) -}; - -/// Maximum number of function arguments -#define MAX_FUNC_ARGS 20 -#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. -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 - int fc_refcount; ///< number of user functions that reference - // this funccal - int fc_copyID; ///< 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; - -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 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_INRANGE, - ASSERT_OTHER, -} assert_type_T; - -#endif // NVIM_EVAL_DEFS_H diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 678102daf6..151a4d375f 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2958,7 +2958,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; } diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index 243b11255e..65bbd8a99e 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -4,8 +4,8 @@ #include #include "nvim/os/time.h" -#include "nvim/eval_defs.h" #include "nvim/pos.h" +#include "nvim/eval/typval.h" // flags for do_ecmd() #define ECMD_HIDE 0x01 // don't free the current buffer diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 9fc4ef2a02..e59a87b335 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -3698,12 +3698,12 @@ static void script_host_execute(char *name, exarg_T *eap) uint8_t *script = script_get(eap, eap->arg); if (!eap->skip) { - list_T *args = list_alloc(); + list_T *args = tv_list_alloc(); // script - list_append_string(args, script ? script : eap->arg, -1); + tv_list_append_string(args, (const char *)(script ? script : eap->arg), -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", args); } @@ -3715,21 +3715,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_docmd.c b/src/nvim/ex_docmd.c index d1557f9c82..dc99c0771d 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8416,8 +8416,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), + (long)i); if (result == NULL) { *errormsg = (char_u *)""; return NULL; diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 4bb6f97035..7a34a181e2 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -1,6 +1,8 @@ -/* - * ex_eval.c: functions for Ex command line for the +eval feature. - */ +// TODO(ZyX-I): move to eval/executor + +/// @file ex_eval.c +/// +/// Functions for Ex command line for the +eval feature. #include #include #include @@ -779,7 +781,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; @@ -800,6 +801,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) { @@ -844,7 +846,6 @@ void ex_endif(exarg_T *eap) */ void ex_else(exarg_T *eap) { - int error; int skip; int result; struct condstack *cstack = eap->cstack; @@ -901,6 +902,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 @@ -925,7 +927,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; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 8758a63bce..9851ed5396 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -4249,7 +4249,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; @@ -4545,7 +4545,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); } @@ -4601,7 +4601,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(); diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h index 24eebdc303..5a1ca5213a 100644 --- a/src/nvim/ex_getln.h +++ b/src/nvim/ex_getln.h @@ -1,7 +1,7 @@ #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" /* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */ diff --git a/src/nvim/globals.h b/src/nvim/globals.h index de79ee2469..d87407f099 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -12,6 +12,7 @@ #include "nvim/syntax_defs.h" #include "nvim/types.h" #include "nvim/event/loop.h" +#include "nvim/os/os_defs.h" #define IOSIZE (1024+1) // file I/O and sprintf buffer size @@ -21,16 +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 file path. Make it a bit long, to stay -// on the safe side. But not too long to put on the stack. -#ifndef MAXPATHL -# ifdef MAXPATHLEN -# define MAXPATHL MAXPATHLEN -# else -# define MAXPATHL 256 -# endif -#endif - #ifdef WIN32 # define _PATHSEPSTR "\\" #else @@ -1226,11 +1217,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); - -// Used for checking if local variables or arguments used in a lambda. -EXTERN int *eval_lavars_used INIT(= NULL); - // If a msgpack-rpc channel should be started over stdin/stdout EXTERN bool embedded_mode INIT(= false); diff --git a/src/nvim/main.c b/src/nvim/main.c index 7b1c912f4b..0c978dc47d 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -391,9 +391,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. diff --git a/src/nvim/mark.c b/src/nvim/mark.c index de2fdd7f13..1d1e13e7e0 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1431,3 +1431,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_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 0ab133a545..57518a9535 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -50,6 +50,7 @@ #include "nvim/strings.h" #include "nvim/os/os.h" #include "nvim/arabic.h" +#include "nvim/mark.h" typedef struct { int rangeStart; @@ -375,16 +376,18 @@ 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; } return utf_class(utf_ptr2char(p)); @@ -1639,38 +1642,16 @@ theend: */ void mb_adjust_cursor(void) { - 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) -{ - char_u *p; - - if (lp->col > 0 - || lp->coladd > 1 - ) { - p = ml_get_buf(buf, lp->lnum, FALSE); - lp->col -= (*mb_head_off)(p, p + lp->col); - /* Reset "coladd" when the cursor would be on the right half of a - * double-wide character. */ - if (lp->coladd == 1 - && p[lp->col] != TAB - && vim_isprintc((*mb_ptr2char)(p + lp->col)) - && ptr2cells(p + lp->col) > 1) - lp->coladd = 0; - } + mark_mb_adjustpos(curbuf, &curwin->w_cursor); } /// 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(win_T *win) +/// @param win_ Places cursor on a valid column for this window. +void mb_check_adjust_col(void *win_) { + win_T *win = (win_T *)win_; colnr_T oldcol = win->w_cursor.col; // Column 0 is always valid. diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index 2c92a0fbb2..5f5bab9fcd 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -3,6 +3,8 @@ #include +#include "nvim/iconv.h" + /* * Return byte length of character that starts with byte "b". * Returns 1 for a single-byte character. @@ -40,6 +42,27 @@ #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; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mbyte.h.generated.h" #endif diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 58c01fbe7a..b4fdd86a6d 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -430,6 +430,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. diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 2ade9cb87d..4cca5ec948 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -2465,7 +2465,7 @@ do_mouse ( &rettv, ARRAY_SIZE(argv), argv, NULL, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &doesrange, true, NULL, NULL); - clear_tv(&rettv); + tv_clear(&rettv); break; } } @@ -7290,11 +7290,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)); @@ -7829,7 +7829,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); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index c13b6f736a..85cef59aec 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2555,9 +2555,9 @@ static void do_autocmd_textyankpost(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); @@ -4844,8 +4844,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; } @@ -4895,9 +4895,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; @@ -5570,9 +5570,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, ®name, 1); + list_T *const args = tv_list_alloc(); + const char regname = (char)name; + tv_list_append_string(args, ®name, 1); typval_T result = eval_call_provider("clipboard", "get", args); @@ -5584,7 +5584,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) { @@ -5628,7 +5629,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) { @@ -5686,35 +5687,39 @@ 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, ®type, 1); - - char_u regname = (char_u)name; - list_append_string(args, ®name, 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, ®type, 1); + + const char regname = (char)name; + tv_list_append_string(args, ®name, 1); (void)eval_call_provider("clipboard", "set", args); } diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 44df2e9e0c..13d0142343 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -6,7 +6,7 @@ #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" typedef int (*Indenter)(void); diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 8d8c20c1d0..323503c4f5 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4003,7 +4003,7 @@ int get_errorlist(win_T *wp, int qf_idx, list_T *list) bufnum = 0; dict = dict_alloc(); - list_append_dict(list, dict); + tv_list_append_dict(list, dict); buf[0] = qfp->qf_type; buf[1] = NUL; diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 1cd334abcd..9c6f02f778 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -3650,9 +3650,11 @@ static long regtry(bt_regprog_T *prog, colnr_T col) */ 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), + reg_buf->b_chartab); + } return -1; } @@ -3918,12 +3920,13 @@ 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, 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 @@ -3938,8 +3941,8 @@ 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, reg_buf->b_chartab); prev_class = reg_prev_class(); if (this_class == prev_class || prev_class == 0 || prev_class == 1) @@ -6617,7 +6620,7 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, if (eval_result != NULL) { eval_result = vim_strsave(eval_result); } - clear_tv(&rettv); + tv_clear(&rettv); } else { eval_result = eval_to_string(source + 2, NULL, true); } @@ -6976,7 +6979,7 @@ 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; @@ -6988,27 +6991,27 @@ list_T *reg_submatch_list(int no) colnr_T scol = submatch_mmatch->startpos[no].col; colnr_T ecol = submatch_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]; + s = (const char *)submatch_match->startp[no]; if (s == NULL || submatch_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 *)submatch_match->endp[no] - s); } return list; diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 3f4e12af4a..5b49ab38f0 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -5410,7 +5410,7 @@ 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, reg_buf->b_chartab); if (this_class <= 1) { result = false; } else if (reg_prev_class() == this_class) { @@ -5435,7 +5435,7 @@ 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, reg_buf->b_chartab); prev_class = reg_prev_class(); if (this_class == prev_class || prev_class == 0 || prev_class == 1) { diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 197b029591..c550cb0888 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -30,7 +30,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" @@ -1223,7 +1223,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; @@ -1435,8 +1435,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 +1573,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 { \ @@ -1965,7 +1967,7 @@ static ShaDaWriteResult shada_pack_encoded_entry(msgpack_packer *const packer, 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); + tv_clear(&entry.data.data.global_var.value); entry.data.data.global_var.value = tgttv; } ret = shada_pack_entry(packer, entry.data, max_kbyte); @@ -2573,13 +2575,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); @@ -3172,18 +3174,18 @@ 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; } @@ -3451,7 +3453,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 +3476,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); \ @@ -3866,7 +3868,7 @@ shada_read_next_item_hist_no_conv: &tgttv, true, 0); - clear_tv(&entry->data.global_var.value); + tv_clear(&entry->data.global_var.value); entry->data.global_var.value = tgttv; } SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2, diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 3b891d998f..5ca5ab3339 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3248,7 +3248,7 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr) add_suggestion(su, &su->su_ga, 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". diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 267832ed2d..b964fed35a 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -571,7 +571,7 @@ static varnumber_T tv_nr(typval_T *tvs, int *idxp) EMSG(_(e_printf)); } else { (*idxp)++; - int err = false; + bool err = false; n = (varnumber_T)get_tv_number_chk(&tvs[idx], &err); if (err) { n = 0; diff --git a/src/nvim/strings.h b/src/nvim/strings.h index 8aea374b96..59b8701a3f 100644 --- a/src/nvim/strings.h +++ b/src/nvim/strings.h @@ -5,7 +5,7 @@ #include #include "nvim/types.h" -#include "nvim/eval_defs.h" +#include "nvim/eval/typval.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "strings.h.generated.h" diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 7bcaff662c..b0ffc12b5f 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -674,7 +674,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; @@ -774,7 +774,7 @@ do_tag ( } dict = dict_alloc(); - list_append_dict(list, dict); + tv_list_append_dict(list, dict); dict_add_nr_str(dict, "text", 0L, tag_name); dict_add_nr_str(dict, "filename", 0L, fname); @@ -786,7 +786,7 @@ do_tag ( vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag); set_errorlist(curwin, list, ' ', IObuff, NULL); - list_free(list); + tv_list_free(list); xfree(fname); xfree(cmd); @@ -2825,7 +2825,7 @@ int get_tags(list_T *list, char_u *pat) continue; dict = dict_alloc(); - list_append_dict(list, dict); + tv_list_append_dict(list, dict); full_fname = tag_full_fname(&tp); if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL diff --git a/src/nvim/undo.c b/src/nvim/undo.c index c95a795587..729cf03e15 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2952,14 +2952,14 @@ void u_eval_tree(u_header_T *first_uhp, list_T *list) dict_add_nr_str(dict, "save", uhp->uh_save_nr, NULL); 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. */ u_eval_tree(uhp->uh_alt_next.ptr, alt_list); dict_add_list(dict, "alt", alt_list); } - list_append_dict(list, dict); + tv_list_append_dict(list, dict); uhp = uhp->uh_prev.ptr; } } diff --git a/src/nvim/window.c b/src/nvim/window.c index 4fac730f02..47a97da0cf 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5582,7 +5582,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; @@ -5594,7 +5594,7 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, goto fail; } lnum = get_tv_number_chk(&subli->li_tv, &error); - if (error == true) { + if (error) { goto fail; } if (lnum == 0) { @@ -5605,12 +5605,13 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, subli = subli->li_next; if (subli != NULL) { col = get_tv_number_chk(&subli->li_tv, &error); - if (error == true) + if (error) { goto fail; + } subli = subli->li_next; if (subli != NULL) { len = get_tv_number_chk(&subli->li_tv, &error); - if (error == true) { + if (error) { goto fail; } } @@ -5881,8 +5882,8 @@ void win_id2tabwin(typval_T *argvars, list_T *list) int id = get_tv_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) @@ -5918,7 +5919,7 @@ void win_findbuf(typval_T *argvars, list_T *list) FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer->b_fnum == bufnr) { - list_append_number(list, wp->handle); + tv_list_append_number(list, wp->handle); } } } -- cgit From e18a5783080f7c94f408ec5f53dedffdb69789e1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 20 Aug 2016 22:24:34 +0300 Subject: *: Move some dictionary functions to typval.h and use char* Also fixes buffer reusage in setmatches() and complete(). --- src/.asan-blacklist | 2 +- src/nvim/api/private/helpers.c | 33 +- src/nvim/api/vim.c | 2 +- src/nvim/ascii.h | 8 +- src/nvim/buffer.c | 12 +- src/nvim/buffer.h | 5 +- src/nvim/charset.h | 10 + src/nvim/diff.c | 2 +- src/nvim/edit.c | 186 ++-- src/nvim/eval.c | 1780 ++++++++++++--------------------------- src/nvim/eval.h | 8 +- src/nvim/eval/decode.c | 26 +- src/nvim/eval/encode.c | 4 +- src/nvim/eval/typval.c | 788 ++++++++++++++++- src/nvim/eval/typval.h | 128 ++- src/nvim/eval/typval_encode.c.h | 10 +- src/nvim/event/process.h | 2 +- src/nvim/ex_cmds.c | 4 +- src/nvim/ex_cmds2.c | 65 +- src/nvim/ex_docmd.c | 28 +- src/nvim/ex_getln.c | 4 +- src/nvim/file_search.c | 2 +- src/nvim/getchar.c | 5 +- src/nvim/hashtab.c | 7 +- src/nvim/hashtab.h | 19 + src/nvim/macros.h | 9 + src/nvim/main.c | 45 +- src/nvim/mark.c | 2 +- src/nvim/mbyte.c | 36 +- src/nvim/mbyte.h | 15 + src/nvim/memline.c | 2 +- src/nvim/ops.c | 5 +- src/nvim/option.c | 364 ++++---- src/nvim/path.c | 73 +- src/nvim/popupmnu.c | 11 +- src/nvim/quickfix.c | 69 +- src/nvim/search.c | 9 +- src/nvim/shada.c | 14 +- src/nvim/spell.c | 9 +- src/nvim/spellfile.c | 2 +- src/nvim/syntax.c | 30 +- src/nvim/tag.c | 8 +- src/nvim/terminal.c | 10 +- src/nvim/undo.c | 4 +- src/nvim/vim.h | 38 +- src/nvim/window.c | 20 +- 46 files changed, 2068 insertions(+), 1847 deletions(-) (limited to 'src') 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/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index ff45cad8f5..6b17ba1a11 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -88,14 +88,13 @@ 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, (char_u *)key.data); + dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); - if (HASHITEM_EMPTY(hi)) { + if (di == NULL) { api_set_error(err, Validation, _("Key not found")); return (Object) OBJECT_INIT; } - dictitem_T *di = dict_lookup(hi); return vim_to_object(&di->di_tv); } @@ -130,7 +129,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, return rv; } - dictitem_T *di = dict_find(dict, (char_u *)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) { @@ -156,9 +155,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, 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 @@ -171,8 +168,8 @@ Object dict_set_var(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) { @@ -706,7 +703,7 @@ 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]; @@ -716,20 +713,20 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) api_set_error(err, Validation, _("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++; @@ -960,11 +957,7 @@ 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; } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 59c0200395..db2f25a2a6 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -185,7 +185,7 @@ Object nvim_eval(String expr, Error *err) typval_T *expr_result = eval_expr((char_u *)expr.data, NULL); if (!expr_result) { - api_set_error(err, Exception, _("Failed to evaluate expression")); + api_set_error(err, Exception, "Failed to evaluate expression"); } if (!try_end(err)) { diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h index 44ff540b40..31851a84e6 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' diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f7333fead4..0ce9ce073e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -661,7 +661,7 @@ static void free_buffer(buf_T *buf) 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); @@ -1481,7 +1481,7 @@ static inline void buf_init_changedtick(buf_T *const buf) }, .di_key = "changedtick", }; - dict_add(buf->b_vars, (dictitem_T *)&buf->changedtick_di); + tv_dict_add(buf->b_vars, (dictitem_T *)&buf->changedtick_di); } /// Add a file name to the buffer list. @@ -1573,7 +1573,7 @@ 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); } @@ -5443,8 +5443,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 ed3e6ab6cc..c915d373aa 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -7,6 +7,7 @@ #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 { @@ -91,8 +92,8 @@ static inline void buf_set_changedtick(buf_T *const buf, const int changedtick) static inline void buf_set_changedtick(buf_T *const buf, const int changedtick) { #ifndef NDEBUG - dictitem_T *const changedtick_di = dict_find( - buf->b_vars, (char_u *)"changedtick", sizeof("changedtick") - 1); + 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); diff --git a/src/nvim/charset.h b/src/nvim/charset.h index 8d25b828e5..c69582c4c6 100644 --- a/src/nvim/charset.h +++ b/src/nvim/charset.h @@ -5,6 +5,16 @@ #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/diff.c b/src/nvim/diff.c index 11ade20c1c..ff76abc01f 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1586,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. diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 77d5b2c816..53b196c61f 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2094,38 +2094,56 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int xfree(wca); - return ins_compl_add(IObuff, len, icase, fname, NULL, dir, - flags, FALSE); + return ins_compl_add(IObuff, len, icase, fname, NULL, true, 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_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. @@ -2133,10 +2151,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); } @@ -2167,16 +2187,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]); + } + } } /* @@ -2299,9 +2329,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); } @@ -2365,8 +2396,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; } @@ -2888,7 +2919,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. @@ -3486,7 +3517,7 @@ expand_by_function ( theend: if (matchdict != NULL) { - dict_unref(matchdict); + tv_dict_unref(matchdict); } if (matchlist != NULL) { tv_list_unref(matchlist); @@ -3519,53 +3550,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 *)get_tv_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); } /* @@ -3980,7 +4018,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. @@ -3995,7 +4033,7 @@ static void ins_compl_insert(int in_compl_func) // Set completed item. // { word, abbr, menu, kind, info } - dict_T *dict = dict_alloc(); + dict_T *dict = tv_dict_alloc(); dict_add_nr_str(dict, "word", 0L, EMPTY_IF_NULL(compl_shown_match->cp_str)); dict_add_nr_str(dict, "abbr", 0L, @@ -4667,8 +4705,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); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 03d6eef9e3..5015deead7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -97,6 +97,7 @@ #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 @@ -432,21 +433,6 @@ static ScopeDictDictItem vimvars_var; /// v: hashtab #define vimvarht vimvardict.dv_hashtab -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 }) - typedef struct { union { LibuvProcess uv; @@ -464,13 +450,6 @@ typedef struct { 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; @@ -596,19 +575,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 = 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]); + 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); } @@ -616,9 +595,9 @@ 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, tv_list_alloc()); @@ -745,7 +724,7 @@ void set_internal_string_var(char_u *name, char_u *value) tvp->v_type = VAR_STRING; tvp->vval.v_string = val; - set_var(name, tvp, FALSE); + set_var((const char *)name, tvp, false); free_tv(tvp); } @@ -1689,7 +1668,7 @@ static void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) { if (!HASHITEM_EMPTY(hi)) { todo--; - di = HI2DI(hi); + di = TV_DICT_HI2DI(hi); if (empty || di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string != NULL) { list_one_var(di, prefix, first); @@ -1951,7 +1930,7 @@ ex_let_one ( } } if (s != NULL) { - set_option_value(arg, n, s, opt_flags); + set_option_value((const char *)arg, n, (char *)s, opt_flags); arg_end = (char_u *)p; } *p = c1; @@ -2220,7 +2199,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, } 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 @@ -2232,16 +2211,19 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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 + && rettv->v_type == VAR_FUNC + && !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) { @@ -2391,12 +2373,12 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch && !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name, STRLEN(lp->ll_name)))) && eexe_mod_op(&tv, rettv, (const char *)op) == OK) { - set_var(lp->ll_name, &tv, false); + set_var((const char *)lp->ll_name, &tv, false); } tv_clear(&tv); } } else { - set_var(lp->ll_name, rettv, copy); + set_var((const char *)lp->ll_name, rettv, copy); } *endp = cc; } else if (tv_check_lock(lp->ll_newkey == NULL @@ -2450,26 +2432,20 @@ 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); - - if (watched) { - init_tv(&oldtv); - } + bool watched = tv_dict_is_watched(dict); - /* - * 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; } @@ -2493,16 +2469,16 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch } 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); + tv_dict_watcher_notify(dict, (char *)di->di_key, lp->ll_tv, &oldtv); tv_clear(&oldtv); } } @@ -2806,7 +2782,7 @@ void ex_call(exarg_T *eap) } end: - dict_unref(fudi.fd_dict); + tv_dict_unref(fudi.fd_dict); xfree(tofree); } @@ -2944,7 +2920,7 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit) // 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; @@ -2954,10 +2930,10 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit) key = xstrdup((char *)di->di_key); } - dictitem_remove(d, di); + tv_dict_item_remove(d, di); if (watched) { - dictwatcher_notify(d, key, NULL, &oldtv); + tv_dict_watcher_notify(d, key, NULL, &oldtv); tv_clear(&oldtv); xfree(key); } @@ -3005,7 +2981,7 @@ int do_unlet(char_u *name, int forceit) hi = find_hi_in_scoped_ht((const char *)name, &ht); } if (hi != NULL && !HASHITEM_EMPTY(hi)) { - di = HI2DI(hi); + di = TV_DICT_HI2DI(hi); if (var_check_fixed(di->di_flags, (const char *)name, STRLEN(name)) || var_check_ro(di->di_flags, (const char *)name, STRLEN(name)) || tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { @@ -3018,7 +2994,7 @@ int do_unlet(char_u *name, int forceit) } typval_T oldtv; - bool watched = is_watched(dict); + bool watched = tv_dict_is_watched(dict); if (watched) { copy_tv(&di->di_tv, &oldtv); @@ -3027,7 +3003,7 @@ int do_unlet(char_u *name, int forceit) delete_var(ht, hi); if (watched) { - dictwatcher_notify(dict, (char *)varname, NULL, &oldtv); + tv_dict_watcher_notify(dict, (char *)varname, NULL, &oldtv); tv_clear(&oldtv); } return OK; @@ -3102,18 +3078,12 @@ static int do_lock_var(lval_T *lp, char_u *name_end, const int deep, */ 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); } @@ -3659,11 +3629,12 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) 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 @@ -3749,11 +3720,12 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) } 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 + if (type != TYPE_MATCH && type != TYPE_NOMATCH) { + i = mb_strcmp_ic((bool)ic, (const char *)s1, (const char *)s2); + } else { i = 0; - n1 = FALSE; + } + n1 = false; switch (type) { case TYPE_EQUAL: n1 = (i == 0); break; case TYPE_NEQUAL: n1 = (i != 0); break; @@ -4355,11 +4327,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; + int range = false; char_u *s; char_u *key = NULL; @@ -4397,8 +4369,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 @@ -4576,7 +4548,7 @@ eval_index ( } } - item = dict_find(rettv->vval.v_dict, key, (int)len); + item = tv_dict_find(rettv->vval.v_dict, (const char *)key, len); if (item == NULL && verbose) { emsgf(_(e_dictkey), key); @@ -4868,7 +4840,7 @@ static void partial_free(partial_T *pt) tv_clear(&pt->pt_argv[i]); } xfree(pt->pt_argv); - dict_unref(pt->pt_dict); + tv_dict_unref(pt->pt_dict); if (pt->pt_name != NULL) { func_unref(pt->pt_name); xfree(pt->pt_name); @@ -4940,64 +4912,7 @@ failret: return OK; } - -// TODO(ZyX-I): move to eval/typval - -/* - * Return the dictitem that an entry in a hashtable points to. - */ -dictitem_T *dict_lookup(hashitem_T *hi) -{ - return HI2DI(hi); -} - -// TODO(ZyX-I): move to eval/typval - -/* - * 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 @@ -5032,7 +4947,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; } @@ -5051,90 +4966,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. - */ -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 compare the function name, bound dict and - // arguments. - 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 = tv_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; -} - /// Get next (unique) copy ID /// /// Used for traversing nested structures e.g. when serializing them or garbage @@ -5400,7 +5231,7 @@ static int free_unref_items(int copyID) // 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; } } @@ -5423,7 +5254,7 @@ static int free_unref_items(int copyID) 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); } } @@ -5460,14 +5291,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) { @@ -5559,7 +5386,7 @@ 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); } } @@ -5704,265 +5531,6 @@ static bool set_ref_in_funccal(funccall_T *fc, int copyID) return abort; } -/// 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 (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 = 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 *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); - size_t todo = (int)d->dv_hashtab.ht_used; - for (hashitem_T *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. - dictitem_T *const di = HI2DI(hi); - hash_remove(&d->dv_hashtab, hi); - dictitem_free(di); - todo--; - } - } - - while (!QUEUE_EMPTY(&d->watchers)) { - QUEUE *w = QUEUE_HEAD(&d->watchers); - DictWatcher *watcher = dictwatcher_node_data(w); - QUEUE_REMOVE(w); - dictwatcher_free(watcher); - } - - hash_clear(&d->dv_hashtab); -} - -static void dict_free_dict(dict_T *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); -} - -void dict_free(dict_T *d) - FUNC_ATTR_NONNULL_ALL -{ - if (!tv_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) -{ - 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) -{ - tv_clear(&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". @@ -5972,7 +5540,7 @@ 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 = tv_dict_item_alloc(key); item->di_tv.v_lock = 0; if (str == NULL) { item->di_tv.v_type = VAR_NUMBER; @@ -5981,8 +5549,8 @@ int dict_add_nr_str(dict_T *d, char *key, long nr, char_u *str) 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); + if (tv_dict_add(d, item) == FAIL) { + tv_dict_item_free(item); return FAIL; } return OK; @@ -5994,13 +5562,13 @@ int dict_add_nr_str(dict_T *d, char *key, long nr, char_u *str) */ int dict_add_list(dict_T *d, char *key, list_T *list) { - dictitem_T *item = dictitem_alloc((char_u *)key); + dictitem_T *item = tv_dict_item_alloc(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); + if (tv_dict_add(d, item) == FAIL) { + tv_dict_item_free(item); return FAIL; } ++list->lv_refcount; @@ -6011,13 +5579,13 @@ int dict_add_list(dict_T *d, char *key, list_T *list) /// 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); + dictitem_T *const item = tv_dict_item_alloc(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); + if (tv_dict_add(d, item) == FAIL) { + tv_dict_item_free(item); return FAIL; } dict->dv_refcount++; @@ -6029,60 +5597,12 @@ int dict_add_dict(dict_T *d, char *key, dict_T *dict) /// 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) +void dict_set_keys_readonly(dict_T *const 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); + TV_DICT_ITER(dict, di, { + di->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX; + }); } /// Get a function from a dictionary @@ -6091,7 +5611,7 @@ dictitem_T *dict_find(dict_T *d, char_u *key, int len) /// @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); + dictitem_T *const di = tv_dict_find(d, key, -1); if (di == NULL) { result->type = kCallbackNone; @@ -6113,40 +5633,6 @@ static bool get_dict_callback(dict_T *d, char *key, Callback *result) return res; } -/// Get a string item from a dictionary. -/// -/// @param save whether memory should be allocated for the return value -/// when false a shared buffer is used, can only be used once! -/// -/// @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; -} - -/// 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; - } - return get_tv_number(&di->di_tv); -} - /* * Allocate a variable for a Dictionary and fill it from "*arg". * Return OK or FAIL. Returns NOTDONE for {expr}. @@ -6176,7 +5662,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; @@ -6207,19 +5693,19 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate) 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); tv_clear(&tvkey); tv_clear(&tv); goto failret; } - item = dictitem_alloc(key); + 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); } } @@ -6236,7 +5722,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; } @@ -8152,9 +7638,10 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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++; + } } } } @@ -8381,7 +7868,7 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) DictWatcher *watcher = NULL; bool matched = false; QUEUE_FOREACH(w, &dict->watchers) { - watcher = dictwatcher_node_data(w); + watcher = tv_dict_watcher_node_data(w); if (callback_equal(&watcher->callback, &callback) && !strcmp(watcher->key_pattern, key_pattern)) { matched = true; @@ -8397,7 +7884,7 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) } QUEUE_REMOVE(w); - dictwatcher_free(watcher); + tv_dict_watcher_free(watcher); } /* @@ -8750,92 +8237,24 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[1].v_type != VAR_UNKNOWN && get_tv_number_chk(&argvars[1], &error)) options |= WILD_KEEP_ALL; - if (!error) { - ExpandInit(&xpc); - xpc.xp_context = EXPAND_FILES; - if (p_wic) - options += WILD_ICASE; - if (rettv->v_type == VAR_STRING) { - rettv->vval.v_string = ExpandOne(&xpc, s, NULL, options, WILD_ALL); - } else { - tv_list_alloc_ret(rettv); - ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP); - for (int i = 0; i < xpc.xp_numfiles; i++) { - tv_list_append_string(rettv->vval.v_list, - (const char *)xpc.xp_files[i], -1); - } - ExpandCleanup(&xpc); - } - } else - rettv->vval.v_string = NULL; - } -} - -/* - * Go over all entries in "d2" and add them to "d1". - * When "action" is "error" then a duplicate key is an error. - * When "action" is "force" then a duplicate key is overwritten. - * Otherwise duplicate keys are ignored ("action" is "keep"). - */ -void dict_extend(dict_T *d1, dict_T *d2, char_u *action) -{ - dictitem_T *di1; - hashitem_T *hi2; - int todo; - bool watched = is_watched(d1); - const char *const arg_errmsg = _("extend() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); - - 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, arg_errmsg_len) - || var_check_ro(di1->di_flags, arg_errmsg, arg_errmsg_len)) { - break; - } - - if (watched) { - copy_tv(&di1->di_tv, &oldtv); - } - - tv_clear(&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); - tv_clear(&oldtv); + if (!error) { + ExpandInit(&xpc); + xpc.xp_context = EXPAND_FILES; + if (p_wic) + options += WILD_ICASE; + if (rettv->v_type == VAR_STRING) { + rettv->vval.v_string = ExpandOne(&xpc, s, NULL, options, WILD_ALL); + } else { + tv_list_alloc_ret(rettv); + ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP); + for (int i = 0; i < xpc.xp_numfiles; i++) { + tv_list_append_string(rettv->vval.v_list, + (const char *)xpc.xp_files[i], -1); } + ExpandCleanup(&xpc); } - } + } else + rettv->vval.v_string = NULL; } } @@ -8880,37 +8299,41 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) { - dict_T *d1, *d2; - char_u *action; - int i; + dict_T *d1; + dict_T *d2; d1 = argvars[0].vval.v_dict; d2 = argvars[1].vval.v_dict; if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, arg_errmsg_len) && d2 != NULL) { - /* Check the third argument. */ + 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 = (const char *)get_tv_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); } - } else + } else { EMSG2(_(e_listdictarg), "extend()"); + } } /* @@ -9076,7 +8499,7 @@ 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, arg_errmsg_len) || var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len))) { @@ -9094,7 +8517,7 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) || var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len)) { break; } - dictitem_remove(d, di); + tv_dict_item_remove(d, di); } } } @@ -9639,9 +9062,10 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } 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, (const char *)get_tv_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) { @@ -9704,7 +9128,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void get_buffer_signs(buf_T *buf, list_T *l) { for (signlist_T *sign = buf->b_signlist; sign; sign = sign->next) { - dict_T *const 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); @@ -9717,7 +9141,7 @@ static void get_buffer_signs(buf_T *buf, list_T *l) /// 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_T *const dict = tv_dict_alloc(); dict_add_nr_str(dict, "bufnr", buf->b_fnum, NULL); dict_add_nr_str(dict, "name", 0L, @@ -9772,12 +9196,12 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) filtered = true; - di = dict_find(sel_d, (char_u *)"buflisted", -1); + di = tv_dict_find(sel_d, S_LEN("buflisted")); if (di != NULL && get_tv_number(&di->di_tv)) { sel_buflisted = true; } - di = dict_find(sel_d, (char_u *)"bufloaded", -1); + di = tv_dict_find(sel_d, S_LEN("bufloaded")); if (di != NULL && get_tv_number(&di->di_tv)) { sel_bufloaded = true; } @@ -10047,7 +9471,7 @@ 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; @@ -10467,7 +9891,7 @@ static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, (void)get_errorlist(wp, -1, rettv->vval.v_list); } } else { - rettv_dict_alloc(rettv); + 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; @@ -10499,7 +9923,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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) { @@ -10678,7 +10102,7 @@ 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); @@ -10776,7 +10200,7 @@ 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); @@ -11286,8 +10710,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, + (const char *)get_tv_string(&argvars[1]), + -1) != NULL; } /// `haslocaldir([{win}[, {tab}]])` function @@ -11912,60 +11337,48 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ 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)); return; } - if ((d = argvars[0].vval.v_dict) == NULL) + dict_T *const d = argvars[0].vval.v_dict; + if (d == NULL) { return; + } tv_list_alloc_ret(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); - - li = tv_list_item_alloc(); - tv_list_append(rettv->vval.v_list, li); + TV_DICT_ITER(d, di, { + listitem_T *const li = tv_list_item_alloc(); + tv_list_append(rettv->vval.v_list, li); - if (what == 0) { - /* keys() */ - li->li_tv.v_type = VAR_STRING; - li->li_tv.v_lock = 0; - li->li_tv.vval.v_string = vim_strsave(di->di_key); - } else if (what == 1) { - /* values() */ - copy_tv(&di->di_tv, &li->li_tv); - } else { - // items() - l2 = 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; + if (what == 0) { + // keys() + li->li_tv.v_type = VAR_STRING; + li->li_tv.v_lock = 0; + li->li_tv.vval.v_string = vim_strsave(di->di_key); + } else if (what == 1) { + // values() + copy_tv(&di->di_tv, &li->li_tv); + } else { + // items() + list_T *const l2 = 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 = tv_list_item_alloc(); - tv_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); + listitem_T *sub_li = tv_list_item_alloc(); + tv_list_append(l2, sub_li); + sub_li->li_tv.v_type = VAR_STRING; + sub_li->li_tv.v_lock = 0; + sub_li->li_tv.vval.v_string = vim_strsave(di->di_key); - li2 = tv_list_item_alloc(); - tv_list_append(l2, li2); - copy_tv(&di->di_tv, &li2->li_tv); - } + sub_li = tv_list_item_alloc(); + tv_list_append(l2, sub_li); + copy_tv(&di->di_tv, &sub_li->li_tv); } - } + }); } /// "id()" function @@ -12230,23 +11643,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. @@ -12268,15 +11684,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; } @@ -12537,7 +11953,7 @@ static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list); break; case VAR_DICT: - rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); + rettv->vval.v_number = tv_dict_len(argvars[0].vval.v_dict); break; case VAR_UNKNOWN: case VAR_SPECIAL: @@ -12714,7 +12130,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) rettv->vval.v_string = str2special_save(rhs, 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); @@ -12980,10 +12396,10 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 = get_tv_string(&di->di_tv); } } } @@ -12996,8 +12412,9 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL, - conceal_char); + rettv->vval.v_number = match_add(curwin, (const char *)grp, + (const char *)pat, prio, id, + NULL, (const char *)conceal_char); } static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) @@ -13005,8 +12422,7 @@ 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); + const char_u *const group = get_tv_string_buf_chk(&argvars[0], buf); if (group == NULL) { return; } @@ -13036,10 +12452,10 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 = get_tv_string(&di->di_tv); } } } @@ -13054,8 +12470,8 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l, - conceal_char); + rettv->vval.v_number = match_add(curwin, (const char *)group, NULL, prio, id, + l, (const char *)conceal_char); } /* @@ -13156,8 +12572,8 @@ static void max_min(typval_T *argvars, typval_T *rettv, int domax) 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); + todo--; + i = get_tv_number_chk(&TV_DICT_HI2DI(hi)->di_tv, &error); if (first) { n = i; first = FALSE; @@ -13845,7 +13261,6 @@ 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; const char *const arg_errmsg = _("remove() argument"); @@ -13856,18 +13271,18 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG2(_(e_toomanyarg), "remove()"); } else if ((d = argvars[0].vval.v_dict) != NULL && !tv_check_lock(d->dv_lock, arg_errmsg, arg_errmsg_len)) { - key = get_tv_string_chk(&argvars[1]); + const char *key = (const char *)get_tv_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, arg_errmsg_len) && !var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len)) { *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); } } } @@ -14967,7 +14382,6 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (buf != NULL && varname != NULL && varp != NULL) { if (*varname == '&') { long numval; - char_u *strval; bool error = false; aco_save_T aco; @@ -14976,9 +14390,9 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) varname++; numval = get_tv_number_chk(varp, &error); - strval = get_tv_string_buf_chk(varp, nbuf); + char *const strval = (char *)get_tv_string_buf_chk(varp, nbuf); if (!error && strval != NULL) { - set_option_value((char_u *)varname, numval, strval, OPT_LOCAL); + set_option_value(varname, numval, strval, OPT_LOCAL); } // reset notion of buffer @@ -14987,7 +14401,7 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) buf_T *save_curbuf = curbuf; const size_t varname_len = STRLEN(varname); - char_u *const bufvarname = xmalloc(STRLEN(varname) + 3); + char *const bufvarname = xmalloc(varname_len + 3); curbuf = buf; memcpy(bufvarname, "b:", 2); memcpy(bufvarname + 2, varname, varname_len + 1); @@ -15002,7 +14416,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)); @@ -15010,7 +14423,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]; @@ -15022,13 +14435,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) + di = tv_dict_find(d, S_LEN("forward")); + if (di != NULL) { set_csearch_direction(get_tv_number(&di->di_tv) ? FORWARD : BACKWARD); + } - di = dict_find(d, (char_u *)"until", -1); - if (di != NULL) + di = tv_dict_find(d, S_LEN("until")); + if (di != NULL) { set_csearch_until(!!get_tv_number(&di->di_tv)); + } } } @@ -15252,11 +14667,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; } @@ -15267,11 +14682,10 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) li = l->lv_first; 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 = tv_list_alloc(); if (s == NULL) { @@ -15280,14 +14694,16 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) } // 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; } - tv_list_append_tv(s, &di->di_tv); + tv_list_append_tv(s, &pos_di->di_tv); s->lv_refcount++; } else { break; @@ -15295,23 +14711,31 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - char_u *group = get_dict_string(d, "group", true); - 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", true) - : NULL; + // Note: there are three number buffers involved: + // - group_buf below. + // - numbuf in tv_dict_get_string(). + // - mybuf in get_tv_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 + ? (const char *)get_tv_string( + &conceal_di->di_tv) + : NULL); if (i == 0) { match_add(curwin, group, - get_dict_string(d, "pattern", false), + tv_dict_get_string(d, "pattern", false), priority, id, NULL, conceal); } else { match_add(curwin, group, NULL, priority, id, s, conceal); tv_list_unref(s); s = NULL; } - xfree(group); - xfree(conceal); li = li->li_next; } rettv->vval.v_number = 0; @@ -15471,35 +14895,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]; - - if (varname != NULL && varp != NULL - && tp != NULL - ) { - 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); + tabpage_T *const tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); + const char *const varname = (const char *)get_tv_string_chk(&argvars[1]); + typval_T *const varp = &argvars[2]; + + if (varname != NULL && varp != NULL && tp != NULL) { + tabpage_T *const save_curtab = curtab; + goto_tabpage_tp(tp, false, false); + + 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, 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); + } } } @@ -15525,44 +14945,42 @@ 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) + tabpage_T *tp = NULL; + if (off == 1) { tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); - else + } 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 = (const char *)get_tv_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; bool error = false; - ++varname; + varname++; numval = get_tv_number_chk(varp, &error); - strval = get_tv_string_buf_chk(varp, nbuf); + char_u nbuf[NUMBUFLEN]; + char *const strval = (char *)get_tv_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); + 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, varp, true); xfree(winvarname); } @@ -17086,15 +16504,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; @@ -17131,7 +16549,7 @@ 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_var(curbuf->b_vars, cstr_as_string("terminal_job_id"), @@ -17177,23 +16595,25 @@ static bool callback_from_typval(Callback *callback, typval_T *arg) /// 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; } @@ -17220,8 +16640,9 @@ static bool callback_equal(Callback *cb1, Callback *cb2) } } -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; @@ -17290,8 +16711,9 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG2(_(e_invarg2), get_tv_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 = get_tv_number(&di->di_tv); if (repeat == 0) { repeat = 1; } @@ -17353,13 +16775,11 @@ static void timer_due_cb(TimeWatcher *tw, void *data) 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); tv_clear(&rettv); @@ -17614,7 +17034,7 @@ 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; @@ -17802,36 +17222,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 = get_tv_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 = get_tv_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 = get_tv_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 = get_tv_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, get_tv_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 = get_tv_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 = get_tv_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 = get_tv_number(&di->di_tv); } check_cursor(); @@ -17854,7 +17275,7 @@ 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); @@ -18027,7 +17448,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); } @@ -18895,10 +18316,10 @@ handle_subscript( } 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) @@ -18919,7 +18340,7 @@ handle_subscript( set_selfdict(rettv, selfdict); } - dict_unref(selfdict); + tv_dict_unref(selfdict); return ret; } @@ -19016,7 +18437,7 @@ void free_tv(typval_T *varp) tv_list_unref(varp->vval.v_list); break; case VAR_DICT: - dict_unref(varp->vval.v_dict); + tv_dict_unref(varp->vval.v_dict); break; case VAR_SPECIAL: case VAR_NUMBER: @@ -19028,15 +18449,6 @@ void free_tv(typval_T *varp) } } -/* - * 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)); -} - // TODO(ZyX-I): move to eval/typval /// Get the number value of a variable @@ -19057,44 +18469,53 @@ varnumber_T get_tv_number(const typval_T *const varp) varnumber_T get_tv_number_chk(const typval_T *const varp, bool *const denote) { - long n = 0L; + varnumber_T n = 0; 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); + case VAR_NUMBER: { + return varp->vval.v_number; } - 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 VAR_FLOAT: { + EMSG(_("E805: Using a Float as a Number")); + break; + } + case VAR_PARTIAL: + case VAR_FUNC: { + EMSG(_("E703: Using a Funcref as a Number")); + break; + } + case VAR_STRING: { + if (varp->vval.v_string != NULL) { + long nr; + vim_str2nr(varp->vval.v_string, NULL, NULL, STR2NR_ALL, &nr, NULL, 0); + n = (varnumber_T)nr; } - case kSpecialVarFalse: - case kSpecialVarNull: { - return 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; } - break; - case VAR_UNKNOWN: - EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)"); - break; } if (denote == NULL) { // useful for values that must be unsigned @@ -19254,16 +18675,17 @@ static dictitem_T *find_var(const char *const name, const size_t name_len, hashtab_T **htp, int no_autoload) { const char *varname; - hashtab_T *ht = find_var_ht(name, name_len, &varname); + hashtab_T *const ht = find_var_ht(name, name_len, &varname); if (htp != NULL) { *htp = ht; } if (ht == NULL) { return NULL; } - dictitem_T *ret = find_var_in_ht(ht, *name, - varname, name_len - (size_t)(varname - name), - no_autoload || htp != NULL); + 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; } @@ -19327,7 +18749,7 @@ static dictitem_T *find_var_in_ht(hashtab_T *const ht, return NULL; } } - return HI2DI(hi); + return TV_DICT_HI2DI(hi); } // Get function call environment based on backtrace debug level @@ -19528,7 +18950,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); } /* @@ -19559,7 +18981,7 @@ 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) { tv_clear(&v->di_tv); } @@ -19578,7 +19000,7 @@ 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); tv_clear(&di->di_tv); @@ -19637,40 +19059,31 @@ static void list_one_var_a(const char *prefix, const char *name, } } -/* - * 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 tv Variable value. +/// @param[in] copy True if value in tv is to be copied. +static void set_var(const char *name, typval_T *const tv, const bool copy) + FUNC_ATTR_NONNULL_ALL { dictitem_T *v; hashtab_T *ht; - typval_T oldtv; dict_T *dict; - const size_t name_len = STRLEN(name); - char_u *varname; - ht = find_var_ht_dict((const char *)name, name_len, (const char **)&varname, - &dict); - bool watched = is_watched(dict); - - if (watched) { - init_tv(&oldtv); - } + const size_t name_len = strlen(name); + 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, - (const char *)varname, name_len - (size_t)(varname - name), - true); + v = find_var_in_ht(ht, 0, varname, name_len - (size_t)(varname - name), true); // Search in parent scope which is possible to reference from lambda if (v == NULL) { @@ -19678,10 +19091,11 @@ set_var ( } if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) - && var_check_func_name(name, v == NULL)) { + && !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, (const char *)name, name_len) @@ -19704,9 +19118,9 @@ set_var ( 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) + 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); } @@ -19727,13 +19141,14 @@ set_var ( 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; } @@ -19745,14 +19160,14 @@ set_var ( } 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); + tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv); tv_clear(&oldtv); } } @@ -19768,8 +19183,8 @@ set_var ( /// /// @return True if variable is read-only: either always or in sandbox when /// sandbox is enabled, false otherwise. -static bool var_check_ro(const int flags, const char *const name, - const size_t name_len) +bool var_check_ro(const int flags, const char *const name, + const size_t name_len) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { if (flags & DI_FLAGS_RO) { @@ -19804,22 +19219,24 @@ static bool var_check_fixed(const int flags, const char *const name, 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 @@ -19827,63 +19244,30 @@ var_check_func_name ( if (new_var && function_exists((const char *)name, false)) { EMSG2(_("E705: Variable name conflicts with existing function: %s"), name); - return true; + 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; - - for (p = varname; *p != NUL; ++p) - if (!eval_isnamec1(*p) && (p == varname || !ascii_isdigit(*p)) - && *p != AUTOLOAD_CHAR) { - EMSG2(_(e_illvar), varname); - return FALSE; - } - return TRUE; -} +// TODO(ZyX-I): move to eval/expressions -/// Check whether typval is locked -/// -/// Also gives an error message. +/// Check if a variable name is valid /// -/// @param[in] lock Lock status. -/// @param[in] name Value name, for use in error message. -/// @param[in] name_len Value name length. +/// @param[in] varname Variable name to check. /// -/// @return True if value is locked. -static bool tv_check_lock(const VarLockStatus lock, - const char *const name, - const size_t name_len) - FUNC_ATTR_WARN_UNUSED_RESULT +/// @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 { - const char *error_message = NULL; - switch (lock) { - case VAR_UNLOCKED: { + for (const char *p = varname; *p != NUL; p++) { + if (!eval_isnamec1((int)(uint8_t)(*p)) + && (p == varname || !ascii_isdigit(*p)) + && *p != AUTOLOAD_CHAR) { + emsgf(_(e_illvar), varname); 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); - - const char *const unknown_name = _("Unknown"); - - emsgf(_(error_message), (name != NULL ? name_len : strlen(unknown_name)), - (name != NULL ? name : unknown_name)); - return true; } @@ -20016,7 +19400,7 @@ 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) ret = FAIL; @@ -20730,9 +20114,9 @@ void ex_function(exarg_T *eap) 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; @@ -21002,7 +20386,7 @@ theend: */ 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((char_u *)p + 1, (char_u *)"SID>", 4) == 0 @@ -21558,9 +20942,9 @@ 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); + // 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 @@ -21675,6 +21059,11 @@ void func_unref(char_u *name) /// 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 != NULL && --fp->uf_refcount <= 0) { @@ -21712,17 +21101,19 @@ void func_ptr_ref(ufunc_T *fp) } } -/// 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" -) +/// 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; @@ -21796,7 +21187,7 @@ call_user_func( 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; @@ -21819,7 +21210,7 @@ call_user_func( 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; @@ -21867,9 +21258,9 @@ call_user_func( // Named arguments can be accessed without the "a:" prefix in lambda // expressions. Add to the l: dict. copy_tv(&v->di_tv, &v->di_tv); - hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); + tv_dict_add(&fc->l_vars, v); } else { - hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); + tv_dict_add(&fc->l_avars, v); } if (ai >= 0 && ai < MAX_FUNC_ARGS) { @@ -22065,29 +21456,22 @@ call_user_func( && 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", // 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, { + copy_tv(&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) + // 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) { copy_tv(&li->li_tv, &li->li_tv); + } } if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0) { @@ -22194,7 +21578,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; @@ -22590,7 +21974,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) { @@ -22599,11 +21983,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; + copy_tv(&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; } } @@ -22614,62 +21997,54 @@ 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, &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(get_tv_string(&this_var->di_tv), + (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; } @@ -23094,7 +22469,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; @@ -23384,8 +22759,7 @@ 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); tv_clear(&rettv); } @@ -23499,91 +22873,3 @@ bool eval_has_provider(char *name) 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; - tv_clear(&rettv); - } - } - - for (size_t i = 1; i < ARRAY_SIZE(argv); i++) { - tv_clear(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) -{ - return d && !QUEUE_EMPTY(&d->watchers); -} diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 57fee5c5a2..7f6fd76c46 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -1,21 +1,23 @@ #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/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) // All user-defined functions are found in this hashtable. extern hashtab_T func_hashtab; + // 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 diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 1d30f51f55..3cb68e093b 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -6,6 +6,7 @@ #include "nvim/eval.h" #include "nvim/eval/encode.h" #include "nvim/ascii.h" +#include "nvim/macros.h" #include "nvim/message.h" #include "nvim/charset.h" // vim_str2nr #include "nvim/lib/kvec.h" @@ -51,16 +52,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, @@ -138,9 +139,10 @@ 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); + dictitem_T *const obj_di = tv_dict_item_alloc( + (const char *)key.val.vval.v_string); tv_clear(&key.val); - if (dict_add(last_container.container.vval.v_dict, obj_di) + if (tv_dict_add(last_container.container.vval.v_dict, obj_di) == FAIL) { assert(false); } @@ -173,8 +175,8 @@ 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))) { + || tv_dict_find(last_container.container.vval.v_dict, + (const char *)obj.val.vval.v_string, -1))) { tv_clear(&obj.val); // Restart @@ -835,7 +837,7 @@ json_decode_string_cycle_start: .vval = { .v_list = val_list }, })); } else { - dict_T *dict = dict_alloc(); + dict_T *dict = tv_dict_alloc(); dict->dv_refcount++; tv = (typval_T) { .v_type = VAR_DICT, @@ -1042,7 +1044,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,7 +1057,7 @@ 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 tv_clear(rettv); xfree(di); diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 1416806ca6..26f9aaa27d 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -744,11 +744,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; } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 7726e106a1..bb7baed7d2 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2,6 +2,7 @@ #include #include +#include "nvim/lib/queue.h" #include "nvim/eval/typval.h" #include "nvim/eval/gc.h" #include "nvim/eval/executor.h" @@ -12,6 +13,9 @@ #include "nvim/assert.h" #include "nvim/memory.h" #include "nvim/globals.h" +#include "nvim/hashtab.h" +#include "nvim/vim.h" +#include "nvim/ascii.h" // TODO(ZyX-I): Move line_breakcheck out of misc1 #include "nvim/misc1.h" // For line_breakcheck @@ -115,8 +119,7 @@ void tv_list_watch_fix(list_T *const l, const listitem_T *const item) } } -//{{{2 Lists -//{{{3 Alloc/free +//{{{2 Alloc/free /// Allocate an empty list /// @@ -205,7 +208,7 @@ void tv_list_unref(list_T *const l) } } -//{{{3 Add/remove +//{{{2 Add/remove /// Remove items "item" to "item2" from list "l". /// @@ -406,7 +409,7 @@ void tv_list_append_number(list_T *const l, const varnumber_T n) tv_list_append(l, li); } -//{{{3 Operations on the whole list +//{{{2 Operations on the whole list /// Make a copy of list /// @@ -596,6 +599,8 @@ int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep) /// @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 @@ -623,7 +628,7 @@ bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic, return true; } -//{{{3 Indexing/searching +//{{{2 Indexing/searching /// Locate item with a given index in a list and return it /// @@ -761,6 +766,552 @@ long tv_list_idx_of_item(const list_T *const l, const listitem_T *const item) } return idx; } + +//{{{1 Dictionaries +//{{{2 Dictionary watchers + +/// Perform all necessary cleanup for a `DictWatcher` instance +/// +/// @param watcher Watcher to free. +void tv_dict_watcher_free(DictWatcher *watcher) + FUNC_ATTR_NONNULL_ALL +{ + callback_free(&watcher->callback); + xfree(watcher->key_pattern); + xfree(watcher); +} + +/// 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 = strlen(watcher->key_pattern); + if (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")); + copy_tv(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")); + copy_tv(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); + } +} + +/// 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); +} + +/// 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 + FUNC_ATTR_MALLOC +{ + dictitem_T *const new_di = tv_dict_item_alloc((const char *)di->di_key); + copy_tv(&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_MALLOC 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_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + 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(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 get_tv_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(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 Numbuf for. +/// +/// @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(dict_T *const d, const char *const key, + char *const numbuf) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + dictitem_T *const di = tv_dict_find(d, key, -1); + if (di == NULL) { + return NULL; + } + return (const char *)get_tv_string_buf(&di->di_tv, (char_u *)numbuf); +} + +//{{{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 + && di2->di_tv.v_type == VAR_FUNC + && !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) { + copy_tv(&di1->di_tv, &oldtv); + } + + tv_clear(&di1->di_tv); + copy_tv(&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 { + copy_tv(&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; +} + //{{{1 Generic typval operations //{{{2 Init/alloc/clear //{{{3 Alloc @@ -783,6 +1334,21 @@ list_T *tv_list_alloc_ret(typval_T *const ret_tv) 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 @@ -884,7 +1450,7 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID) #define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ do { \ assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \ - dict_unref((dict_T *)dict); \ + tv_dict_unref((dict_T *)dict); \ *((dict_T **)&dict) = NULL; \ if (tv != NULL) { \ ((typval_T *)tv)->v_lock = VAR_UNLOCKED; \ @@ -966,7 +1532,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, FUNC_ATTR_ALWAYS_INLINE { if ((const void *)dictp != nodictvar) { - dict_unref(*dictp); + tv_dict_unref(*dictp); *dictp = NULL; } } @@ -1077,13 +1643,9 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock) CHANGE_LOCK(lock, d->dv_lock); if (deep < 0 || deep > 1) { // recursive: lock/unlock the items the List contains - int todo = (int)d->dv_hashtab.ht_used; - for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) { - if (!HASHITEM_EMPTY(hi)) { - todo--; - tv_item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); - } - } + TV_DICT_ITER(d, di, { + tv_item_lock(&di->di_tv, deep - 1, lock); + }); } } break; @@ -1121,6 +1683,140 @@ bool tv_islocked(const typval_T *const tv) && (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] use_gettext True if variable name also is to be translated. +/// +/// @return true if variable is locked, false otherwise. +bool tv_check_lock(const VarLockStatus lock, const char *const name, + const 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); + + const char *const unknown_name = _("Unknown"); + + emsgf(_(error_message), (name != NULL ? name_len : strlen(unknown_name)), + (name != NULL ? name : unknown_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 (!((tv1->v_type == VAR_FUNC || tv1->v_type == VAR_PARTIAL) + && (tv2->v_type == VAR_FUNC || tv2->v_type == VAR_PARTIAL)) + && 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 = (const char *)get_tv_string_buf(tv1, (char_u *)buf1); + const char *s2 = (const char *)get_tv_string_buf(tv2, (char_u *)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 @@ -1135,37 +1831,37 @@ bool tv_islocked(const typval_T *const tv) bool tv_check_str_or_nr(const typval_T *const tv) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE { - switch (tv->v_type) { - case VAR_NUMBER: - case VAR_STRING: { - return true; - } - case VAR_FLOAT: { - EMSG(_("E805: Expected a Number or a String, Float found")); - return false; - } - case VAR_PARTIAL: - case VAR_FUNC: { - EMSG(_("E703: Expected a Number or a String, Funcref found")); - return false; - } - case VAR_LIST: { - EMSG(_("E745: Expected a Number or a String, List found")); - return false; - } - case VAR_DICT: { - EMSG(_("E728: Expected a Number or a String, Dictionary found")); - return false; - } - case VAR_SPECIAL: { - EMSG(_("E5300: Expected a Number or a String")); - return false; - } - case VAR_UNKNOWN: { - EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)"); - return false; - } + switch (tv->v_type) { + case VAR_NUMBER: + case VAR_STRING: { + return true; } - assert(false); - return false; + 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; } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index cf83904ffc..6183397d12 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -8,6 +8,7 @@ #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 @@ -31,6 +32,31 @@ 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, + 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; + QUEUE node; + bool busy; // prevent recursion if the dict is changed in the callback +} DictWatcher; + /// Special variable values typedef enum { kSpecialVarFalse, ///< v:false @@ -134,7 +160,7 @@ struct dictitem_S { struct { \ typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ uint8_t di_flags; /* Flags. */ \ - char_u di_key[KEY_LEN]; /* NUL. */ \ + char_u di_key[KEY_LEN]; /* Key value. */ \ } /// Structure to hold a scope dictionary @@ -181,9 +207,7 @@ typedef int scid_T; // 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. -typedef struct ufunc ufunc_T; - +/// Structure to hold info for a user function. struct ufunc { int uf_varargs; ///< variable nr of arguments int uf_flags; @@ -207,12 +231,12 @@ struct ufunc { 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 + ///< 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 123_ ( is K_SPECIAL - // KS_EXTRA KE_SNR) + ///< start with 123_ ( is K_SPECIAL + ///< KS_EXTRA KE_SNR) }; /// Maximum number of function arguments @@ -245,24 +269,17 @@ typedef struct list_stack_S { // 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) +#define TV_DICT_HI2DI(hi) \ + ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) + +static inline long tv_list_len(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(list_T *const l) - FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { if (l == NULL) { return 0; @@ -270,6 +287,64 @@ static inline long tv_list_len(list_T *const l) 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); +} + +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; + +/// 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); +} + +/// 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 @@ -279,6 +354,21 @@ 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 \ + } \ + } \ + }) + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/typval.h.generated.h" #endif diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index eb89a601ff..ad54eef4a0 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -406,11 +406,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]) { @@ -662,7 +662,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], diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 5cbf7f9ce7..26d70a5e6d 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -21,7 +21,7 @@ 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; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 151a4d375f..9681527fee 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4764,8 +4764,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) { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index e59a87b335..b84834d351 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2073,9 +2073,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) { @@ -2138,9 +2138,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. @@ -2496,16 +2496,16 @@ 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 *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; @@ -2521,13 +2521,13 @@ 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; + size_t fname_len = strlen(ffname); + const char *insp = (const char *)p_rtp; for (;;) { - if (vim_fnamencmp(insp, ffname, fname_len) == 0) { + if (path_fnamencmp(insp, ffname, fname_len) == 0) { break; } - insp = vim_strchr(insp, ','); + insp = strchr(insp, ','); if (insp == NULL) { break; } @@ -2536,10 +2536,10 @@ static void add_pack_plugin(char_u *fname, void *cookie) if (insp == NULL) { // 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); + insp += strlen(ffname); while (*insp != NUL && *insp != ',') { insp++; } @@ -2547,31 +2547,40 @@ static void add_pack_plugin(char_u *fname, void *cookie) *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); } @@ -2580,7 +2589,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; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index dc99c0771d..87fe52c119 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9483,18 +9483,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); + } } /* @@ -9608,8 +9608,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) @@ -9695,7 +9696,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; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 9851ed5396..872b7fe365 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -5173,7 +5173,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; @@ -5191,7 +5191,7 @@ static int ex_window(void) add_map((char_u *)" ", INSERT); add_map((char_u *)" a", 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 diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index b73d9944ce..8ab6955042 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1556,7 +1556,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope) apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false, NULL); - dict_clear(dict); + tv_dict_clear(dict); recursive = false; } diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 0c131d7b33..076ee13a80 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1881,9 +1881,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; diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index b14bb01c0e..354c9718ba 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -82,7 +82,7 @@ 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, const char_u *key) +hashitem_T *hash_find(const hashtab_T *const ht, const char_u *const key) { return hash_lookup(ht, (const char *)key, STRLEN(key), hash_hash(key)); } @@ -99,7 +99,8 @@ hashitem_T *hash_find(hashtab_T *ht, const char_u *key) /// /// @warning Returned pointer becomes invalid as soon as the hash table /// is changed in any way. -hashitem_T *hash_find_len(hashtab_T *ht, const char *key, const size_t len) +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)); } @@ -115,7 +116,7 @@ hashitem_T *hash_find_len(hashtab_T *ht, const char *key, const size_t len) /// 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 *const ht, +hashitem_T *hash_lookup(const hashtab_T *const ht, const char *const key, const size_t key_len, const hash_T hash) { 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/macros.h b/src/nvim/macros.h index 650bf76156..5042663041 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -19,6 +19,15 @@ # define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) #endif +/// 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) + /* * Position comparisons */ diff --git a/src/nvim/main.c b/src/nvim/main.c index 0c978dc47d..33e1551351 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -803,17 +803,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; @@ -830,24 +831,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(); @@ -946,8 +950,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; @@ -956,7 +959,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; @@ -1088,7 +1091,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; } diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 1d1e13e7e0..ae94ec7ecd 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -62,7 +62,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 diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 57518a9535..621fa6fefc 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -583,7 +583,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; @@ -1233,7 +1233,8 @@ bool utf_isupper(int a) return utf_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]; @@ -1392,19 +1393,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 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); } /* @@ -2020,8 +2028,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; @@ -2306,7 +2314,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); } @@ -2316,7 +2324,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 5f5bab9fcd..c20e6d47ff 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -2,8 +2,10 @@ #define NVIM_MBYTE_H #include +#include #include "nvim/iconv.h" +#include "nvim/func_attr.h" /* * Return byte length of character that starts with byte "b". @@ -66,4 +68,17 @@ typedef struct { #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/memline.c b/src/nvim/memline.c index f9d3751390..5ea2397db3 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -992,7 +992,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); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 85cef59aec..d634a8c393 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -16,6 +16,7 @@ #include "nvim/cursor.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" @@ -888,7 +889,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; } @@ -2581,7 +2582,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) textlock++; apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, false, curbuf); textlock--; - dict_clear(dict); + tv_dict_clear(dict); recursive = false; } diff --git a/src/nvim/option.c b/src/nvim/option.c index b037b0ae35..4c8606a999 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -25,6 +25,7 @@ #include #include "nvim/vim.h" +#include "nvim/macros.h" #include "nvim/ascii.h" #include "nvim/edit.h" #include "nvim/option.h" @@ -34,6 +35,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" @@ -604,7 +606,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. */ @@ -614,7 +616,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; } @@ -645,7 +647,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; @@ -764,8 +766,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(); @@ -775,7 +778,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; @@ -882,7 +885,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]); @@ -904,9 +907,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) @@ -947,17 +951,19 @@ 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 */ @@ -976,16 +982,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); @@ -1029,7 +1037,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)) { @@ -1048,14 +1056,16 @@ void set_helplang_default(const char *lang) { int idx; - if (lang == NULL || STRLEN(lang) < 2) /* safety check */ + const size_t lang_len = strlen(lang); + if (lang == NULL || lang_len < 2) { // safety check return; - idx = findoption((char_u *)"hlg"); + } + 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]); @@ -1082,12 +1092,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; @@ -1193,7 +1203,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) { @@ -1209,7 +1219,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); } @@ -1391,11 +1401,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 - || prefix != 1) { + errmsg = (char_u *)set_bool_option(opt_idx, varp, (int)value, + opt_flags); + } else { // Numeric or string. + if (strchr("=:&<", nextchar) == NULL || prefix != 1) { errmsg = e_invarg; goto skip; } @@ -1448,15 +1457,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, 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 @@ -2221,7 +2234,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); @@ -2283,9 +2296,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; @@ -2765,7 +2778,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 @@ -3575,24 +3588,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 */ @@ -3605,20 +3618,18 @@ 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; + // '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; @@ -3740,8 +3751,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"); } } } @@ -3889,9 +3900,8 @@ set_bool_option ( /* 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; @@ -3957,20 +3967,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; @@ -3981,7 +3989,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; @@ -4251,8 +4259,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) { @@ -4357,7 +4366,7 @@ set_num_option ( curwin->w_set_curswant = TRUE; check_redraw(options[opt_idx].flags); - return errmsg; + return (char *)errmsg; } /* @@ -4395,39 +4404,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 { @@ -4435,7 +4441,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; } } @@ -4444,20 +4450,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 @@ -4493,7 +4501,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); @@ -4504,23 +4512,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)); } /* @@ -4548,9 +4557,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); @@ -4608,7 +4618,7 @@ 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; } @@ -4702,21 +4712,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 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; } @@ -4724,9 +4732,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)) { @@ -4734,11 +4742,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 */ @@ -4757,12 +4765,11 @@ 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); + } } } } @@ -4773,9 +4780,10 @@ char_u *get_highlight_default(void) { int i; - i = findoption((char_u *)"hl"); - if (i >= 0) + i = findoption("hl"); + if (i >= 0) { return options[i].def_val[VI_DEFAULT]; + } return (char_u *)NULL; } @@ -5212,7 +5220,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; @@ -5775,11 +5783,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; + } } /* @@ -5877,15 +5886,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; @@ -6047,7 +6056,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) { @@ -6447,20 +6456,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; } /* @@ -6945,10 +6956,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 FUNC_ATTR_MALLOC { - 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]; diff --git a/src/nvim/path.c b/src/nvim/path.c index dfcafc85de..2bd87b608e 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -282,48 +282,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, + const 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(p1); + c2 = PTR2CHAR(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(p1); + p1 += MB_PTR2LEN(p1); + p2 += MB_PTR2LEN(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 } diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index ea00afbd86..6346951c05 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -610,13 +610,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); } } diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 323503c4f5..d23059ff22 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1236,7 +1236,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; @@ -2581,15 +2581,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 @@ -2901,14 +2899,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' @@ -4002,7 +4000,7 @@ int get_errorlist(win_T *wp, int qf_idx, list_T *list) if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) bufnum = 0; - dict = dict_alloc(); + dict = tv_dict_alloc(); tv_list_append_dict(list, dict); buf[0] = qfp->qf_type; @@ -4057,7 +4055,7 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) int flags = QF_GETLIST_NONE; int qf_idx = qi->qf_curlist; // default is the current list - if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) { + 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 = di->di_tv.vval.v_number - 1; @@ -4070,15 +4068,15 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) } } - if (dict_find(what, (char_u *)"all", -1) != NULL) { + if (tv_dict_find(what, S_LEN("all")) != NULL) { flags |= QF_GETLIST_ALL; } - if (dict_find(what, (char_u *)"title", -1) != NULL) { + if (tv_dict_find(what, S_LEN("title")) != NULL) { flags |= QF_GETLIST_TITLE; } - if (dict_find(what, (char_u *)"winid", -1) != NULL) { + if (tv_dict_find(what, S_LEN("winid")) != NULL) { flags |= QF_GETLIST_WINID; } @@ -4132,17 +4130,18 @@ static int qf_add_entries(qf_info_T *qi, list_T *list, 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 = 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)) { @@ -4162,21 +4161,20 @@ static int qf_add_entries(qf_info_T *qi, list_T *list, 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; @@ -4213,7 +4211,7 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action) newlist = true; } int qf_idx = qi->qf_curlist; // default is the current list - if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) { + 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 = di->di_tv.vval.v_number - 1; @@ -4231,10 +4229,11 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action) qf_idx = qi->qf_curlist; } - if ((di = dict_find(what, (char_u *)"title", -1)) != NULL) { + 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 = get_dict_string(what, "title", true); + 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); } diff --git a/src/nvim/search.c b/src/nvim/search.c index 8c56eda7cf..fb9e820928 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -282,7 +282,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) @@ -1290,10 +1290,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) diff --git a/src/nvim/shada.c b/src/nvim/shada.c index c550cb0888..2fe042cda8 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1623,10 +1623,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) { \ @@ -3156,17 +3156,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]); } @@ -3192,7 +3192,7 @@ static void shada_free_shada_entry(ShadaEntry *const entry) 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; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 5ca5ab3339..56f0350aef 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -7134,16 +7134,17 @@ 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()) { diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index c108ae4a2c..6ba2801203 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -5439,7 +5439,7 @@ static void init_spellfile(void) fname != NULL && strstr((char *)path_tail(fname), ".ascii.") != NULL ? (char_u *)"ascii" : spell_enc()); - set_option_value((char_u *)"spellfile", 0L, buf, OPT_LOCAL); + set_option_value("spellfile", 0L, (const char *)buf, OPT_LOCAL); break; } aspath = false; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 0a27d9dd92..632a5bf2a5 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -1406,14 +1406,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) @@ -6510,16 +6510,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); + } } } } @@ -7113,7 +7113,7 @@ 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) +int syn_name2id(const char_u *name) { int i; char_u name_u[200]; diff --git a/src/nvim/tag.c b/src/nvim/tag.c index b0ffc12b5f..af19a1bfc4 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -773,7 +773,7 @@ do_tag ( cmd[len] = NUL; } - dict = dict_alloc(); + dict = tv_dict_alloc(); tv_list_append_dict(list, dict); dict_add_nr_str(dict, "text", 0L, tag_name); @@ -2768,8 +2768,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); @@ -2824,7 +2824,7 @@ int get_tags(list_T *list, char_u *pat) if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0) continue; - dict = dict_alloc(); + dict = tv_dict_alloc(); tv_list_append_dict(list, dict); full_fname = tag_full_fname(&tp); diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index c81e883fb9..85c4950b42 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -226,17 +226,17 @@ 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); + set_option_value("buftype", 0, "terminal", OPT_LOCAL); // 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((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((uint8_t *)"list", false, NULL, OPT_LOCAL); + set_option_value("wrap", false, NULL, OPT_LOCAL); + set_option_value("number", false, NULL, OPT_LOCAL); + set_option_value("relativenumber", false, NULL, OPT_LOCAL); + set_option_value("list", false, NULL, OPT_LOCAL); buf_set_term_title(curbuf, (char *)curbuf->b_ffname); RESET_BINDING(curwin); // Reset cursor in current window. diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 729cf03e15..6e21dccebb 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -317,7 +317,7 @@ static long get_undolevel(void) 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; } } @@ -2941,7 +2941,7 @@ void u_eval_tree(u_header_T *first_uhp, list_T *list) dict_T *dict; while (uhp != NULL) { - dict = dict_alloc(); + dict = tv_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) diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 87e9889465..ae654251f9 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -109,11 +109,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)) @@ -282,15 +285,22 @@ enum { #define SHOWCMD_COLS 10 /* columns needed by shown command */ #define STL_MAX_ITEM 80 /* max nr of % 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). diff --git a/src/nvim/window.c b/src/nvim/window.c index 47a97da0cf..a3b0e6fc2d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2983,8 +2983,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; @@ -3811,8 +3811,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 @@ -5504,9 +5504,9 @@ void restore_buffer(bufref_T *save_curbuf) // 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, +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; @@ -5534,11 +5534,11 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, 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; } @@ -5557,14 +5557,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 -- cgit From 54bd2e8b731376b29c150f909c6b50103bfbb91a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 20 Aug 2016 22:25:57 +0300 Subject: eval: Make setmatches() return -1 in case of some failures --- src/nvim/eval.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 5015deead7..7ec1fda0a8 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14680,6 +14680,7 @@ 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; @@ -14728,17 +14729,23 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) &conceal_di->di_tv) : NULL); if (i == 0) { - match_add(curwin, group, - tv_dict_get_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); + 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; + } } } -- cgit From ecff8387f465bbf5d57de09498059ff1de671131 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 20 Aug 2016 23:12:15 +0300 Subject: eval: Move get_dict_callback to typval.c --- src/nvim/eval.c | 265 ++++++++++++++++++++++++------------------------- src/nvim/eval/typval.c | 36 +++++++ 2 files changed, 164 insertions(+), 137 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7ec1fda0a8..8d6b6d2dc1 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -729,8 +729,8 @@ void set_internal_string_var(char_u *name, char_u *value) } 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; /* @@ -761,9 +761,9 @@ 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); + // 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); @@ -839,12 +839,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); } @@ -1457,11 +1458,13 @@ 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] == '=')) { @@ -1527,7 +1530,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; @@ -1606,9 +1609,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 ']'. */ @@ -1645,7 +1650,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; @@ -1825,34 +1830,36 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) // TODO(ZyX-I): move to eval/ex_cmds -/* - * 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*/ -) +/// 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 *name; - char_u *arg_end = NULL; + char_u *name; + 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; + // Find the end of the name. + arg++; name = arg; - len = get_env_len(&arg); + len = get_env_len((const char_u **)&arg); if (len == 0) { EMSG2(_(e_invarg2), name - 1); } else { @@ -1975,9 +1982,9 @@ ex_let_one ( 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; } @@ -2020,7 +2027,6 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, FUNC_ATTR_NONNULL_ARG(1, 3) { char_u *p; - char_u *expr_start, *expr_end; int cc; dictitem_T *v; typval_T var1; @@ -2036,13 +2042,17 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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 = (char_u *)name; + return (char_u *)find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); } - /* Find the end of the name. */ - p = find_name_end(name, &expr_start, &expr_end, fne_flags); + // Find the end of the name. + char_u *expr_start; + char_u *expr_end; + 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) @@ -2063,8 +2073,9 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, } } lp->ll_name = lp->ll_exp_name; - } else - lp->ll_name = name; + } else { + lp->ll_name = (char_u *)name; + } /* Without [idx] or .key we are done. */ if ((*p != '[' && *p != '.') || lp->ll_name == NULL) @@ -2351,7 +2362,8 @@ static void clear_lval(lval_T *lp) * "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; @@ -2493,10 +2505,10 @@ notify: * 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, bool *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; @@ -2824,16 +2836,17 @@ void ex_lockvar(exarg_T *eap) 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) { @@ -2868,7 +2881,7 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep) // TODO(ZyX-I): move to eval/ex_cmds -static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit) +static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit) { int ret = OK; int cc; @@ -3022,7 +3035,7 @@ int do_unlet(char_u *name, int forceit) * "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, const int deep, +static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep, const bool lock) { int ret = OK; @@ -5605,34 +5618,6 @@ void dict_set_keys_readonly(dict_T *const dict) }); } -/// 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 *const di = tv_dict_find(d, 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); - tv_clear(&tv); - return res; -} - /* * Allocate a variable for a Dictionary and fill it from "*arg". * Return OK or FAIL. Returns NOTDONE for {expr}. @@ -5997,7 +5982,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) { @@ -11291,16 +11276,16 @@ 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|GLV_READ_ONLY, FNE_CHECK_START); + const char_u *const end = get_lval(get_tv_string(&argvars[0]), NULL, + &lv, false, false, + GLV_NO_AUTOLOAD, FNE_CHECK_START); if (end != NULL && lv.ll_name != NULL) { - if (*end != NUL) + if (*end != NUL) { EMSG(_(e_trailing)); - else { + } else { if (lv.ll_tv == NULL) { di = find_var((const char *)lv.ll_name, STRLEN(lv.ll_name), NULL, true); if (di != NULL) { @@ -16580,7 +16565,8 @@ static void f_test_garbagecollect_now(typval_T *argvars, garbage_collect(true); } -static bool callback_from_typval(Callback *callback, typval_T *arg) +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; @@ -17698,15 +17684,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; @@ -17758,8 +17745,6 @@ static int get_name_len(const char **const arg, int verbose) { int len; - char_u *expr_start; - char_u *expr_end; *alias = NULL; /* default to no alias */ @@ -17775,12 +17760,12 @@ static int get_name_len(const char **const arg, *arg += len; } - /* - * Find the end of the name; check for {} construction. - */ + // 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), - &expr_start, - &expr_end, + (const char_u **)&expr_start, + (const char_u **)&expr_end, len > 0 ? 0 : FNE_CHECK_START); if (expr_start != NULL) { if (!evaluate) { @@ -17816,12 +17801,11 @@ static int get_name_len(const char **const arg, // "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) { @@ -17834,6 +17818,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 == '{' @@ -17905,7 +17890,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; @@ -17934,7 +17920,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, @@ -18351,7 +18339,7 @@ handle_subscript( 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). @@ -20195,15 +20183,15 @@ ret_free: static char_u * 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; @@ -20229,9 +20217,9 @@ trans_function_name( 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")); @@ -20244,10 +20232,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; } @@ -20260,11 +20250,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(partial_name(lv.ll_tv->vval.v_partial)); - *pp = end; + *pp = (char_u *)end; if (partial != NULL) { *partial = lv.ll_tv->vval.v_partial; } @@ -20274,7 +20264,7 @@ trans_function_name( || fdp->fd_newkey == NULL)) { EMSG(_(e_funcref)); } else { - *pp = end; + *pp = (char_u *)end; } name = NULL; } @@ -20282,8 +20272,8 @@ 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; } @@ -20305,7 +20295,7 @@ trans_function_name( } if (name != NULL) { name = vim_strsave(name); - *pp = end; + *pp = (char_u *)end; if (strncmp((char *)name, "", 5) == 0) { // Change "" to the byte sequence. name[0] = K_SPECIAL; @@ -20379,7 +20369,7 @@ trans_function_name( } memmove(name + lead, lv.ll_name, (size_t)len); name[lead + len] = NUL; - *pp = end; + *pp = (char_u *)end; theend: clear_lval(&lv); @@ -20408,8 +20398,8 @@ static int eval_fname_script(const char *const p) /// Check whether function name starts with or s: /// -/// Only works for names previously checked by eval_fname_script(), if it -/// returned non-zero. +/// @warning Only works for names previously checked by eval_fname_script(), if +/// it returned non-zero. /// /// @param[in] name Name to check. /// @@ -20558,14 +20548,15 @@ bool translated_function_exists(const char *name) /// @return True if it exists, false otherwise. static bool function_exists(const char *const name, bool no_deref) { - char_u *nm = (char_u *)name; + const char_u *nm = (const char_u *)name; bool n = false; int flag = TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD; if (no_deref) { flag |= TFN_NO_DEREF; } - char *const p = (char *)trans_function_name(&nm, false, flag, NULL, NULL); + char *const p = (char *)trans_function_name((char_u **)&nm, false, flag, NULL, + NULL); nm = skipwhite(nm); /* Only accept "funcname", "funcname ", "funcname (..." and @@ -22510,9 +22501,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; } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index bb7baed7d2..f4f34e0d92 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1130,6 +1130,42 @@ const char *tv_dict_get_string_buf(dict_T *const d, const char *const key, return (const char *)get_tv_string_buf(&di->di_tv, (char_u *)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_ALL 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 (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")); + return false; + } + + typval_T tv; + copy_tv(&di->di_tv, &tv); + set_selfdict(&tv, d); + bool res = callback_from_typval(result, &tv); + tv_clear(&tv); + return res; +} + //{{{2 Operations on the whole dict /// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary. -- cgit From 983a5532ca17060508ea308a9b7069dae4facb59 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 20 Aug 2016 23:14:50 +0300 Subject: eval: Move dict_set_keys_readonly to typval.c --- src/nvim/eval.c | 15 +-------------- src/nvim/eval/typval.c | 17 +++++++++++++++-- src/nvim/file_search.c | 2 +- src/nvim/ops.c | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8d6b6d2dc1..afbb93ef92 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5605,19 +5605,6 @@ int dict_add_dict(dict_T *d, char *key, dict_T *dict) 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 *const dict) - FUNC_ATTR_NONNULL_ALL -{ - TV_DICT_ITER(dict, di, { - di->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX; - }); -} - /* * Allocate a variable for a Dictionary and fill it from "*arg". * Return OK or FAIL. Returns NOTDONE for {expr}. @@ -18083,7 +18070,7 @@ void set_vim_var_dict(const VimVarIndex idx, dict_T *const val) if (val != NULL) { val->dv_refcount++; // Set readonly - dict_set_keys_readonly(val); + tv_dict_set_keys_readonly(val); } } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index f4f34e0d92..0df818040b 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1135,8 +1135,8 @@ const char *tv_dict_get_string_buf(dict_T *const d, const char *const key, /// @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. +/// @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, @@ -1348,6 +1348,19 @@ dict_T *tv_dict_copy(const vimconv_T *const conv, 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 diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 8ab6955042..d7120a7309 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1551,7 +1551,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope) dict_add_nr_str(dict, "scope", 0L, (char_u *)buf); dict_add_nr_str(dict, "cwd", 0L, (char_u *)new_dir); - dict_set_keys_readonly(dict); + tv_dict_set_keys_readonly(dict); apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false, NULL); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index d634a8c393..4bca2f0889 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2578,7 +2578,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) buf[1] = NUL; dict_add_nr_str(dict, "operator", 0, (char_u *)buf); - dict_set_keys_readonly(dict); + tv_dict_set_keys_readonly(dict); textlock++; apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, false, curbuf); textlock--; -- cgit From 210342d795a13e88579d3e55ae931463d16f241d Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 11 Jan 2017 23:20:03 +0300 Subject: eval: Move dict_add_list and dict_add_dict to typval.c --- src/nvim/eval.c | 57 ++++++++++---------------------------------------- src/nvim/eval/typval.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ src/nvim/ops.c | 3 ++- src/nvim/undo.c | 3 ++- 4 files changed, 67 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index afbb93ef92..e7c2d95cdd 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5569,42 +5569,6 @@ int dict_add_nr_str(dict_T *d, char *key, long nr, char_u *str) 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 = tv_dict_item_alloc(key); - - item->di_tv.v_lock = 0; - item->di_tv.v_type = VAR_LIST; - item->di_tv.vval.v_list = list; - if (tv_dict_add(d, item) == FAIL) { - tv_dict_item_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 *const item = tv_dict_item_alloc(key); - - item->di_tv.v_lock = 0; - item->di_tv.v_type = VAR_DICT; - item->di_tv.vval.v_dict = dict; - if (tv_dict_add(d, item) == FAIL) { - tv_dict_item_free(item); - return FAIL; - } - dict->dv_refcount++; - return OK; -} - /* * Allocate a variable for a Dictionary and fill it from "*arg". * Return OK or FAIL. Returns NOTDONE for {expr}. @@ -9128,7 +9092,7 @@ static dict_T *get_buffer_info(buf_T *buf) NULL); // 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 *const windows = tv_list_alloc(); @@ -9137,13 +9101,13 @@ static dict_T *get_buffer_info(buf_T *buf) 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 *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; @@ -9900,7 +9864,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) // 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) { @@ -9912,8 +9876,9 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); @@ -10082,10 +10047,10 @@ static dict_T *get_tabpage_info(tabpage_T *tp, int tp_idx) FOR_ALL_WINDOWS_IN_TAB(wp, tp) { 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; } @@ -10187,7 +10152,7 @@ static dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr) 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; } @@ -17029,7 +16994,7 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); } /* diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 0df818040b..f9885926c7 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1166,6 +1166,58 @@ bool tv_dict_get_callback(dict_T *const d, return res; } +//{{{2 dict_add* + +/// 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 *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; + if (tv_dict_add(d, item) == FAIL) { + tv_dict_item_free(item); + return FAIL; + } + list->lv_refcount++; + 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(key); + + item->di_tv.v_lock = VAR_UNLOCKED; + item->di_tv.v_type = VAR_DICT; + item->di_tv.vval.v_dict = dict; + if (tv_dict_add(d, item) == FAIL) { + tv_dict_item_free(item); + return FAIL; + } + dict->dv_refcount++; + return OK; +} + //{{{2 Operations on the whole dict /// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary. diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 4bca2f0889..28ac5aad4e 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -42,6 +42,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" @@ -2561,7 +2562,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) 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]; diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 6e21dccebb..8c75d28f2a 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -82,6 +82,7 @@ #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" @@ -2956,7 +2957,7 @@ void u_eval_tree(u_header_T *first_uhp, list_T *list) /* 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); } tv_list_append_dict(list, dict); -- cgit From 2dcfc439b2ec2be4d830826061e89860977516be Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 20 Aug 2016 23:56:49 +0300 Subject: eval: Split and move dict_add_nr_str to typval.c Function was split into tv_dict_add_nr() and tv_dict_add_str(). --- src/nvim/edit.c | 24 +++++---- src/nvim/eval.c | 143 ++++++++++++++++++++----------------------------- src/nvim/eval/typval.c | 50 ++++++++++++++++- src/nvim/eval/typval.h | 1 + src/nvim/file_search.c | 4 +- src/nvim/ops.c | 31 ++++++----- src/nvim/option.c | 5 +- src/nvim/quickfix.c | 44 +++++++++------ src/nvim/search.c | 5 +- src/nvim/tag.c | 29 +++++----- src/nvim/undo.c | 21 ++++---- 11 files changed, 202 insertions(+), 155 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 53b196c61f..d1cceb435a 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -4034,16 +4034,20 @@ static void ins_compl_insert(int in_compl_func) // Set completed item. // { word, abbr, menu, kind, info } dict_T *dict = tv_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])); + 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; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e7c2d95cdd..a64eb3c959 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5544,31 +5544,6 @@ static bool set_ref_in_funccal(funccall_T *fc, int copyID) return abort; } -/* - * 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 = tv_dict_item_alloc(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 (tv_dict_add(d, item) == FAIL) { - tv_dict_item_free(item); - return FAIL; - } - return OK; -} - /* * Allocate a variable for a Dictionary and fill it from "*arg". * Return OK or FAIL. Returns NOTDONE for {expr}. @@ -9066,9 +9041,10 @@ static void get_buffer_signs(buf_T *buf, list_T *l) for (signlist_T *sign = buf->b_signlist; sign; sign = sign->next) { 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)); tv_list_append_dict(l, d); } @@ -9079,17 +9055,16 @@ static dict_T *get_buffer_info(buf_T *buf) { dict_T *const dict = tv_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); + 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"), 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 tv_dict_add_dict(dict, S_LEN("variables"), buf->b_vars); @@ -9411,9 +9386,9 @@ static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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()); } /* @@ -9881,17 +9856,18 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); } tv_list_append_dict(rettv->vval.v_list, dict); @@ -10041,7 +10017,7 @@ static dict_T *get_tabpage_info(tabpage_T *tp, int tp_idx) { 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 *const l = tv_list_alloc(); FOR_ALL_WINDOWS_IN_TAB(wp, tp) { @@ -10139,17 +10115,16 @@ static dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr) { 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 tv_dict_add_dict(dict, S_LEN("variables"), wp->w_vars); @@ -12074,15 +12049,15 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) char *const mapmode = map_mode_to_chars(mp->m_mode); dict_T *dict = rettv->vval.v_dict; - dict_add_nr_str(dict, "lhs", 0L, lhs); - dict_add_nr_str(dict, "rhs", 0L, mp->m_orig_str); - dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L, NULL); - dict_add_nr_str(dict, "expr", mp->m_expr ? 1L : 0L, NULL); - dict_add_nr_str(dict, "silent", mp->m_silent ? 1L : 0L, NULL); - dict_add_nr_str(dict, "sid", (long)mp->m_script_ID, NULL); - dict_add_nr_str(dict, "buffer", (long)buffer_local, NULL); - dict_add_nr_str(dict, "nowait", mp->m_nowait ? 1L : 0L, NULL); - dict_add_nr_str(dict, "mode", 0L, (char_u *)mapmode); + tv_dict_add_str(dict, S_LEN("lhs"), (const char *)lhs); + tv_dict_add_str(dict, S_LEN("rhs"), (const char *)mp->m_orig_str); + tv_dict_add_nr(dict, S_LEN("noremap"), mp->m_noremap ? 1 : 0); + 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_local); + tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0); + tv_dict_add_str(dict, S_LEN("mode"), mapmode); xfree(lhs); xfree(mapmode); @@ -16984,13 +16959,13 @@ static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 = tv_list_alloc(); u_eval_tree(curbuf->b_u_oldhead, list); @@ -17223,16 +17198,16 @@ static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index f9885926c7..62460bcc3a 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1180,7 +1180,7 @@ 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 *item = tv_dict_item_alloc_len(key, key_len); + 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; @@ -1218,6 +1218,54 @@ int tv_dict_add_dict(dict_T *const d, const char *const key, 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 +{ + 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 *)xstrdup(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. diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 6183397d12..6929e37e43 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "nvim/hashtab.h" #include "nvim/garray.h" diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index d7120a7309..f7932bc296 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1549,8 +1549,8 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope) assert(false); } - dict_add_nr_str(dict, "scope", 0L, (char_u *)buf); - dict_add_nr_str(dict, "cwd", 0L, (char_u *)new_dir); + 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, diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 28ac5aad4e..fd1e2d20f2 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -14,6 +14,7 @@ #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" @@ -2567,17 +2568,17 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) // 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); tv_dict_set_keys_readonly(dict); textlock++; @@ -5484,17 +5485,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 diff --git a/src/nvim/option.c b/src/nvim/option.c index 4c8606a999..1881b329ec 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -6971,9 +6971,10 @@ dict_T *get_winbuf_options(const 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 { - dict_add_nr_str(d, opt->fullname, *varp, NULL); + tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname), *varp); } } } diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index d23059ff22..06ac2821b0 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3972,7 +3972,6 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start) 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; @@ -4000,23 +3999,34 @@ int get_errorlist(win_T *wp, int qf_idx, list_T *list) if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) bufnum = 0; - dict = tv_dict_alloc(); + 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) { @@ -4085,15 +4095,15 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) if (t == NULL) { t = (char_u *)""; } - status = dict_add_nr_str(retdict, "title", 0L, t); + status = tv_dict_add_str(retdict, S_LEN("title"), (const char *)t); } if ((status == OK) && (flags & QF_GETLIST_NR)) { - status = dict_add_nr_str(retdict, "nr", qf_idx + 1, NULL); + 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 = dict_add_nr_str(retdict, "winid", win->handle, NULL); + status = tv_dict_add_nr(retdict, S_LEN("winid"), win->handle); } } diff --git a/src/nvim/search.c b/src/nvim/search.c index fb9e820928..c5c92b41c5 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -356,9 +356,10 @@ int pat_has_uppercase(char_u *pat) 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) diff --git a/src/nvim/tag.c b/src/nvim/tag.c index af19a1bfc4..b812dd2ffd 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -776,11 +776,12 @@ do_tag ( 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); @@ -2203,7 +2204,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; @@ -2790,7 +2791,8 @@ 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; } @@ -2806,7 +2808,7 @@ int get_tags(list_T *list, char_u *pat) 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); @@ -2829,14 +2831,13 @@ int get_tags(list_T *list, char_u *pat) 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/undo.c b/src/nvim/undo.c index 8c75d28f2a..ba687bf6da 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2943,19 +2943,22 @@ void u_eval_tree(u_header_T *first_uhp, list_T *list) while (uhp != NULL) { dict = tv_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); + 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 = 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); tv_dict_add_list(dict, S_LEN("alt"), alt_list); } -- cgit From 5cdf7177ec71e4b9b3295ead93bedf7ff226a2b2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 21 Aug 2016 00:20:01 +0300 Subject: eval: Move get_float_arg to typval.h Assuming `inline` is there for a reason, so it is kept and function was moved to typval.h and not to typval.c which does not have problems with #including message.h. --- src/nvim/eval.c | 60 +++++++++++++++++++------------------------------- src/nvim/eval/typval.h | 27 +++++++++++++++++++++++ src/nvim/gettext.h | 21 ++++++++++++++++++ src/nvim/vim.h | 17 +------------- 4 files changed, 72 insertions(+), 53 deletions(-) create mode 100644 src/nvim/gettext.h (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a64eb3c959..1d060eff33 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6473,24 +6473,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 @@ -6502,7 +6484,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(argvars, &f)) { rettv->vval.v_float = function(f); } else { rettv->vval.v_float = 0.0; @@ -6957,14 +6939,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(argvars, &fx) && tv_get_float(&argvars[1], &fy)) { rettv->vval.v_float = atan2(fx, fy); - else + } else { rettv->vval.v_float = 0.0; + } } /* @@ -8557,13 +8540,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(argvars, &f)) { + if (f < VARNUMBER_MIN) { + rettv->vval.v_number = VARNUMBER_MIN; + } else if (f > VARNUMBER_MAX) { + rettv->vval.v_number = VARNUMBER_MAX; + } else { rettv->vval.v_number = (varnumber_T)f; + } } } @@ -8572,14 +8556,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(argvars, &fx) && tv_get_float(&argvars[1], &fy)) { rettv->vval.v_float = fmod(fx, fy); - else + } else { rettv->vval.v_float = 0.0; + } } /* @@ -12790,14 +12775,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(argvars, &fx) && tv_get_float(&argvars[1], &fy)) { rettv->vval.v_float = pow(fx, fy); - else + } else { rettv->vval.v_float = 0.0; + } } /* diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 6929e37e43..0eef2ddaac 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -13,6 +13,7 @@ #include "nvim/lib/queue.h" #include "nvim/profile.h" // for proftime_T #include "nvim/pos.h" // for linenr_T +#include "nvim/gettext.h" /// Type used for VimL VAR_NUMBER values typedef int varnumber_T; @@ -370,6 +371,32 @@ extern bool tv_in_free_unref_items; } \ }) +static inline bool tv_get_float(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 +/// +/// @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(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; +} + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/typval.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 +# 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/vim.h b/src/nvim/vim.h index ae654251f9..e16ee00309 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -51,22 +51,7 @@ Error: configure did not run properly.Check auto/config.log. /* ================ end of the header file puzzle =============== */ -#ifdef HAVE_WORKING_LIBINTL -# include -# 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 -- cgit From 28dafe3ff0b0dc082fb62b2251fd64a167ce7188 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 21 Aug 2016 08:16:47 +0300 Subject: eval,*: Move get_tv_string to typval.c Function was renamed and changed to return `const char *`. --- src/nvim/api/private/helpers.c | 2 +- src/nvim/buffer.c | 6 +- src/nvim/edit.c | 14 +- src/nvim/eval.c | 1432 ++++++++++++++++++++-------------------- src/nvim/eval.h | 2 +- src/nvim/eval/executor.c | 6 +- src/nvim/eval/typval.c | 28 +- src/nvim/eval/typval.h | 2 + src/nvim/ex_docmd.c | 6 +- src/nvim/ex_eval.c | 20 +- src/nvim/ex_getln.c | 69 +- src/nvim/fileio.c | 36 +- src/nvim/getchar.c | 113 ++-- src/nvim/hardcopy.c | 8 +- src/nvim/message.c | 2 +- src/nvim/msgpack_rpc/channel.c | 20 +- src/nvim/msgpack_rpc/helpers.c | 4 +- src/nvim/normal.c | 21 +- src/nvim/os/fs.c | 25 +- src/nvim/os_unix.c | 4 +- src/nvim/path.c | 36 +- src/nvim/sha256.c | 14 +- src/nvim/shada.c | 2 - src/nvim/spell.c | 48 +- src/nvim/strings.c | 38 +- src/nvim/syntax.c | 92 +-- src/nvim/undo.c | 2 +- src/nvim/version.c | 12 +- 28 files changed, 1072 insertions(+), 992 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 6b17ba1a11..2c8a56cc1a 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -625,7 +625,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. diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0ce9ce073e..0fb9a21354 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4207,11 +4207,11 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) #ifdef WIN32 if (!buf->b_p_bin) { // If the file name is a shortcut file, use the file it links to. - char_u *rfname = (char_u *)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 diff --git a/src/nvim/edit.c b/src/nvim/edit.c index d1cceb435a..b396251051 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -3464,7 +3464,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; @@ -3475,9 +3474,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; @@ -4589,7 +4587,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; @@ -4608,8 +4605,7 @@ static int ins_complete(int c, bool enable_pum) 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; @@ -7111,8 +7107,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; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1d060eff33..7e40f5e828 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -965,31 +965,34 @@ eval_to_bool ( 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)); + } else { + retval = xstrdup(tv_get_string(&tv)); tv_clear(&tv); } - if (skip) - --emsg_skip; + if (skip) { + emsg_skip--; + } return retval; } @@ -1015,13 +1018,12 @@ 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) { @@ -1031,16 +1033,18 @@ char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert) } } 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)); + 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; } /* @@ -1159,14 +1163,15 @@ 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) @@ -1198,9 +1203,9 @@ typval_T *eval_expr(char_u *arg, char_u **nextcmd) // // 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 @@ -1233,7 +1238,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]; } } @@ -1268,8 +1273,8 @@ long call_func_retnr ( char_u *func, int argc, - char_u **argv, - int safe /* use the sandbox */ + const char_u *const *const argv, + int safe // use the sandbox ) { typval_T rettv; @@ -1284,27 +1289,28 @@ call_func_retnr ( 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 VimL 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 failes, 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)); + char *const retval = xstrdup(tv_get_string(&rettv)); tv_clear(&rettv); return retval; } @@ -1318,8 +1324,8 @@ void * call_func_retlist ( char_u *func, int argc, - char_u **argv, - int safe /* use the sandbox */ + const char_u *const *const argv, + int safe // use the sandbox ) { typval_T rettv; @@ -2202,7 +2208,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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) { tv_clear(&var1); return NULL; @@ -4343,9 +4349,8 @@ eval_index ( bool empty1 = false; bool empty2 = false; long n1, n2 = 0; - long len = -1; + ptrdiff_t len = -1; int range = false; - char_u *s; char_u *key = NULL; switch (rettv->v_type) { @@ -4455,103 +4460,109 @@ eval_index ( tv_clear(&var1); } if (range) { - if (empty2) + if (empty2) { n2 = -1; - else { + } else { n2 = get_tv_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); - } - tv_clear(rettv); - rettv->v_type = VAR_STRING; - rettv->vval.v_string = s; - break; - - case VAR_LIST: - len = tv_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 = 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; + 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 { + copy_tv(&tv_list_find(rettv->vval.v_list, n1)->li_tv, &var1); + tv_clear(rettv); + *rettv = var1; } - tv_clear(rettv); - rettv->v_type = VAR_LIST; - rettv->vval.v_list = l; - ++l->lv_refcount; - } else { - copy_tv(&tv_list_find(rettv->vval.v_list, n1)->li_tv, &var1); - tv_clear(rettv); - *rettv = var1; + break; } - break; - - case VAR_DICT: - if (range) { - if (verbose) { - emsgf(_(e_dictrange)); - } - if (len == -1) { - tv_clear(&var1); + case VAR_DICT: { + if (range) { + if (verbose) { + emsgf(_(e_dictrange)); + } + if (len == -1) { + tv_clear(&var1); + } + return FAIL; } - return FAIL; - } - { - dictitem_T *item; if (len == -1) { key = get_tv_string_chk(&var1); @@ -4561,7 +4572,8 @@ eval_index ( } } - item = tv_dict_find(rettv->vval.v_dict, (const char *)key, len); + dictitem_T *const item = tv_dict_find(rettv->vval.v_dict, + (const char *)key, len); if (item == NULL && verbose) { emsgf(_(e_dictkey), key); @@ -4576,14 +4588,15 @@ eval_index ( copy_tv(&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 } } @@ -6251,7 +6264,7 @@ bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID) /// 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" @@ -7249,24 +7262,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_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 @@ -7299,15 +7312,15 @@ 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) + if (argvars[1].v_type != VAR_UNKNOWN) { utf8 = get_tv_number_chk(&argvars[1], NULL); + } - if (utf8) - rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0])); - else - rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); - } else - rettv->vval.v_number = get_tv_string(&argvars[0])[0]; + rettv->vval.v_number = (utf8 ? *utf_ptr2char : *mb_ptr2char)( + (const char_u *)tv_get_string(&argvars[0])); + } else { + rettv->vval.v_number = (uint8_t)(tv_get_string(&argvars[0])[0]); + } } /* @@ -7552,16 +7565,17 @@ 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 *dbpath = NULL; + char_u *prepend = NULL; char_u buf[NUMBUFLEN]; if (argvars[0].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_UNKNOWN) { num = (int)get_tv_number(&argvars[0]); - dbpath = get_tv_string(&argvars[1]); - if (argvars[2].v_type != VAR_UNKNOWN) + dbpath = (char_u *)tv_get_string(&argvars[1]); + if (argvars[2].v_type != VAR_UNKNOWN) { prepend = get_tv_string_buf(&argvars[2], buf); + } } rettv->vval.v_number = cs_connection(num, dbpath, prepend); @@ -7648,7 +7662,6 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -7656,7 +7669,7 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -7670,10 +7683,10 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (*flags == NUL) { // delete a file - rettv->vval.v_number = os_remove((char *)name) == 0 ? 0 : -1; + 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; + 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); @@ -7894,7 +7907,8 @@ static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char_u buf[NUMBUFLEN]; - rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), + rettv->vval.v_string = vim_strsave_escaped( + (const char_u *)tv_get_string(&argvars[0]), get_tv_string_buf(&argvars[1], buf)); rettv->v_type = VAR_STRING; } @@ -7936,11 +7950,13 @@ 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) @@ -7993,11 +8009,11 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) capture_ga = &capture_local; if (argvars[0].v_type != VAR_LIST) { - do_cmdline_cmd((char *)get_tv_string(&argvars[0])); + do_cmdline_cmd(tv_get_string(&argvars[0])); } else if (argvars[0].vval.v_list != NULL) { - list_T *list = argvars[0].vval.v_list; + list_T *const list = argvars[0].vval.v_list; list->lv_refcount++; - listitem_T *item = list->lv_first; + 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--; @@ -8017,10 +8033,10 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "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; @@ -8034,21 +8050,21 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr) int n = false; int len = 0; - char *p = (char *)get_tv_string(&argvars[0]); + 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}. - p = (char *)expand_env_save((char_u *)p); - if (p != NULL && *p != '$') { + char_u *const exp = expand_env_save((char_u *)p); + if (exp != NULL && *exp != '$') { n = true; } - xfree(p); + xfree(exp); } } else if (*p == '&' || *p == '+') { // Option. - n = (get_option_tv((const char **)&p, NULL, true) == OK); + n = (get_option_tv(&p, NULL, true) == OK); if (*skipwhite((const char_u *)p) != NUL) { n = false; // Trailing garbage. } @@ -8076,7 +8092,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr) n = (get_var_tv(name, len, &tv, NULL, false, true) == OK); if (n) { // Handle d.key, l[idx], f(expr). - n = (handle_subscript((const char **)&p, &tv, true, false) == OK); + n = (handle_subscript(&p, &tv, true, false) == OK); if (n) { tv_clear(&tv); } @@ -8096,7 +8112,6 @@ 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; @@ -8113,11 +8128,11 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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) { tv_list_alloc_ret(rettv); if (result != NULL) { @@ -8134,21 +8149,24 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); + rettv->vval.v_string = ExpandOne(&xpc, (char_u *)s, NULL, options, + WILD_ALL); } else { tv_list_alloc_ret(rettv); - ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP); + ExpandOne(&xpc, (char_u *)s, NULL, options, WILD_ALL_KEEP); for (int i = 0; i < xpc.xp_numfiles; i++) { tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i], -1); } ExpandCleanup(&xpc); } - } else + } else { rettv->vval.v_string = NULL; + } } } @@ -8235,7 +8253,6 @@ 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 @@ -8244,10 +8261,11 @@ static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (check_secure()) return; - keys = get_tv_string(&argvars[0]); + const char *const keys = tv_get_string(&argvars[0]); + const char *flags = NULL; if (argvars[1].v_type != VAR_UNKNOWN) { - flags = get_tv_string_buf(&argvars[1], nbuf); + flags = (const char *)get_tv_string_buf(&argvars[1], nbuf); } nvim_feedkeys(cstr_as_string((char *)keys), @@ -8257,9 +8275,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)); } /* @@ -8268,14 +8286,13 @@ 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; @@ -8287,7 +8304,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) rettv->vval.v_string = NULL; rettv->v_type = VAR_STRING; - fname = get_tv_string(&argvars[0]); + const char *fname = tv_get_string(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) { p = get_tv_string_buf_chk(&argvars[1], pathbuf); @@ -8311,8 +8328,8 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) 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 @@ -8572,8 +8589,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; } @@ -8765,7 +8782,7 @@ static void common_function(typval_T *argvars, typval_T *rettv, 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; } @@ -8780,7 +8797,9 @@ static void common_function(typval_T *argvars, typval_T *rettv, } if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s)) || (is_funcref && trans_name == NULL)) { - EMSG2(_(e_invarg2), use_string ? get_tv_string(&argvars[0]) : s); + 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 @@ -8958,7 +8977,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } else if (argvars[0].v_type == VAR_DICT) { if ((d = argvars[0].vval.v_dict) != NULL) { - di = tv_dict_find(d, (const char *)get_tv_string(&argvars[1]), -1); + di = tv_dict_find(d, tv_get_string(&argvars[1]), -1); if (di != NULL) { tv = &di->di_tv; } @@ -8977,27 +8996,26 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (pt != NULL) { - char_u *what = get_tv_string(&argvars[1]); - char_u *n; + 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); - n = partial_name(pt); + const char *const n = (const char *)partial_name(pt); if (n == NULL) { rettv->vval.v_string = NULL; } else { - rettv->vval.v_string = vim_strsave(n); + 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 (tv_list_alloc_ret(rettv) != NULL) { for (int i = 0; i < pt->pt_argc; i++) { @@ -9448,9 +9466,10 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) } ExpandInit(&xpc); - xpc.xp_pattern = get_tv_string(&argvars[0]); + 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(get_tv_string(&argvars[1])); + xpc.xp_context = cmdcomplete_str_to_type( + (char_u *)tv_get_string(&argvars[1])); if (xpc.xp_context == EXPAND_NOTHING) { EMSG2(_(e_invarg2), argvars[1].vval.v_string); return; @@ -9623,20 +9642,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; } /* @@ -9644,16 +9664,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 */ @@ -9671,7 +9691,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)) { @@ -9686,15 +9706,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)) @@ -9746,10 +9765,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); @@ -10345,11 +10365,12 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); + 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, get_tv_string(&argvars[0]), NULL, options, WILD_ALL_KEEP); + ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options, + WILD_ALL_KEEP); for (int i = 0; i < xpc.xp_numfiles; i++) { tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i], -1); @@ -10393,7 +10414,7 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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]), file, &ga, flags); if (rettv->v_type == VAR_STRING) { rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n"); @@ -10425,7 +10446,7 @@ static void f_glob2regpat(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "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 @@ -10536,13 +10557,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; @@ -10608,7 +10627,7 @@ static void f_has_key(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; rettv->vval.v_number = tv_dict_find(argvars[0].vval.v_dict, - (const char *)get_tv_string(&argvars[1]), + tv_get_string(&argvars[1]), -1) != NULL; } @@ -10718,24 +10737,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; + const char *mode; + const char *const name = tv_get_string(&argvars[0]); + bool abbr = false; 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) + if (argvars[1].v_type == VAR_UNKNOWN) { + mode = "nvo"; + } else { + mode = (const char *)get_tv_string_buf(&argvars[1], buf); + if (argvars[2].v_type != VAR_UNKNOWN) { abbr = get_tv_number(&argvars[2]); + } } - if (map_to_exists(name, mode, abbr)) - rettv->vval.v_number = TRUE; - else - rettv->vval.v_number = FALSE; + if (map_to_exists(name, mode, abbr)) { + rettv->vval.v_number = true; + } else { + rettv->vval.v_number = false; + } } /* @@ -10840,7 +10859,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])); } /* @@ -10848,7 +10868,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])); } /* @@ -10868,25 +10889,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_u buf1[NUMBUFLEN]; + char_u *const from = enc_canonize(enc_skip( + get_tv_string_buf(&argvars[1], buf1))); + char_u buf2[NUMBUFLEN]; + char_u *const to = enc_canonize(enc_skip( + get_tv_string_buf(&argvars[2], buf2))); vimconv.vc_type = CONV_NONE; convert_setup(&vimconv, from, to); - /* If the encodings are equal, no conversion needed. */ - if (vimconv.vc_type == CONV_NONE) - rettv->vval.v_string = vim_strsave(str); - else - rettv->vval.v_string = string_convert(&vimconv, str, NULL); + // 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); @@ -11075,7 +11098,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((const char *)get_tv_string(&li->li_tv)); + msg_puts(tv_get_string(&li->li_tv)); msg_putchar('\n'); } @@ -11179,7 +11202,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])); } /* @@ -11191,9 +11214,11 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) dictitem_T *di; rettv->vval.v_number = -1; - const char_u *const end = get_lval(get_tv_string(&argvars[0]), NULL, + const char_u *const end = get_lval((char_u *)tv_get_string(&argvars[0]), + NULL, &lv, false, false, - GLV_NO_AUTOLOAD, FNE_CHECK_START); + GLV_NO_AUTOLOAD|GLV_READ_ONLY, + FNE_CHECK_START); if (end != NULL && lv.ll_name != NULL) { if (*end != NUL) { EMSG(_(e_trailing)); @@ -11416,8 +11441,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. @@ -11462,10 +11487,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; } @@ -11504,7 +11529,7 @@ static char **tv_to_argv(typval_T *cmd_tv, char **cmd, bool *executable) for (listitem_T *arg = argl->lv_first; arg != NULL; arg = arg->li_next) { char *a = (char *)get_tv_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; } @@ -11841,24 +11866,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 = 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_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; + } } } @@ -11983,7 +12012,6 @@ 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; @@ -11994,13 +12022,14 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) 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; + } if (argvars[1].v_type != VAR_UNKNOWN) { which = get_tv_string_buf_chk(&argvars[1], buf); @@ -12118,7 +12147,7 @@ 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); } @@ -12278,7 +12307,7 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) int prio = 10; /* default priority */ int id = -1; bool error = false; - char_u *conceal_char = NULL; + const char *conceal_char = NULL; rettv->vval.v_number = -1; @@ -12296,7 +12325,7 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) dictitem_T *di; if ((di = tv_dict_find(argvars[4].vval.v_dict, S_LEN("conceal"))) != NULL) { - conceal_char = get_tv_string(&di->di_tv); + conceal_char = tv_get_string(&di->di_tv); } } } @@ -12311,7 +12340,7 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = match_add(curwin, (const char *)grp, (const char *)pat, prio, id, - NULL, (const char *)conceal_char); + NULL, conceal_char); } static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) @@ -12338,7 +12367,7 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); @@ -12352,7 +12381,7 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) dictitem_T *di; if ((di = tv_dict_find(argvars[4].vval.v_dict, S_LEN("conceal"))) != NULL) { - conceal_char = get_tv_string(&di->di_tv); + conceal_char = tv_get_string(&di->di_tv); } } } @@ -12368,7 +12397,7 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) } rettv->vval.v_number = match_add(curwin, (const char *)group, NULL, prio, id, - l, (const char *)conceal_char); + l, conceal_char); } /* @@ -12523,9 +12552,10 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) *path_tail_with_sep(dir) = NUL; if (argvars[1].v_type != VAR_UNKNOWN) { - if (argvars[2].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 (prot != -1 && strcmp(tv_get_string(&argvars[1]), "p") == 0) { char *failed_dir; int ret = os_mkdir_recurse((char *) dir, prot, &failed_dir); if (ret != 0) { @@ -12894,8 +12924,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); @@ -12909,19 +12938,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) + if (strcmp(tv_get_string(&argvars[1]), "b") == 0) { + binary = true; + } + if (argvars[2].v_type != VAR_UNKNOWN) { maxline = get_tv_number(&argvars[2]); + } } 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 *)_("") : 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 ? _("") : fname); return; } @@ -13241,11 +13272,13 @@ 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]), + } else { + rettv->vval.v_number = vim_rename( + (char_u *)tv_get_string(&argvars[0]), get_tv_string_buf(&argvars[1], buf)); + } } /* @@ -13253,32 +13286,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 = get_tv_number(&argvars[1]); if (argvars[0].v_type == VAR_LIST) { tv_list_alloc_ret(rettv); - if (argvars[0].vval.v_list != NULL) { - while (n-- > 0) { - tv_list_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL); - } + while (n-- > 0) { + tv_list_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL); } } else { - p = get_tv_string(&argvars[0]); rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (n <= 0) { + return; + } + + const char *const p = tv_get_string(&argvars[0]); - int slen = (int)STRLEN(p); - int len = slen * n; - if (len <= 0) + const size_t slen = strlen(p); + if (slen == 0) { return; + } + const size_t len = slen * n; + // Detect overflow. + if (len / n != slen) { + return; + } - char_u *r = xmallocz(len); - for (int i = 0; i < n; i++) - memmove(r + i * slen, p, (size_t)slen); + char *const r = xmallocz(len); + for (varnumber_T i = 0; i < n; i++) { + memmove(r + i * slen, p, slen); + } - rettv->vval.v_string = r; + rettv->vval.v_string = (char_u *)r; } } @@ -13287,59 +13325,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 *v = os_resolve_shortcut(p); - if (v != NULL) { - rettv->vval.v_string = (char_u *)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) { @@ -13347,66 +13375,74 @@ 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); + if (q > p && !path_is_absolute_path((const char_u *)buf)) { + // Symlink is relative to directory of argument. + const size_t p_len = strlen(p); + const size_t buf_len = strlen(buf); + cpy = xmalloc(p_len + buf_len + 1); + memcpy(cpy, p, p_len); + memcpy(path_tail((char_u *)cpy), buf, buf_len + 1); xfree(p); p = cpy; } 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); + strncat(cpy + p_len, remain, len); 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 @@ -13416,42 +13452,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; } /* @@ -13542,7 +13576,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; @@ -13554,10 +13587,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; @@ -13592,13 +13626,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; @@ -13655,7 +13689,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; @@ -13722,7 +13756,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); @@ -13797,7 +13831,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)); } } @@ -13962,7 +13996,7 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) */ 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; } @@ -14232,7 +14266,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_invarg)); return; } else { - rettv->vval.v_string = vim_strsave(get_tv_string(argvars)); + rettv->vval.v_string = (char_u *)xstrdup(tv_get_string(argvars)); } } else { rettv->vval.v_string = (char_u *)server_address_new(); @@ -14613,7 +14647,7 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Note: there are three number buffers involved: // - group_buf below. // - numbuf in tv_dict_get_string(). - // - mybuf in get_tv_string(). + // - mybuf in tv_get_string(). // // If you change this code make sure that buffers will not get // accidentally reused. @@ -14623,8 +14657,7 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 - ? (const char *)get_tv_string( - &conceal_di->di_tv) + ? tv_get_string(&conceal_di->di_tv) : NULL); if (i == 0) { if (match_add(curwin, group, @@ -14899,11 +14932,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; } @@ -14913,7 +14946,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; } @@ -14930,11 +14964,9 @@ 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; } @@ -14950,7 +14982,7 @@ 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; bool item_compare_func_err; @@ -15058,7 +15090,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 @@ -15072,7 +15104,7 @@ 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_name(partial); + func_name = (const char *)partial_name(partial); } // Copy the values. This is needed to be able to set v_lock to VAR_FIXED @@ -15081,7 +15113,7 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) copy_tv(&si2->item->li_tv, &argv[1]); rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this - res = call_func(func_name, + res = call_func((const char_u *)func_name, (int)STRLEN(func_name), &rettv, 2, argv, NULL, 0L, 0L, &dummy, true, partial, sortinfo->item_compare_selfdict); @@ -15167,7 +15199,7 @@ 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 { @@ -15180,7 +15212,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) 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; @@ -15189,16 +15221,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; } @@ -15332,11 +15364,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); } /* @@ -15387,7 +15417,6 @@ 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; bool typeerr = false; int maxcount; garray_T ga; @@ -15397,7 +15426,7 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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) @@ -15410,15 +15439,15 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr) } 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 = tv_list_item_alloc(); li->li_tv.v_type = VAR_STRING; li->li_tv.v_lock = 0; - li->li_tv.vval.v_string = str; + li->li_tv.vval.v_string = (char_u *)p; tv_list_append(rettv->vval.v_list, li); } ga_clear(&ga); @@ -15427,8 +15456,6 @@ 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]; @@ -15442,7 +15469,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) save_cpo = p_cpo; p_cpo = (char_u *)""; - str = get_tv_string(&argvars[0]); + const char *str = tv_get_string(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) { pat = get_tv_string_buf_chk(&argvars[1], patbuf); if (pat == NULL) { @@ -15464,29 +15491,33 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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(®match, 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(®match, (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])) { - tv_list_append_string(rettv->vval.v_list, (const char *)str, 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); @@ -15500,11 +15531,12 @@ 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])); - if (*p == '+') + if (*p == '+') { p = skipwhite(p + 1); - (void) string2float((char *) p, &rettv->vval.v_float); + } + (void)string2float((char *)p, &rettv->vval.v_float); rettv->v_type = VAR_FLOAT; } @@ -15512,7 +15544,6 @@ 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; int what; @@ -15524,22 +15555,26 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - p = skipwhite(get_tv_string(&argvars[0])); + char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0])); if (*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; @@ -15550,17 +15585,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 + } else { seconds = (time_t)get_tv_number(&argvars[1]); + } struct tm curtime; struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime); @@ -15574,23 +15608,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); } @@ -15672,8 +15710,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])); } /* @@ -15681,7 +15718,7 @@ 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); @@ -15694,8 +15731,8 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) } 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((char_u **)&s); + len++; } rettv->vval.v_number = len; } @@ -15706,13 +15743,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) + if (argvars[1].v_type != VAR_UNKNOWN) { col = get_tv_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); } /* @@ -15720,15 +15758,15 @@ 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 *const p = get_tv_string(&argvars[0]); + const char *const p = tv_get_string(&argvars[0]); const size_t slen = STRLEN(p); int nbyte = 0; @@ -15737,7 +15775,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (!error) { if (nchar > 0) { while (nchar > 0 && (size_t)nbyte < slen) { - nbyte += MB_CPTR2LEN(p + nbyte); + nbyte += MB_CPTR2LEN((const char_u *)p + nbyte); nchar--; } } else { @@ -15753,7 +15791,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (off < 0) { len += 1; } else { - len += MB_CPTR2LEN(p + off); + len += (size_t)MB_CPTR2LEN((const char_u *)p + off); } charlen--; } @@ -15776,7 +15814,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } 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); } /* @@ -15784,39 +15822,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; 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 = get_tv_number_chk(&argvars[1], &error); + varnumber_T len; + if (error) { len = 0; - else if (argvars[2].v_type != VAR_UNKNOWN) + } 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 { + 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); } /* @@ -15871,7 +15907,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])); } /* @@ -15962,20 +15998,17 @@ 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 = get_tv_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 = (const char *)get_tv_string_buf(&argvars[2], + (char_u *)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 { @@ -15983,54 +16016,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 = (char_u *)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)); } /* @@ -16147,8 +16182,8 @@ 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; @@ -16359,15 +16394,14 @@ 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(tv_list_alloc_ret(rettv), tag_pattern); + (void)get_tags(tv_list_alloc_ret(rettv), (char_u *)tag_pattern); } /* @@ -16391,7 +16425,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) { @@ -16614,7 +16648,7 @@ 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; } dictitem_T *const di = tv_dict_find(dict, S_LEN("repeat")); @@ -16740,7 +16774,7 @@ void timer_teardown(void) */ static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u *p = vim_strsave(get_tv_string(&argvars[0])); + char_u *p = (char_u *)xstrdup(tv_get_string(&argvars[0])); rettv->v_type = VAR_STRING; rettv->vval.v_string = p; @@ -16772,7 +16806,7 @@ 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 *)strup_save(tv_get_string(&argvars[0])); } /* @@ -16780,56 +16814,48 @@ 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; - 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_u *fromstr = get_tv_string_buf_chk(&argvars[1], buf); + const char_u *tostr = get_tv_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 + } ga_init(&ga, (int)sizeof(char), 80); - if (!has_mbyte) - /* not multi-byte: fromstr and tostr must be the same length */ + 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; + 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; + const char *cpstr = in_str; + const int inlen = (*mb_ptr2len)((const char_u *)in_str); + int cplen = inlen; idx = 0; - for (p = fromstr; *p != NUL; p += fromlen) { + for (const char_u *p = fromstr; *p != NUL; p += fromlen) { fromlen = (*mb_ptr2len)(p); if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) { for (p = tostr; *p != NUL; p += tolen) { tolen = (*mb_ptr2len)(p); if (idx-- == 0) { cplen = tolen; - cpstr = p; + cpstr = (char *)p; break; } } @@ -16841,16 +16867,17 @@ error: } 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) { + // 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 (const char_u *p = tostr; *p != NUL; p += tolen) { tolen = (*mb_ptr2len)(p); - --idx; + idx--; } - if (idx != 0) + if (idx != 0) { goto error; + } } ga_grow(&ga, cplen); @@ -16859,13 +16886,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. + char_u *p = vim_strchr(fromstr, *in_str); + if (p != NULL) { ga_append(&ga, tostr[p - fromstr]); - else + } else { ga_append(&ga, *in_str); - ++in_str; + } + in_str++; } } @@ -16873,6 +16901,11 @@ error: ga_append(&ga, NUL); rettv->vval.v_string = ga.ga_data; + return; +error: + EMSG2(_(e_invarg2), fromstr); + ga_clear(&ga); + return; } /* @@ -16918,20 +16951,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); } } @@ -17290,7 +17321,7 @@ void init_static_list(staticList10_T *sl) /// @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) { @@ -17301,9 +17332,9 @@ static char_u *save_tv_as_string(typval_T *tv, ssize_t *len, bool endnl) // For types other than list, let get_tv_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); + char *ret = (char *)get_tv_string_chk(tv); + if (ret && (*len = strlen(ret))) { + ret = xstrdup(ret); } else { ret = NULL; *len = -1; @@ -17315,17 +17346,17 @@ static char_u *save_tv_as_string(typval_T *tv, ssize_t *len, bool endnl) *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) { @@ -17879,7 +17910,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); } /* @@ -18499,28 +18530,6 @@ static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf) // TODO(ZyX-I): move to eval/typval -/// Get the string value of a variable -/// -/// @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 -/// get_tv_string_buf() if you need to use get_tv_string() output after -/// calling it again. -/// -/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but -/// return NULL on error. -/// -/// @param[in] varp Varible to get value of. -/// -/// @return Variable value if it is VAR_STRING variable, number converted to -/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or empty -/// string. -char_u *get_tv_string(const typval_T *const varp) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT -{ - static char_u mybuf[NUMBUFLEN]; - return get_tv_string_buf(varp, mybuf); -} - char_u *get_tv_string_buf(const typval_T *varp, char_u *buf) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { @@ -18787,7 +18796,7 @@ static hashtab_T *find_var_ht(const char *name, const size_t name_len, /* * 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(const char *const name) @@ -18798,7 +18807,7 @@ char_u *get_var_value(const char *const name) if (v == NULL) { return NULL; } - return get_tv_string(&v->di_tv); + return (char_u *)tv_get_string(&v->di_tv); } /* @@ -19016,9 +19025,9 @@ static void set_var(const char *name, typval_T *const tv, const bool copy) 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; @@ -19439,7 +19448,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); @@ -19461,12 +19469,13 @@ 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; } @@ -21920,8 +21929,9 @@ int store_session_globals(FILE *fd) && 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(get_tv_string(&this_var->di_tv), - (char_u *)"\\\"\n\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'; @@ -21992,7 +22002,7 @@ void ex_oldfiles(exarg_T *eap) 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_outtrans((char_u *)tv_get_string(&li->li_tv)); msg_clr_eos(); msg_putchar('\n'); ui_flush(); /* output one line at a time */ @@ -22007,15 +22017,15 @@ void ex_oldfiles(exarg_T *eap) nr = prompt_for_number(false); msg_starthere(); if (nr > 0 && nr <= l->lv_len) { - char *p = tv_list_find_str(l, nr); + const char *const p = tv_list_find_str(l, nr); if (p == NULL) { return; } - p = (char *)expand_env_save((char_u *)p); - eap->arg = (char_u *)p; + char *const s = (char *)expand_env_save((char_u *)p); + eap->arg = (char_u *)s; eap->cmdidx = CMD_edit; do_exedit(eap, NULL); - xfree(p); + xfree(s); } } } @@ -22728,7 +22738,7 @@ 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, @@ -22750,7 +22760,7 @@ 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) \ if (has_##name == -1) { \ diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 7f6fd76c46..070bc35bd5 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -2,7 +2,7 @@ #define NVIM_EVAL_H #include "nvim/hashtab.h" // For hashtab_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" diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index ab48ace400..41b55e4a57 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -77,10 +77,10 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, if (tv2->v_type == VAR_FLOAT) { break; } - char *s = (char *)get_tv_string(tv1); + const char *tvs = tv_get_string(tv1); char numbuf[NUMBUFLEN]; - s = (char *)concat_str((char_u *)s, - get_tv_string_buf(tv2, (char_u *)numbuf)); + char *const s = (char *)concat_str( + (const char_u *)tvs, get_tv_string_buf(tv2, (char_u *)numbuf)); tv_clear(tv1); tv1->v_type = VAR_STRING; tv1->vval.v_string = (char_u *)s; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 62460bcc3a..cbeb2e059c 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -733,7 +733,7 @@ varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *ret_error) /// @param[in] n Index in a list. /// /// @return [allocated] Copy of the list item string value. -char *tv_list_find_str(list_T *l, int n) +const char *tv_list_find_str(list_T *l, int n) FUNC_ATTR_MALLOC { const listitem_T *const li = tv_list_find(l, n - 1); @@ -741,7 +741,7 @@ char *tv_list_find_str(list_T *l, int n) EMSGN(_(e_listidx), n); return NULL; } - return (char *)get_tv_string(&li->li_tv); + return tv_get_string(&li->li_tv); } /// Locate item in a list and return its index @@ -2014,3 +2014,27 @@ bool tv_check_str_or_nr(const typval_T *const tv) assert(false); return false; } + +//{{{2 Get + +/// Get the string value of a variable +/// +/// @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 +/// get_tv_string_buf() if you need to use tv_get_string() output after +/// calling it again. +/// +/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// return NULL on error. +/// +/// @param[in] varp Varible to get value of. +/// +/// @return Variable value if it is VAR_STRING variable, 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 varp) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT +{ + static char_u mybuf[NUMBUFLEN]; + return (const char *)get_tv_string_buf((typval_T *)varp, mybuf); +} diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 0eef2ddaac..5645772124 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -205,6 +205,8 @@ struct dictvar_S { /// 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; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 87fe52c119..5209dfc451 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -270,7 +270,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); @@ -9347,8 +9347,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 */ diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 7a34a181e2..3f71ae1795 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -1149,23 +1149,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_getln.c b/src/nvim/ex_getln.c index 872b7fe365..3bd8d580ab 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -8,6 +8,7 @@ #include #include +#include "nvim/assert.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/arabic.h" @@ -960,7 +961,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) { @@ -3120,9 +3121,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; @@ -3152,42 +3154,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; @@ -4197,9 +4206,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) { @@ -4237,9 +4248,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. */ diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index d948e20b32..67ac9f9957 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -428,7 +428,7 @@ readfile ( } if (!read_buffer && !read_stdin) { - perm = os_getperm(fname); + 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(). @@ -2606,10 +2606,10 @@ buf_write ( newfile = TRUE; perm = -1; } else { - perm = os_getperm(fname); - if (perm < 0) - newfile = TRUE; - else if (os_isdir(fname)) { + perm = os_getperm((const char *)fname); + if (perm < 0) { + newfile = true; + } else if (os_isdir(fname)) { errnum = (char_u *)"E502: "; errmsg = (char_u *)_("is a directory"); goto fail; @@ -3628,7 +3628,7 @@ restore_backup: close(empty_fd); } if (org != NULL) { - os_setperm((char_u *)org, os_getperm(fname) & 0777); + os_setperm((char_u *)org, os_getperm((const char *)fname) & 0777); xfree(org); } } @@ -4548,9 +4548,9 @@ 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) { int fd_in; int fd_out; @@ -4569,10 +4569,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. @@ -4638,9 +4640,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); @@ -5261,7 +5263,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; @@ -5275,7 +5277,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; } } @@ -5285,9 +5287,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; @@ -5299,7 +5301,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; } diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 076ee13a80..b64f089b96 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -3218,82 +3218,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, false, + 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; } /* diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 19d97ecfef..4cb05ffc12 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -369,7 +369,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 +376,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); diff --git a/src/nvim/message.c b/src/nvim/message.c index bf54284881..423f5a27e7 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -718,7 +718,7 @@ int delete_first_msg(void) void ex_messages(void *const eap_p) FUNC_ATTR_NONNULL_ALL { - exarg_T *eap = (exarg_T *)eap_p; + const exarg_T *const eap = (const exarg_T *)eap_p; struct msg_hist *p; int c = 0; diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index de6167c7fc..259dcc523c 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -147,7 +147,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 +160,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,7 +182,7 @@ 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) { @@ -519,10 +519,10 @@ static void send_error(Channel *channel, uint64_t id, char *err) 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, @@ -532,10 +532,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, @@ -544,7 +544,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; @@ -560,7 +560,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, @@ -728,7 +728,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) diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 5137b375f0..808bb863fd 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -322,7 +322,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); @@ -478,7 +478,7 @@ Object msgpack_rpc_handle_invalid_arguments(uint64_t channel_id, /// 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) diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 4cca5ec948..6ef929120e 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -2075,7 +2075,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) @@ -2089,16 +2088,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); @@ -4757,7 +4756,7 @@ static void nv_ident(cmdarg_T *cap) ptr = vim_strnsave(ptr, n); if (kp_ex) { // Escape the argument properly for an Ex command - p = vim_strsave_fnameescape(ptr, false); + 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); diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 2beeae7ec6..0372bc8a8c 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -91,11 +91,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 +111,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; } @@ -236,7 +236,8 @@ bool os_can_exe(const char_u *name, char_u **abspath, bool use_path) pathext); #else // Must have path separator, cannot execute files in the current directory. - bool ok = gettail_dir(name) != name && is_executable((char *)name); + const bool ok = ((const char_u *)gettail_dir((const char *)name) != name + && is_executable((char *)name)); #endif if (ok) { if (abspath != NULL) { @@ -254,7 +255,7 @@ bool os_can_exe(const char_u *name, char_u **abspath, bool use_path) static bool is_executable(const char *name) FUNC_ATTR_NONNULL_ALL { - int32_t mode = os_getperm((char_u *)name); + int32_t mode = os_getperm((const char *)name); if (mode < 0) { return false; @@ -606,11 +607,11 @@ 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) +int32_t os_getperm(const char *name) FUNC_ATTR_NONNULL_ALL { 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 { @@ -979,13 +980,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 *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 *rfname = NULL; - int len; IShellLinkW *pslw = NULL; WIN32_FIND_DATAW ffdw; @@ -994,7 +995,7 @@ char *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; } @@ -1006,7 +1007,7 @@ char *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)); } @@ -1036,7 +1037,7 @@ char *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)); } diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index ed3410ffe5..acd86f06dc 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -110,14 +110,14 @@ void mch_copy_sec(char_u *from_file, char_u *to_file) // 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) +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) +void mch_set_acl(const char_u *fname, vim_acl_T aclent) { if (aclent == NULL) return; diff --git a/src/nvim/path.c b/src/nvim/path.c index 2bd87b608e..e92261f4fd 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -159,7 +159,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)) { @@ -431,7 +431,7 @@ bool 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) +char *FullName_save(const char *fname, bool force) FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC { if (fname == NULL) { @@ -906,9 +906,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; @@ -1010,18 +1010,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; @@ -1034,7 +1038,7 @@ char_u *gettail_dir(const char_u *fname) } mb_ptr_adv(p); } - return (char_u *)dir_end; + return dir_end; } @@ -1553,8 +1557,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); } diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c index 7670b64468..c72dafd08e 100644 --- a/src/nvim/sha256.c +++ b/src/nvim/sha256.c @@ -259,11 +259,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 +277,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 +308,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 +320,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/shada.c b/src/nvim/shada.c index 2fe042cda8..0f04a5e9cf 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -82,8 +82,6 @@ KHASH_SET_INIT_STR(strset) (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)) diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 56f0350aef..84bee9b97f 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3232,7 +3232,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. @@ -3244,9 +3244,10 @@ 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); + } } tv_list_unref(list); } @@ -5616,7 +5617,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, @@ -5630,13 +5631,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); @@ -5656,9 +5655,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". @@ -5857,27 +5857,31 @@ 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]". diff --git a/src/nvim/strings.c b/src/nvim/strings.c index b964fed35a..9cfa126a56 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -291,30 +291,33 @@ 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 +/// +/// Handels multi-byte characters as good as possible. +/// +/// @param[in] orig Input string. +/// +/// @return [allocated] upper-cased string. +char *strup_save(const char *const orig) 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 c = utf_ptr2char((const char_u *)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); + // 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_u *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l)); + 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); @@ -322,12 +325,13 @@ char_u *strup_save(const char_u *orig) res = s; } - utf_char2bytes(uc, p); + utf_char2bytes(uc, (char_u *)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 + } else if (has_mbyte && (l = (*mb_ptr2len)((const char_u *)p)) > 1) { + p += l; // Skip multi-byte character. + } else { + // note that toupper() can be a macro + *p = (char)(uint8_t)TOUPPER_LOC(*p); p++; } } diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 632a5bf2a5..3f84b8080f 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6930,21 +6930,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 Highilght 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; @@ -6952,39 +6952,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) { @@ -6997,19 +7000,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; @@ -7019,10 +7023,10 @@ 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; } @@ -7133,7 +7137,7 @@ int syn_name2id(const 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; } diff --git a/src/nvim/undo.c b/src/nvim/undo.c index ba687bf6da..010ef2c8fa 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1081,7 +1081,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; } diff --git a/src/nvim/version.c b/src/nvim/version.c index dd583f6ffd..f1d39b8492 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -73,7 +73,7 @@ static char *features[] = { }; // clang-format off -static int included_patches[] = { +static const int included_patches[] = { // 2367,NA // 2366 NA // 2365 NA @@ -2461,10 +2461,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; @@ -2473,7 +2473,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. @@ -2481,7 +2481,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)) { -- cgit From 949f09bdbba592a12629c71e20ff7bb49a21db6c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 21 Aug 2016 08:47:56 +0300 Subject: eval: Move get_tv_string_buf() to eval/typval.c --- src/nvim/eval.c | 184 +++++++++++++++++++++++------------------------ src/nvim/eval/executor.c | 3 +- src/nvim/eval/typval.c | 36 ++++++++-- src/nvim/ex_docmd.c | 13 +++- 4 files changed, 130 insertions(+), 106 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7e40f5e828..d26ff5e41d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3531,8 +3531,6 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) 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]; int ic; /* @@ -3737,31 +3735,33 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) case TYPE_NOMATCH: break; /* avoid gcc warning */ } } else { - s1 = get_tv_string_buf(rettv, buf1); - s2 = get_tv_string_buf(&var2, buf2); + 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, (const char *)s1, (const char *)s2); + i = mb_strcmp_ic((bool)ic, s1, s2); } else { i = 0; } n1 = false; switch (type) { - case TYPE_EQUAL: n1 = (i == 0); break; - case TYPE_NEQUAL: n1 = (i != 0); break; - case TYPE_GREATER: n1 = (i > 0); break; - case TYPE_GEQUAL: n1 = (i >= 0); break; - case TYPE_SMALLER: n1 = (i < 0); break; - case TYPE_SEQUAL: n1 = (i <= 0); break; - - case TYPE_MATCH: - case TYPE_NOMATCH: - 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. } } tv_clear(rettv); @@ -3794,8 +3794,6 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) int op; long n1, n2; float_T f1 = 0, f2 = 0; - char_u *s1, *s2; - char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; char_u *p; /* @@ -3842,14 +3840,17 @@ 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 ? + char buf1[NUMBUFLEN]; + char_u buf2[NUMBUFLEN]; + // s1 already checked + const char *const s1 = tv_get_string_buf(rettv, buf1); + const char *const s2 = (const char *)get_tv_string_buf_chk(&var2, buf2); + if (s2 == NULL) { // Type error? tv_clear(rettv); tv_clear(&var2); return FAIL; } - p = concat_str(s1, s2); + p = concat_str((const char_u *)s1, (const char_u *)s2); tv_clear(rettv); rettv->v_type = VAR_STRING; rettv->vval.v_string = p; @@ -7565,20 +7566,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 = (char_u *)tv_get_string(&argvars[1]); + dbpath = tv_get_string(&argvars[1]); if (argvars[2].v_type != VAR_UNKNOWN) { - prepend = get_tv_string_buf(&argvars[2], buf); + 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 @@ -7661,9 +7663,6 @@ 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 *flags; - rettv->vval.v_number = -1; if (check_restricted() || check_secure()) { return; @@ -7675,19 +7674,21 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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(name) == 0 ? 0 : -1; - } else if (STRCMP(flags, "d") == 0) { + } else if (strcmp(flags, "d") == 0) { // delete an empty directory rettv->vval.v_number = os_rmdir(name) == 0 ? 0 : -1; - } else if (STRCMP(flags, "rf") == 0) { + } else if (strcmp(flags, "rf") == 0) { // delete a directory recursively rettv->vval.v_number = delete_recursive(name); } else { @@ -7905,11 +7906,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( (const char_u *)tv_get_string(&argvars[0]), - get_tv_string_buf(&argvars[1], buf)); + (const char_u *)tv_get_string_buf(&argvars[1], buf)); rettv->v_type = VAR_STRING; } @@ -8253,19 +8254,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 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; + } const char *const keys = tv_get_string(&argvars[0]); - + char nbuf[NUMBUFLEN]; const char *flags = NULL; if (argvars[1].v_type != VAR_UNKNOWN) { - flags = (const char *)get_tv_string_buf(&argvars[1], nbuf); + flags = tv_get_string_buf(&argvars[1], nbuf); } nvim_feedkeys(cstr_as_string((char *)keys), @@ -10740,11 +10740,11 @@ static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *mode; const char *const name = tv_get_string(&argvars[0]); bool abbr = false; - char_u buf[NUMBUFLEN]; + char buf[NUMBUFLEN]; if (argvars[1].v_type == VAR_UNKNOWN) { mode = "nvo"; } else { - mode = (const char *)get_tv_string_buf(&argvars[1], buf); + mode = tv_get_string_buf(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { abbr = get_tv_number(&argvars[2]); } @@ -10763,17 +10763,16 @@ 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 + char_u *str = get_tv_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 = (char_u *)tv_get_string_buf(&argvars[1], buf); if (*str != NUL) { init_history(); add_to_history(histype, str, false, NUL); @@ -10789,7 +10788,6 @@ 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 @@ -10801,11 +10799,12 @@ static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) } 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])); + (int)get_tv_number(&argvars[1])); } else { // string given: remove all matching entries + char buf[NUMBUFLEN]; n = del_history_entry(get_histtype(str, STRLEN(str), false), - get_tv_string_buf(&argvars[1], buf)); + (char_u *)tv_get_string_buf(&argvars[1], buf)); } rettv->vval.v_number = n; } @@ -10895,12 +10894,12 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_string = NULL; const char *const str = tv_get_string(&argvars[0]); - char_u buf1[NUMBUFLEN]; + char buf1[NUMBUFLEN]; char_u *const from = enc_canonize(enc_skip( - get_tv_string_buf(&argvars[1], buf1))); - char_u buf2[NUMBUFLEN]; + (char_u *)tv_get_string_buf(&argvars[1], buf1))); + char buf2[NUMBUFLEN]; char_u *const to = enc_canonize(enc_skip( - get_tv_string_buf(&argvars[2], buf2))); + (char_u *)tv_get_string_buf(&argvars[2], buf2))); vimconv.vc_type = CONV_NONE; convert_setup(&vimconv, from, to); @@ -10983,7 +10982,6 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) char_u *prompt = get_tv_string_chk(&argvars[0]); char_u *p = NULL; int c; - char_u buf[NUMBUFLEN]; int cmd_silent_save = cmd_silent; char_u *defstr = (char_u *)""; int xp_type = EXPAND_NOTHING; @@ -11013,9 +11011,11 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) cmdline_row = msg_row; if (argvars[1].v_type != VAR_UNKNOWN) { + char_u buf[NUMBUFLEN]; defstr = get_tv_string_buf_chk(&argvars[1], buf); - if (defstr != NULL) + if (defstr != NULL) { stuffReadbuffSpec(defstr); + } if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) { char_u *xp_name; @@ -11026,8 +11026,9 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) rettv->vval.v_string = NULL; xp_name = get_tv_string_buf_chk(&argvars[2], buf); - if (xp_name == NULL) + if (xp_name == NULL) { return; + } xp_namelen = (int)STRLEN(xp_name); @@ -11047,9 +11048,11 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) } 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)); + && argvars[2].v_type != VAR_UNKNOWN) { + char buf[NUMBUFLEN]; + rettv->vval.v_string = (char_u *)xstrdup(tv_get_string_buf( + &argvars[2], buf)); + } xfree(xp_arg); @@ -12535,21 +12538,21 @@ 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; 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) { @@ -12557,7 +12560,7 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } 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); @@ -12840,14 +12843,13 @@ 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); + // 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); @@ -13270,14 +13272,13 @@ 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()) { rettv->vval.v_number = -1; } else { + char buf[NUMBUFLEN]; rettv->vval.v_number = vim_rename( - (char_u *)tv_get_string(&argvars[0]), - get_tv_string_buf(&argvars[1], buf)); + (const char_u *)tv_get_string(&argvars[0]), + (const char_u *)tv_get_string_buf(&argvars[1], buf)); } } @@ -16003,8 +16004,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) int modec; if (argvars[2].v_type != VAR_UNKNOWN) { char modebuf[NUMBUFLEN]; - const char *const mode = (const char *)get_tv_string_buf(&argvars[2], - (char_u *)modebuf); + 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. @@ -18530,14 +18530,6 @@ static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf) // TODO(ZyX-I): move to eval/typval -char_u *get_tv_string_buf(const typval_T *varp, char_u *buf) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT -{ - char_u *const 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 FUNC_ATTR_WARN_UNUSED_RESULT diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index 41b55e4a57..d2d0873792 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -80,7 +80,8 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *tvs = tv_get_string(tv1); char numbuf[NUMBUFLEN]; char *const s = (char *)concat_str( - (const char_u *)tvs, get_tv_string_buf(tv2, (char_u *)numbuf)); + (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; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index cbeb2e059c..2c2d0ecaab 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1127,7 +1127,7 @@ const char *tv_dict_get_string_buf(dict_T *const d, const char *const key, if (di == NULL) { return NULL; } - return (const char *)get_tv_string_buf(&di->di_tv, (char_u *)numbuf); + return tv_get_string_buf(&di->di_tv, numbuf); } /// Get a function from a dictionary @@ -1948,8 +1948,8 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, case VAR_STRING: { char buf1[NUMBUFLEN]; char buf2[NUMBUFLEN]; - const char *s1 = (const char *)get_tv_string_buf(tv1, (char_u *)buf1); - const char *s2 = (const char *)get_tv_string_buf(tv2, (char_u *)buf2); + 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: { @@ -2021,7 +2021,7 @@ bool tv_check_str_or_nr(const typval_T *const tv) /// /// @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 -/// get_tv_string_buf() if you need to use tv_get_string() output after +/// tv_get_string_buf() if you need to use tv_get_string() output after /// calling it again. /// /// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but @@ -2035,6 +2035,30 @@ bool tv_check_str_or_nr(const typval_T *const tv) const char *tv_get_string(const typval_T *const varp) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { - static char_u mybuf[NUMBUFLEN]; - return (const char *)get_tv_string_buf((typval_T *)varp, mybuf); + static char mybuf[NUMBUFLEN]; + return tv_get_string_buf((typval_T *)varp, mybuf); +} + +/// Get the string value of a variable +/// +/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// return NULL on error. +/// +/// @param[in] varp Varible 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 Variable value if it is VAR_STRING variable, 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 varp, char *const buf) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT +{ + const char *const res = (const char *)get_tv_string_buf_chk( + (typval_T *)varp, (char_u *)buf); + + return res != NULL ? res : ""; } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 5209dfc451..6b661cff11 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7724,7 +7724,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); @@ -7836,10 +7836,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; } -- cgit From 7ee5cc7429017a4a08a8b62b628bea156fea0008 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 28 Aug 2016 08:09:29 +0300 Subject: eval: Move get_tv_lnum and get_tv_float to eval/typval.h Additionally - Rename former tv_get_float to tv_get_float_chk due to name conflict (former get_tv_float is better suited for being tv_get_float). - Add E907 error to get_tv_float() and test that it is being raised when appropriate. --- src/nvim/eval.c | 261 ++++++++++++++++++++----------------------------- src/nvim/eval/typval.c | 94 +++++++++++++++--- src/nvim/eval/typval.h | 9 +- 3 files changed, 193 insertions(+), 171 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d26ff5e41d..6307dd8abc 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6498,7 +6498,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 (tv_get_float(argvars, &f)) { + if (tv_get_float_chk(argvars, &f)) { rettv->vval.v_float = function(f); } else { rettv->vval.v_float = 0.0; @@ -6610,7 +6610,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) { @@ -6957,7 +6957,7 @@ static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr) float_T fy; rettv->v_type = VAR_FLOAT; - if (tv_get_float(argvars, &fx) && tv_get_float(&argvars[1], &fy)) { + if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) { rettv->vval.v_float = atan2(fx, fy); } else { rettv->vval.v_float = 0.0; @@ -7333,7 +7333,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(); @@ -7613,7 +7613,7 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr) set_curswant = false; } } else { - line = get_tv_lnum(argvars); + line = tv_get_lnum(argvars); col = get_tv_number_chk(&argvars[1], NULL); if (argvars[2].v_type != VAR_UNKNOWN) { coladd = get_tv_number_chk(&argvars[2], NULL); @@ -7808,7 +7808,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)); } /* @@ -7816,7 +7816,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; @@ -8557,7 +8557,7 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { float_T f; - if (tv_get_float(argvars, &f)) { + if (tv_get_float_chk(argvars, &f)) { if (f < VARNUMBER_MIN) { rettv->vval.v_number = VARNUMBER_MIN; } else if (f > VARNUMBER_MAX) { @@ -8577,7 +8577,7 @@ static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr) float_T fy; rettv->v_type = VAR_FLOAT; - if (tv_get_float(argvars, &fx) && tv_get_float(&argvars[1], &fy)) { + if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) { rettv->vval.v_float = fmod(fx, fy); } else { rettv->vval.v_float = 0.0; @@ -8629,16 +8629,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; } } @@ -8666,11 +8666,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); + } } /* @@ -8734,7 +8733,6 @@ 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]; foldinfo_T foldinfo; @@ -8742,10 +8740,11 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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, @@ -9782,17 +9781,16 @@ 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); @@ -10920,13 +10918,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; + } } /* @@ -11975,15 +11972,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++; + } } /* @@ -11991,17 +11988,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; + } } /* @@ -12746,13 +12741,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; } @@ -12812,7 +12808,7 @@ static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr) float_T fy; rettv->v_type = VAR_FLOAT; - if (tv_get_float(argvars, &fx) && tv_get_float(&argvars[1], &fy)) { + if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) { rettv->vval.v_float = pow(fx, fy); } else { rettv->vval.v_float = 0.0; @@ -12824,14 +12820,14 @@ 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; } @@ -14428,14 +14424,13 @@ 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]); if (argvars[1].v_type == VAR_LIST) { l = argvars[1].vval.v_list; li = l->lv_first; @@ -15017,8 +15012,8 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero) } 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; } @@ -15977,19 +15972,18 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "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; - bool transerr = false; + // -1 on type error (both) + const linenr_T lnum = tv_get_lnum(argvars); + const colnr_T col = (colnr_T)get_tv_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 = get_tv_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; } @@ -16090,8 +16084,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; @@ -16100,15 +16092,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)get_tv_number(&argvars[1]) - 1; memset(str, NUL, sizeof(str)); 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 @@ -16137,21 +16130,19 @@ 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)get_tv_number(&argvars[1]) - 1; if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count && col >= 0 - && col <= (long)STRLEN(ml_get(lnum))) { + && (size_t)col <= STRLEN(ml_get(lnum))) { tv_list_alloc_ret(rettv); - (void)syn_get_id(curwin, lnum, (colnr_T)col, false, NULL, true); + (void)syn_get_id(curwin, lnum, col, false, NULL, true); int id; int i = 0; @@ -17457,31 +17448,35 @@ static void f_xor(typval_T *argvars, typval_T *rettv, FunPtr fptr) } -/* - * 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; 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 = tv_list_find_nr(l, 0L, &error); @@ -17521,20 +17516,24 @@ var2fpos ( return &pos; } - name = get_tv_string_chk(varp); - if (name == NULL) + name = get_tv_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, name[1], false, ret_fnum); + if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) { return NULL; + } return pp; } @@ -18465,54 +18464,6 @@ varnumber_T get_tv_number_chk(const typval_T *const varp, bool *const denote) 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; - tv_clear(&rettv); - } - return lnum; -} - /* * Get the lnum from the first argument. * Also accepts "$", then "buf" is used. diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 2c2d0ecaab..6a16b3869a 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -16,6 +16,7 @@ #include "nvim/hashtab.h" #include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/pos.h" // TODO(ZyX-I): Move line_breakcheck out of misc1 #include "nvim/misc1.h" // For line_breakcheck @@ -1730,11 +1731,11 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, /// Free memory for a variable value and set the value to NULL or 0 /// -/// @param[in,out] varp Value to free. -void tv_clear(typval_T *varp) +/// @param[in,out] tv Value to free. +void tv_clear(typval_T *tv) { - if (varp != NULL && varp->v_type != VAR_UNKNOWN) { - const int evn_ret = encode_vim_to_nothing(varp, varp, "tv_clear argument"); + if (tv != NULL && tv->v_type != VAR_UNKNOWN) { + const int evn_ret = encode_vim_to_nothing(NULL, tv, "tv_clear argument"); (void)evn_ret; assert(evn_ret == OK); } @@ -2017,7 +2018,72 @@ bool tv_check_str_or_nr(const typval_T *const tv) //{{{2 Get -/// Get the string value of a variable +/// 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) +{ + linenr_T lnum = get_tv_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) +{ + switch (tv->v_type) { + case VAR_NUMBER: { + return (float_T)(tv->vval.v_number); + } + case VAR_FLOAT: { + return tv->vval.v_float; + } + case VAR_PARTIAL: + case VAR_FUNC: { + EMSG(_("E891: Using a Funcref as a Float")); + break; + } + case VAR_STRING: { + EMSG(_("E892: Using a String as a Float")); + break; + } + case VAR_LIST: { + EMSG(_("E893: Using a List as a Float")); + break; + } + case VAR_DICT: { + EMSG(_("E894: Using a Dictionary as a Float")); + break; + } + case VAR_SPECIAL: { + EMSG(_("E907: Using a special value as a Float")); + break; + } + case VAR_UNKNOWN: { + EMSG2(_(e_intern2), "get_tv_float()"); + break; + } + } + return 0; +} + +/// 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 @@ -2027,38 +2093,38 @@ bool tv_check_str_or_nr(const typval_T *const tv) /// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but /// return NULL on error. /// -/// @param[in] varp Varible to get value of. +/// @param[in] tv Object to get value of. /// -/// @return Variable value if it is VAR_STRING variable, number converted to +/// @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 varp) +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 *)varp, mybuf); + return tv_get_string_buf((typval_T *)tv, mybuf); } -/// Get the string value of a variable +/// Get the string value of a VimL object /// /// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but /// return NULL on error. /// -/// @param[in] varp Varible to get value of. +/// @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 Variable value if it is VAR_STRING variable, number converted to +/// @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 varp, char *const buf) +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 *)get_tv_string_buf_chk( - (typval_T *)varp, (char_u *)buf); + (typval_T *)tv, (char_u *)buf); return res != NULL ? res : ""; } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 5645772124..3c294b45b8 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -14,6 +14,7 @@ #include "nvim/profile.h" // for proftime_T #include "nvim/pos.h" // for linenr_T #include "nvim/gettext.h" +#include "nvim/message.h" /// Type used for VimL VAR_NUMBER values typedef int varnumber_T; @@ -373,7 +374,8 @@ extern bool tv_in_free_unref_items; } \ }) -static inline bool tv_get_float(const typval_T *const tv, float_T *const ret_f) +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. @@ -381,11 +383,14 @@ 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(const typval_T *const tv, float_T *const ret_f) +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; -- cgit From 1b3e13da5be48739ac4291208e421b68e607cc0f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 28 Aug 2016 08:18:29 +0300 Subject: eval: Refactor get_tv_lnum_buf --- src/nvim/eval.c | 50 +++++++++++++++++++++++++++----------------------- src/nvim/eval/typval.c | 2 ++ 2 files changed, 29 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6307dd8abc..2a7314d969 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -9190,13 +9190,34 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli } } +/// 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 get_tv_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 = NULL; if (tv_check_str_or_nr(&argvars[0])) { @@ -9205,12 +9226,10 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); } @@ -18464,21 +18483,6 @@ varnumber_T get_tv_number_chk(const typval_T *const varp, bool *const denote) return n; } -/* - * 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); -} - // TODO(ZyX-I): move to eval/typval /// Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE! diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 6a16b3869a..38032762dc 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2026,6 +2026,7 @@ bool tv_check_str_or_nr(const typval_T *const tv) /// /// @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 = get_tv_number_chk(tv, NULL); if (lnum == 0) { // No valid number, try using same function as line() does. @@ -2046,6 +2047,7 @@ linenr_T tv_get_lnum(const typval_T *const tv) /// /// @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: { -- cgit From 233b0c93bba66492d7b8b61f8ac61082f03668a1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 28 Aug 2016 08:55:58 +0300 Subject: eval: Move get_tv_number[_chk] to eval/typval.c --- src/nvim/eval.c | 659 ++++++++++++++++++++++------------------------- src/nvim/eval/executor.c | 8 +- src/nvim/eval/typval.c | 130 +++++++++- src/nvim/strings.c | 2 +- src/nvim/window.c | 20 +- 5 files changed, 446 insertions(+), 373 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2a7314d969..676df1a301 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -954,7 +954,7 @@ eval_to_bool ( } else { *error = false; if (!skip) { - retval = (get_tv_number_chk(&tv, error) != 0); + retval = (tv_get_number_chk(&tv, error) != 0); tv_clear(&tv); } } @@ -1081,10 +1081,10 @@ int eval_to_number(char_u *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); + } else { + retval = tv_get_number_chk(&rettv, NULL); tv_clear(&rettv); } --emsg_off; @@ -1174,9 +1174,10 @@ int get_spellword(list_T *list, const char **pp) *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); + } + return tv_get_number(&li->li_tv); } /* @@ -1284,7 +1285,7 @@ call_func_retnr ( if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL) return -1; - retval = get_tv_number_chk(&rettv, NULL); + retval = tv_get_number_chk(&rettv, NULL); tv_clear(&rettv); return retval; } @@ -1912,7 +1913,6 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, && vim_strchr(endchars, *skipwhite((const char_u *)p)) == NULL)) { EMSG(_(e_letunexp)); } else { - long n; int opt_type; long numval; char_u *stringval = NULL; @@ -1921,8 +1921,8 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, 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); + s = get_tv_string_chk(tv); // != NULL if number or string. if (s != NULL && op != NULL && *op != '=') { opt_type = get_option_value(arg, &numval, &stringval, opt_flags); if ((opt_type == 1 && *op == '.') @@ -2284,13 +2284,11 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, } lp->ll_tv = &lp->ll_di->di_tv; } else { - /* - * Get the number and item for the only or first index of the List. - */ + // 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. + lp->ll_n1 = tv_get_number(&var1); // Is number or string. tv_clear(&var1); } lp->ll_dict = NULL; @@ -2319,7 +2317,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, * 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. + lp->ll_n2 = tv_get_number(&var2); // Is number or string. tv_clear(&var2); if (lp->ll_n2 < 0) { ni = tv_list_find(lp->ll_list, lp->ll_n2); @@ -3320,7 +3318,7 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate) if (evaluate) { bool error = false; - if (get_tv_number_chk(rettv, &error) != 0) { + if (tv_get_number_chk(rettv, &error) != 0) { result = true; } tv_clear(rettv); @@ -3395,7 +3393,7 @@ 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) { + if (tv_get_number_chk(rettv, &error) != 0) { result = true; } tv_clear(rettv); @@ -3416,7 +3414,7 @@ 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) { + if (tv_get_number_chk(&var2, &error) != 0) { result = true; } tv_clear(&var2); @@ -3464,7 +3462,7 @@ 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) { + if (tv_get_number_chk(rettv, &error) == 0) { result = false; } tv_clear(rettv); @@ -3485,7 +3483,7 @@ 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) { + if (tv_get_number_chk(&var2, &error) == 0) { result = false; } tv_clear(&var2); @@ -3694,25 +3692,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; } } /* @@ -3721,18 +3721,18 @@ 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 { char buf1[NUMBUFLEN]; @@ -3872,7 +3872,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) 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 @@ -3887,7 +3887,7 @@ 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) { tv_clear(rettv); tv_clear(&var2); @@ -3968,8 +3968,9 @@ eval6 ( f1 = rettv->vval.v_float; use_float = TRUE; n1 = 0; - } else - n1 = get_tv_number_chk(rettv, &error); + } else { + n1 = tv_get_number_chk(rettv, &error); + } tv_clear(rettv); if (error) { return FAIL; @@ -3994,7 +3995,7 @@ eval6 ( f2 = var2.vval.v_float; n2 = 0; } else { - n2 = get_tv_number_chk(&var2, &error); + n2 = tv_get_number_chk(&var2, &error); tv_clear(&var2); if (error) { return FAIL; @@ -4296,7 +4297,7 @@ static int eval7( 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) { tv_clear(rettv); @@ -4457,14 +4458,14 @@ eval_index ( if (evaluate) { n1 = 0; if (!empty1 && rettv->v_type != VAR_DICT) { - n1 = get_tv_number(&var1); + n1 = tv_get_number(&var1); tv_clear(&var1); } if (range) { if (empty2) { n2 = -1; } else { - n2 = get_tv_number(&var2); + n2 = tv_get_number(&var2); tv_clear(&var2); } } @@ -6543,13 +6544,14 @@ static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr) varnumber_T n; 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; + } } } @@ -6578,8 +6580,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); } @@ -6680,11 +6682,13 @@ 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 = 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 { tv_list_alloc_ret(rettv); @@ -6855,9 +6859,9 @@ static void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr) void assert_inrange(typval_T *argvars) { bool error = false; - const varnumber_T lower = get_tv_number_chk(&argvars[0], &error); - const varnumber_T upper = get_tv_number_chk(&argvars[1], &error); - const varnumber_T actual = get_tv_number_chk(&argvars[2], &error); + 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; @@ -6884,7 +6888,7 @@ static void assert_bool(typval_T *argvars, bool is_true) 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 @@ -7118,7 +7122,7 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) // new buffer. 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) { @@ -7176,7 +7180,7 @@ 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 = get_tv_number(&argvars[0]) - 1; + long boff = tv_get_number(&argvars[0]) - 1; if (boff < 0) { rettv->vval.v_number = -1; } else { @@ -7192,7 +7196,7 @@ static void byteidx(typval_T *argvars, typval_T *rettv, int comp) long idx; str = get_tv_string_chk(&argvars[0]); - idx = get_tv_number_chk(&argvars[1], NULL); + idx = tv_get_number_chk(&argvars[1], NULL); rettv->vval.v_number = -1; if (str == NULL || idx < 0) return; @@ -7314,7 +7318,7 @@ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) int utf8 = 0; if (argvars[1].v_type != VAR_UNKNOWN) { - utf8 = get_tv_number_chk(&argvars[1], NULL); + utf8 = tv_get_number_chk(&argvars[1], NULL); } rettv->vval.v_number = (utf8 ? *utf_ptr2char : *mb_ptr2char)( @@ -7392,8 +7396,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; @@ -7409,9 +7411,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 int startcol = tv_get_number_chk(&argvars[0], NULL); + if (startcol <= 0) { return; + } set_completion(startcol - 1, argvars[1].vval.v_list); } @@ -7459,7 +7462,7 @@ static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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) @@ -7511,9 +7514,9 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[2].v_type != VAR_UNKNOWN) { 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 = tv_list_find(l, idx); if (li == NULL) { @@ -7538,9 +7541,10 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -7572,7 +7576,7 @@ static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_UNKNOWN) { - num = (int)get_tv_number(&argvars[0]); + 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); @@ -7614,9 +7618,9 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } else { line = tv_get_lnum(argvars); - col = get_tv_number_chk(&argvars[1], NULL); + col = tv_get_number_chk(&argvars[1], NULL); if (argvars[2].v_type != VAR_UNKNOWN) { - coladd = get_tv_number_chk(&argvars[2], NULL); + coladd = tv_get_number_chk(&argvars[2], NULL); } } if (line < 0 || col < 0 @@ -7649,10 +7653,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() @@ -7851,11 +7856,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; } @@ -8123,7 +8129,7 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -8145,8 +8151,9 @@ 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; @@ -8191,9 +8198,10 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, arg_errmsg_len) && l2 != NULL) { if (argvars[2].v_type != VAR_UNKNOWN) { - before = get_tv_number_chk(&argvars[2], &error); - if (error) - return; /* type error; errmsg already given */ + before = tv_get_number_chk(&argvars[2], &error); + if (error) { + return; // Type error; errmsg already given. + } if (before == l1->lv_len) { item = NULL; @@ -8315,7 +8323,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) path = p; if (argvars[2].v_type != VAR_UNKNOWN) { - count = get_tv_number_chk(&argvars[2], &error); + count = tv_get_number_chk(&argvars[2], &error); } } } @@ -8512,10 +8520,10 @@ static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) bool error = false; // filter(): when expr is zero remove the item - *remp = (get_tv_number_chk(&rettv, &error) == 0); + *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 get_tv_number_chk(). + // loop. The error message was given by tv_get_number_chk(). if (error) { goto theend; } @@ -8946,12 +8954,13 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr 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; + } } /* @@ -8969,7 +8978,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) if ((l = argvars[0].vval.v_list) != NULL) { bool error = false; - li = tv_list_find(l, get_tv_number_chk(&argvars[1], &error)); + li = tv_list_find(l, tv_get_number_chk(&argvars[1], &error)); if (!error && li != NULL) { tv = &li->li_tv; } @@ -9110,23 +9119,24 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) filtered = true; di = tv_dict_find(sel_d, S_LEN("buflisted")); - if (di != NULL && get_tv_number(&di->di_tv)) { + if (di != NULL && tv_get_number(&di->di_tv)) { sel_buflisted = true; } di = tv_dict_find(sel_d, S_LEN("bufloaded")); - if (di != NULL && get_tv_number(&di->di_tv)) { + 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; + } } } @@ -9210,7 +9220,7 @@ static linenr_T tv_get_lnum_buf(const typval_T *const tv, && buf != NULL) { return buf->b_ml.ml_line_count; } - return get_tv_number_chk(tv, NULL); + return tv_get_number_chk(tv, NULL); } /* @@ -9321,7 +9331,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) { @@ -9332,8 +9342,9 @@ 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--; @@ -9460,7 +9471,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) { @@ -9970,9 +9981,9 @@ static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) strregname = get_tv_string_chk(&argvars[0]); error = strregname == NULL; if (argvars[1].v_type != VAR_UNKNOWN) { - arg2 = get_tv_number_chk(&argvars[1], &error); + 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 { @@ -10062,7 +10073,7 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; } @@ -10099,7 +10110,7 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_string = NULL; const char *const varname = (const char *)get_tv_string_chk(&argvars[1]); - tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); + 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. @@ -10216,7 +10227,7 @@ find_win_by_nr ( tabpage_T *tp /* NULL for current tab page */ ) { - int nr = (int)get_tv_number_chk(vp, NULL); + int nr = (int)tv_get_number_chk(vp, NULL); if (nr < 0) { return NULL; @@ -10251,7 +10262,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); } @@ -10291,10 +10302,11 @@ getwinvar ( 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); const char *varname = (const char *)get_tv_string_chk( &argvars[off + 1]); @@ -10363,15 +10375,16 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr) * 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; } } @@ -10410,17 +10423,17 @@ 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; } } @@ -10763,7 +10776,7 @@ static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { mode = tv_get_string_buf(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { - abbr = get_tv_number(&argvars[2]); + abbr = tv_get_number(&argvars[2]); } } @@ -10816,7 +10829,7 @@ static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) } 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])); + (int)tv_get_number(&argvars[1])); } else { // string given: remove all matching entries char buf[NUMBUFLEN]; @@ -10843,7 +10856,7 @@ static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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)); @@ -10968,12 +10981,14 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr) // 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, get_tv_number_chk(&argvars[2], &error)); + 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) @@ -11186,7 +11201,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { 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 @@ -11213,7 +11228,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); } /* @@ -12051,9 +12066,10 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) if (argvars[1].v_type != VAR_UNKNOWN) { which = get_tv_string_buf_chk(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { - abbr = get_tv_number(&argvars[2]); - if (argvars[3].v_type != VAR_UNKNOWN) - get_dict = get_tv_number(&argvars[3]); + abbr = tv_get_number(&argvars[2]); + if (argvars[3].v_type != VAR_UNKNOWN) { + get_dict = tv_get_number(&argvars[3]); + } } } else which = (char_u *)""; @@ -12175,9 +12191,10 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type) if (argvars[2].v_type != VAR_UNKNOWN) { 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 = tv_list_find(l, start); if (li == NULL) { @@ -12200,10 +12217,12 @@ 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); @@ -12331,9 +12350,9 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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)); @@ -12387,9 +12406,9 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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)); @@ -12424,7 +12443,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr) { 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; @@ -12446,7 +12465,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); } /* @@ -12493,14 +12512,16 @@ static void max_min(typval_T *argvars, typval_T *rettv, int domax) if (l != NULL) { li = l->lv_first; if (li != NULL) { - n = get_tv_number_chk(&li->li_tv, &error); + n = tv_get_number_chk(&li->li_tv, &error); for (;; ) { li = li->li_next; - if (li == NULL) + if (li == NULL) { break; - i = get_tv_number_chk(&li->li_tv, &error); - if (domax ? i > n : i < n) + } + i = tv_get_number_chk(&li->li_tv, &error); + if (domax ? i > n : i < n) { n = i; + } } } } @@ -12516,7 +12537,7 @@ static void max_min(typval_T *argvars, typval_T *rettv, int domax) for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) { todo--; - i = get_tv_number_chk(&TV_DICT_HI2DI(hi)->di_tv, &error); + i = tv_get_number_chk(&TV_DICT_HI2DI(hi)->di_tv, &error); if (first) { n = i; first = FALSE; @@ -12570,7 +12591,7 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_UNKNOWN) { - prot = get_tv_number_chk(&argvars[2], NULL); + prot = tv_get_number_chk(&argvars[2], NULL); } if (prot != -1 && strcmp(tv_get_string(&argvars[1]), "p") == 0) { char *failed_dir; @@ -12782,14 +12803,16 @@ static void f_nr2char(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 (utf8) - buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; - else - buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; + if (argvars[1].v_type != VAR_UNKNOWN) { + utf8 = tv_get_number_chk(&argvars[1], NULL); + } + if (utf8) { + buf[(*utf_char2bytes)((int)tv_get_number(&argvars[0]), buf)] = NUL; + } else { + buf[(*mb_char2bytes)((int)tv_get_number(&argvars[0]), buf)] = NUL; + } } else { - buf[0] = (char_u)get_tv_number(&argvars[0]); + buf[0] = (char_u)tv_get_number(&argvars[0]); buf[1] = NUL; } rettv->v_type = VAR_STRING; @@ -12801,8 +12824,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); } /* @@ -12911,14 +12934,15 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) long 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) { @@ -12959,7 +12983,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) binary = true; } if (argvars[2].v_type != VAR_UNKNOWN) { - maxline = get_tv_number(&argvars[2]); + maxline = tv_get_number(&argvars[2]); } } @@ -13239,7 +13263,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { bool error = false; - idx = get_tv_number_chk(&argvars[1], &error); + 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) { @@ -13251,8 +13275,8 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) *rettv = item->li_tv; xfree(item); } else { - /* Remove range of items, return list with values. */ - end = get_tv_number_chk(&argvars[2], &error); + // 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) { @@ -13302,7 +13326,7 @@ static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - varnumber_T n = get_tv_number(&argvars[1]); + varnumber_T n = tv_get_number(&argvars[1]); if (argvars[0].v_type == VAR_LIST) { tv_list_alloc_ret(rettv); while (n-- > 0) { @@ -13621,13 +13645,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; + } } } @@ -13889,17 +13915,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; } @@ -13908,17 +13933,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]; @@ -13969,9 +13992,10 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u *name = get_tv_string_chk(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) { - locally = get_tv_number_chk(&argvars[1], &error) == 0; - if (!error && argvars[2].v_type != VAR_UNKNOWN) - thisblock = get_tv_number_chk(&argvars[2], &error) != 0; + 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, @@ -14027,13 +14051,15 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) else { skip = get_tv_string_buf_chk(&argvars[4], nbuf3); if (argvars[5].v_type != VAR_UNKNOWN) { - lnum_stop = get_tv_number_chk(&argvars[5], NULL); - if (lnum_stop < 0) + 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; + } } } } @@ -14337,7 +14363,7 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) aucmd_prepbuf(&aco, buf); varname++; - numval = get_tv_number_chk(varp, &error); + numval = tv_get_number_chk(varp, &error); char *const strval = (char *)get_tv_string_buf_chk(varp, nbuf); if (!error && strval != NULL) { set_option_value(varname, numval, strval, OPT_LOCAL); @@ -14385,12 +14411,12 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr) di = tv_dict_find(d, S_LEN("forward")); if (di != NULL) { - set_csearch_direction(get_tv_number(&di->di_tv) ? FORWARD : BACKWARD); + set_csearch_direction(tv_get_number(&di->di_tv) ? FORWARD : BACKWARD); } di = tv_dict_find(d, S_LEN("until")); if (di != NULL) { - set_csearch_until(!!get_tv_number(&di->di_tv)); + set_csearch_until(!!tv_get_number(&di->di_tv)); } } } @@ -14400,10 +14426,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); + } } @@ -14854,7 +14881,7 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - tabpage_T *const tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); + tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); const char *const varname = (const char *)get_tv_string_chk(&argvars[1]); typval_T *const varp = &argvars[2]; @@ -14904,7 +14931,7 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off) tabpage_T *tp = NULL; if (off == 1) { - tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); + tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); } else { tp = curtab; } @@ -14923,7 +14950,7 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off) bool error = false; varname++; - numval = get_tv_number_chk(varp, &error); + numval = tv_get_number_chk(varp, &error); char_u nbuf[NUMBUFLEN]; char *const strval = (char *)get_tv_string_buf_chk(varp, nbuf); if (!error && strval != NULL) { @@ -15024,8 +15051,8 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero) typval_T *tv2 = &si2->item->li_tv; 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; } @@ -15138,7 +15165,7 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) 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 @@ -15220,7 +15247,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } else { 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 } @@ -15443,13 +15470,15 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) { 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; @@ -15491,7 +15520,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) typeerr = true; } if (argvars[2].v_type != VAR_UNKNOWN) { - keepempty = (bool)get_tv_number_chk(&argvars[2], &typeerr); + keepempty = (bool)tv_get_number_chk(&argvars[2], &typeerr); } } if (pat == NULL || *pat == NUL) @@ -15563,7 +15592,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -15608,7 +15637,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[1].v_type == VAR_UNKNOWN) { seconds = time(NULL); } else { - seconds = (time_t)get_tv_number(&argvars[1]); + seconds = (time_t)tv_get_number(&argvars[1]); } struct tm curtime; @@ -15658,9 +15687,8 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (str == NULL) { return; } - bool error = false; - varnumber_T charidx = get_tv_number_chk(&argvars[1], &error); + varnumber_T charidx = tv_get_number_chk(&argvars[1], &error); if (error) { return; } @@ -15699,11 +15727,13 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[2].v_type != VAR_UNKNOWN) { bool error = false; - start_idx = get_tv_number_chk(&argvars[2], &error); - if (error || start_idx >= (int)STRLEN(haystack)) + start_idx = tv_get_number_chk(&argvars[2], &error); + if (error || start_idx >= (int)STRLEN(haystack)) { return; - if (start_idx >= 0) + } + if (start_idx >= 0) { haystack += start_idx; + } } pos = (char_u *)strstr((char *)haystack, (char *)needle); @@ -15739,7 +15769,7 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) int (*func_mb_ptr2char_adv)(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)); @@ -15762,7 +15792,7 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) int col = 0; if (argvars[1].v_type != VAR_UNKNOWN) { - col = get_tv_number(&argvars[1]); + col = tv_get_number(&argvars[1]); } rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char_u *)s) - col); @@ -15786,7 +15816,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) int nbyte = 0; bool error = false; - varnumber_T nchar = get_tv_number_chk(&argvars[1], &error); + varnumber_T nchar = tv_get_number_chk(&argvars[1], &error); if (!error) { if (nchar > 0) { while (nchar > 0 && (size_t)nbyte < slen) { @@ -15799,7 +15829,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) } int len = 0; if (argvars[2].v_type != VAR_UNKNOWN) { - int charlen = get_tv_number(&argvars[2]); + int charlen = tv_get_number(&argvars[2]); while (charlen > 0 && nbyte + len < (int)slen) { int off = nbyte + len; @@ -15842,12 +15872,12 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *const p = tv_get_string(&argvars[0]); const size_t slen = strlen(p); - varnumber_T n = get_tv_number_chk(&argvars[1], &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]); + len = tv_get_number(&argvars[2]); } else { len = slen - n; // Default len: all bytes that are available. } @@ -15891,12 +15921,14 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) haystack_len = (int)STRLEN(haystack); if (argvars[2].v_type != VAR_UNKNOWN) { - /* Third argument: upper limit for index */ - end_idx = get_tv_number_chk(&argvars[2], NULL); - if (end_idx < 0) - return; /* can never find a match */ - } else + // Third argument: upper limit for index. + end_idx = tv_get_number_chk(&argvars[2], NULL); + if (end_idx < 0) { + return; // Can never find a match. + } + } else { end_idx = haystack_len; + } if (*needle == NUL) { /* Empty string matches past the end. */ @@ -15931,7 +15963,7 @@ static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr) { bool error = false; - int no = (int)get_tv_number_chk(&argvars[0], &error); + int no = (int)tv_get_number_chk(&argvars[0], &error); if (error) { return; } @@ -15943,7 +15975,7 @@ static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; } @@ -15993,10 +16025,10 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr) { // -1 on type error (both) const linenr_T lnum = tv_get_lnum(argvars); - const colnr_T col = (colnr_T)get_tv_number(&argvars[1]) - 1; + const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1; bool transerr = false; - const int trans = get_tv_number_chk(&argvars[2], &transerr); + const int trans = tv_get_number_chk(&argvars[2], &transerr); int id = 0; if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count @@ -16012,7 +16044,7 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - const int id = get_tv_number(&argvars[0]); + const int id = (int)tv_get_number(&argvars[0]); const char *const what = tv_get_string(&argvars[1]); int modec; if (argvars[2].v_type != VAR_UNKNOWN) { @@ -16086,14 +16118,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; } @@ -16113,7 +16144,7 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) // -1 on type error (both) const linenr_T lnum = tv_get_lnum(argvars); - const colnr_T col = (colnr_T)get_tv_number(&argvars[1]) - 1; + const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1; memset(str, NUL, sizeof(str)); @@ -16154,7 +16185,7 @@ static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) // -1 on type error (both) const linenr_T lnum = tv_get_lnum(argvars); - const colnr_T col = (colnr_T)get_tv_number(&argvars[1]) - 1; + const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1; if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count @@ -16232,7 +16263,7 @@ 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(res, nread, (bool)keepempty); rettv->vval.v_list->lv_refcount++; @@ -16277,15 +16308,15 @@ 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) { tv_list_alloc_ret(rettv); @@ -16367,13 +16398,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; } @@ -16648,7 +16678,7 @@ static bool set_ref_in_callback(Callback *callback, int copyID, /// "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; @@ -16663,7 +16693,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) } dictitem_T *const di = tv_dict_find(dict, S_LEN("repeat")); if (di != NULL) { - repeat = get_tv_number(&di->di_tv); + repeat = tv_get_number(&di->di_tv); if (repeat == 0) { repeat = 1; } @@ -16703,7 +16733,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; @@ -17177,29 +17207,29 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { dictitem_T *di; if ((di = tv_dict_find(dict, S_LEN("lnum"))) != NULL) { - curwin->w_cursor.lnum = get_tv_number(&di->di_tv); + curwin->w_cursor.lnum = tv_get_number(&di->di_tv); } if ((di = tv_dict_find(dict, S_LEN("col"))) != NULL) { - curwin->w_cursor.col = get_tv_number(&di->di_tv); + curwin->w_cursor.col = tv_get_number(&di->di_tv); } if ((di = tv_dict_find(dict, S_LEN("coladd"))) != NULL) { - curwin->w_cursor.coladd = get_tv_number(&di->di_tv); + curwin->w_cursor.coladd = tv_get_number(&di->di_tv); } if ((di = tv_dict_find(dict, S_LEN("curswant"))) != NULL) { - curwin->w_curswant = get_tv_number(&di->di_tv); + curwin->w_curswant = tv_get_number(&di->di_tv); curwin->w_set_curswant = false; } if ((di = tv_dict_find(dict, S_LEN("topline"))) != NULL) { - set_topline(curwin, get_tv_number(&di->di_tv)); + set_topline(curwin, tv_get_number(&di->di_tv)); } if ((di = tv_dict_find(dict, S_LEN("topfill"))) != NULL) { - curwin->w_topfill = get_tv_number(&di->di_tv); + curwin->w_topfill = tv_get_number(&di->di_tv); } if ((di = tv_dict_find(dict, S_LEN("leftcol"))) != NULL) { - curwin->w_leftcol = get_tv_number(&di->di_tv); + curwin->w_leftcol = tv_get_number(&di->di_tv); } if ((di = tv_dict_find(dict, S_LEN("skipcol"))) != NULL) { - curwin->w_skipcol = get_tv_number(&di->di_tv); + curwin->w_skipcol = tv_get_number(&di->di_tv); } check_cursor(); @@ -17462,8 +17492,8 @@ 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); } @@ -18408,83 +18438,6 @@ void free_tv(typval_T *varp) // TODO(ZyX-I): move to eval/typval -/// Get the number value of a variable -/// -/// @note Use get_tv_number_chk() if you need to determine whether there was an -/// error. -/// -/// @param[in] varp Variable to get value from. -/// -/// @return Number value: vim_str2nr() output for VAR_STRING variables, value -/// for VAR_NUMBER variables, -1 for other types. -varnumber_T get_tv_number(const typval_T *const varp) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT -{ - bool error = false; - return get_tv_number_chk(varp, &error); -} - -varnumber_T get_tv_number_chk(const typval_T *const varp, bool *const denote) -{ - varnumber_T n = 0; - - switch (varp->v_type) { - case VAR_NUMBER: { - return varp->vval.v_number; - } - case VAR_FLOAT: { - EMSG(_("E805: Using a Float as a Number")); - break; - } - case VAR_PARTIAL: - case VAR_FUNC: { - EMSG(_("E703: Using a Funcref as a Number")); - break; - } - case VAR_STRING: { - if (varp->vval.v_string != NULL) { - long nr; - vim_str2nr(varp->vval.v_string, NULL, NULL, STR2NR_ALL, &nr, NULL, 0); - n = (varnumber_T)nr; - } - 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; -} - -// TODO(ZyX-I): move to eval/typval - /// 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 FUNC_ATTR_WARN_UNUSED_RESULT @@ -18981,7 +18934,7 @@ static void set_var(const char *name, typval_T *const tv, const bool copy) } return; } else if (v->di_tv.v_type == VAR_NUMBER) { - v->di_tv.vval.v_number = get_tv_number(tv); + 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) { diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index d2d0873792..ec6c86ac64 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -50,7 +50,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, } if (*op == '+' || *op == '-') { // nr += nr or nr -= nr - varnumber_T n = get_tv_number(tv1); + varnumber_T n = tv_get_number(tv1); if (tv2->v_type == VAR_FLOAT) { float_T f = n; @@ -64,9 +64,9 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, tv1->vval.v_float = f; } else { if (*op == '+') { - n += get_tv_number(tv2); + n += tv_get_number(tv2); } else { - n -= get_tv_number(tv2); + n -= tv_get_number(tv2); } tv_clear(tv1); tv1->v_type = VAR_NUMBER; @@ -96,7 +96,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, } const float_T f = (tv2->v_type == VAR_FLOAT ? tv2->vval.v_float - : get_tv_number(tv2)); + : tv_get_number(tv2)); if (*op == '+') { tv1->vval.v_float += f; } else { diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 38032762dc..087e76de10 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -17,6 +17,7 @@ #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/pos.h" +#include "nvim/charset.h" // TODO(ZyX-I): Move line_breakcheck out of misc1 #include "nvim/misc1.h" // For line_breakcheck @@ -725,7 +726,7 @@ varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *ret_error) } return -1; } - return get_tv_number_chk(&li->li_tv, ret_error); + return tv_get_number_chk(&li->li_tv, ret_error); } /// Get list item l[n - 1] as a string @@ -1087,7 +1088,7 @@ varnumber_T tv_dict_get_number(dict_T *const d, const char *const key) if (di == NULL) { return 0; } - return get_tv_number(&di->di_tv); + return tv_get_number(&di->di_tv); } /// Get a string item from a dictionary @@ -1971,7 +1972,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, /// Check that given value is a number or string /// -/// Error messages are compatible with get_tv_number() previously used for the +/// 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). /// @@ -2016,8 +2017,127 @@ bool tv_check_str_or_nr(const typval_T *const tv) 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() previously used for +/// the same purpose. +/// +/// @param[in] tv Value to check. +/// +/// @return true if everything is OK, false otherwise. +bool tv_check_num(const typval_T *const tv) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + switch (tv->v_type) { + case VAR_NUMBER: + case VAR_SPECIAL: + case VAR_STRING: { + return true; + } + case VAR_FUNC: + case VAR_PARTIAL: + case VAR_LIST: + case VAR_DICT: + case VAR_FLOAT: + case VAR_UNKNOWN: { + EMSG(_(num_errors[tv->v_type])); + return false; + } + } + assert(false); + return false; +} + //{{{2 Get +/// Get the number value of a VimL object +/// +/// @note Use tv_get_number_chk() if you need to determine whether there was an +/// error. +/// +/// @param[in] tv Object to get value from. +/// +/// @return Number value: vim_str2nr() output for VAR_STRING objects, value +/// for VAR_NUMBER objects, -1 for other types. +varnumber_T tv_get_number(const typval_T *const tv) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + bool error = false; + return tv_get_number_chk(tv, &error); +} + +/// Get the number value of a VimL object +/// +/// @param[in] tv Object to get value from. +/// @param[out] ret_error If type error occurred then `true` will be written +/// to this location. Otherwise it is not touched. +/// +/// @note Needs to be initialized to `false` to be +/// useful. +/// +/// @return Number value: vim_str2nr() output for VAR_STRING objects, value +/// for VAR_NUMBER objects, -1 (ret_error == NULL) or 0 (otherwise) for +/// other types. +varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) +{ + switch (tv->v_type) { + case VAR_FUNC: + case VAR_PARTIAL: + case VAR_LIST: + case VAR_DICT: + case VAR_FLOAT: { + EMSG(_(num_errors[tv->v_type])); + break; + } + case VAR_NUMBER: { + return tv->vval.v_number; + } + case VAR_STRING: { + varnumber_T n = 0; + if (tv->vval.v_string != NULL) { + long nr; + vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &nr, NULL, 0); + n = (varnumber_T)nr; + } + return n; + } + case VAR_SPECIAL: { + switch (tv->vval.v_special) { + case kSpecialVarTrue: { + return 1; + } + case kSpecialVarFalse: + case kSpecialVarNull: { + return 0; + } + } + break; + } + case VAR_UNKNOWN: { + EMSG2(_(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 @@ -2028,7 +2148,7 @@ bool tv_check_str_or_nr(const typval_T *const tv) linenr_T tv_get_lnum(const typval_T *const tv) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - linenr_T lnum = get_tv_number_chk(tv, NULL); + linenr_T lnum = 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); @@ -2078,7 +2198,7 @@ float_T tv_get_float(const typval_T *const tv) break; } case VAR_UNKNOWN: { - EMSG2(_(e_intern2), "get_tv_float()"); + EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)"); break; } } diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 9cfa126a56..e20979c307 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -576,7 +576,7 @@ static varnumber_T tv_nr(typval_T *tvs, int *idxp) } else { (*idxp)++; bool err = false; - n = (varnumber_T)get_tv_number_chk(&tvs[idx], &err); + n = tv_get_number_chk(&tvs[idx], &err); if (err) { n = 0; } diff --git a/src/nvim/window.c b/src/nvim/window.c index a3b0e6fc2d..6020159af9 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5593,7 +5593,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, if (subli == NULL) { goto fail; } - lnum = get_tv_number_chk(&subli->li_tv, &error); + lnum = tv_get_number_chk(&subli->li_tv, &error); if (error) { goto fail; } @@ -5604,13 +5604,13 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, m->pos.pos[i].lnum = lnum; subli = subli->li_next; if (subli != NULL) { - col = get_tv_number_chk(&subli->li_tv, &error); + 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); + len = tv_get_number_chk(&subli->li_tv, &error); if (error) { goto fail; } @@ -5810,14 +5810,14 @@ 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 = NULL; - int tabnr = get_tv_number(&argvars[1]); + int tabnr = tv_get_number(&argvars[1]); FOR_ALL_TABS(tp2) { if (--tabnr == 0) { tp = tp2; @@ -5844,7 +5844,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) { @@ -5879,7 +5879,7 @@ 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); tv_list_append_number(list, tabnr); @@ -5888,7 +5888,7 @@ void win_id2tabwin(typval_T *argvars, list_T *list) 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) { @@ -5902,7 +5902,7 @@ win_T * win_id2wp(typval_T *argvars) int win_id2win(typval_T *argvars) { int nr = 1; - int id = get_tv_number(&argvars[0]); + int id = tv_get_number(&argvars[0]); FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->handle == id) { @@ -5915,7 +5915,7 @@ 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_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer->b_fnum == bufnr) { -- cgit From 50ebd1dff5c4e995c4f7e7980870e43d9defabc6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 28 Aug 2016 09:15:28 +0300 Subject: eval: Move free_tv to eval/typval.h, remove most of its usages --- src/nvim/api/vim.c | 11 ++++++----- src/nvim/eval.c | 53 ++++++-------------------------------------------- src/nvim/eval/typval.c | 40 +++++++++++++++++++++++++++++++++++++ src/nvim/ex_eval.c | 15 +++++++------- src/nvim/quickfix.c | 13 ++++++------- 5 files changed, 66 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index db2f25a2a6..975446057c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -182,19 +182,20 @@ Object nvim_eval(String expr, Error *err) Object rv = OBJECT_INIT; // Evaluate the expression try_start(); - typval_T *expr_result = eval_expr((char_u *)expr.data, NULL); - if (!expr_result) { + typval_T rettv; + if (eval0((char_u *)expr.data, &rettv, NULL, true) == FAIL) { api_set_error(err, Exception, "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; } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 676df1a301..65bb90fc15 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -719,13 +719,12 @@ 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((const char *)name, tvp, false); - free_tv(tvp); + set_var((const char *)name, (typval_T *)&tv, true); } static lval_T *redir_lval = NULL; @@ -3264,7 +3263,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; @@ -18404,38 +18403,6 @@ void set_selfdict(typval_T *rettv, dict_T *selfdict) } } -/* - * Free the memory for a variable type-value. - */ -void free_tv(typval_T *varp) -{ - if (varp != NULL) { - switch (varp->v_type) { - case VAR_FUNC: - func_unref(varp->vval.v_string); - // FALLTHROUGH - case VAR_STRING: - xfree(varp->vval.v_string); - break; - case VAR_PARTIAL: - partial_unref(varp->vval.v_partial); - break; - case VAR_LIST: - tv_list_unref(varp->vval.v_list); - break; - case VAR_DICT: - tv_dict_unref(varp->vval.v_dict); - break; - case VAR_SPECIAL: - case VAR_NUMBER: - case VAR_FLOAT: - case VAR_UNKNOWN: - break; - } - xfree(varp); - } -} - // TODO(ZyX-I): move to eval/typval /// Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE! @@ -21525,14 +21492,6 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) return idx < 0; } -/* - * 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. diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 087e76de10..ca635dcae9 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1742,6 +1742,46 @@ void tv_clear(typval_T *tv) } } +//{{{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); + } +} + //{{{2 Locks /// Lock or unlock an item diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 3f71ae1795..65112c4dd8 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -14,6 +14,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" @@ -21,8 +22,6 @@ #include "nvim/regexp.h" #include "nvim/strings.h" - - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_eval.c.generated.h" #endif @@ -59,12 +58,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 diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 06ac2821b0..4fa5c85abd 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4372,7 +4372,6 @@ void ex_cbuffer(exarg_T *eap) */ void ex_cexpr(exarg_T *eap) { - typval_T *tv; qf_info_T *qi = &ql_info; const char *au_name = NULL; @@ -4412,11 +4411,11 @@ void ex_cexpr(exarg_T *eap) /* 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, + 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) { @@ -4431,7 +4430,7 @@ void ex_cexpr(exarg_T *eap) } else { EMSG(_("E777: String or List expected")); } - free_tv(tv); + tv_clear(&tv); } } -- cgit From c8e63a8db84e9d9f7bd855085a87d93631504fc7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Sep 2016 02:25:24 +0300 Subject: eval: Move remaining get_tv_string* functions to eval/typval.c --- src/nvim/ascii.h | 8 +- src/nvim/charset.c | 8 +- src/nvim/edit.c | 204 ++++---- src/nvim/eval.c | 1280 +++++++++++++++++++++++------------------------- src/nvim/eval/typval.c | 118 ++++- src/nvim/eval/typval.h | 1 + src/nvim/ex_cmds.c | 4 +- src/nvim/ex_docmd.c | 2 +- src/nvim/ex_getln.c | 31 +- src/nvim/fileio.c | 37 +- src/nvim/getchar.c | 159 +++--- src/nvim/globals.h | 1 + src/nvim/mbyte.c | 4 +- src/nvim/normal.c | 71 +-- src/nvim/ops.c | 60 +-- src/nvim/option.c | 19 +- src/nvim/os/fs.c | 4 +- src/nvim/regexp.c | 15 +- src/nvim/screen.c | 2 +- src/nvim/spell.c | 82 ++-- src/nvim/spellfile.c | 54 +- src/nvim/strings.c | 11 +- src/nvim/undo.c | 4 +- 23 files changed, 1142 insertions(+), 1037 deletions(-) (limited to 'src') diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h index 31851a84e6..37b83efb61 100644 --- a/src/nvim/ascii.h +++ b/src/nvim/ascii.h @@ -20,15 +20,13 @@ #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 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/charset.c b/src/nvim/charset.c index cb6a9fa43c..6c22108853 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -90,7 +90,6 @@ int buf_init_chartab(buf_T *buf, int global) { int c; int c2; - char_u *p; int i; bool tilde; bool do_isalpha; @@ -144,7 +143,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; @@ -169,7 +169,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); } @@ -179,7 +179,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); } diff --git a/src/nvim/edit.c b/src/nvim/edit.c index b396251051..da09aed3dc 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1423,7 +1423,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); @@ -1977,7 +1977,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. */ @@ -1987,11 +1986,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); @@ -2002,7 +2001,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); @@ -2018,27 +2017,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 (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; + } } } } @@ -2048,49 +2055,57 @@ 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) + // Rule 2 is satisfied. + for (i = actual_compl_length; i < actual_len; i++) { wca[i] = vim_toupper(wca[i]); + } break; } was_letter = vim_islower(c) || vim_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 (vim_islower(c)) { + wca[i] = vim_tolower(wca[i]); + } else if (vim_isupper(c)) { + wca[i] = vim_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); @@ -3594,7 +3609,7 @@ int ins_compl_add_tv(typval_T *const tv, const Direction dir) adup = (bool)tv_dict_get_number(tv->vval.v_dict, "dup"); aempty = (bool)tv_dict_get_number(tv->vval.v_dict, "empty"); } else { - word = (const char *)get_tv_string_chk(tv); + word = (const char *)tv_get_string_chk(tv); memset(cptext, 0, sizeof(cptext)); } if (word == NULL || (!aempty && *word == NUL)) { @@ -5785,15 +5800,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. @@ -5822,8 +5838,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(); } @@ -5880,7 +5896,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) @@ -6345,12 +6361,13 @@ stuff_inserted ( } do { - stuffReadbuff(ptr); - /* a trailing "0" is inserted as "048", "^" as "^" */ - if (last) - stuffReadbuff((char_u *)(last == '0' - ? "\026\060\064\070" - : "\026^")); + stuffReadbuff((const char *)ptr); + // A trailing "0" is inserted as "048", "^" as "^". + if (last) { + stuffReadbuff((last == '0' + ? "\026\060\064\070" + : "\026^")); + } } while (--count > 0); if (last) @@ -7143,13 +7160,12 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) disabled_redraw = false; } if (!arrow_used) { - /* - * Don't append the ESC for "r" 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" 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 @@ -7303,7 +7319,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); @@ -8111,11 +8128,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); @@ -8380,8 +8397,8 @@ static int ins_digraph(void) 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; } @@ -8443,12 +8460,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); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 65bb90fc15..3a0075e48a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -173,7 +173,6 @@ static char *e_funcref = N_("E718: Funcref required"); static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 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\""); @@ -1852,7 +1851,6 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, const char_u *const op) FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT { - char_u *name; char_u *arg_end = NULL; int len; int opt_flags; @@ -1864,7 +1862,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, if (*arg == '$') { // Find the end of the name. arg++; - name = arg; + char *name = (char *)arg; len = get_env_len((const char_u **)&arg); if (len == 0) { EMSG2(_(e_invarg2), name - 1); @@ -1875,26 +1873,28 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, && vim_strchr(endchars, *skipwhite(arg)) == NULL) { EMSG(_(e_letunexp)); } else if (!check_secure()) { - const char_u c1 = name[len]; + const char c1 = name[len]; name[len] = NUL; - char_u *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; @@ -1914,16 +1914,16 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, } else { int opt_type; long numval; - char_u *stringval = NULL; - char_u *s; + char *stringval = NULL; const char c1 = *p; *p = NUL; varnumber_T n = tv_get_number(tv); - s = get_tv_string_chk(tv); // != NULL if number or string. + 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 != '.')) { EMSG2(_(e_letwrong), op); @@ -1935,44 +1935,45 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, n = numval - n; } } else if (opt_type == 0 && stringval != NULL) { // string - s = concat_str(stringval, s); - xfree(stringval); - stringval = s; + 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((const char *)arg, n, (char *)s, opt_flags); + 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; - char_u *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); @@ -2129,13 +2130,14 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, } 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) { + } + if (!tv_check_str(&var1)) { // Not a number or string. tv_clear(&var1); return NULL; @@ -2174,7 +2176,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, } return NULL; } - if (get_tv_string_chk(&var2) == NULL) { + if (!tv_check_str(&var2)) { // Not a number or string. if (!empty1) { tv_clear(&var1); @@ -3810,16 +3812,15 @@ 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) { + && (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; } @@ -3840,10 +3841,10 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) */ if (op == '.') { char buf1[NUMBUFLEN]; - char_u buf2[NUMBUFLEN]; + char buf2[NUMBUFLEN]; // s1 already checked const char *const s1 = tv_get_string_buf(rettv, buf1); - const char *const s2 = (const char *)get_tv_string_buf_chk(&var2, buf2); + const char *const s2 = tv_get_string_buf_chk(&var2, buf2); if (s2 == NULL) { // Type error? tv_clear(rettv); tv_clear(&var2); @@ -4411,7 +4412,7 @@ eval_index ( empty1 = true; } else if (eval1(arg, &var1, evaluate) == FAIL) { // Recursive! return FAIL; - } else if (evaluate && get_tv_string_chk(&var1) == NULL) { + } else if (evaluate && !tv_check_str(&var1)) { // Not a number or string. tv_clear(&var1); return FAIL; @@ -4430,7 +4431,7 @@ eval_index ( tv_clear(&var1); } return FAIL; - } else if (evaluate && get_tv_string_chk(&var2) == NULL) { + } else if (evaluate && !tv_check_str(&var2)) { // Not a number or string. if (!empty1) { tv_clear(&var1); @@ -4566,7 +4567,7 @@ eval_index ( } if (len == -1) { - key = get_tv_string_chk(&var1); + key = (char_u *)tv_get_string_chk(&var1); if (key == NULL) { tv_clear(&var1); return FAIL; @@ -5570,7 +5571,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}. @@ -5602,9 +5603,9 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate) 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 + // "key" is NULL when tv_get_string_buf_chk() gave an errmsg tv_clear(&tvkey); goto failret; } @@ -6598,7 +6599,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; @@ -6622,21 +6622,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; } @@ -6802,7 +6804,7 @@ 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"); @@ -6821,22 +6823,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) { @@ -6911,14 +6913,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); @@ -7107,7 +7110,6 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { bool error = false; - char_u *name; rettv->vval.v_number = -1; if (!tv_check_str_or_nr(&argvars[0])) { @@ -7119,13 +7121,14 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) // 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 && tv_get_number_chk(&argvars[1], &error) != 0 && !error - && (name = get_tv_string_chk(&argvars[0])) != NULL + && (name = tv_get_string_chk(&argvars[0])) != NULL && !error) { - buf = buflist_new(name, NULL, (linenr_T)1, 0); + buf = buflist_new((char_u *)name, NULL, 1, 0); } if (buf != NULL) { @@ -7190,24 +7193,23 @@ static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 = tv_get_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); } @@ -7444,47 +7446,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; + 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 = 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); + } } /* @@ -7708,32 +7714,29 @@ 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"); + 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])) { - EMSG2(e_invarg2, "funcref"); + emsgf(_(e_invarg2), "funcref"); return; } DictWatcher *watcher = xmalloc(sizeof(DictWatcher)); - watcher->key_pattern = xmemdupz(key_pattern, key_len); + watcher->key_pattern = xmemdupz(key_pattern, key_pattern_len); watcher->callback = callback; watcher->busy = false; QUEUE_INSERT_TAIL(&argvars[0].vval.v_dict->watchers, &watcher->node); @@ -7747,26 +7750,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; } @@ -7924,16 +7918,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; @@ -7965,75 +7958,74 @@ static void f_executable(typval_T *argvars, typval_T *rettv, FunPtr fptr) && 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, S_LEN("silent")) == 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(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--; + 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 @@ -8231,7 +8223,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[2].v_type != VAR_UNKNOWN) { const char *const av[] = { "keep", "force", "error" }; - action = (const char *)get_tv_string_chk(&argvars[2]); + action = tv_get_string_chk(&argvars[2]); if (action == NULL) { return; // Type error; error message already given. } @@ -8300,10 +8292,8 @@ static void f_filewritable(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) { - 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; bool first = true; bool error = false; @@ -8313,13 +8303,15 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) 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 = tv_get_number_chk(&argvars[2], &error); @@ -8473,8 +8465,6 @@ static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) { typval_T rettv; typval_T argv[3]; - char_u buf[NUMBUFLEN]; - char_u *s; int retval = FAIL; int dummy; @@ -8482,7 +8472,7 @@ static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) argv[0] = vimvars[VV_KEY].vv_tv; argv[1] = vimvars[VV_VAL].vv_tv; if (expr->v_type == VAR_FUNC) { - s = expr->vval.v_string; + 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; @@ -8490,23 +8480,24 @@ static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) } else if (expr->v_type == VAR_PARTIAL) { partial_T *partial = expr->vval.v_partial; - s = partial_name(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 { - s = get_tv_string_buf_chk(expr, buf); + char buf[NUMBUFLEN]; + const char *s = tv_get_string_buf_chk(expr, buf); if (s == NULL) { goto theend; } - s = skipwhite(s); - if (eval1(&s, &rettv, true) == FAIL) { + 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 - EMSG2(_(e_invexpr2), s); + emsgf(_(e_invexpr2), s); goto theend; } } @@ -8606,27 +8597,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); } @@ -9257,7 +9247,7 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) goto f_getbufvar_end; } - const char *varname = (const char *)get_tv_string_chk(&argvars[1]); + const char *varname = tv_get_string_chk(&argvars[1]); emsg_off++; buf_T *const buf = get_buf_tv(&argvars[0], false); @@ -9970,14 +9960,13 @@ static void f_getqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "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; 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 = tv_get_number_chk(&argvars[1], &error); @@ -9986,16 +9975,17 @@ static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } 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; @@ -10016,23 +10006,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]; @@ -10108,7 +10099,7 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - const char *const varname = (const char *)get_tv_string_chk(&argvars[1]); + 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 @@ -10307,8 +10298,7 @@ getwinvar ( tp = curtab; } win = find_win_by_nr(&argvars[off], tp); - const char *varname = (const char *)get_tv_string_chk( - &argvars[off + 1]); + const char *varname = tv_get_string_chk(&argvars[off + 1]); rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -10438,12 +10428,12 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - 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((char_u *)tv_get_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"); @@ -10464,12 +10454,13 @@ 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 @@ -10797,14 +10788,14 @@ static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (check_restricted() || check_secure()) { return; } - char_u *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) { char buf[NUMBUFLEN]; - str = (char_u *)tv_get_string_buf(&argvars[1], buf); + 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; } @@ -10817,22 +10808,20 @@ 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 *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), + n = del_history_idx(get_histtype(str, strlen(str), false), (int)tv_get_number(&argvars[1])); } else { // string given: remove all matching entries char buf[NUMBUFLEN]; - n = del_history_entry(get_histtype(str, STRLEN(str), false), + n = del_history_entry(get_histtype(str, strlen(str), false), (char_u *)tv_get_string_buf(&argvars[1], buf)); } rettv->vval.v_number = n; @@ -10845,13 +10834,12 @@ 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 { @@ -10870,9 +10858,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); @@ -11009,11 +10997,8 @@ static int inputsecret_flag = 0; */ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) { - char_u *prompt = get_tv_string_chk(&argvars[0]); - char_u *p = NULL; - int c; + const char *prompt = tv_get_string_chk(&argvars[0]); int cmd_silent_save = cmd_silent; - char_u *defstr = (char_u *)""; int xp_type = EXPAND_NOTHING; char_u *xp_arg = NULL; @@ -11022,49 +11007,45 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) 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) + // 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; - c = *p; - *p = NUL; + } else { + p++; msg_start(); msg_clr_eos(); - msg_puts_attr((const char *)prompt, echo_attr); + msg_puts_attr_len(prompt, p - prompt, echo_attr); msg_didout = false; msg_starthere(); - *p = c; } cmdline_row = msg_row; + const char *defstr = ""; if (argvars[1].v_type != VAR_UNKNOWN) { - char_u buf[NUMBUFLEN]; - defstr = get_tv_string_buf_chk(&argvars[1], buf); + char buf[NUMBUFLEN]; + defstr = tv_get_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 */ + // input() with a third argument: completion rettv->vval.v_string = NULL; - xp_name = get_tv_string_buf_chk(&argvars[2], buf); + const char *const xp_name = tv_get_string_buf_chk(&argvars[2], buf); if (xp_name == NULL) { return; } - xp_namelen = (int)STRLEN(xp_name); + const int xp_namelen = (int)strlen(xp_name); - if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, - &xp_arg) == FAIL) + uint32_t argt; + if (parse_compl_arg((char_u *)xp_name, xp_namelen, &xp_type, &argt, + &xp_arg) == FAIL) { return; + } } } @@ -11072,8 +11053,8 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) 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); + getcmdline_prompt(inputsecret_flag ? NUL : '@', (char_u *)p, echo_attr, + xp_type, xp_arg); ex_normal_busy = save_ex_normal_busy; } if (inputdialog && rettv->vval.v_string == NULL @@ -11544,8 +11525,8 @@ static char **tv_to_argv(typval_T *cmd_tv, const 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; } @@ -11553,14 +11534,14 @@ static char **tv_to_argv(typval_T *cmd_tv, const 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 tv_get_string_chk; just deallocate argv. shell_free_argv(argv); @@ -11803,50 +11784,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); - tv_list_join(&ga, argvars[0].vval.v_list, (const 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 { @@ -12043,10 +12023,8 @@ 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 *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; @@ -12062,20 +12040,24 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) 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 = 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, CPO_TO_CPO_FLAGS); @@ -12141,9 +12123,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; @@ -12183,9 +12163,11 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type) 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) { bool error = false; @@ -12224,7 +12206,7 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type) } } - 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; @@ -12336,18 +12318,20 @@ 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; 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 = tv_get_number_chk(&argvars[2], &error); if (argvars[3].v_type != VAR_UNKNOWN) { @@ -12365,7 +12349,7 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } - if (error == true) { + if (error) { return; } if (id >= 1 && id <= 3) { @@ -12373,17 +12357,16 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - rettv->vval.v_number = match_add(curwin, (const char *)grp, - (const char *)pat, prio, id, - NULL, conceal_char); + rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL, + conceal_char); } static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) { rettv->vval.v_number = -1; - - char_u buf[NUMBUFLEN]; - const char_u *const 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; } @@ -12431,8 +12414,8 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - rettv->vval.v_number = match_add(curwin, (const char *)group, NULL, prio, id, - l, conceal_char); + rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l, + conceal_char); } /* @@ -12833,11 +12816,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)); } /* @@ -13240,7 +13223,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG2(_(e_toomanyarg), "remove()"); } else if ((d = argvars[0].vval.v_dict) != NULL && !tv_check_lock(d->dv_lock, arg_errmsg, arg_errmsg_len)) { - const char *key = (const char *)get_tv_string_chk(&argvars[1]); + const char *key = tv_get_string_chk(&argvars[1]); if (key != NULL) { di = tv_dict_find(d, key, -1); if (di == NULL) { @@ -13572,40 +13555,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; @@ -13989,16 +13977,17 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 = 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; + } } /* @@ -14006,49 +13995,53 @@ 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), 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 = tv_get_number_chk(&argvars[5], NULL); if (lnum_stop < 0) { @@ -14062,11 +14055,10 @@ static int searchpair_cmn(typval_T *argvars, pos_T *match_pos) } } } - 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; @@ -14341,14 +14333,12 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u nbuf[NUMBUFLEN]; - if (check_restricted() || check_secure() || !tv_check_str_or_nr(&argvars[0])) { return; } - const char *varname = (const char *)get_tv_string_chk(&argvars[1]); + const char *varname = tv_get_string_chk(&argvars[1]); buf_T *const buf = get_buf_tv(&argvars[0], false); typval_T *varp = &argvars[2]; @@ -14363,7 +14353,8 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) varname++; numval = tv_get_number_chk(varp, &error); - char *const strval = (char *)get_tv_string_buf_chk(varp, nbuf); + 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); } @@ -14438,17 +14429,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; } @@ -14469,26 +14460,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) { - char_u *line = NULL; list_T *l = NULL; listitem_T *li = NULL; long added = 0; linenr_T lcount = curbuf->b_ml.ml_line_count; 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; } @@ -14504,18 +14497,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 */ @@ -14544,7 +14539,7 @@ 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; @@ -14563,7 +14558,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 { @@ -14576,7 +14571,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) // Option argument was not given. goto skip_args; } else if (title_arg->v_type == VAR_STRING) { - title = get_tv_string_chk(title_arg); + title = tv_get_string_chk(title_arg); if (!title) { // Type error. Error already printed by get_tv_string_chk(). return; @@ -14584,17 +14579,17 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) } else if (title_arg->v_type == VAR_DICT) { d = title_arg->vval.v_dict; } else { - EMSG(_(e_dictreq)); + 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, d) == OK) { + if (l && set_errorlist(wp, l, action, (char_u *)title, d) == OK) { rettv->vval.v_number = 0; } } @@ -14728,11 +14723,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) { @@ -14753,7 +14747,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 { @@ -14777,8 +14771,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; @@ -14786,39 +14778,47 @@ 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 = '"'; + } 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; } - break; } + } } if (argvars[1].v_type == VAR_LIST) { @@ -14828,42 +14828,44 @@ 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; @@ -14881,7 +14883,7 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) } tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); - const char *const varname = (const char *)get_tv_string_chk(&argvars[1]); + const char *const varname = tv_get_string_chk(&argvars[1]); typval_T *const varp = &argvars[2]; if (varname != NULL && varp != NULL && tp != NULL) { @@ -14935,7 +14937,7 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off) tp = curtab; } win_T *const win = find_win_by_nr(&argvars[off], tp); - const char *varname = (const char *)get_tv_string_chk(&argvars[off + 1]); + const char *varname = tv_get_string_chk(&argvars[off + 1]); typval_T *varp = &argvars[off + 2]; if (win != NULL && varname != NULL && varp != NULL) { @@ -14950,8 +14952,8 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off) varname++; numval = tv_get_number_chk(varp, &error); - char_u nbuf[NUMBUFLEN]; - char *const strval = (char *)get_tv_string_buf_chk(varp, nbuf); + 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); } @@ -15415,25 +15417,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; 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; @@ -15444,7 +15447,7 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr) } assert(len <= INT_MAX); - tv_list_append_string(rettv->vval.v_list, (const char *)word, len); + 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" @@ -15499,9 +15502,7 @@ 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 *pat = NULL; regmatch_T regmatch; - char_u patbuf[NUMBUFLEN]; char_u *save_cpo; int match; colnr_T col = 0; @@ -15513,8 +15514,10 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) p_cpo = (char_u *)""; 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); + pat = tv_get_string_buf_chk(&argvars[1], patbuf); if (pat == NULL) { typeerr = true; } @@ -15522,15 +15525,16 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) keepempty = (bool)tv_get_number_chk(&argvars[2], &typeerr); } } - if (pat == NULL || *pat == NUL) - pat = (char_u *)"[\\x01- ]\\+"; + if (pat == NULL || *pat == NUL) { + pat = "[\\x01- ]\\+"; + } 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) { @@ -15682,7 +15686,7 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) { rettv->vval.v_number = -1; - char_u *str = get_tv_string_chk(&argvars[0]); + const char *const str = tv_get_string_chk(&argvars[0]); if (str == NULL) { return; } @@ -15697,11 +15701,11 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) while (charidx >= 0 && byteidx < len) { if (charidx == 0) { - rettv->vval.v_number = mb_ptr2char(str + byteidx); + rettv->vval.v_number = mb_ptr2char((const char_u *)str + byteidx); break; } charidx--; - byteidx += MB_CPTR2LEN(str + byteidx); + byteidx += MB_CPTR2LEN((const char_u *)str + byteidx); } } @@ -15710,24 +15714,22 @@ 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) { bool error = false; - start_idx = tv_get_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) { @@ -15735,9 +15737,10 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - 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); + } } /* @@ -15765,7 +15768,7 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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 = tv_get_number_chk(&argvars[1], NULL); @@ -15775,7 +15778,7 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv; while (*s != NUL) { - func_mb_ptr2char_adv((char_u **)&s); + func_mb_ptr2char_adv((const char_u **)&s); len++; } rettv->vval.v_number = len; @@ -15904,47 +15907,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 = tv_get_number_chk(&argvars[2], NULL); + end_idx = (ptrdiff_t)tv_get_number_chk(&argvars[2], NULL); if (end_idx < 0) { return; // Can never find a match. } } else { - end_idx = haystack_len; + 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); + } } /* @@ -15994,20 +15996,20 @@ 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]; - char_u *str = get_tv_string_chk(&argvars[0]); - char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); - char_u *sub = NULL; - typval_T *expr = NULL; - char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); + 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); + typval_T *expr = NULL; if (argvars[2].v_type == VAR_FUNC || argvars[2].v_type == VAR_PARTIAL) { expr = &argvars[2]; } else { - sub = get_tv_string_buf_chk(&argvars[2], subbuf); + sub = tv_get_string_buf_chk(&argvars[2], subbuf); } rettv->v_type = VAR_STRING; @@ -16015,7 +16017,8 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr) || flg == NULL) { rettv->vval.v_string = NULL; } else { - rettv->vval.v_string = do_string_sub(str, pat, sub, expr, flg); + rettv->vval.v_string = do_string_sub((char_u *)str, (char_u *)pat, + (char_u *)sub, expr, (char_u *)flg); } } @@ -16333,19 +16336,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; } @@ -16359,19 +16363,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; @@ -16853,28 +16857,25 @@ static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int fromlen; - int tolen; - int idx; - char_u buf[NUMBUFLEN]; - char_u buf2[NUMBUFLEN]; - garray_T ga; + char buf[NUMBUFLEN]; + char buf2[NUMBUFLEN]; const char *in_str = tv_get_string(&argvars[0]); - const char_u *fromstr = get_tv_string_buf_chk(&argvars[1], buf); - const char_u *tostr = get_tv_string_buf_chk(&argvars[2], buf2); + 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. rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; if (fromstr == NULL || tostr == NULL) { - return; // type error; errmsg already given + 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)) { + if (strlen(fromstr) != strlen(tostr)) { goto error; } } @@ -16886,23 +16887,26 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *cpstr = in_str; const int inlen = (*mb_ptr2len)((const char_u *)in_str); int cplen = inlen; - idx = 0; - for (const char_u *p = fromstr; *p != NUL; p += fromlen) { - fromlen = (*mb_ptr2len)(p); + 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 = (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) { @@ -16910,8 +16914,9 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr) // (multi-byte) characters. Done only once when a character // of in_str doesn't appear in fromstr. first = false; - for (const char_u *p = tostr; *p != NUL; p += tolen) { - tolen = (*mb_ptr2len)(p); + int tolen; + for (const char *p = tostr; *p != NUL; p += tolen) { + tolen = (*mb_ptr2len)((const char_u *)p); idx--; } if (idx != 0) { @@ -16926,7 +16931,7 @@ static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr) in_str += inlen; } else { // When not using multi-byte chars we can do it faster. - char_u *p = vim_strchr(fromstr, *in_str); + const char *const p = strchr(fromstr, *in_str); if (p != NULL) { ga_append(&ga, tostr[p - fromstr]); } else { @@ -17278,8 +17283,7 @@ static bool write_list(FileDescriptor *const fp, const list_T *const list, { int error = 0; for (const listitem_T *li = list->lv_first; li != NULL; li = li->li_next) { - const char *const s = (const char *)get_tv_string_chk( - (typval_T *)&li->li_tv); + const char *const s = tv_get_string_chk(&li->li_tv); if (s == NULL) { return false; } @@ -17368,17 +17372,16 @@ static char *save_tv_as_string(typval_T *tv, ptrdiff_t *const 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 *ret = (char *)get_tv_string_chk(tv); + const char *ret = tv_get_string_chk(tv); if (ret && (*len = strlen(ret))) { - ret = xstrdup(ret); + return xmemdupz(ret, (size_t)(*len)); } else { - ret = NULL; *len = -1; + return NULL; } - return ret; } // Pre-calculate the resulting length. @@ -17448,7 +17451,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool binary = false; bool append = false; if (argvars[2].v_type != VAR_UNKNOWN) { - const char *const flags = (const char *)get_tv_string_chk(&argvars[2]); + const char *const flags = tv_get_string_chk(&argvars[2]); if (flags == NULL) { return; } @@ -17460,9 +17463,8 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - const char buf[NUMBUFLEN]; - const char *const fname = (const char *)get_tv_string_buf_chk(&argvars[1], - (char_u *)buf); + char buf[NUMBUFLEN]; + const char *const fname = tv_get_string_buf_chk(&argvars[1], buf); if (fname == NULL) { return; } @@ -17510,7 +17512,6 @@ 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; @@ -17564,7 +17565,7 @@ pos_T *var2fpos(const typval_T *const tv, const int dollar_lnum, return &pos; } - name = get_tv_string_chk(tv); + const char *const name = tv_get_string_chk(tv); if (name == NULL) { return NULL; } @@ -17578,7 +17579,7 @@ pos_T *var2fpos(const typval_T *const tv, const int dollar_lnum, return &curwin->w_cursor; } if (name[0] == '\'') { // Mark. - pp = getmark_buf_fnum(curbuf, name[1], false, ret_fnum); + pp = getmark_buf_fnum(curbuf, (uint8_t)name[1], false, ret_fnum); if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) { return NULL; } @@ -18403,58 +18404,11 @@ void set_selfdict(typval_T *rettv, dict_T *selfdict) } } -// TODO(ZyX-I): move to eval/typval - -/// 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 FUNC_ATTR_WARN_UNUSED_RESULT -{ - static char_u mybuf[NUMBUFLEN]; - - return get_tv_string_buf_chk(varp, mybuf); -} - -char_u *get_tv_string_buf_chk(const typval_T *varp, char_u *buf) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT -{ - 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. - */ +// 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) { diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index ca635dcae9..78eca15fec 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -796,7 +796,7 @@ static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key) // of the string means it should match everything up to the '*' instead of the // whole string. const size_t len = strlen(watcher->key_pattern); - if (watcher->key_pattern[len - 1] == '*') { + if (len && watcher->key_pattern[len - 1] == '*') { return strncmp(key, watcher->key_pattern, len - 1) == 0; } else { return strcmp(key, watcher->key_pattern) == 0; @@ -2020,7 +2020,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, /// /// @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 FUNC_ATTR_PURE + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { switch (tv->v_type) { case VAR_NUMBER: @@ -2072,7 +2072,7 @@ static const char *const num_errors[] = { /// Check that given value is a number or can be converted to it /// -/// Error messages are compatible with tv_get_number() previously used for +/// Error messages are compatible with tv_get_number_chk() previously used for /// the same purpose. /// /// @param[in] tv Value to check. @@ -2101,6 +2101,50 @@ bool tv_check_num(const typval_T *const tv) 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: { + EMSG(_(str_errors[tv->v_type])); + return false; + } + } + assert(false); + return false; +} + //{{{2 Get /// Get the number value of a VimL object @@ -2245,6 +2289,67 @@ float_T tv_get_float(const typval_T *const tv) 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: { + EMSG(_(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 @@ -2252,7 +2357,7 @@ float_T tv_get_float(const typval_T *const tv) /// tv_get_string_buf() if you need to use tv_get_string() output after /// calling it again. /// -/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// @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. @@ -2269,7 +2374,7 @@ const char *tv_get_string(const typval_T *const tv) /// Get the string value of a VimL object /// -/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// @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. @@ -2285,8 +2390,7 @@ const char *tv_get_string(const typval_T *const tv) 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 *)get_tv_string_buf_chk( - (typval_T *)tv, (char_u *)buf); + 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 index 3c294b45b8..42581939e3 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -27,6 +27,7 @@ typedef double float_T; /// Mimimal possible value of varnumber_T variable #define VARNUMBER_MIN INT_MIN +#define PRIdVARNUMBER "d" /// %d printf format specifier for varnumber_T #define PRIdVARNUMBER "d" diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 9681527fee..9a847a4c0a 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1008,8 +1008,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. diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 6b661cff11..73b81ac2d9 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6794,7 +6794,7 @@ do_exedit ( int ms = msg_scroll; if (eap->nextcmd != NULL) { - stuffReadbuff(eap->nextcmd); + stuffReadbuff((const char *)eap->nextcmd); eap->nextcmd = NULL; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 3bd8d580ab..a0981a42ce 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -2554,19 +2554,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); } } @@ -4636,7 +4639,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 { @@ -5029,7 +5032,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; @@ -5288,18 +5291,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 */ diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 67ac9f9957..127efda65c 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -614,10 +614,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 } @@ -2870,9 +2872,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 /* @@ -2883,7 +2885,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); @@ -3037,8 +3040,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 @@ -3402,8 +3405,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) { @@ -3421,8 +3425,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). */ @@ -3628,7 +3633,7 @@ restore_backup: close(empty_fd); } if (org != NULL) { - os_setperm((char_u *)org, os_getperm((const char *)fname) & 0777); + os_setperm(org, os_getperm((const char *)fname) & 0777); xfree(org); } } @@ -4690,8 +4695,8 @@ int vim_rename(const char_u *from, const 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); diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index b64f089b96..7143819e21 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -235,19 +235,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 +291,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 +302,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]; + char 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, (char_u *)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 +479,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 +512,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 +529,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; + } - 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) + 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++; + } + + // 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 +596,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 +618,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 +748,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 +1092,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); } } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index d87407f099..c15287aa38 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1199,6 +1199,7 @@ 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")); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 621fa6fefc..d96848754c 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -625,7 +625,7 @@ static int utf_safe_read_char_adv(const 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; @@ -638,7 +638,7 @@ 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; diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 6ef929120e..d4919dc3b6 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1155,7 +1155,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; @@ -1469,8 +1469,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 @@ -1853,10 +1854,11 @@ 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. + } case OP_INDENT: case OP_COLON: @@ -2026,43 +2028,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 (*curbuf->b_p_fp != NUL) { - stuffReadbuff(curbuf->b_p_fp); + stuffReadbuff((const char *)curbuf->b_p_fp); } else if (*p_fp != NUL) { - stuffReadbuff(p_fp); + stuffReadbuff((const char *)p_fp); } else { - stuffReadbuff((char_u *)"fmt"); + stuffReadbuff("fmt"); } - stuffReadbuff((char_u *)"\n']"); + stuffReadbuff("\n']"); } /* @@ -2304,7 +2307,7 @@ do_mouse ( if (VIsual_active) { if (VIsual_select) { stuffcharReadbuff(Ctrl_G); - stuffReadbuff((char_u *)"\"+p"); + stuffReadbuff("\"+p"); } else { stuffcharReadbuff('y'); stuffcharReadbuff(K_MIDDLEMOUSE); @@ -4476,7 +4479,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); } } @@ -6156,17 +6159,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; } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index fd1e2d20f2..68ef27222c 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1109,7 +1109,6 @@ int insert_reg( ) { int retval = OK; - char_u *arg; int allocated; /* @@ -1125,21 +1124,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) { @@ -1156,29 +1158,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); } } @@ -2663,7 +2665,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) // 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((char_u *)"\n "); + stuffReadbuff("\n "); stuffcharReadbuff(Ctrl_U); } } @@ -2675,7 +2677,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) // character. Simulate it with motion commands after the insert. if (flags & PUT_CURSEND) { if (flags & PUT_LINE) { - stuffReadbuff((char_u *)"j0"); + 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: @@ -2705,7 +2707,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } } } else if (flags & PUT_LINE) { - stuffReadbuff((char_u *)"g'["); + stuffReadbuff("g'["); } // So the 'u' command restores cursor position after ".p, save the cursor @@ -4981,7 +4983,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) { diff --git a/src/nvim/option.c b/src/nvim/option.c index 1881b329ec..8a80c46cf2 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3419,15 +3419,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) { @@ -6887,8 +6890,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++; @@ -6896,7 +6899,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`. diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 0372bc8a8c..3833a43f5f 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -622,11 +622,11 @@ int32_t os_getperm(const char *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); } diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 9c6f02f778..9baa53d2a2 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -2221,10 +2221,11 @@ collection: if (*regparse == '[') endc = get_coll_element(®parse); if (endc == 0) { - if (has_mbyte) - endc = mb_ptr2char_adv(®parse); - else + if (has_mbyte) { + endc = mb_ptr2char_adv((const char_u **)®parse); + } else { endc = *regparse++; + } } /* Handle \o40, \x20 and \u20AC style sequences */ @@ -6271,8 +6272,8 @@ 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 @@ -6586,7 +6587,6 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, if (expr != NULL) { typval_T argv[2]; int dummy; - char_u buf[NUMBUFLEN]; typval_T rettv; staticList10_T matchList; @@ -6616,7 +6616,8 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, clear_submatch_list(&matchList); } } - eval_result = get_tv_string_buf_chk(&rettv, buf); + char buf[NUMBUFLEN]; + eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf); if (eval_result != NULL) { eval_result = vim_strsave(eval_result); } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 505d04ed56..cf460adb82 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -3141,7 +3141,7 @@ 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; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 84bee9b97f..d4f49bffb2 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2309,10 +2309,11 @@ int captype(char_u *word, char_u *end) for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p)) if (end == NULL ? *p == NUL : p >= end) return 0; // only non-word characters, illegal word - if (has_mbyte) - c = mb_ptr2char_adv(&p); - else + if (has_mbyte) { + c = mb_ptr2char_adv((const char_u **)&p); + } else { c = *p++; + } firstcap = allcap = SPELL_ISUPPER(c); // Need to check all letters to find a word with mixed upper/lower. @@ -2607,14 +2608,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. -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]; @@ -2675,7 +2677,7 @@ 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; @@ -2937,7 +2939,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); @@ -3406,17 +3408,19 @@ void onecap_copy(char_u *word, char_u *wcopy, bool upper) 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; } @@ -3433,10 +3437,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'; @@ -5938,12 +5943,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; @@ -6228,9 +6233,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; @@ -6250,9 +6253,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) @@ -6261,8 +6264,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; @@ -6309,7 +6313,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; @@ -6708,25 +6712,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; @@ -6960,19 +6969,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 diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 6ba2801203..4d7ff558ad 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1435,7 +1435,7 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to) // 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); + c = mb_cptr2char_adv((const char_u **)&p); mb_cptr_adv(s); if (c >= 256) ++lp->sl_sal_first[c & 0xff]; @@ -1455,8 +1455,8 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to) // 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); + 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. @@ -1542,8 +1542,9 @@ 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); + for (char_u *p = s; *p != NUL; ) { + res[i++] = mb_ptr2char_adv((const char_u **)&p); + } res[i] = NUL; return res; @@ -2486,13 +2487,14 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) // Check that every character appears only once. for (p = items[1]; *p != NUL; ) { - c = mb_ptr2char_adv(&p); + 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) + || 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 @@ -2717,12 +2719,12 @@ static unsigned get_affitem(int flagtype, char_u **pp) } res = getdigits_int(pp); } else { - res = mb_ptr2char_adv(pp); + 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(pp) + (res << 16); + res = mb_ptr2char_adv((const char_u **)pp) + (res << 16); } } return res; @@ -2823,12 +2825,14 @@ static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag) case AFT_CAPLONG: case AFT_LONG: for (p = afflist; *p != NUL; ) { - n = mb_ptr2char_adv(&p); + n = mb_ptr2char_adv((const char_u **)&p); if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z')) - && *p != NUL) - n = mb_ptr2char_adv(&p) + (n << 16); - if (n == flag) + && *p != NUL) { + n = mb_ptr2char_adv((const char_u **)&p) + (n << 16); + } + if (n == flag) { return true; + } } break; @@ -5436,9 +5440,10 @@ static void init_spellfile(void) 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()); + ((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; } @@ -5465,9 +5470,9 @@ static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp) EMSG(_(e_affform)); return FAIL; } - f = mb_ptr2char_adv(&pf); - l = mb_ptr2char_adv(&pl); - u = mb_ptr2char_adv(&pu); + 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; @@ -5532,7 +5537,7 @@ set_spell_charflags ( } if (*p != NUL) { - c = mb_ptr2char_adv(&p); + 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; @@ -5619,12 +5624,13 @@ static void set_map_str(slang_T *lp, char_u *map) // "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 == '/') + c = mb_cptr2char_adv((const char_u **)&p); + if (c == '/') { headc = 0; - else { - if (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 diff --git a/src/nvim/strings.c b/src/nvim/strings.c index e20979c307..5dcffe00e0 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -598,22 +598,21 @@ static varnumber_T tv_nr(typval_T *tvs, int *idxp) /// free "*tofree". /// /// @return String value or NULL in case of error. -static char *tv_str(typval_T *tvs, int *idxp, char ** const tofree) +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; - char *s = NULL; + 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 = (char *)get_tv_string_chk(&tvs[idx]); + s = tv_get_string_chk(&tvs[idx]); *tofree = NULL; } else { - s = encode_tv2echo(&tvs[idx], NULL); - *tofree = s; + s = *tofree = encode_tv2echo(&tvs[idx], NULL); } } return s; @@ -953,7 +952,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, case 's': case 'S': str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree) - : va_arg(ap, char *); + : va_arg(ap, const char *); if (!str_arg) { str_arg = "[NULL]"; str_arg_l = 6; diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 010ef2c8fa..4d4e8d9bb9 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1140,7 +1140,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); @@ -1165,7 +1165,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) -- cgit From 5df35297f832b3247c18253c916be6066c603739 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Sep 2016 02:50:50 +0300 Subject: eval: Remove eval_expr() completely --- src/nvim/eval.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 3a0075e48a..51ffa8887d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1178,23 +1178,6 @@ int get_spellword(list_T *list, const char **pp) return tv_get_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; -} - // Call some vimL function and return the result in "*rettv". // Uses argv[argc] for the function arguments. Only Number and String -- cgit From 31a3158d0b574385186ab55c074edf85356d1d6c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Sep 2016 03:46:49 +0300 Subject: eval: Make sort always stable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Should fix test failures on QB: 20:00:51,837 INFO - not ok 420 - sort() sorts “wrong” values between -0.0001 and 0.0001, preserving order 20:00:51,837 INFO - # test/functional/eval/sort_spec.lua @ 21 20:00:51,837 INFO - # Failure message: test/functional/eval/sort_spec.lua:39: Expected objects to be the same. 20:00:51,837 INFO - # Passed in: 20:00:51,837 INFO - # (string) '[-1.0e-4, v:true, v:false, v:null, function('tr'), {'a': 42}, 'check', [], 1.0e-4]' 20:00:51,837 INFO - # Expected: 20:00:51,837 INFO - # (string) '[-1.0e-4, function('tr'), v:true, v:false, v:null, [], {'a': 42}, 'check', 1.0e-4]' 20:00:51,837 INFO - # stack traceback: 20:00:51,837 INFO - # test/functional/eval/sort_spec.lua:39: in function 20:00:51,837 INFO - # --- src/nvim/eval.c | 58 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 51ffa8887d..2dc1cb50af 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -15022,58 +15022,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) { - const varnumber_T v1 = tv_get_number(tv1); - const varnumber_T v2 = tv_get_number(tv2); + const long v1 = tv_get_number(tv1); + const long 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) { 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) { @@ -15083,19 +15086,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; } -- cgit From 6cc3d59ec8e4d6f32c8c3d9755c625e32512b8e2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Sep 2016 04:29:56 +0300 Subject: misc1: Refactor ask_yesno() --- src/nvim/misc1.c | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index d751f13644..0b74b4437e 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2211,39 +2211,44 @@ 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(const char *str, bool 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 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 + 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--; -- cgit From c4fe656fef5ade20da4861a2f1e5d0f776b0df8f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Sep 2016 17:56:24 +0300 Subject: typval.h: Allow non-var expressions in TV_DICT_ITER first argument --- src/nvim/eval.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2dc1cb50af..a5b0a65497 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -11248,26 +11248,26 @@ 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) -{ - 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; } - dict_T *const d = argvars[0].vval.v_dict; - if (d == NULL) { + if (tv->vval.v_dict == NULL) { return; } tv_list_alloc_ret(rettv); - TV_DICT_ITER(d, di, { + TV_DICT_ITER(tv->vval.v_dict, di, { listitem_T *const li = tv_list_item_alloc(); tv_list_append(rettv->vval.v_list, li); -- cgit From 86fc4580b83f20211d7f85566e84a0e1dad0a136 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Sep 2016 18:40:19 +0300 Subject: eval: Fix max_min functions Found two bugs: 1. Multiple unneeded error messages, vim/vim#1039. 2. Unformatted error string, vim/vim#1040. --- src/nvim/eval.c | 76 ++++++++++++++++++++++++-------------------------- src/nvim/eval/typval.h | 4 +-- 2 files changed, 38 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a5b0a65497..c96abfa149 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12463,53 +12463,49 @@ 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; + 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 = tv_get_number_chk(&li->li_tv, &error); - for (;; ) { - li = li->li_next; - if (li == NULL) { - break; - } - i = tv_get_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 = tv_get_number_chk(&TV_DICT_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 { EMSG2(_(e_listdictarg), domax ? "max()" : "min()"); diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 42581939e3..3b41314b46 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -279,13 +279,13 @@ typedef struct list_stack_S { #define TV_DICT_HI2DI(hi) \ ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) -static inline long tv_list_len(list_T *const l) +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(list_T *const l) +static inline long tv_list_len(const list_T *const l) { if (l == NULL) { return 0; -- cgit From 3a3816c990362e1ad8321e6b4748a33c94d1d797 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Sep 2016 21:42:24 +0300 Subject: cmake: Use CMAKE_CURRENT_LIST_DIR and remove vars used only once --- src/nvim/CMakeLists.txt | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index e752f5d4df..1c2932ed50 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -22,7 +22,6 @@ set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.genera set(GENERATED_FUNCS_METADATA ${GENERATED_DIR}/api/private/funcs_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) @@ -31,10 +30,6 @@ 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(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode) file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt) @@ -112,7 +107,7 @@ set(CONV_SOURCES 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() @@ -167,11 +162,11 @@ endfunction() # NVIM_GENERATED_SOURCES: generated source files # These lists must be mutually exclusive. foreach(sfile ${NVIM_SOURCES} - "${PROJECT_SOURCE_DIR}/src/nvim/regexp_nfa.c" + "${CMAKE_CURRENT_LIST_DIR}/regexp_nfa.c" ${GENERATED_API_DISPATCH}) 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) @@ -239,8 +234,8 @@ list(APPEND NVIM_GENERATED_SOURCES 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) @@ -248,24 +243,24 @@ 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 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. -- cgit From 40feac6efcc75395bb20da2b028b67a2b6e95bd9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 10 Sep 2016 22:32:14 +0300 Subject: message: Revise maxlen argument in msg_puts_attr_len `attr` argument is enough to forbid putting message in history. Also forbid strings with NUL before `len` just in case (it appears that this does not ever happen). --- src/nvim/message.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index 423f5a27e7..1eab9a403b 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1562,13 +1562,17 @@ 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. -void msg_puts_attr_len(const char *str, const ptrdiff_t 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) { @@ -1576,8 +1580,9 @@ void msg_puts_attr_len(const char *str, const ptrdiff_t 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) { + assert(len < 0); + add_msg_hist(str, (int)len, attr); attr &= ~MSG_HIST; } @@ -1596,9 +1601,9 @@ void msg_puts_attr_len(const char *str, const ptrdiff_t 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(str, maxlen); + msg_puts_printf(str, len); } else { - msg_puts_display((const char_u *)str, maxlen, attr, false); + msg_puts_display((const char_u *)str, len, attr, false); } } -- cgit From 8b0fa64ed3dbd4376cbfa195526ec97d8c944a97 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 10 Sep 2016 22:35:47 +0300 Subject: message: Remove incorrect assertion It was there only to prove that *now* `len` argument is not used to forbid putting message into history (i.e. that Neovim behaviour did not change). After this commit it should be possible to use msg_puts_attr_len with len>=0 to put message into history should new code need this. --- src/nvim/message.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index 1eab9a403b..83f2735b50 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1581,7 +1581,6 @@ void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr) // if MSG_HIST flag set, add message to history if (attr & MSG_HIST) { - assert(len < 0); add_msg_hist(str, (int)len, attr); attr &= ~MSG_HIST; } -- cgit From 2ad4fba46db26d0724106b194f7cb628fb9b02e8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 11 Sep 2016 03:37:03 +0300 Subject: eval: Move copy_tv to eval/typval --- src/nvim/api/private/helpers.c | 2 +- src/nvim/eval.c | 215 +++++++++++++++++------------------------ src/nvim/eval/typval.c | 86 ++++++++++++++--- src/nvim/move.PVS-Studio.cfg | 10 ++ src/nvim/shada.c | 2 +- 5 files changed, 176 insertions(+), 139 deletions(-) create mode 100644 src/nvim/move.PVS-Studio.cfg (limited to 'src') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 2c8a56cc1a..b245132ba7 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -179,7 +179,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, } // Update the value - copy_tv(&tv, &di->di_tv); + tv_copy(&tv, &di->di_tv); // Clear the temporary variable tv_clear(&tv); } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c96abfa149..a2b6d12288 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -494,6 +494,13 @@ typedef enum 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 @@ -2412,7 +2419,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, eexe_mod_op(&lp->ll_li->li_tv, &ri->li_tv, (const char *)op); } else { tv_clear(&lp->ll_li->li_tv); - copy_tv(&ri->li_tv, &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)) @@ -2452,7 +2459,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, 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 != '=') { @@ -2465,7 +2472,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, // 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; @@ -2926,7 +2933,7 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit) 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); } @@ -2998,7 +3005,7 @@ int do_unlet(char_u *name, int forceit) 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); @@ -4532,7 +4539,7 @@ eval_index ( rettv->vval.v_list = l; l->lv_refcount++; } else { - copy_tv(&tv_list_find(rettv->vval.v_list, n1)->li_tv, &var1); + tv_copy(&tv_list_find(rettv->vval.v_list, n1)->li_tv, &var1); tv_clear(rettv); *rettv = var1; } @@ -4570,7 +4577,7 @@ eval_index ( return FAIL; } - copy_tv(&item->di_tv, &var1); + tv_copy(&item->di_tv, &var1); tv_clear(rettv); *rettv = var1; break; @@ -6298,7 +6305,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]; @@ -6552,7 +6559,7 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr) if ((l = argvars[0].vval.v_list) != NULL && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { tv_list_append_tv(l, &argvars[1]); - copy_tv(&argvars[0], rettv); + tv_copy(&argvars[0], rettv); } } else EMSG(_(e_listreq)); @@ -7231,7 +7238,7 @@ 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) { @@ -8190,7 +8197,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) item = NULL; 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) { @@ -8224,7 +8231,7 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_dict_extend(d1, d2, action); - copy_tv(&argvars[0], rettv); + tv_copy(&argvars[0], rettv); } } else { EMSG2(_(e_listdictarg), "extend()"); @@ -8441,7 +8448,7 @@ 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, typval_T *expr, int map, int *remp) @@ -8451,7 +8458,7 @@ static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp) int retval = FAIL; int dummy; - copy_tv(tv, &vimvars[VV_VAL].vv_tv); + 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) { @@ -8859,13 +8866,13 @@ static void common_function(typval_T *argvars, typval_T *rettv, } int i = 0; for (; i < arg_len; i++) { - copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[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) { - copy_tv(&li->li_tv, &pt->pt_argv[i++]); + tv_copy(&li->li_tv, &pt->pt_argv[i++]); } } } @@ -9012,10 +9019,12 @@ 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. @@ -9260,7 +9269,7 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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); + tv_copy(&v->di_tv, rettv); done = true; } } @@ -9273,7 +9282,7 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) f_getbufvar_end: if (!done && argvars[2].v_type != VAR_UNKNOWN) { // use the default value - copy_tv(&argvars[2], rettv); + tv_copy(&argvars[2], rettv); } } @@ -10094,7 +10103,7 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; } } @@ -10104,7 +10113,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); } } @@ -10315,7 +10324,7 @@ getwinvar ( 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; } } @@ -10330,7 +10339,7 @@ getwinvar ( if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) { // use the default return value - copy_tv(&argvars[off + 2], rettv); + tv_copy(&argvars[off + 2], rettv); } } @@ -11181,7 +11190,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (l != NULL) { tv_list_insert_tv(l, &argvars[1], item); - copy_tv(&argvars[0], rettv); + tv_copy(&argvars[0], rettv); } } } @@ -11271,31 +11280,36 @@ static void dict_list(typval_T *const tv, typval_T *const rettv, listitem_T *const li = tv_list_item_alloc(); tv_list_append(rettv->vval.v_list, li); - if (what == 0) { - // keys() - li->li_tv.v_type = VAR_STRING; - li->li_tv.v_lock = 0; - li->li_tv.vval.v_string = vim_strsave(di->di_key); - } else if (what == 1) { - // values() - copy_tv(&di->di_tv, &li->li_tv); - } else { - // items() - list_T *const l2 = 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++; - - listitem_T *sub_li = tv_list_item_alloc(); - tv_list_append(l2, sub_li); - sub_li->li_tv.v_type = VAR_STRING; - sub_li->li_tv.v_lock = 0; - sub_li->li_tv.vval.v_string = vim_strsave(di->di_key); - - sub_li = tv_list_item_alloc(); - tv_list_append(l2, sub_li); - copy_tv(&di->di_tv, &sub_li->li_tv); + switch (what) { + case kDictListKeys: { + li->li_tv.v_type = VAR_STRING; + li->li_tv.v_lock = VAR_UNLOCKED; + li->li_tv.vval.v_string = vim_strsave(di->di_key); + 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 = 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; + } } }); } @@ -12256,21 +12270,24 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type) } } } 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); } } @@ -15135,8 +15152,8 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) // 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; // tv_clear() uses this res = call_func((const char_u *)func_name, @@ -18203,7 +18220,7 @@ static int get_var_tv( } ret = FAIL; } else if (rettv != NULL) { - copy_tv(tv, rettv); + tv_copy(tv, rettv); } return ret; @@ -18375,7 +18392,7 @@ 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]); } } } @@ -18852,7 +18869,7 @@ static void set_var(const char *name, typval_T *const tv, const bool copy) } if (watched) { - copy_tv(&v->di_tv, &oldtv); + tv_copy(&v->di_tv, &oldtv); } tv_clear(&v->di_tv); } else { // Add a new variable. @@ -18877,7 +18894,7 @@ static void set_var(const char *name, typval_T *const tv, const bool copy) } 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; @@ -18992,56 +19009,6 @@ bool valid_varname(const char *varname) return true; } -/* - * 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; - } -} - /// Make a copy of an item /// /// Lists and Dictionaries are also copied. @@ -19080,11 +19047,11 @@ 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); + tv_copy(from, to); } else { to->v_type = VAR_STRING; to->v_lock = 0; @@ -20981,7 +20948,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, if (addlocal) { // Named arguments can be accessed without the "a:" prefix in lambda // expressions. Add to the l: dict. - copy_tv(&v->di_tv, &v->di_tv); + tv_copy(&v->di_tv, &v->di_tv); tv_dict_add(&fc->l_vars, v); } else { tv_dict_add(&fc->l_avars, v); @@ -21188,13 +21155,13 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, // Make a copy of the a: variables, since we didn't do that above. TV_DICT_ITER(&fc->l_avars, di, { - copy_tv(&di->di_tv, &di->di_tv); + tv_copy(&di->di_tv, &di->di_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) { - copy_tv(&li->li_tv, &li->li_tv); + tv_copy(&li->li_tv, &li->li_tv); } } @@ -21700,7 +21667,7 @@ const void *var_shada_iter(const void *const iter, const char **const name, hi = (const hashitem_T *) iter; } *name = (char *)TV_DICT_HI2DI(hi)->di_key; - copy_tv(&TV_DICT_HI2DI(hi)->di_tv, rettv); + 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; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 78eca15fec..8a407a4513 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1,6 +1,8 @@ +#include #include -#include +#include #include +#include #include "nvim/lib/queue.h" #include "nvim/eval/typval.h" @@ -276,7 +278,7 @@ void tv_list_insert(list_T *const l, listitem_T *const ni, /// Insert VimL value into a list /// /// @param[out] l List to insert to. -/// @param[in,out] tv Value to insert. Is copied (@see copy_tv()) to an +/// @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. @@ -285,7 +287,7 @@ void tv_list_insert_tv(list_T *const l, typval_T *const tv, { listitem_T *const ni = tv_list_item_alloc(); - copy_tv(tv, &ni->li_tv); + tv_copy(tv, &ni->li_tv); tv_list_insert(l, ni, item); } @@ -313,13 +315,13 @@ void tv_list_append(list_T *const l, listitem_T *const item) /// 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 copy_tv()) to an +/// @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(); - copy_tv(tv, &li->li_tv); + tv_copy(tv, &li->li_tv); tv_list_append(l, li); } @@ -447,7 +449,7 @@ list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig, break; } } else { - copy_tv(&item->li_tv, &ni->li_tv); + tv_copy(&item->li_tv, &ni->li_tv); } tv_list_append(copy, ni); } @@ -828,13 +830,13 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key, if (newtv) { dictitem_T *const v = tv_dict_item_alloc_len(S_LEN("new")); - copy_tv(newtv, &v->di_tv); + 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")); - copy_tv(oldtv, &v->di_tv); + tv_copy(oldtv, &v->di_tv); tv_dict_add(argv[2].vval.v_dict, v); } @@ -926,7 +928,7 @@ static dictitem_T *tv_dict_item_copy(dictitem_T *const di) FUNC_ATTR_MALLOC { dictitem_T *const new_di = tv_dict_item_alloc((const char *)di->di_key); - copy_tv(&di->di_tv, &new_di->di_tv); + tv_copy(&di->di_tv, &new_di->di_tv); return new_di; } @@ -1161,7 +1163,7 @@ bool tv_dict_get_callback(dict_T *const d, } typval_T tv; - copy_tv(&di->di_tv, &tv); + tv_copy(&di->di_tv, &tv); set_selfdict(&tv, d); bool res = callback_from_typval(result, &tv); tv_clear(&tv); @@ -1338,11 +1340,11 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, } if (watched) { - copy_tv(&di1->di_tv, &oldtv); + tv_copy(&di1->di_tv, &oldtv); } tv_clear(&di1->di_tv); - copy_tv(&di2->di_tv, &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, @@ -1433,7 +1435,7 @@ dict_T *tv_dict_copy(const vimconv_T *const conv, break; } } else { - copy_tv(&di->di_tv, &new_di->di_tv); + tv_copy(&di->di_tv, &new_di->di_tv); } if (tv_dict_add(copy, new_di) == FAIL) { tv_dict_item_free(new_di); @@ -1782,6 +1784,64 @@ void tv_free(typval_T *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: { + EMSG2(_(e_intern2), "tv_copy(UNKNOWN)"); + break; + } + } +} + //{{{2 Locks /// Lock or unlock an item diff --git a/src/nvim/move.PVS-Studio.cfg b/src/nvim/move.PVS-Studio.cfg new file mode 100644 index 0000000000..cb6da32f12 --- /dev/null +++ b/src/nvim/move.PVS-Studio.cfg @@ -0,0 +1,10 @@ + +source-file=/home/zyx/a.a/Proj/c/neovim/src/nvim/move.c +i-file=/home/zyx/a.a/Proj/c/neovim/src/nvim/move.i +language=C +skip-cl-exe=yes +preprocessor=gcc +platform=linux64 +lic-file=/home/zyx/a.a/Proj/c/neovim/build/../PVS-Studio.lic +output-file=/home/zyx/a.a/Proj/c/neovim/build/../PVS-Studio.log.x +analysis-mode=4 diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 0f04a5e9cf..f65fdaf1c0 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -2559,7 +2559,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, 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) { -- cgit From a32db8ed19c35847373d4a7fd56d7797a5a26897 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 11 Sep 2016 03:54:13 +0300 Subject: eval/typval: Add missing includes, also add a script to find them Contains unfinished attempt to integrate IWYU (ref #549). To finish it different job should be done, specifically: - Instead of feeding IWYU with modified file a mirror source tree should be created with the help of CMake which will contain modified sources. This solves the problem with IWYU thinking that `*.generated.h` headers should be included in place of `*` headers. - Build IWYU as all other third-party utilities. - Make modified sources avoid problems with `nvim/func_attr.h` includes and various related tricks. Current script may only be used for manual checks like this: ./scripts/check-includes.py \ --generated-includes-dir build/include \ --generated-includes-dir build/src/nvim/auto \ --file src/nvim/eval/typval.c \ -- -Isrc -Ibuild/include -Ibuild/src/nvim/auto \ -DINCLUDE_GENERATED_DECLARATIONS (it is also somewhat fine with `--file src/nvim/eval/typval.h`). I have no idea why (I mean, why developer think that these lines are needed, why they are suggested is pretty obvious: because there is typedef which mentions them before structs are defined), but for typval.h it reports, among other things, that it should add lines struct dictvar_S; struct listitem_S; struct listvar_S; struct listwatch_S; --- src/nvim/eval/typval.c | 5 +++++ src/nvim/eval/typval.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 8a407a4513..4777e00a76 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -20,6 +20,11 @@ #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 diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 3b41314b46..791b191009 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -3,9 +3,11 @@ #include #include -#include +#include #include +#include +#include "nvim/types.h" #include "nvim/hashtab.h" #include "nvim/garray.h" #include "nvim/mbyte.h" -- cgit From a394167177390a66c275d32e3862c82c546970ff Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 12 Mar 2017 13:41:11 +0300 Subject: unittests: Test tv_list_item_\* functions To check that memory is free()d correctly. --- src/nvim/eval/typval.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 4777e00a76..a26afb20c6 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -228,6 +228,7 @@ void tv_list_unref(list_T *const l) /// @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 != NULL; ip = ip->li_next) { -- cgit From 9898f36aa306d2a7f53fbe08c64048260992d3bb Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Sep 2016 22:06:11 +0300 Subject: unittests: Test tv_list_copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also found some bugs: 1. var_item_copy() always fails to copy v:_null_list and v:_null_dict. Fixing this should mean fixing `deepcopy(v:_null_list)` which should’ve been, but was not listed in #4615. This also fixes `deepcopy(v:_null_dict)`. 2. var_item_copy() crashes when trying to copy NULL string with `conv != NULL`. 3. `conv` argument is ignored when copying list unless `deep` is true, but it was not reflected in documentation. 4. `tv_dict_item_alloc_len()` allocated more memory then needed. 5. typvalt2lua was not able to handle self-referencing containers. --- src/nvim/eval.c | 11 +++++++---- src/nvim/eval/typval.c | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a2b6d12288..7c3754607e 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -19024,7 +19024,7 @@ bool valid_varname(const char *varname) /// 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, @@ -19050,7 +19050,8 @@ int var_item_copy(const vimconv_T *const conv, tv_copy(from, to); break; case VAR_STRING: - if (conv == NULL || conv->vc_type == CONV_NONE) { + if (conv == NULL || conv->vc_type == CONV_NONE + || from->vval.v_string == NULL) { tv_copy(from, to); } else { to->v_type = VAR_STRING; @@ -19075,8 +19076,9 @@ int var_item_copy(const vimconv_T *const conv, } else { 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; @@ -19090,8 +19092,9 @@ int var_item_copy(const vimconv_T *const conv, } else { 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)"); diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index a26afb20c6..ae4199697f 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -424,6 +424,7 @@ void tv_list_append_number(list_T *const l, const varnumber_T n) /// 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(). -- cgit From f80a00469fdba8a3dec0edae30c911d050485055 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 18 Sep 2016 01:59:07 +0300 Subject: eval/typval: Make tv_list_concat handle NULL lists correctly Fixes some FIXMEs in eval/null_spec.lua. --- src/nvim/eval/typval.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index ae4199697f..9dd1b62d7d 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -498,20 +498,25 @@ void tv_list_extend(list_T *const l1, list_T *const l2, int tv_list_concat(list_T *const l1, list_T *const l2, typval_T *const tv) FUNC_ATTR_WARN_UNUSED_RESULT { - if (l1 == NULL || l2 == NULL) { - return FAIL; - } + list_T *l; - // make a copy of the first list. - list_T *const l = tv_list_copy(NULL, l1, false, 0); - if (l == NULL) { + 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->v_type = VAR_LIST; - tv->vval.v_list = l; - // append all items from the second list - tv_list_extend(l, l2, NULL); + tv->vval.v_list = l; return OK; } -- cgit From 56e4c2f67e54b88f637d30e565313bc6b2c22f29 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 19 Sep 2016 00:50:07 +0300 Subject: unittests: Test tv_list_concat() --- src/nvim/eval/typval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 9dd1b62d7d..1cc195ddc4 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -481,7 +481,7 @@ void tv_list_extend(list_T *const l1, list_T *const l2, 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 (listitem_T *item = l2->lv_first + for (listitem_T *item = l2->lv_first ; item != NULL && --todo >= 0 ; item = item->li_next) { tv_list_insert_tv(l1, &item->li_tv, bef); -- cgit From 7ceebacb3fad49ba8321397cf839948caa55b3f5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 24 Sep 2016 00:51:34 +0300 Subject: eval/typval,tests: Fix extending list with itself, add tests Adds unit test for tv_list_extend and regression test for extend() VimL function. --- src/nvim/eval/typval.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 1cc195ddc4..746cbbfe1c 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -479,11 +479,13 @@ void tv_list_extend(list_T *const l1, list_T *const l2, 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->li_next) { + ; item = (item == befbef ? saved_next : item->li_next)) { tv_list_insert_tv(l1, &item->li_tv, bef); } } -- cgit From b3672ae2fced4715963442d2e19048f8fadbe0b8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 2 Oct 2016 04:34:30 +0300 Subject: eval/typval: Add tv_list_equal() tests, compare NULL lists equal --- src/nvim/eval/typval.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 746cbbfe1c..b0b95e955f 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -623,13 +623,12 @@ 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 == NULL || l2 == NULL) { - // FIXME? compare empty list with NULL list equal - return false; - } if (l1 == l2) { return true; } + if (l1 == NULL || l2 == NULL) { + return false; + } if (tv_list_len(l1) != tv_list_len(l2)) { return false; } -- cgit From e5edf07ec44f8d147d7482cae2997be62c30373f Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 4 Nov 2016 19:33:36 +0300 Subject: unittests: Add tests for tv_list_find*() functions Additional modifications: - More `const` qualifiers in tested functions. - `tv_list_find_str()` second argument is more in-line with other `tv_list_find*()` functions. --- src/nvim/eval.c | 2 +- src/nvim/eval/typval.c | 12 ++++++------ src/nvim/ex_docmd.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7c3754607e..d5624f354a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -21783,7 +21783,7 @@ void ex_oldfiles(exarg_T *eap) nr = prompt_for_number(false); msg_starthere(); if (nr > 0 && nr <= l->lv_len) { - const char *const p = tv_list_find_str(l, nr); + const char *const p = tv_list_find_str(l, nr - 1); if (p == NULL) { return; } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index b0b95e955f..ef64467ee5 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -731,7 +731,7 @@ listitem_T *tv_list_find(list_T *const l, int n) /// `*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 *ret_error) +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); @@ -744,16 +744,16 @@ varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *ret_error) return tv_get_number_chk(&li->li_tv, ret_error); } -/// Get list item l[n - 1] as a string +/// Get list item l[n] as a string /// /// @param[in] l List to index. /// @param[in] n Index in a list. /// -/// @return [allocated] Copy of the list item string value. -const char *tv_list_find_str(list_T *l, int n) - FUNC_ATTR_MALLOC +/// @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 - 1); + const listitem_T *const li = tv_list_find(l, n); if (li == NULL) { EMSGN(_(e_listidx), n); return NULL; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 73b81ac2d9..26cfec991f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8424,7 +8424,7 @@ eval_vars ( return NULL; } result = (char_u *)tv_list_find_str(get_vim_var_list(VV_OLDFILES), - (long)i); + i - 1); if (result == NULL) { *errormsg = (char_u *)""; return NULL; -- cgit From 56e51033abf00d66e9c6f9412e8f57c9a24b86ae Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 5 Nov 2016 00:07:34 +0300 Subject: unittests: Add tests for tv_list_idx_of_item --- src/nvim/eval/typval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index ef64467ee5..4adc31d10a 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -774,7 +774,7 @@ long tv_list_idx_of_item(const list_T *const l, const listitem_T *const item) return -1; } long idx = 0; - listitem_T *li; + const listitem_T *li; for (li = l->lv_first; li != NULL && li != item; li = li->li_next) { idx++; } -- cgit From 9ed9af7e11e3a707f65abfeb1d02b029e39241ea Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 5 Nov 2016 00:26:33 +0300 Subject: eval/typval: More `const` qualifiers in `tv_dict*` function signatures --- src/nvim/eval/typval.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 4adc31d10a..57025250d4 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1096,7 +1096,7 @@ dictitem_T *tv_dict_find(const dict_T *const d, const char *const key, /// @param[in] key Key to find in dictionary. /// /// @return Dictionary item. -varnumber_T tv_dict_get_number(dict_T *const d, const char *const key) +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); @@ -1116,7 +1116,7 @@ varnumber_T tv_dict_get_number(dict_T *const d, const char *const key) /// @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(dict_T *const d, const char *const key, +char *tv_dict_get_string(const dict_T *const d, const char *const key, const bool save) FUNC_ATTR_WARN_UNUSED_RESULT { @@ -1136,11 +1136,11 @@ char *tv_dict_get_string(dict_T *const d, const char *const key, /// /// @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(dict_T *const d, const char *const key, +const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key, char *const numbuf) FUNC_ATTR_WARN_UNUSED_RESULT { - dictitem_T *const di = tv_dict_find(d, key, -1); + const dictitem_T *const di = tv_dict_find(d, key, -1); if (di == NULL) { return NULL; } -- cgit From 4bcee963471abd939bb9edd1709418e30be7290f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 5 Nov 2016 01:03:44 +0300 Subject: *: Fix some Windows-specific warnings Also fixed an error in path_fnamecmp(). --- src/nvim/api/buffer.c | 4 ++-- src/nvim/event/rstream.c | 10 ++++++++-- src/nvim/ex_getln.c | 2 +- src/nvim/file_search.c | 5 ++++- src/nvim/fileio.c | 2 +- src/nvim/indent_c.c | 2 +- src/nvim/os/env.c | 1 + src/nvim/os/pty_process_win.h | 5 +++-- src/nvim/path.c | 26 +++++++++++++------------- 9 files changed, 34 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index b75a2c7211..037a6ee1da 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -395,10 +395,10 @@ void nvim_buf_set_lines(uint64_t channel_id, mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra); } - changed_lines((linenr_T)start, 0, (linenr_T)end, extra); + changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra); if (save_curbuf.br_buf == NULL) { - fix_cursor((linenr_T)start, (linenr_T)end, extra); + fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra); } end: diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 92efc9fa2e..2737dad305 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -89,7 +89,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 @@ -136,7 +139,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/ex_getln.c b/src/nvim/ex_getln.c index a0981a42ce..e140dfa886 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -579,7 +579,7 @@ static int command_line_execute(VimState *state, int key) } if (vim_ispathsep(ccline.cmdbuff[s->j]) #ifdef BACKSLASH_IN_FILENAME - && vim_strchr(" *?[{`$%#", ccline.cmdbuff[s->j + 1]) + && strchr(" *?[{`$%#", ccline.cmdbuff[s->j + 1]) == NULL #endif ) { diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index f7932bc296..9592235905 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -322,8 +322,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 diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 127efda65c..bd632b2755 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -5207,7 +5207,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++) { diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 7b758b4dac..4a73fbaf61 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -174,7 +174,7 @@ static char_u *skip_string(char_u *p) char_u *paren = vim_strchr(delim, '('); if (paren != NULL) { - ptrdiff_t delim_len = paren - delim; + const ptrdiff_t delim_len = paren - delim; for (p += 3; *p; ++p) if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0 diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index a73d753e46..ae69462055 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -18,6 +18,7 @@ #include "nvim/eval.h" #include "nvim/ex_getln.h" #include "nvim/version.h" +#include "nvim/fileio.h" #ifdef WIN32 #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h index 20cc589925..8e2b37a1c1 100644 --- a/src/nvim/os/pty_process_win.h +++ b/src/nvim/os/pty_process_win.h @@ -12,8 +12,9 @@ typedef struct pty_process { #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) +#define pty_process_resize(job, width, height) ( \ + (void)job, (void)width, (void)height, 0) +#define pty_process_teardown(loop) ((void)loop, 0) static inline PtyProcess pty_process_init(Loop *loop, void *data) { diff --git a/src/nvim/path.c b/src/nvim/path.c index e92261f4fd..d0248690d9 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -312,7 +312,7 @@ int path_fnamecmp(const char *fname1, const char *fname2) /// /// @return 0 if they are equal, non-zero otherwise. int path_fnamencmp(const char *const fname1, const char *const fname2, - const size_t len) + size_t len) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { #ifdef BACKSLASH_IN_FILENAME @@ -322,16 +322,16 @@ int path_fnamencmp(const char *const fname1, const char *const fname2, const char *p1 = fname1; const char *p2 = fname2; while (len > 0) { - c1 = PTR2CHAR(p1); - c2 = PTR2CHAR(p2); - if (c1 == NUL || c2 == NUL - || (!((c1 == '/' || c1 == '\\') && (c2 == '\\' || c2 == '/'))) - || (p_fic ? (c1 != c2 && CH_FOLD(c1) != CH_FOLD(c2)) : c1 != c2)) { + 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(p1); - p1 += MB_PTR2LEN(p1); - p2 += MB_PTR2LEN(p2); + len -= MB_PTR2LEN((const char_u *)p1); + p1 += MB_PTR2LEN((const char_u *)p1); + p2 += MB_PTR2LEN((const char_u *)p2); } return c1 - c2; #else @@ -819,7 +819,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); } @@ -1333,12 +1333,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); } -- cgit From 1e3e302dc2bdced563ecd2c3fb101af31f72b3df Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Dec 2016 21:58:19 +0300 Subject: eval: Move part of dictwatcher* functions to eval/typval --- src/nvim/eval.c | 57 ++++++-------------------------- src/nvim/eval/typval.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/nvim/eval/typval.h | 27 +++++++-------- src/nvim/os/env.c | 1 - 4 files changed, 111 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d5624f354a..80278cf3bb 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7706,6 +7706,11 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type != VAR_DICT) { emsgf(_(e_invarg2), "dict"); return; + } 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[1].v_type != VAR_STRING && argvars[1].v_type != VAR_NUMBER) { @@ -7725,11 +7730,8 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - DictWatcher *watcher = xmalloc(sizeof(DictWatcher)); - watcher->key_pattern = xmemdupz(key_pattern, key_pattern_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 @@ -7759,28 +7761,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 = tv_dict_watcher_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); - tv_dict_watcher_free(watcher); + callback_free(&callback); } /* @@ -16576,7 +16562,6 @@ bool callback_from_typval(Callback *const callback, typval_T *const arg) return true; } - /// Unref/free callback void callback_free(Callback *const callback) FUNC_ATTR_NONNULL_ALL @@ -16601,28 +16586,6 @@ void callback_free(Callback *const callback) 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(); - } -} - bool callback_call(Callback *const callback, const int argcount_in, typval_T *const argvars_in, typval_T *const rettv) FUNC_ATTR_NONNULL_ALL diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 57025250d4..243e738c50 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -790,7 +790,7 @@ long tv_list_idx_of_item(const list_T *const l, const listitem_T *const item) /// Perform all necessary cleanup for a `DictWatcher` instance /// /// @param watcher Watcher to free. -void tv_dict_watcher_free(DictWatcher *watcher) +static void tv_dict_watcher_free(DictWatcher *watcher) FUNC_ATTR_NONNULL_ALL { callback_free(&watcher->callback); @@ -798,6 +798,91 @@ void tv_dict_watcher_free(DictWatcher *watcher) 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) +{ + 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. +static 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; + } + } +} + +/// 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. @@ -810,7 +895,7 @@ static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key) // 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 = strlen(watcher->key_pattern); + 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 { diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 791b191009..fa0105197f 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -59,6 +59,7 @@ typedef struct { 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; @@ -322,19 +323,6 @@ static inline bool tv_dict_is_watched(const dict_T *const d) return d && !QUEUE_EMPTY(&d->watchers); } -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; - -/// 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); -} - /// Initialize VimL object /// /// Initializes to unlocked VAR_UNKNOWN object. @@ -407,6 +395,19 @@ static inline bool tv_get_float_chk(const typval_T *const tv, 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); +} + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/typval.h.generated.h" #endif diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index ae69462055..a73d753e46 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -18,7 +18,6 @@ #include "nvim/eval.h" #include "nvim/ex_getln.h" #include "nvim/version.h" -#include "nvim/fileio.h" #ifdef WIN32 #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 -- cgit From a56f2d27e3c09aaae00a58a70652ac5db3287dee Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Dec 2016 22:35:10 +0300 Subject: eval: Make dictionary watchers work with empty keys Looks like dict_notifications_spec test used to depend on some state which should not be preserved. Changed all `setup()` calls to `before_each()` and added necessary state in addition to changes required to test empty keys. Note: unit tests for tv_dict_watcher* are still needed. --- src/nvim/eval.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 80278cf3bb..bd88678f16 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -160,7 +160,6 @@ 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"); @@ -2112,8 +2111,9 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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; -- cgit From 3025431c81daac873e69a71aee695ebfd00504f7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 4 Dec 2016 22:59:25 +0300 Subject: eval: Make sure that v:_null_dict does not crash dictwatcher*() Ref #4615 --- src/nvim/eval/typval.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 243e738c50..8c11f4bd8f 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -808,6 +808,9 @@ 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; -- cgit From 506b938947b7083fc8bef20eabc08ed033298add Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 14 Feb 2017 00:12:57 +0300 Subject: *: Make some more things const and with length --- src/nvim/buffer.c | 2 +- src/nvim/eval.c | 197 +++++++++++++++++++++++++------------------------ src/nvim/eval/typval.c | 2 +- src/nvim/ex_cmds2.c | 6 +- src/nvim/option.c | 2 +- src/nvim/syntax.c | 19 ++--- 6 files changed, 116 insertions(+), 112 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0fb9a21354..c9101c5b53 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3504,7 +3504,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); // } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index bd88678f16..67f6c8ba3a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -137,25 +137,24 @@ * "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_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_( @@ -729,7 +728,7 @@ void set_internal_string_var(char_u *name, char_u *value) .vval.v_string = value, }; - set_var((const char *)name, (typval_T *)&tv, true); + set_var((const char *)name, STRLEN(name), (typval_T *)&tv, true); } static lval_T *redir_lval = NULL; @@ -768,8 +767,8 @@ var_redir_start ( // 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) { + 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 */ @@ -2021,15 +2020,11 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, const int flags, const int fne_flags) FUNC_ATTR_NONNULL_ARG(1, 3) { - char_u *p; - 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; @@ -2038,16 +2033,18 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, if (skip) { // When skipping just find the end of the name. - lp->ll_name = (char_u *)name; - return (char_u *)find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); + 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. char_u *expr_start; char_u *expr_end; - p = (char_u *)find_name_end(name, - (const char_u **)&expr_start, - (const char_u **)&expr_end, fne_flags); + 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) @@ -2056,7 +2053,8 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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); if (lp->ll_exp_name == NULL) { /* Report an invalid expression in braces, unless the * expression evaluation has been cancelled due to an @@ -2068,22 +2066,22 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, } } lp->ll_name = lp->ll_exp_name; + lp->ll_name_len = strlen(lp->ll_name); } else { - lp->ll_name = (char_u *)name; + 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((const char *)lp->ll_name, STRLEN(lp->ll_name), &ht, - flags & GLV_NO_AUTOLOAD); + v = find_var(lp->ll_name, lp->ll_name_len, &ht, flags & GLV_NO_AUTOLOAD); if (v == NULL && !quiet) { - EMSG2(_(e_undefvar), lp->ll_name); + emsgf(_("E121: Undefined variable: %.*s"), + (int)lp->ll_name_len, lp->ll_name); } - *p = cc; if (v == NULL) return NULL; @@ -2105,11 +2103,12 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, return NULL; } - len = -1; + int len = -1; + char_u *key; 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(_("E713: Cannot use empty key after .")); @@ -2380,12 +2379,12 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, && !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name, STRLEN(lp->ll_name)))) && eexe_mod_op(&tv, rettv, (const char *)op) == OK) { - set_var((const char *)lp->ll_name, &tv, false); + set_var(lp->ll_name, lp->ll_name_len, &tv, false); } tv_clear(&tv); } } else { - set_var((const char *)lp->ll_name, rettv, copy); + set_var(lp->ll_name, lp->ll_name_len, rettv, copy); } *endp = cc; } else if (tv_check_lock(lp->ll_newkey == NULL @@ -2886,17 +2885,17 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit) *name_end = NUL; // Normal name or expanded name. - if (do_unlet(lp->ll_name, forceit) == FAIL) { + 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, (const char *)lp->ll_name, - STRLEN(lp->ll_name))) + lp->ll_name_len)) || (lp->ll_dict != NULL && tv_check_lock(lp->ll_dict->dv_lock, (const char *)lp->ll_name, - STRLEN(lp->ll_name)))) { + lp->ll_name_len))) { return FAIL; } else if (lp->ll_range) { listitem_T *li; @@ -2906,7 +2905,7 @@ static int do_unlet_var(lval_T *const lp, char_u *const 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, (const char *)lp->ll_name, - STRLEN(lp->ll_name))) { + lp->ll_name_len)) { return false; } ll_li = li; @@ -2953,22 +2952,22 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit) // TODO(ZyX-I): move to eval/ex_cmds -/* - * "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) +/// 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((const char *)name, STRLEN(name), - (const char **)&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 @@ -2977,19 +2976,19 @@ int do_unlet(char_u *name, int forceit) } else if (ht == &compat_hashtab) { d = &vimvardict; } else { - di = find_var_in_ht(ht, *name, "", 0, 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); + 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)) { - di = TV_DICT_HI2DI(hi); + dictitem_T *const di = TV_DICT_HI2DI(hi); if (var_check_fixed(di->di_flags, (const char *)name, STRLEN(name)) || var_check_ro(di->di_flags, (const char *)name, STRLEN(name)) || tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { @@ -3011,7 +3010,7 @@ int do_unlet(char_u *name, int forceit) delete_var(ht, hi); if (watched) { - tv_dict_watcher_notify(dict, (char *)varname, NULL, &oldtv); + tv_dict_watcher_notify(dict, varname, NULL, &oldtv); tv_clear(&oldtv); } return OK; @@ -3041,9 +3040,8 @@ static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep, if (lp->ll_tv == NULL) { // Normal name or expanded name. - const size_t name_len = (size_t)(name_end - lp->ll_name); dictitem_T *const di = find_var( - (const char *)lp->ll_name, name_len, NULL, + (const char *)lp->ll_name, lp->ll_name_len, NULL, true); if (di == NULL) { ret = FAIL; @@ -6561,8 +6559,9 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_list_append_tv(l, &argvars[1]); tv_copy(&argvars[0], rettv); } - } else + } else { EMSG(_(e_listreq)); + } } /* @@ -11216,7 +11215,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_trailing)); } else { if (lv.ll_tv == NULL) { - di = find_var((const char *)lv.ll_name, STRLEN(lv.ll_name), NULL, true); + 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 @@ -14351,7 +14350,7 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) curbuf = buf; memcpy(bufvarname, "b:", 2); memcpy(bufvarname + 2, varname, varname_len + 1); - set_var(bufvarname, varp, true); + set_var(bufvarname, varname_len + 2, varp, true); xfree(bufvarname); curbuf = save_curbuf; } @@ -14876,7 +14875,7 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) char *const tabvarname = xmalloc(varname_len + 3); memcpy(tabvarname, "t:", 2); memcpy(tabvarname + 2, varname, varname_len + 1); - set_var(tabvarname, varp, true); + set_var(tabvarname, varname_len + 2, varp, true); xfree(tabvarname); // Restore current tabpage. @@ -14944,7 +14943,7 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off) char *const winvarname = xmalloc(varname_len + 3); memcpy(winvarname, "w:", 2); memcpy(winvarname + 2, varname, varname_len + 1); - set_var(winvarname, varp, true); + set_var(winvarname, varname_len + 2, varp, true); xfree(winvarname); } } @@ -18766,16 +18765,17 @@ static void list_one_var_a(const char *prefix, const char *name, /// 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, typval_T *const tv, const bool copy) +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; hashtab_T *ht; dict_T *dict; - const size_t name_len = strlen(name); const char *varname; ht = find_var_ht_dict(name, name_len, &varname, &dict); const bool watched = tv_dict_is_watched(dict); @@ -18799,8 +18799,8 @@ static void set_var(const char *name, typval_T *const tv, const bool copy) typval_T oldtv = TV_INITIAL_VALUE; if (v != NULL) { // existing variable, need to clear the value - if (var_check_ro(v->di_flags, (const char *)name, name_len) - || tv_check_lock(v->di_tv.v_lock, (const char *)name, name_len)) { + if (var_check_ro(v->di_flags, name, name_len) + || tv_check_lock(v->di_tv.v_lock, name, name_len)) { return; } @@ -19852,7 +19852,6 @@ trans_function_name( const char_u *start; const char_u *end; int lead; - char_u sid_buf[20]; int len; lval_T lv; @@ -19938,10 +19937,10 @@ trans_function_name( /* Check if the name is a Funcref. If so, use the value. */ if (lv.ll_exp_name != NULL) { - len = (int)STRLEN(lv.ll_exp_name); - name = deref_func_name((const char *)lv.ll_exp_name, &len, partial, + 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 if (!(flags & TFN_NO_DEREF)) { @@ -19966,12 +19965,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) { + && 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; } @@ -19979,38 +19979,40 @@ 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 name() inside a script, translate into 123_name(). - * Accept 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 name() inside a script, translate into 123_name(). + // Accept 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((const char *)lv.ll_exp_name)) + if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) || eval_fname_sid((const char *)(*pp))) { // It's "s:" or "". 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(S_LEN(sid_buf), "%" PRIdSCID "_", current_SID); + lead += sid_buf_len; } } else if (!(flags & TFN_INT) - && builtin_function((const char *)lv.ll_name, len)) { + && 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) && !(flags & TFN_NO_DEREF)) { - char_u *cp = vim_strchr(lv.ll_name, ':'); + 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); @@ -20023,10 +20025,11 @@ trans_function_name( name[0] = K_SPECIAL; name[1] = KS_EXTRA; name[2] = (int)KE_SNR; - if (lead > 3) /* If it's "" */ - STRCPY(name + 3, sid_buf); + if (sid_buf_len > 0) { // If it's "" + 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 = (char_u *)end; @@ -21646,7 +21649,7 @@ void var_set_global(const char *const name, typval_T vartv) { funccall_T *const saved_current_funccal = current_funccal; current_funccal = NULL; - set_var(name, &vartv, false); + set_var(name, strlen(name), &vartv, false); current_funccal = saved_current_funccal; } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 8c11f4bd8f..2f3415a59d 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2041,7 +2041,7 @@ bool tv_islocked(const typval_T *const tv) /// /// @param[in] lock Lock status. /// @param[in] name Variable name, used in the error message. -/// @param[in] use_gettext True if variable name also is to be translated. +/// @param[in] name_len Variable name length. /// /// @return true if variable is locked, false otherwise. bool tv_check_lock(const VarLockStatus lock, const char *const name, diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index b84834d351..213641667d 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2256,8 +2256,8 @@ void ex_compiler(exarg_T *eap) } do_cmdline_cmd("command -nargs=* CompilerSet setlocal "); } - 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) { @@ -2280,7 +2280,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); } } } diff --git a/src/nvim/option.c b/src/nvim/option.c index 8a80c46cf2..9b31e14ea7 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2582,7 +2582,7 @@ did_set_string_option ( // 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); + 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); diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 3f84b8080f..c0adfb10fc 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -3259,9 +3259,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 +3338,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 +3351,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); } } @@ -5538,9 +5539,9 @@ void ex_ownsyntax(exarg_T *eap) } /* restore value of b:current_syntax */ - if (old_value == NULL) - do_unlet((char_u *)"b:current_syntax", TRUE); - else { + 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); } @@ -6231,7 +6232,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(); /* -- cgit From 6aa6e5007596f1eaa23c45376e3a72d908c6688e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 4 Mar 2017 21:35:23 +0300 Subject: eval: Fix linter errors --- src/nvim/eval.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 67f6c8ba3a..937b56179d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2082,8 +2082,9 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, emsgf(_("E121: Undefined variable: %.*s"), (int)lp->ll_name_len, lp->ll_name); } - if (v == NULL) + if (v == NULL) { return NULL; + } /* * Loop until no more [idx] or .key is following. @@ -13431,7 +13432,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) const size_t p_len = strlen(p); cpy = xmallocz(p_len + len); memcpy(cpy, p, p_len + 1); - strncat(cpy + p_len, remain, len); + xstrlcat(cpy + p_len, remain, len); xfree(p); p = cpy; @@ -19968,8 +19969,8 @@ trans_function_name( len = (int)strlen(lv.ll_exp_name); if (lead <= 2 && lv.ll_name == lv.ll_exp_name && 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. */ + // 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; -- cgit From 78a0de2c1b722d5445dfc44cc0635e5ce4bcd23e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 4 Mar 2017 23:30:10 +0300 Subject: eval/typval: Fix -Werror=return-type --- src/nvim/eval/typval.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 2f3415a59d..326334f149 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -845,6 +845,8 @@ static bool tv_callback_equal(const Callback *const cb1, return true; } } + assert(false); + return false; } /// Remove watcher from a dictionary -- cgit From c6c48e8672ab6adbf78453e2b133fe3bd2ee1eb5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 4 Mar 2017 23:30:42 +0300 Subject: syntax: Fix linter error --- src/nvim/syntax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index c0adfb10fc..a54e36a609 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -5538,7 +5538,7 @@ void ex_ownsyntax(exarg_T *eap) set_internal_string_var((char_u *)"w:current_syntax", new_value); } - /* restore value of b:current_syntax */ + // Restore value of b:current_syntax. if (old_value == NULL) { do_unlet(S_LEN("b:current_syntax"), true); } else { -- cgit From 2c8ad276523489223d2d804075a19367280b0f10 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Mar 2017 00:14:11 +0300 Subject: ascii: Readd DEL_STR define --- src/nvim/ascii.h | 1 + src/nvim/tui/tui.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h index 37b83efb61..adde91f9ec 100644 --- a/src/nvim/ascii.h +++ b/src/nvim/ascii.h @@ -26,6 +26,7 @@ #define ESC '\033' #define ESC_STR "\033" #define DEL 0x7f +#define DEL_STR "\177" #define CSI 0x9b // Control Sequence Introducer #define CSI_STR "\233" #define DCS 0x90 /* Device Control String */ diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 9fbbe8be92..55936ad58d 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1015,7 +1015,7 @@ static const char *tui_tk_ti_getstr(const char *name, const char *value, ILOG("libtermkey:kdch1=%s", value); // Vim: "If and are now the same, redefine ." if (stty_erase != NULL && value != NULL && strcmp(stty_erase, value) == 0) { - return stty_erase[0] == DEL ? (char *)CTRL_H_STR : (char *)DEL_STR; + return stty_erase[0] == DEL ? CTRL_H_STR : DEL_STR; } } -- cgit From cdb1aa3e47cb0ec19d2ae597c1d21b7e892d0d7e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Mar 2017 00:47:37 +0300 Subject: eval: Fix len argument to xstrlcat --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 937b56179d..cab9d07e56 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13432,7 +13432,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) const size_t p_len = strlen(p); cpy = xmallocz(p_len + len); memcpy(cpy, p, p_len + 1); - xstrlcat(cpy + p_len, remain, len); + xstrlcat(cpy + p_len, remain, len + 1); xfree(p); p = cpy; -- cgit From faddd83db8a71623e78a4d919b2bb55e6a58439d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Mar 2017 01:37:16 +0300 Subject: eval: Fix SEGV in test49 --- src/nvim/eval.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index cab9d07e56..882b2dfa74 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2055,6 +2055,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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 @@ -2064,9 +2065,10 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, 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; - lp->ll_name_len = strlen(lp->ll_name); } else { lp->ll_name = (const char *)name; lp->ll_name_len = (size_t)((const char *)p - lp->ll_name); -- cgit From 38dd81c136c2edbda66614622a4747bf1785af94 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Mar 2017 02:15:17 +0300 Subject: eval/typval: Fix SEGV in test_alot.vim test --- src/nvim/eval/typval.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 326334f149..8d1ecf8f14 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1167,8 +1167,11 @@ void tv_dict_unref(dict_T *const d) /// @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_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT + 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)); -- cgit From 3bf87a5a6b0e8b2e81534081196c20dddc45474b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Mar 2017 02:51:44 +0300 Subject: eval: Do not use S_LEN as snprintf argument --- src/nvim/eval.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 882b2dfa74..88ba0b95cc 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -20004,7 +20004,8 @@ trans_function_name( EMSG(_(e_usingsid)); goto theend; } - sid_buf_len = snprintf(S_LEN(sid_buf), "%" PRIdSCID "_", current_SID); + sid_buf_len = snprintf(sid_buf, sizeof(sid_buf), + "%" PRIdSCID "_", current_SID); lead += sid_buf_len; } } else if (!(flags & TFN_INT) -- cgit From f830243ff7b78b9bb41e72fd602b99c2893b5437 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Mar 2017 03:10:34 +0300 Subject: mbyte: Include os_defs.h in mbyte.h --- src/nvim/mbyte.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index c20e6d47ff..3565202466 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -6,6 +6,7 @@ #include "nvim/iconv.h" #include "nvim/func_attr.h" +#include "nvim/os/os_defs.h" // For WCHAR, indirect /* * Return byte length of character that starts with byte "b". -- cgit From b222453c95dbe466b79abd578642fa6038770a55 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 12 Mar 2017 21:58:38 +0300 Subject: eval/typval: Refactor errors a bit: use emsgf always --- src/nvim/eval/typval.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 8d1ecf8f14..867330c137 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -755,7 +755,7 @@ const char *tv_list_find_str(list_T *const l, const int n) { const listitem_T *const li = tv_list_find(l, n); if (li == NULL) { - EMSGN(_(e_listidx), n); + emsgf(_(e_listidx), (int64_t)n); return NULL; } return tv_get_string(&li->li_tv); @@ -1264,14 +1264,14 @@ bool tv_dict_get_callback(dict_T *const d, 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")); + 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); - bool res = callback_from_typval(result, &tv); + const bool res = callback_from_typval(result, &tv); tv_clear(&tv); return res; } @@ -1942,7 +1942,7 @@ void tv_copy(typval_T *const from, typval_T *const to) break; } case VAR_UNKNOWN: { - EMSG2(_(e_intern2), "tv_copy(UNKNOWN)"); + emsgf(_(e_intern2), "tv_copy(UNKNOWN)"); break; } } @@ -2259,7 +2259,7 @@ bool tv_check_num(const typval_T *const tv) case VAR_DICT: case VAR_FLOAT: case VAR_UNKNOWN: { - EMSG(_(num_errors[tv->v_type])); + emsgf(_(num_errors[tv->v_type])); return false; } } @@ -2303,7 +2303,7 @@ bool tv_check_str(const typval_T *const tv) case VAR_DICT: case VAR_FLOAT: case VAR_UNKNOWN: { - EMSG(_(str_errors[tv->v_type])); + emsgf(_(str_errors[tv->v_type])); return false; } } @@ -2350,7 +2350,7 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error) case VAR_LIST: case VAR_DICT: case VAR_FLOAT: { - EMSG(_(num_errors[tv->v_type])); + emsgf(_(num_errors[tv->v_type])); break; } case VAR_NUMBER: { @@ -2378,7 +2378,7 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error) break; } case VAR_UNKNOWN: { - EMSG2(_(e_intern2), "tv_get_number(UNKNOWN)"); + emsgf(_(e_intern2), "tv_get_number(UNKNOWN)"); break; } } @@ -2428,27 +2428,27 @@ float_T tv_get_float(const typval_T *const tv) } case VAR_PARTIAL: case VAR_FUNC: { - EMSG(_("E891: Using a Funcref as a Float")); + emsgf(_("E891: Using a Funcref as a Float")); break; } case VAR_STRING: { - EMSG(_("E892: Using a String as a Float")); + emsgf(_("E892: Using a String as a Float")); break; } case VAR_LIST: { - EMSG(_("E893: Using a List as a Float")); + emsgf(_("E893: Using a List as a Float")); break; } case VAR_DICT: { - EMSG(_("E894: Using a Dictionary as a Float")); + emsgf(_("E894: Using a Dictionary as a Float")); break; } case VAR_SPECIAL: { - EMSG(_("E907: Using a special value as a Float")); + emsgf(_("E907: Using a special value as a Float")); break; } case VAR_UNKNOWN: { - EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)"); + emsgf(_(e_intern2), "get_tv_float(UNKNOWN)"); break; } } @@ -2490,7 +2490,7 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf) case VAR_DICT: case VAR_FLOAT: case VAR_UNKNOWN: { - EMSG(_(str_errors[tv->v_type])); + emsgf(_(str_errors[tv->v_type])); return false; } } -- cgit From bc87d23c28c10c70b4addaf18ae16bcbe0682c8a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 12 Mar 2017 21:58:57 +0300 Subject: unittests: Add tests for dictionary indexing --- src/nvim/vim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/vim.h b/src/nvim/vim.h index e16ee00309..cc0587fb88 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -30,7 +30,7 @@ Error: configure did not run properly.Check auto/config.log. #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 -- cgit From 270a3889af024485fa7b63f34c4dd3f92f6e0f98 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 13 Mar 2017 01:45:44 +0300 Subject: unittests: Add tv_dict_add* unit tests Also fixes incorrect location of `tv_dict_add` function and three bugs in other functions: 1. `tv_dict_add_list` may free list it does not own (vim/vim#1555). 2. `tv_dict_add_dict` may free dictionary it does not own (vim/vim#1555). 3. `tv_dict_add_dict` ignores `key_len` argument. --- src/nvim/eval/typval.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 867330c137..d9feb2d88e 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1009,18 +1009,6 @@ void tv_dict_item_free(dictitem_T *const item) } } -/// 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); -} - /// Make a copy of a dictionary item /// /// @param[in] di Item to copy. @@ -1278,6 +1266,18 @@ bool tv_dict_get_callback(dict_T *const d, //{{{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. @@ -1295,11 +1295,11 @@ int tv_dict_add_list(dict_T *const d, const char *const key, 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; } - list->lv_refcount++; return OK; } @@ -1313,18 +1313,18 @@ int tv_dict_add_list(dict_T *const d, const char *const key, /// @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 + FUNC_ATTR_NONNULL_ALL { - dictitem_T *const item = tv_dict_item_alloc(key); + 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; } - dict->dv_refcount++; return OK; } -- cgit From 43e9fad1c8835a3136f4db53c82608e034df2a5e Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 13 Mar 2017 13:43:01 +0300 Subject: eval: Use tv_is_func in place of ==VAR_FUNC||==VAR_PARTIAL Also fixes same error as in vim/vim#1557 --- src/nvim/eval.c | 25 ++++++++----------------- src/nvim/eval/typval.c | 9 +++------ src/nvim/eval/typval.h | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 88ba0b95cc..cab22c599a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2225,7 +2225,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, prevval = 0; // Avoid compiler warning. } wrong = ((lp->ll_dict->dv_scope == VAR_DEF_SCOPE - && rettv->v_type == VAR_FUNC + && tv_is_func(*rettv) && !var_check_func_name((const char *)key, lp->ll_di == NULL)) || !valid_varname((const char *)key)); if (len != -1) { @@ -3643,9 +3643,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) 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")); tv_clear(rettv); @@ -8957,8 +8955,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; @@ -15994,7 +15991,7 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *const flg = tv_get_string_buf_chk(&argvars[3], flagsbuf); typval_T *expr = NULL; - if (argvars[2].v_type == VAR_FUNC || argvars[2].v_type == VAR_PARTIAL) { + if (tv_is_func(argvars[2])) { expr = &argvars[2]; } else { sub = tv_get_string_buf_chk(&argvars[2], subbuf); @@ -18229,8 +18226,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; @@ -18286,9 +18282,7 @@ handle_subscript( } // 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); } @@ -18794,8 +18788,7 @@ static void set_var(const char *name, const size_t name_len, typval_T *const tv, v = find_var_in_scoped_ht((const char *)name, name_len, true); } - if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) - && !var_check_func_name(name, v == NULL)) { + if (tv_is_func(*tv) && !var_check_func_name(name, v == NULL)) { return; } @@ -19463,9 +19456,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]))) diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index d9feb2d88e..620da0032e 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1250,8 +1250,7 @@ bool tv_dict_get_callback(dict_T *const d, return true; } - if (di->di_tv.v_type != VAR_FUNC && di->di_tv.v_type != VAR_STRING - && di->di_tv.v_type != VAR_PARTIAL) { + 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; } @@ -1418,7 +1417,7 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, // 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 - && di2->di_tv.v_type == VAR_FUNC + && tv_is_func(di2->di_tv) && !var_check_func_name((const char *)di2->di_key, di1 == NULL)) { break; } @@ -2101,9 +2100,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, // TODO(ZyX-I): Make this not recursive static int recursive_cnt = 0; // Catch recursive loops. - if (!((tv1->v_type == VAR_FUNC || tv1->v_type == VAR_PARTIAL) - && (tv2->v_type == VAR_FUNC || tv2->v_type == VAR_PARTIAL)) - && tv1->v_type != tv2->v_type) { + if (!(tv_is_func(*tv1) && tv_is_func(*tv2)) && tv1->v_type != tv2->v_type) { return false; } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index fa0105197f..7eab22bc12 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -408,6 +408,21 @@ 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; +} + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/typval.h.generated.h" #endif -- cgit From fa852e7cdc365b6fcd39d677f4067963274c44c3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 13 Mar 2017 14:17:35 +0300 Subject: eval: Fix extend() behaviour with NULL lists and dictionaries Ref #4615 Ref vim/vim#768 --- src/nvim/eval.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index cab22c599a..9950f8b196 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8155,15 +8155,20 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) const size_t arg_errmsg_len = strlen(arg_errmsg); if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) { - list_T *l1, *l2; - listitem_T *item; long before; bool error = false; - l1 = argvars[0].vval.v_list; - l2 = argvars[1].vval.v_list; - if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, arg_errmsg_len) - && l2 != NULL) { + 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, arg_errmsg_len); + (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, arg_errmsg_len)) { + listitem_T *item; if (argvars[2].v_type != VAR_UNKNOWN) { before = tv_get_number_chk(&argvars[2], &error); if (error) { @@ -8187,13 +8192,16 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) { - dict_T *d1; - dict_T *d2; - - d1 = argvars[0].vval.v_dict; - d2 = argvars[1].vval.v_dict; - if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, arg_errmsg_len) - && d2 != NULL) { + 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, arg_errmsg_len); + (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, arg_errmsg_len)) { const char *action = "force"; // Check the third argument. if (argvars[2].v_type != VAR_UNKNOWN) { -- cgit From 218fa1d8069c1f1d8c5154b1abc2b686adc0c742 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 13 Mar 2017 14:39:34 +0300 Subject: charset: Remove useless condition from vim_iswordc_tab --- src/nvim/charset.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 6c22108853..ad0efa2c28 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -787,10 +787,9 @@ bool vim_iswordc(int c) bool vim_iswordc_tab(const int c, const uint64_t *const chartab) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - if (c >= 0x100) { - return utf_class(c) >= 2; - } - return c > 0 && c < 0x100 && GET_CHARTAB_TAB(chartab, c) != 0; + return (c >= 0x100 + ? (utf_class(c) >= 2) + : (c > 0 && GET_CHARTAB_TAB(chartab, c) != 0)); } /// Check that "c" is a keyword character: -- cgit From f0bbd1e825841c55a1f75d66a9caeaa50cc2259c Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 13 Mar 2017 19:35:12 +0300 Subject: unittests: Add tests for tv_clear() --- src/nvim/eval/typval.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 620da0032e..c245b9222e 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1840,10 +1840,11 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, /// 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 *tv) +void tv_clear(typval_T *const tv) { if (tv != NULL && tv->v_type != VAR_UNKNOWN) { - const int evn_ret = encode_vim_to_nothing(NULL, tv, "tv_clear argument"); + const int evn_ret = encode_vim_to_nothing(NULL, tv, + _("tv_clear() argument")); (void)evn_ret; assert(evn_ret == OK); } -- cgit From 630ff33dc144a64b5488b4132c0fc4351a5c84db Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 25 Mar 2017 19:52:20 +0300 Subject: unittests: Test locks section --- src/nvim/eval/typval.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index c245b9222e..185dd0e86c 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1956,6 +1956,7 @@ void tv_copy(typval_T *const from, typval_T *const to) /// @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; @@ -2031,13 +2032,13 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock) 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) + 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->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))); + && (tv->vval.v_dict->dv_lock == VAR_LOCKED))); } /// Return true if typval is locked -- cgit From e08b27ba4acf22fe180c2a4a6b00f0ea0cfc3a79 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 25 Mar 2017 20:46:39 +0300 Subject: unittests: Add tv_get number tests --- src/nvim/eval/typval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 185dd0e86c..48ff3ab623 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2447,7 +2447,7 @@ float_T tv_get_float(const typval_T *const tv) break; } case VAR_UNKNOWN: { - emsgf(_(e_intern2), "get_tv_float(UNKNOWN)"); + emsgf(_(e_intern2), "tv_get_float(UNKNOWN)"); break; } } -- cgit From 29bad04f9e2e70b7c1c198ca0d86d23282bee8a1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 25 Mar 2017 22:35:34 +0300 Subject: eval: Do not supply S_LEN to strncmp It may be a macro as well. --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 9950f8b196..0d7c585099 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7967,7 +7967,7 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (s == NULL) { return; } - if (strncmp(s, S_LEN("silent")) == 0) { + if (strncmp(s, "silent", 6) == 0) { msg_silent++; } if (strcmp(s, "silent!") == 0) { -- cgit From f4256243dbdbd2858be716f9f52763bd9a76be4d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 25 Mar 2017 22:49:23 +0300 Subject: eval: Fix -Werror=unitialized from QB --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0d7c585099..6890bdc522 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2107,7 +2107,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, } int len = -1; - char_u *key; + char_u *key = NULL; if (*p == '.') { key = p + 1; for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; len++) { -- cgit From 58e34e8d99b01bf3937824fc50502e39a8c39eba Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 26 Mar 2017 03:42:23 +0300 Subject: eval/typval: Allow NULL dict as tv_dict_get_callback() argument Also removes NULL key input: tv_dict_find() does not allow this. --- src/nvim/eval/typval.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 48ff3ab623..da58cf5ca9 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -825,8 +825,7 @@ void tv_dict_watcher_add(dict_T *const dict, const char *const key_pattern, /// @param[in] cb2 Second callback to check. /// /// @return True if they are equal, false otherwise. -static bool tv_callback_equal(const Callback *const cb1, - const Callback *const cb2) +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) { @@ -1240,7 +1239,7 @@ const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key, bool tv_dict_get_callback(dict_T *const d, const char *const key, const ptrdiff_t key_len, Callback *const result) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_NONNULL_ARG(2, 4) FUNC_ATTR_WARN_UNUSED_RESULT { result->type = kCallbackNone; -- cgit From 114eaa15f009cbd3e3deb177a2a67affa430fbb8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 28 Mar 2017 01:07:34 +0300 Subject: eval/typval,api/buffer: Fix review comments --- src/nvim/api/buffer.c | 6 +++--- src/nvim/eval/typval.c | 12 ++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 037a6ee1da..26f9a6f592 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -296,7 +296,7 @@ void nvim_buf_set_lines(uint64_t channel_id, 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++) { @@ -342,8 +342,8 @@ void nvim_buf_set_lines(uint64_t channel_id, } } - 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 diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index da58cf5ca9..779bb18175 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -164,9 +164,8 @@ void tv_list_free_contents(list_T *const l) } l->lv_len = 0; l->lv_idx_item = NULL; - for (listwatch_T *lw = l->lv_watch; lw != NULL; lw = lw->lw_next) { - lw->lw_item = NULL; - } + l->lv_last = NULL; + assert(l->lv_watch == NULL); } /// Free a list itself, ignoring items it contains @@ -230,13 +229,10 @@ 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 != NULL; ip = ip->li_next) { + // 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 (ip == item2) { - break; - } } if (item2->li_next == NULL) { -- cgit From a1d590a08bd9d40d0e20a9907381573c2d069738 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 28 Mar 2017 02:17:51 +0300 Subject: *: Use const char * in set_one_cmd_context Also renames functions added in master and renamed here. --- src/nvim/charset.c | 23 +-- src/nvim/eval.c | 8 +- src/nvim/ex_cmds2.c | 12 +- src/nvim/ex_docmd.c | 444 +++++++++++++++++++++++++++------------------------ src/nvim/ex_getln.c | 9 +- src/nvim/if_cscope.c | 29 ++-- src/nvim/syntax.c | 69 ++++---- 7 files changed, 311 insertions(+), 283 deletions(-) (limited to 'src') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index ad0efa2c28..99d3e2dd88 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1397,7 +1397,8 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, /// /// @return Pointer to character after the skipped whitespace. char_u *skipwhite(const char_u *q) - FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_RET { const char_u *p = q; while (ascii_iswhite(*p)) { @@ -1406,19 +1407,21 @@ char_u *skipwhite(const char_u *q) 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 @@ -1564,17 +1567,17 @@ int vim_tolower(int c) return TOLOWER_LOC(c); } -/// skiptowhite: skip over text until ' ' or '\t' or NUL. +/// Skip over text until ' ' or '\t' or NUL /// -/// @param p +/// @param[in] p Text to skip over. /// /// @return Pointer to the next whitespace or NUL character. -char_u* skiptowhite(char_u *p) +char_u *skiptowhite(const char_u *p) { while (*p != ' ' && *p != '\t' && *p != NUL) { p++; } - return p; + return (char_u *)p; } /// skiptowhite_esc: Like skiptowhite(), but also skip escaped chars diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6890bdc522..80c2fe10d7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -9462,8 +9462,8 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - if (STRCMP(get_tv_string(&argvars[1]), "cmdline") == 0) { - set_one_cmd_context(&xpc, get_tv_string(&argvars[0])); + 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; } @@ -9484,7 +9484,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (xpc.xp_context == EXPAND_CSCOPE) { - set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope); + set_context_in_cscope_cmd(&xpc, (const char *)xpc.xp_pattern, CMD_cscope); xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern); } @@ -14562,7 +14562,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) } else if (title_arg->v_type == VAR_STRING) { title = tv_get_string_chk(title_arg); if (!title) { - // Type error. Error already printed by get_tv_string_chk(). + // Type error. Error already printed by tv_get_string_chk(). return; } } else if (title_arg->v_type == VAR_DICT) { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 213641667d..eeace789b2 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -957,23 +957,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; } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 26cfec991f..0fd4ae48be 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2633,32 +2633,27 @@ int cmd_exists(const char *const 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; strchr(" \t:|", *cmd) != NULL; cmd++) { + } + xp->xp_pattern = (char_u *)cmd; if (*cmd == NUL) return NULL; @@ -2670,14 +2665,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; @@ -2693,6 +2689,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; @@ -2715,20 +2712,21 @@ set_one_cmd_context ( } } // check for non-alpha command - if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL) { + if (p == cmd && strchr("@*!=><&~#", *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 @@ -2745,16 +2743,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' && strchr("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) { @@ -2777,16 +2774,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; } } @@ -2799,23 +2797,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); } /* @@ -2844,19 +2843,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 */ @@ -2866,25 +2864,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; @@ -2897,22 +2896,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); @@ -2922,8 +2925,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. */ @@ -2931,33 +2935,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 will be replaced by user's home - * directory i.e. something like ~user -> /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 will be replaced by user's home + // directory i.e. something like ~user -> /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; @@ -2987,7 +2994,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. @@ -3030,13 +3037,14 @@ set_one_cmd_context ( 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. @@ -3045,15 +3053,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; } @@ -3061,73 +3069,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: @@ -3137,36 +3153,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: @@ -3178,15 +3198,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); @@ -3203,20 +3224,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: @@ -3231,33 +3253,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 == ' ') @@ -3267,9 +3293,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: @@ -3281,8 +3307,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: @@ -3292,18 +3318,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: @@ -3313,47 +3339,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 @@ -3362,16 +3390,16 @@ 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_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; @@ -3390,10 +3418,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; @@ -3418,7 +3445,7 @@ skip_range ( while (*cmd == ':') cmd = skipwhite(cmd + 1); - return cmd; + return (char_u *)cmd; } /* @@ -4585,14 +4612,15 @@ 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; } /* diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index e140dfa886..8810204c03 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -3636,7 +3636,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 @@ -3645,7 +3644,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 @@ -3654,9 +3653,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. */ diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 550d256de5..b647b8146a 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -140,31 +140,30 @@ 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; + } } } } diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index a54e36a609..4a7b4a0eac 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -5574,43 +5574,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; + } } } } @@ -7474,41 +7473,41 @@ int highlight_changed(void) /* * 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; + } } } } -- cgit From b9603218be3b7bf3fbc30eee6c7c458b01902584 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 28 Mar 2017 08:12:09 +0300 Subject: eval/executor: Fix check-single-includes --- src/nvim/eval/executor.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nvim/eval/executor.h b/src/nvim/eval/executor.h index 19e2a75914..3d789f76a5 100644 --- a/src/nvim/eval/executor.h +++ b/src/nvim/eval/executor.h @@ -1,6 +1,8 @@ #ifndef NVIM_EVAL_EXECUTOR_H #define NVIM_EVAL_EXECUTOR_H +#include "nvim/eval/typval.h" + extern char *e_listidx; #ifdef INCLUDE_GENERATED_DECLARATIONS -- cgit From 2846d508b24eb9f8ab59d21a060fd8130906392f Mon Sep 17 00:00:00 2001 From: lonerover Date: Wed, 29 Mar 2017 22:48:50 +0800 Subject: vim-patch:7.4.2276 (#6393) * vim-patch:7.4.2276 Problem: Command line test fails on Windows when run twice. Solution: Wipe the buffer so that the directory can be deleted. https://github.com/vim/vim/commit/1773ddfdcd106fa3bbf479c9b62ccde03c2a86ba * version.c: mark vim-patch 7.4.2269 as included (#5659) --- src/nvim/testdir/test_cmdline.vim | 1 + src/nvim/version.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index f56227250c..0c9d1297d6 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -201,5 +201,6 @@ func Test_expand_star_star() call writefile(['asdfasdf'], 'a/b/fileXname') call feedkeys(":find **/fileXname\\", 'xt') call assert_equal('find a/b/fileXname', getreg(':')) + bwipe! call delete('a', 'rf') endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index dd583f6ffd..020737ac8c 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -165,14 +165,14 @@ static int included_patches[] = { 2279, // 2278 NA 2277, - // 2276, + 2276, 2275, 2274, 2273, 2272, // 2271 NA // 2270 NA - // 2269, + 2269, // 2268, // 2267 NA 2266, -- cgit From 05b74399aa40c813b195d595aa3878ff42e61ab8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 29 Mar 2017 17:39:06 +0200 Subject: build: remove unused get_preproc_output() call ref https://github.com/neovim/neovim/pull/6375#discussion_r108573471 --- src/nvim/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index e752f5d4df..bad43e7f72 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -461,10 +461,8 @@ foreach(hfile ${NVIM_HEADERS}) if(NOT ${hfile} MATCHES "[.]c[.]h$") set(tsource "${GENERATED_DIR}/${r}.test-include.c") - set(tresult "${GENERATED_DIR}/${r}.test-include.i") string(REPLACE "/" "-" texe "test-incl-${r}") write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }") - get_preproc_output(PREPROC_OUTPUT ${tresult}) add_executable( ${texe} EXCLUDE_FROM_ALL -- cgit From 6964b67c00f9aa029791137f44f30ed4aef20ef4 Mon Sep 17 00:00:00 2001 From: relnod Date: Thu, 30 Mar 2017 00:50:11 +0200 Subject: refactor/single-include: buffer.h (#6396) --- src/nvim/CMakeLists.txt | 1 - src/nvim/buffer.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index c5bf79c0e5..a3bacaa9d2 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -394,7 +394,6 @@ target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES}) set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTING) set(NO_SINGLE_CHECK_HEADERS - buffer cursor_shape diff digraph diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h index c915d373aa..016c5ce3b7 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -1,6 +1,7 @@ #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 -- cgit From 1f478cebeb929332e90c1b50de4b8a4f311a0df2 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 29 Mar 2017 18:29:46 +0200 Subject: win: tempname(): Use $TMPDIR if defined. --- src/nvim/os/win_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 827fb2f247..7c980c3768 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -19,7 +19,7 @@ #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 "\"*?><|" -- cgit From 3116f870ba274862fa6d6643d9fa0870215fed12 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 29 Mar 2017 16:30:06 -0400 Subject: coverity/161195: Increase scope of exe_name Since exe_name is a stack allocated array, we need it to be in scope for the lifetime that vim_path points to it. --- src/nvim/os/env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index a73d753e46..a10c835591 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -615,9 +615,9 @@ char *vim_getenv(const char *name) vim_path = (char *)p_hf; } + char exe_name[MAXPATHL]; // Find runtime path relative to the nvim binary: ../share/nvim/runtime if (vim_path == NULL) { - char exe_name[MAXPATHL]; size_t exe_name_len = MAXPATHL; if (os_exepath(exe_name, &exe_name_len) == 0) { char *path_end = (char *)path_tail_with_sep((char_u *)exe_name); -- cgit From 1c6ae58fd1301bfe2b27ed168b5a117e92c9c4cd Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 29 Mar 2017 16:51:46 -0400 Subject: coverity/161194: Restore check for 'keywordprg' being ":help" 998d0ffc09d5c7358db62dc88c2e2b87622f60b5 removed the explicit check for ":help", relying instead on whether the user was in a help buffer. However, this breaks escaping the identifier for use in the lookup command. 2f54d6927cc02484b528a5e8b25b64c8d6580ddd tried to fix this by removing "!kp_ex" in "if (cmdchar == 'K' && !kp_ex)", but that causes shell escaping to be used instead of escaping for tag lookup. --- src/nvim/normal.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index d4919dc3b6..388ddfc8bb 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4670,6 +4670,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; @@ -4692,7 +4693,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)); } @@ -4755,7 +4758,7 @@ static void nv_ident(cmdarg_T *cap) } // Now grab the chars in the identifier - if (cmdchar == 'K') { + if (cmdchar == 'K' && !kp_help) { ptr = vim_strnsave(ptr, n); if (kp_ex) { // Escape the argument properly for an Ex command -- cgit From 91dfebf0506c4389af77071323798fdd7360c589 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 29 Mar 2017 20:45:22 -0400 Subject: ci: Update Coverity model for typval refactoring [ci skip] --- src/coverity-model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/coverity-model.c b/src/coverity-model.c index a01ea6d316..3c38e4ae4d 100644 --- a/src/coverity-model.c +++ b/src/coverity-model.c @@ -64,7 +64,7 @@ void *je_realloc(void *ptr, size_t size) // of the memory allocated for item. typedef struct {} dictitem_T; typedef struct {} dict_T; -int dict_add(dict_T *d, dictitem_T *item) +int tv_dict_add(dict_T *const d, dictitem_T *const item) { __coverity_escape__(item); } -- cgit From 1222c82799b9a853c5adaf8761309b616e664c95 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 29 Mar 2017 21:34:04 -0400 Subject: coverity/16127: Verify lang is non-NULL before calling strlen --- src/nvim/option.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 9b31e14ea7..69c12e2cc7 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1054,13 +1054,15 @@ void set_init_3(void) */ void set_helplang_default(const char *lang) { - int idx; + if (lang == NULL) { + return; + } const size_t lang_len = strlen(lang); - if (lang == NULL || lang_len < 2) { // safety check + if (lang_len < 2) { // safety check return; } - idx = findoption("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); -- cgit From 75b98f7c3f23b18e30c362028af3bf3dae663a02 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 30 Mar 2017 10:09:33 -0400 Subject: Remove PVS-Studio cruft [ci skip] --- src/nvim/move.PVS-Studio.cfg | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/nvim/move.PVS-Studio.cfg (limited to 'src') diff --git a/src/nvim/move.PVS-Studio.cfg b/src/nvim/move.PVS-Studio.cfg deleted file mode 100644 index cb6da32f12..0000000000 --- a/src/nvim/move.PVS-Studio.cfg +++ /dev/null @@ -1,10 +0,0 @@ - -source-file=/home/zyx/a.a/Proj/c/neovim/src/nvim/move.c -i-file=/home/zyx/a.a/Proj/c/neovim/src/nvim/move.i -language=C -skip-cl-exe=yes -preprocessor=gcc -platform=linux64 -lic-file=/home/zyx/a.a/Proj/c/neovim/build/../PVS-Studio.lic -output-file=/home/zyx/a.a/Proj/c/neovim/build/../PVS-Studio.log.x -analysis-mode=4 -- cgit From eb0e94f71b1f44cebf7ae5c1bcff348264af6cef Mon Sep 17 00:00:00 2001 From: Jakob Schnitzer Date: Thu, 30 Mar 2017 22:03:52 +0200 Subject: api: {get,set}_option should {get,set} global value of local options (#6405) - nvim_get_option should return the global default of a local option. - nvim_set_option should set the global default of a local option. --- src/nvim/api/private/helpers.c | 2 +- src/nvim/api/vim.c | 2 +- src/nvim/option.c | 24 +++++++++++++----------- src/nvim/option_defs.h | 6 +++--- 4 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index b245132ba7..fe15b28041 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -289,7 +289,7 @@ 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) { diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 975446057c..6926436d2f 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -440,7 +440,7 @@ 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) { diff --git a/src/nvim/option.c b/src/nvim/option.c index 9b31e14ea7..0bf81b4d3a 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4619,14 +4619,13 @@ int get_option_value_strict(char *name, } char_u *varp = NULL; - vimoption_T *p; int rv = 0; 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) { @@ -4642,26 +4641,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; } @@ -4673,7 +4671,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 @@ -4720,7 +4722,7 @@ int get_option_value_strict(char *name, /// @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 or 0 (both). +/// @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, diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 94c6361236..2475a0b6a1 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'. -- cgit From 831eb2a9bf9fdffc1b6942e4c43bc2458f4af794 Mon Sep 17 00:00:00 2001 From: Michael Ennen Date: Thu, 30 Mar 2017 16:07:39 -0700 Subject: vim-patch:7.4.2104 (#6332) Problem: Code duplication when unreferencing a function. Solution: De-duplicate. https://github.com/vim/vim/commit/97baee80f0906ee2f651ee1215ec033e84f866ad --- src/nvim/eval.c | 8 +------- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 80c2fe10d7..a83e93090a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -20711,13 +20711,7 @@ void func_unref(char_u *name) abort(); #endif } - 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_clear_free(fp, false); - } - } + func_ptr_unref(fp); } /// Unreference a Function: decrement the reference count and free it when it diff --git a/src/nvim/version.c b/src/nvim/version.c index 9275a2e5bd..fdf5436a98 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -337,7 +337,7 @@ static const int included_patches[] = { 2107, 2106, // 2105 NA - // 2104, + 2104, 2103, // 2102 NA 2101, -- cgit From 3a9dd13f9e6471215a738cf22bf180e60a2e0bcd Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Fri, 31 Mar 2017 00:21:26 +0100 Subject: fold.c: more edge-cases when updating (#6207) When foldUpdateIEMSRecurse() re-uses an existing fold, it misses the case where the existing fold spans from before startlnum to after firstlnum, the new fold does not span this range, and there is no "forced start" of a fold. We add a case for this in. Ensure that if there was no forced break in folds, we merge folds that now touch each other. Include testing for a tricky foldmethod=expr case that has never been a bug. This case works at the moment because of some effects that are not obvious when reading the code. A test for this could be useful to ensure a regression doesn't happen. vim-patch:8.0.0408 --- src/nvim/fold.c | 71 +++++++++++++++++-------- src/nvim/testdir/test_fold.vim | 118 +++++++++++++++++++++++++++++++++++------ 2 files changed, 152 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 36a5b0efd7..d810aee0ce 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -2232,32 +2232,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 @@ -2267,6 +2286,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) { diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 976c6b5cd1..46c54e8614 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -100,22 +100,6 @@ func! Test_indent_fold2() bw! 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 Test_manual_fold_with_filter() if !executable('cat') return @@ -138,6 +122,108 @@ func Test_manual_fold_with_filter() endfor endfunc +func! Test_indent_fold_with_read() + new + set foldmethod=indent + call setline(1, repeat(["\a"], 4)) + for n in range(1, 4) + call assert_equal(1, foldlevel(n)) + endfor + + call writefile(["a", "", "\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 = "\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") -- cgit From f4a3a96b6852f2eb5cf68d26b2bf58123c39c602 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 30 Mar 2017 11:06:26 -0400 Subject: Add handling for MSGPACK_OBJECT_FLOAT{32,64} msgpack-c previously only had MSGPACK_OBJECT_FLOAT, which was a 64-bit value. Now, 32-bit and 64-bit floats are supported as distinct types, but we'll simply continue to treat everything as 64-bit types. --- src/nvim/eval/decode.c | 8 +++++++- src/nvim/msgpack_rpc/helpers.c | 13 ++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 3cb68e093b..fb31a65971 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -973,7 +973,13 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) } 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, diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 808bb863fd..4d8a9984e1 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -114,7 +114,13 @@ 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); @@ -181,7 +187,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: { -- cgit From 338da727cdb19a15a0b001707e8778e10977e65c Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 30 Mar 2017 22:11:40 -0400 Subject: coverity/161216: Ensure buf is valid for lifetime of defstr Depending on the type of argument for input()/inputdialog()'s {text} argument, defstr may point to buf. Therefore it needs to be in scope for the lifetime of defstr. Also, use a different buffer for the handling of the 3rd argument to input()/inputdialog(). Although the buffer defstr points to is used immediately, it avoids potential mishaps if the code changes. --- src/nvim/eval.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 80c2fe10d7..c683fe4e10 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -11008,18 +11008,19 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) cmdline_row = msg_row; const char *defstr = ""; + char buf[NUMBUFLEN]; if (argvars[1].v_type != VAR_UNKNOWN) { - char buf[NUMBUFLEN]; defstr = tv_get_string_buf_chk(&argvars[1], buf); if (defstr != NULL) { stuffReadbuffSpec(defstr); } if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) { + char buf2[NUMBUFLEN]; // input() with a third argument: completion rettv->vval.v_string = NULL; - const char *const xp_name = tv_get_string_buf_chk(&argvars[2], buf); + const char *const xp_name = tv_get_string_buf_chk(&argvars[2], buf2); if (xp_name == NULL) { return; } -- cgit From 030c0588a04c7b201ed21ab6bcbc38c040e3d5b6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 31 Mar 2017 10:51:41 +0300 Subject: cmake: Add `clint` target to build Makefile Allows linting only modified files and linting multiple files in parallel. In the current state is rather slow because errors.json is a 6 MiB file and needs to be reparsed each time. Results on my system (6-core): # In build dir, actually parallel make -j5 clint 241.24s user 8.39s system 334% cpu 1:14.74 total # In root, one process make -j5 clint 60.69s user 0.37s system 93% cpu 1:05.19 total In both cases download time included. That is not well for travis (though I would keep travis as-is because new variant will fail before checking all files), but already good enough for regular development: total times are nearly identical and this is the *full* build, further `make -C build clint` will check only modified files. --- src/nvim/CMakeLists.txt | 147 ++++++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index a3bacaa9d2..68c0339dc5 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -10,6 +10,7 @@ if(USE_GCOV) endif() endif() +set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches) set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendispatch.lua) file(GLOB API_HEADERS api/*.h) @@ -34,11 +35,16 @@ set(UNICODE_TABLES_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genunicodetables.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(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json) +set(LINT_SUPPRESS_URL "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/errors.json") +set(LINT_PRG ${PROJECT_SOURCE_DIR}/src/clint.py) +set(DOWNLOAD_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/Download.cmake) 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}) @@ -73,6 +79,8 @@ file(GLOB UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c) list(SORT NVIM_SOURCES) list(SORT NVIM_HEADERS) +list(APPEND LINT_NVIM_SOURCES ${NVIM_SOURCES} ${NVIM_HEADERS}) + foreach(sfile ${NVIM_SOURCES}) get_filename_component(f ${sfile} NAME) if(${f} MATCHES "^(regexp_nfa.c)$") @@ -393,76 +401,82 @@ add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NVIM_GENERATED_FOR_SOURCES} ${NV target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES}) set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTING) -set(NO_SINGLE_CHECK_HEADERS - cursor_shape - diff - digraph - ex_cmds - ex_getln - file_search - fold - getchar - hardcopy - if_cscope - if_cscope_defs - mark - mbyte - memfile_defs - memline - memline_defs - menu - misc2 - move - msgpack_rpc/server - ops - option - os/shell - os_unix - os/win_defs - popupmnu - quickfix - regexp - regexp_defs - screen - search - sha256 - sign_defs - spell - spellfile - syntax - syntax_defs - tag - terminal - tui/tui - ugrid - ui - ui_bridge - undo - undo_defs - version - window -) -foreach(hfile ${NVIM_HEADERS}) - get_filename_component(full_d ${hfile} PATH) +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 ${hfile} NAME_WE) + get_filename_component(r "${sfile}" NAME) if(NOT ${d} EQUAL ".") set(r "${d}/${r}") endif() + string(REGEX REPLACE "[/.]" "-" suffix "${r}") + set(${relative_path_var} ${r} PARENT_SCOPE) + set(${target_var} "${prefix}-${suffix}" PARENT_SCOPE) +endfunction() + +set(NO_SINGLE_CHECK_HEADERS + cursor_shape.h + diff.h + digraph.h + ex_cmds.h + ex_getln.h + file_search.h + fold.h + getchar.h + hardcopy.h + if_cscope.h + if_cscope_defs.h + mark.h + mbyte.h + memfile_defs.h + memline.h + memline_defs.h + menu.h + misc2.h + move.h + msgpack_rpc/server.h + ops.h + option.h + os/shell.h + os_unix.h + os/win_defs.h + popupmnu.h + quickfix.h + regexp.h + regexp_defs.h + screen.h + search.h + sha256.h + sign_defs.h + spell.h + spellfile.h + syntax.h + syntax_defs.h + tag.h + terminal.h + tui/tui.h + ugrid.h + ui.h + ui_bridge.h + undo.h + undo_defs.h + version.h + window.h +) +foreach(hfile ${NVIM_HEADERS}) + get_test_target(test-includes "${hfile}" relative_path texe) if(NOT ${hfile} MATCHES "[.]c[.]h$") - set(tsource "${GENERATED_DIR}/${r}.test-include.c") - string(REPLACE "/" "-" texe "test-incl-${r}") + 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}) - list(FIND NO_SINGLE_CHECK_HEADERS "${r}" hfile_exclude_idx) + list(FIND NO_SINGLE_CHECK_HEADERS "${relative_path}" hfile_exclude_idx) if(${hfile_exclude_idx} EQUAL -1) list(APPEND HEADER_CHECK_TARGETS ${texe}) endif() @@ -470,4 +484,27 @@ foreach(hfile ${NVIM_HEADERS}) endforeach() add_custom_target(check-single-includes DEPENDS ${HEADER_CHECK_TARGETS}) +function(add_download output url) + add_custom_command( + OUTPUT "${output}" + COMMAND ${CMAKE_COMMAND} -DURL=${url} -DFILE=${output} -P ${DOWNLOAD_SCRIPT} + DEPENDS ${DOWNLOAD_SCRIPT} + ) +endfunction() + +add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL}) + +foreach(sfile ${LINT_NVIM_SOURCES}) + get_test_target("${TOUCHES_DIR}/ran-clint" "${sfile}" r touch_file) + add_custom_command( + OUTPUT ${touch_file} + COMMAND ${LINT_PRG} --suppress-errors=${LINT_SUPPRESS_FILE} src/nvim/${r} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -E touch ${touch_file} + DEPENDS ${sfile} ${LINT_SUPPRESS_FILE} + ) + list(APPEND LINT_TARGETS ${touch_file}) +endforeach() +add_custom_target(clint DEPENDS ${LINT_TARGETS}) + add_subdirectory(po) -- cgit From 0b528fc4b55a8875579d0a1a5dde852b6c3f55dc Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 31 Mar 2017 11:38:08 +0300 Subject: cmake: Use file-specific supprresses `make -C build clint` time is now make -j5 clint 95.29s user 1.86s system 409% cpu 23.751 total *without* downloading anything (much worse if something was not cached, still a bit better then top-level `make clint`). But since without neovim/bot-ci#95 it is downloading each file one-by-one total time with download (download also parallel!) is make -j5 -B clint 99.29s user 2.98s system 258% cpu 39.634 total Top-level makefile still gives make -j5 clint 59.33s user 0.28s system 95% cpu 1:02.41 total --- src/nvim/CMakeLists.txt | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 68c0339dc5..b4bc3afc05 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -36,9 +36,12 @@ 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(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json) -set(LINT_SUPPRESS_URL "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/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 "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/errors.tar.gz") include_directories(${GENERATED_DIR}) include_directories(${CACHED_GENERATED_DIR}) @@ -404,16 +407,20 @@ set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTIN 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 "^[.][.]") + if(d MATCHES "^[.][.]") file(RELATIVE_PATH d "${GENERATED_DIR}" "${full_d}") endif() get_filename_component(r "${sfile}" NAME) - if(NOT ${d} EQUAL ".") + if(NOT d MATCHES "^[.]?$") set(r "${d}/${r}") endif() string(REGEX REPLACE "[/.]" "-" suffix "${r}") set(${relative_path_var} ${r} PARENT_SCOPE) - set(${target_var} "${prefix}-${suffix}" 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 @@ -495,13 +502,17 @@ endfunction() add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL}) foreach(sfile ${LINT_NVIM_SOURCES}) - get_test_target("${TOUCHES_DIR}/ran-clint" "${sfile}" r touch_file) + get_test_target("" "${sfile}" r suffix) + set(suppress_file ${LINT_SUPPRESSES_ROOT}/${suffix}.json) + set(suppress_url "${LINT_SUPPRESS_URL_BASE}/${suffix}.json") + add_download(${suppress_file} ${suppress_url}) + set(touch_file "${TOUCHES_DIR}/ran-clint-${suffix}") add_custom_command( OUTPUT ${touch_file} - COMMAND ${LINT_PRG} --suppress-errors=${LINT_SUPPRESS_FILE} src/nvim/${r} + COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} src/nvim/${r} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -E touch ${touch_file} - DEPENDS ${sfile} ${LINT_SUPPRESS_FILE} + DEPENDS ${sfile} ${suppress_file} ) list(APPEND LINT_TARGETS ${touch_file}) endforeach() -- cgit From 24fd125893203c667789cb574b289fc1c9eaf6bc Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 31 Mar 2017 11:49:18 +0300 Subject: cmake: Allow failing to download small suppress files --- src/nvim/CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index b4bc3afc05..f5f4173879 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -491,21 +491,25 @@ foreach(hfile ${NVIM_HEADERS}) endforeach() add_custom_target(check-single-includes DEPENDS ${HEADER_CHECK_TARGETS}) -function(add_download output url) +function(add_download output url allow_failure) add_custom_command( OUTPUT "${output}" - COMMAND ${CMAKE_COMMAND} -DURL=${url} -DFILE=${output} -P ${DOWNLOAD_SCRIPT} + COMMAND + ${CMAKE_COMMAND} + -DURL=${url} -DFILE=${output} + -DALLOW_FAILURE=${allow_failure} + -P ${DOWNLOAD_SCRIPT} DEPENDS ${DOWNLOAD_SCRIPT} ) endfunction() -add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL}) +add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL} off) 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") - add_download(${suppress_file} ${suppress_url}) + add_download(${suppress_file} ${suppress_url} on) set(touch_file "${TOUCHES_DIR}/ran-clint-${suffix}") add_custom_command( OUTPUT ${touch_file} -- cgit From c61858a9978504c645f09de60daf4f9786c2220e Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 31 Mar 2017 12:02:59 +0300 Subject: cmake: Replace RunLint.cmake with code in src/nvim/CMakeLists.txt This also removes LINT_FILE environment variable, other then that functionality is kept. It is expected that developers needing partial linting will use `make lint`, touching interesting file before (if not done already by writing to them). --- src/nvim/CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index f5f4173879..b19bdf2326 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -505,21 +505,32 @@ endfunction() 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}) add_download(${suppress_file} ${suppress_url} on) set(touch_file "${TOUCHES_DIR}/ran-clint-${suffix}") add_custom_command( OUTPUT ${touch_file} - COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} src/nvim/${r} + COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} ${rsfile} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -E touch ${touch_file} DEPENDS ${sfile} ${suppress_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_NVIM_SOURCES} ${LINT_SUPPRESS_FILE} +) + add_subdirectory(po) -- cgit From 4fc2be490cd075d08ef8532f954424051fe49300 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 31 Mar 2017 12:27:13 +0300 Subject: clint: Do not report zero errors --- src/clint.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 61c53d128e..5174521fb8 100755 --- a/src/clint.py +++ b/src/clint.py @@ -571,7 +571,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""" -- cgit From 4d0f90f94db6040841b9987d02a021b785cfe0f3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 31 Mar 2017 12:28:10 +0300 Subject: cmake: Also depend on LINT_PRG --- src/nvim/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index b19bdf2326..5a5ebc4415 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -518,7 +518,7 @@ foreach(sfile ${LINT_NVIM_SOURCES}) COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} ${rsfile} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -E touch ${touch_file} - DEPENDS ${sfile} ${suppress_file} + DEPENDS ${LINT_PRG} ${sfile} ${suppress_file} ) list(APPEND LINT_TARGETS ${touch_file}) list(APPEND LINT_NVIM_REL_SOURCES ${rsfile}) @@ -530,7 +530,7 @@ add_custom_target( COMMAND ${LINT_PRG} --suppress-errors=${LINT_SUPPRESS_FILE} ${LINT_NVIM_REL_SOURCES} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - DEPENDS ${LINT_NVIM_SOURCES} ${LINT_SUPPRESS_FILE} + DEPENDS ${LINT_PRG} ${LINT_NVIM_SOURCES} ${LINT_SUPPRESS_FILE} ) add_subdirectory(po) -- cgit From 53da57d27a8ee47fe42604ad07bb7c956d9012f5 Mon Sep 17 00:00:00 2001 From: lonerover Date: Wed, 22 Mar 2017 12:24:07 +0800 Subject: vim-patch:7.4.2236 Problem: The 'langnoremap' option leads to double negatives. And it does not work for the last character of a mapping. Solution: Add 'langremap' with the opposite value. Keep 'langnoremap' for backwards compatibility. Make it work for the last character of a mapping. Make the test work. https://github.com/vim/vim/commit/920694c1b60fac8017b8909efcc24f189804a9bb --- src/nvim/macros.h | 2 +- src/nvim/option.c | 6 ++++ src/nvim/option_defs.h | 5 +-- src/nvim/options.lua | 6 ++++ src/nvim/testdir/test_mapping.vim | 74 +++++++++++++++++++++++++++++++-------- src/nvim/version.c | 2 +- 6 files changed, 76 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/macros.h b/src/nvim/macros.h index 5042663041..a8df6322cf 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -94,7 +94,7 @@ do { \ if (*p_langmap \ && (condition) \ - && (!p_lnr || (p_lnr && typebuf_maplen() == 0)) \ + && (p_lrm || (!p_lrm && KeyTyped)) \ && !KeyStuffed \ && (c) >= 0) \ { \ diff --git a/src/nvim/option.c b/src/nvim/option.c index 0b4d9aae5d..b3b4dc1e0a 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3630,6 +3630,12 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, } 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 diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 2475a0b6a1..4ee0f4f225 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -476,8 +476,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' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index ee2b8a563d..9dff3410d6 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1346,6 +1346,12 @@ return { varname='p_lnr', 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'}, diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index d937565ce5..3b6dcdccf5 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -35,29 +35,73 @@ func Test_map_ctrl_c_visual() endfunc func Test_map_langmap() - " langmap should not get remapped in insert mode - inoremap { FAIL_ilangmap - set langmap=+{ langnoremap + 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) + + " langmap should not apply in insert mode, 'langremap' doesn't matter + set langmap=+{ nolangremap call feedkeys("Go+\", "xt") call assert_equal('+', getline('$')) - - " Insert-mode expr mapping with langmap - inoremap { "FAIL_iexplangmap" + set langmap=+{ langremap call feedkeys("Go+\", "xt") call assert_equal('+', getline('$')) - iunmap { - " langmap should not get remapped in Command-line mode - cnoremap { FAIL_clangmap + " 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\a\", "xt") + call assert_equal('bbbb', getline('$')) + call feedkeys("Go\\a\", "xt") + call assert_equal('bbbb', getline('$')) + " mapping does not apply + imap c a + call feedkeys("Go\c\", "xt") + call assert_equal('cccc', getline('$')) + imap a c + call feedkeys("Go\a\", "xt") + call assert_equal('bbbb', getline('$')) + + " langmap should not apply in Command-line mode + set langmap=+{ nolangremap call feedkeys(":call append(line('$'), '+')\", "xt") call assert_equal('+', getline('$')) - cunmap { - " Command-line mode expr mapping with langmap - cnoremap { "FAIL_cexplangmap" - call feedkeys(":call append(line('$'), '+')\", "xt") - call assert_equal('+', getline('$')) - cunmap { set nomodified endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index fdf5436a98..ba1ebc8f2c 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -205,7 +205,7 @@ static const int included_patches[] = { // 2239, // 2238 NA 2237, - // 2236, + 2236, 2235, // 2234 NA 2233, -- cgit From 45a13c4bbc4a7c4f62a299c832ecc192d8f3cd0a Mon Sep 17 00:00:00 2001 From: lonerover Date: Wed, 22 Mar 2017 12:52:15 +0800 Subject: vim-patch:7.4.2306 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Default value for 'langremap' is wrong. Solution: Set the right value. (Jürgen Krämer) Add a test. https://github.com/vim/vim/commit/da9ce2cde11ddd0e16cdfbab6d4ac4e8110218e1 --- src/nvim/testdir/test_mapping.vim | 8 ++++++++ src/nvim/version.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index 3b6dcdccf5..6b313ff54f 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -72,6 +72,14 @@ func Test_map_langmap() 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+\", "xt") diff --git a/src/nvim/version.c b/src/nvim/version.c index ba1ebc8f2c..0ee0419849 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -135,7 +135,7 @@ static const int included_patches[] = { 2309, // 2308 NA 2307, - // 2306, + 2306, 2305, // 2304 NA 2303, -- cgit From cc4523013f8e693f92de3b96ff36065895c60974 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 1 Apr 2017 21:13:21 +0300 Subject: eval,fileio: Omit additional fsync() call Fixes #6420 --- src/nvim/eval.c | 2 +- src/nvim/os/fileio.c | 31 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 15b712e7de..a6774a3a0b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17289,7 +17289,7 @@ static bool write_list(FileDescriptor *const fp, const list_T *const list, } } } - if ((error = file_fsync(fp)) != 0) { + if ((error = file_flush(fp)) != 0) { goto write_list_error; } return true; diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 775f2bd449..3c928363cc 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -143,21 +143,36 @@ 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 error = os_fsync(fp->fd); - if (error != UV_EINVAL && error != UV_EROFS) { - return error; + const int flush_error = file_flush(fp); + if (flush_error != 0) { + return flush_error; + } + const int fsync_error = os_fsync(fp->fd); + if (fsync_error != UV_EINVAL && fsync_error != UV_EROFS) { + return fsync_error; } return 0; } -- cgit From 19690d4a25f15dfa752ac3723384f1d33f06329a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 1 Apr 2017 22:26:50 +0300 Subject: eval: Do not allocate FileDescriptor --- src/nvim/eval.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a6774a3a0b..f0d78a2508 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17439,21 +17439,21 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (fname == NULL) { return; } - FileDescriptor *fp; + FileDescriptor fp; int error; rettv->vval.v_number = -1; if (*fname == NUL) { EMSG(_("E482: Can't open file with an empty name")); - } else if ((fp = file_open_new(&error, fname, - ((append ? kFileAppend : kFileTruncate) - | kFileCreate), 0666)) == NULL) { + } 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(fp, argvars[0].vval.v_list, binary)) { + if (write_list(&fp, argvars[0].vval.v_list, binary)) { rettv->vval.v_number = 0; } - if ((error = file_free(fp)) != 0) { + if ((error = file_close(&fp)) != 0) { emsgf(_("E80: Error when closing file %s: %s"), fname, os_strerror(error)); } -- cgit From 337b6179df852350b52409fd3806e4b47ab2875b Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Sat, 1 Apr 2017 20:50:29 +0100 Subject: 'pastetoggle': support value >1 char (#6421) If we `set pastetoggle=abcde`, and manually type it, then `vgetorpeek()` sees part of the option before it has all been inserted into the typebuffer. To signify this it sets `keylen = KEYLEN_PART_KEY`, but the condition about whether to return the current key from `vgetorpeek()` only checks for `keylen = KEYLEN_PART_MAP`. Add a check for `KEYLEN_PART_KEY` to account for the `'pastetoggle'` option. --- src/nvim/getchar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 7143819e21..b83681ad01 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1903,7 +1903,7 @@ static int vgetorpeek(int advance) } if ((mp == NULL || max_mlen >= mp_match_len) - && keylen != KEYLEN_PART_MAP) { + && keylen != KEYLEN_PART_MAP && keylen != KEYLEN_PART_KEY) { // No matching mapping found or found a non-matching mapping that // matches at least what the matching mapping matched keylen = 0; -- cgit From dd4a5fcbb65ade08b5d2c7951b2924d2d04dc99e Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Mon, 20 Mar 2017 22:56:58 +0100 Subject: tui: 'guicursor' shape #6044 Closes #2583 --- src/nvim/api/ui.c | 10 +++ src/nvim/cursor_shape.c | 140 +++++++++++++++++++++++++++------------ src/nvim/cursor_shape.h | 73 +++++++++++---------- src/nvim/syntax.c | 53 +++++++-------- src/nvim/tui/tui.c | 170 +++++++++++++++++++++++++++++++++++------------- src/nvim/tui/tui.h | 2 + src/nvim/ui.c | 9 +++ src/nvim/ui.h | 1 + src/nvim/ui_bridge.c | 19 ++++++ 9 files changed, 330 insertions(+), 147 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 625bcc6b4b..a95be0fabb 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -12,6 +12,7 @@ #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" @@ -69,6 +70,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->clear = remote_ui_clear; ui->eol_clear = remote_ui_eol_clear; ui->cursor_goto = remote_ui_cursor_goto; + ui->cursor_style_set = remote_ui_cursor_style_set; ui->update_menu = remote_ui_update_menu; ui->busy_start = remote_ui_busy_start; ui->busy_stop = remote_ui_busy_stop; @@ -298,6 +300,14 @@ static void remote_ui_scroll(UI *ui, int count) push_call(ui, "scroll", args); } +static void remote_ui_cursor_style_set(UI *ui, Dictionary styles) +{ + Array args = ARRAY_DICT_INIT; + Object copy = copy_object(DICTIONARY_OBJ(styles)); + ADD(args, copy); + push_call(ui, "cursor_style_set", args); +} + static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) { Array args = ARRAY_DICT_INIT; diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index b50462664c..9f0eb215ef 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -7,40 +7,84 @@ #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. - */ - +/// Handling of cursor and mouse pointer shapes in various modes. static 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}, + // The values will be filled in from the 'guicursor' and 'mouseshape' + // defaults when Vim starts. + // Adjust the SHAPE_IDX_ defines when making changes! + { "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 }, + { "cmd_normal", + 0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE }, + { "cmd_insert", 0, + 0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE }, + { "cmd_replace", + 0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE }, + { "pending", + 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 }, + { "cmd_line", 0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE }, + { "statusline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE }, + { "drag_statusline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE }, + { "vsep", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE }, + { "vdrag", 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 }, + { "match_paren", 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 a Dictionary of dictionaries +/// @return a dictionary of the form {"normal" : { "cursor_shape": ... }, ...} +Dictionary cursor_shape_dict(void) +{ + Dictionary 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, "short_name", STRING_OBJ(cstr_to_string(cur->name))); + + PUT(all, cur->full_name, DICTIONARY_OBJ(dic)); + } + + return all; +} + +/// Parse the 'guicursor' option +/// +/// @param what either 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; @@ -71,19 +115,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 mode's 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,11 +143,11 @@ 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; @@ -208,6 +251,23 @@ char_u *parse_shape_opt(int what) shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm; } } - + ui_cursor_style_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; + } + } + ELOG("Unknown mode %s", mode); + return -1; +} + diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h index 9ce1b6e0a0..127d0df555 100644 --- a/src/nvim/cursor_shape.h +++ b/src/nvim/cursor_shape.h @@ -1,32 +1,34 @@ #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 +/// 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, ///< status line +SHAPE_IDX_SDRAG = 11, ///< dragging a status line +SHAPE_IDX_VSEP = 12, ///< A 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 +} MouseMode; -#define SHAPE_BLOCK 0 /* block cursor */ -#define SHAPE_HOR 1 /* horizontal bar cursor */ -#define SHAPE_VER 2 /* vertical bar cursor */ +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,16 +37,17 @@ #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 full name + 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; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 4a7b4a0eac..4f2f44ff86 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -42,29 +42,29 @@ 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 + 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 // 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 + 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 }; #define SG_CTERM 2 // cterm has been set @@ -7165,12 +7165,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 it's 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); diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index ebdfb1e7a1..ebcef33fa1 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -31,6 +31,8 @@ #include "nvim/ugrid.h" #include "nvim/tui/input.h" #include "nvim/tui/tui.h" +#include "nvim/cursor_shape.h" +#include "nvim/syntax.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. @@ -69,12 +71,12 @@ typedef struct { bool can_use_terminal_scroll; bool mouse_enabled; bool busy; + cursorentry_T cursor_shapes[SHAPE_IDX_COUNT]; HlAttrs print_attrs; int 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 set_rgb_foreground, set_rgb_background; int enable_focus_reporting, disable_focus_reporting; } unibi_ext; @@ -97,6 +99,7 @@ UI *tui_start(void) ui->clear = tui_clear; ui->eol_clear = tui_eol_clear; ui->cursor_goto = tui_cursor_goto; + ui->cursor_style_set = tui_cursor_style_set; ui->update_menu = tui_update_menu; ui->busy_start = tui_busy_start; ui->busy_stop = tui_busy_stop; @@ -131,9 +134,6 @@ static void terminfo_start(UI *ui) data->unibi_ext.disable_mouse = -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_focus_reporting = -1; data->unibi_ext.disable_focus_reporting = -1; data->out_fd = 1; @@ -147,7 +147,6 @@ static void terminfo_start(UI *ui) } fix_terminfo(data); // Initialize the cursor shape. - unibi_out(ui, data->unibi_ext.set_cursor_shape_block); // 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 @@ -434,6 +433,64 @@ static void tui_cursor_goto(UI *ui, int row, int col) unibi_goto(ui, row, col); } +CursorShape tui_cursor_decode_shape(const char *shape_str) +{ + CursorShape shape = 0; + if (strcmp(shape_str, "block") == 0) { + shape = SHAPE_BLOCK; + } else if (strcmp(shape_str, "vertical") == 0) { + shape = SHAPE_VER; + } else if (strcmp(shape_str, "horizontal") == 0) { + 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 *keyStr = args.items[i].key.data; + Object value = args.items[i].value; + + if (strcmp(keyStr, "cursor_shape") == 0) { + r.shape = tui_cursor_decode_shape(args.items[i].value.data.string.data); + } else if (strcmp(keyStr, "blinkon") == 0) { + r.blinkon = (int)value.data.integer; + } else if (strcmp(keyStr, "blinkoff") == 0) { + r.blinkoff = (int)value.data.integer; + } else if (strcmp(keyStr, "hl_id") == 0) { + r.id = (int)value.data.integer; + } + } + return r; +} + +static void tui_cursor_style_set(UI *ui, Dictionary args) +{ + TUIData *data = ui->data; + + for (size_t i = 0; i < args.size; i++) { + char *mode_name = args.items[i].key.data; + const int mode_id = cursor_mode_str2int(mode_name); + + if (mode_id < 0) { + WLOG("Unknown mode '%s'", mode_name); + continue; + } + cursorentry_T r = decode_cursor_entry(args.items[i].value.data.dictionary); + r.full_name = mode_name; + data->cursor_shapes[mode_id] = r; + } + + // force redrawal + MouseMode cursor_mode = tui_mode2cursor(data->showing_mode); + tui_set_cursor(ui, cursor_mode); +} + static void tui_update_menu(UI *ui) { // Do nothing; menus are for GUI only @@ -467,33 +524,90 @@ static void tui_mouse_off(UI *ui) } } +/// @param mode one of SHAPE_XXX +static void tui_set_cursor(UI *ui, MouseMode mode) +{ + TUIData *data = ui->data; + cursorentry_T c = data->cursor_shapes[mode]; + int shape = c.shape; + bool inside_tmux = os_getenv("TMUX") != NULL; + unibi_var_t vars[26 + 26] = { { 0 } }; + +# 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. + switch (shape) { + case SHAPE_BLOCK: shape = 0; break; + case SHAPE_VER: shape = 1; break; + case SHAPE_HOR: shape = 3; break; + default: WLOG("Unknown shape value %d", shape); break; + } + printf(TMUX_WRAP("\x1b]50;CursorShape=%d;BlinkingCursorEnabled=%d\x07"), + shape, (c.blinkon !=0)); + } 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. + + switch (shape) { + case SHAPE_BLOCK: shape = 1; break; + case SHAPE_VER: shape = 5; break; + case SHAPE_HOR: shape = 3; break; + default: WLOG("Unknown shape value %d", shape); break; + } + data->params[0].i = shape + (c.blinkon ==0); + unibi_format(vars, vars + 26, "\x1b[%p1%d q", + data->params, out, ui, NULL, NULL); + } +} + +/// Returns cursor mode from edit mode +static MouseMode tui_mode2cursor(int mode) +{ + switch (mode) { + case INSERT: return SHAPE_IDX_I; + case CMDLINE: return SHAPE_IDX_C; + case REPLACE: return SHAPE_IDX_R; + case NORMAL: + default: return SHAPE_IDX_N; + } +} + +/// @param mode editor mode static void tui_mode_change(UI *ui, int mode) { TUIData *data = ui->data; if (mode == INSERT) { if (data->showing_mode != INSERT) { - unibi_out(ui, data->unibi_ext.set_cursor_shape_bar); + tui_set_cursor(ui, SHAPE_IDX_I); } } else if (mode == CMDLINE) { if (data->showing_mode != CMDLINE) { - unibi_out(ui, data->unibi_ext.set_cursor_shape_bar); + tui_set_cursor(ui, SHAPE_IDX_C); } } else if (mode == REPLACE) { if (data->showing_mode != REPLACE) { - unibi_out(ui, data->unibi_ext.set_cursor_shape_ul); + tui_set_cursor(ui, SHAPE_IDX_R); } } else { assert(mode == NORMAL); if (data->showing_mode != NORMAL) { - unibi_out(ui, data->unibi_ext.set_cursor_shape_block); + tui_set_cursor(ui, SHAPE_IDX_N); } } data->showing_mode = mode; } static void tui_set_scroll_region(UI *ui, int top, int bot, int left, - int right) + int right) { TUIData *data = ui->data; ugrid_set_scroll_region(&data->grid, top, bot, left, right); @@ -831,8 +945,6 @@ static void fix_terminfo(TUIData *data) goto end; } - bool inside_tmux = os_getenv("TMUX") != NULL; - #define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1)) if (STARTS_WITH(term, "rxvt")) { @@ -890,40 +1002,6 @@ static void fix_terminfo(TUIData *data) unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB); } - const char * env_cusr_shape = os_getenv("NVIM_TUI_ENABLE_CURSOR_SHAPE"); - if (env_cusr_shape && strncmp(env_cusr_shape, "0", 1) == 0) { - goto end; - } - bool cusr_blink = env_cusr_shape && strncmp(env_cusr_shape, "2", 1) == 0; - -#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\x07")); - data->unibi_ext.set_cursor_shape_ul = (int)unibi_add_ext_str(ut, NULL, - TMUX_WRAP("\x1b]50;CursorShape=2\x07")); - data->unibi_ext.set_cursor_shape_block = (int)unibi_add_ext_str(ut, NULL, - TMUX_WRAP("\x1b]50;CursorShape=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, cusr_blink ? "\x1b[5 q" : "\x1b[6 q"); - data->unibi_ext.set_cursor_shape_ul = - (int)unibi_add_ext_str(ut, NULL, cusr_blink ? "\x1b[3 q" : "\x1b[4 q"); - data->unibi_ext.set_cursor_shape_block = - (int)unibi_add_ext_str(ut, NULL, cusr_blink ? "\x1b[1 q" : "\x1b[2 q"); - } - end: // Fill some empty slots with common terminal strings data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, NULL, diff --git a/src/nvim/tui/tui.h b/src/nvim/tui/tui.h index 07523bc124..2915b0e2f8 100644 --- a/src/nvim/tui/tui.h +++ b/src/nvim/tui/tui.h @@ -1,6 +1,8 @@ #ifndef NVIM_TUI_TUI_H #define NVIM_TUI_TUI_H +#include "nvim/cursor_shape.h" + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tui/tui.h.generated.h" #endif diff --git a/src/nvim/ui.c b/src/nvim/ui.c index ea42e3e357..babb4efa96 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -29,6 +29,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 @@ -179,6 +180,7 @@ void ui_refresh(void) row = col = 0; screen_resize(width, height); pum_set_external(pum_external); + ui_cursor_style_set(); } static void ui_refresh_event(void **argv) @@ -376,6 +378,13 @@ void ui_cursor_goto(int new_row, int new_col) pending_cursor_update = true; } +void ui_cursor_style_set(void) +{ + Dictionary style = cursor_shape_dict(); + UI_CALL(cursor_style_set, style); + api_free_dictionary(style); +} + void ui_update_menu(void) { UI_CALL(update_menu); diff --git a/src/nvim/ui.h b/src/nvim/ui.h index d14bc5812c..0af0c0db65 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -22,6 +22,7 @@ struct ui_t { void (*clear)(UI *ui); void (*eol_clear)(UI *ui); void (*cursor_goto)(UI *ui, int row, int col); + void (*cursor_style_set)(UI *ui, Dictionary cursor_shapes); void (*update_menu)(UI *ui); void (*busy_start)(UI *ui); void (*busy_stop)(UI *ui); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 25861abc1b..c9bad6b254 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -13,6 +13,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" @@ -59,6 +60,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->bridge.clear = ui_bridge_clear; rv->bridge.eol_clear = ui_bridge_eol_clear; rv->bridge.cursor_goto = ui_bridge_cursor_goto; + rv->bridge.cursor_style_set = ui_bridge_cursor_styleset; rv->bridge.update_menu = ui_bridge_update_menu; rv->bridge.busy_start = ui_bridge_busy_start; rv->bridge.busy_stop = ui_bridge_busy_stop; @@ -178,6 +180,23 @@ static void ui_bridge_cursor_goto_event(void **argv) ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2])); } +static void ui_bridge_cursor_styleset(UI *b, Dictionary style) +{ + Object copy = copy_object(DICTIONARY_OBJ(style)); + Object *pobj = xmalloc(sizeof(copy)); + *pobj = copy; + UI_CALL(b, cursor_styleset, 2, b, pobj); +} +static void ui_bridge_cursor_styleset_event(void **argv) +{ + UI *ui = UI(argv[0]); + Object *styles = (Object *)argv[1]; + + ui->cursor_style_set(ui, styles->data.dictionary); + api_free_object(*styles); + xfree(styles); +} + static void ui_bridge_update_menu(UI *b) { UI_CALL(b, update_menu, 1, b); -- cgit From 54bab0019b3638f213608757b523062195be156b Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Tue, 21 Mar 2017 00:03:01 +0100 Subject: tui: 'guicursor' color For now only supports valid hex colors (does not check for the validity the hex color) when termguicolors is set, otherwise it won't attempt to change the cursor color. --- src/nvim/syntax.c | 45 +++++++++++++++++++++++++++------------------ src/nvim/syntax.h | 10 ++++++---- src/nvim/tui/tui.c | 19 +++++++++++++++++-- 3 files changed, 50 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 4f2f44ff86..acda25e738 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -48,9 +48,9 @@ static bool did_syntax_onoff = false; 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_attr; ///< Screen attr @see ATTR_ENTRY int sg_link; ///< link to this highlight group ID - int sg_set; ///< combination of SG_* flags + 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 @@ -59,6 +59,7 @@ struct hl_group { int sg_cterm_bold; ///< bold attr was set for light color // for RGB UIs 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 @@ -67,9 +68,12 @@ struct hl_group { 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; @@ -6093,16 +6097,16 @@ 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 ( + +/// 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 /* TRUE when called for initializing */ + int init ) { char_u *name_end; @@ -6704,12 +6708,10 @@ static garray_T attr_table = GA_EMPTY_INIT_VALUE; #define ATTR_ENTRY(idx) ((attrentry_T *)attr_table.ga_data)[idx] -/* - * Return the attr number for a set of colors and font. - * Add a new entry to the term_attr_table, attr_table or gui_attr_table - * if the combination is new. - * Return 0 for error. - */ +/// 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; @@ -6932,7 +6934,7 @@ static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg /// Check whether highlight group has attribute /// -/// @param[in] id Highilght group to check. +/// @param[in] id Highlight group to check. /// @param[in] flag Attribute to check. /// @param[in] modec 'g' for GUI, 'c' for term. /// @@ -8245,7 +8247,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..574e3372e2 100644 --- a/src/nvim/syntax.h +++ b/src/nvim/syntax.h @@ -5,10 +5,11 @@ #include "nvim/buffer_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/tui/tui.c b/src/nvim/tui/tui.c index ebcef33fa1..12281246fe 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -78,6 +78,7 @@ typedef struct { int enable_mouse, disable_mouse; int enable_bracketed_paste, disable_bracketed_paste; int set_rgb_foreground, set_rgb_background; + int set_cursor_color; int enable_focus_reporting, disable_focus_reporting; } unibi_ext; } TUIData; @@ -132,6 +133,7 @@ static void terminfo_start(UI *ui) data->showing_mode = 0; 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.enable_focus_reporting = -1; @@ -548,8 +550,12 @@ static void tui_set_cursor(UI *ui, MouseMode mode) case SHAPE_HOR: shape = 3; break; default: WLOG("Unknown shape value %d", shape); break; } - printf(TMUX_WRAP("\x1b]50;CursorShape=%d;BlinkingCursorEnabled=%d\x07"), - shape, (c.blinkon !=0)); + data->params[0].i = shape; + data->params[1].i = (c.blinkon ==0); + + unibi_format(vars, vars + 26, + TMUX_WRAP("\x1b]50;CursorShape=%p1%d;BlinkingCursorEnabled=%p2%d\x07"), + data->params, out, ui, NULL, NULL); } 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, @@ -566,6 +572,13 @@ static void tui_set_cursor(UI *ui, MouseMode mode) unibi_format(vars, vars + 26, "\x1b[%p1%d q", data->params, out, ui, NULL, NULL); } + + if (c.id != 0 && ui->rgb) { + int attr = syn_id2attr(c.id); + attrentry_T *aep = syn_cterm_attr2entry(attr); + data->params[0].i = aep->rgb_bg_color; + unibi_out(ui, data->unibi_ext.set_cursor_color); + } } /// Returns cursor mode from edit mode @@ -1004,6 +1017,8 @@ static void fix_terminfo(TUIData *data) end: // Fill some empty slots with common terminal strings + data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( + ut, NULL, "\033]12;#%p1%06x\007"); 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, -- cgit From c2826a7830ddba66261afdf45fcf4d0043506342 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 1 Apr 2017 13:08:42 +0200 Subject: 'guicursor': Empty means "block cursor in all modes". Also: update default 'guicursor' to match the documentation. --- src/nvim/cursor_shape.c | 13 +++++++------ src/nvim/cursor_shape.h | 4 ++-- src/nvim/options.lua | 2 +- src/nvim/tui/tui.c | 1 - 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index 9f0eb215ef..c78bcbc29d 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -45,7 +45,7 @@ static cursorentry_T shape_table[SHAPE_IDX_COUNT] = }; /// Converts cursor_shapes into a Dictionary of dictionaries -/// @return a dictionary of the form {"normal" : { "cursor_shape": ... }, ...} +/// @return dictionary of the form {"normal" : { "cursor_shape": ... }, ...} Dictionary cursor_shape_dict(void) { Dictionary all = ARRAY_DICT_INIT; @@ -82,7 +82,7 @@ Dictionary cursor_shape_dict(void) /// Parse the 'guicursor' option /// -/// @param what either SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape') +/// @param what SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape') /// /// @returns error message for an illegal option, NULL otherwise. char_u *parse_shape_opt(int what) @@ -103,10 +103,11 @@ char_u *parse_shape_opt(int what) * First round: check for errors; second round: do it for real. */ for (round = 1; round <= 2; ++round) { - /* - * Repeat for all comma separated parts. - */ + // 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) @@ -115,7 +116,7 @@ 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. + // Repeat for all modes before the colon. // For the 'a' mode, we loop to handle all the modes. all_idx = -1; assert(modep < colonp); diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h index 127d0df555..14ace2a861 100644 --- a/src/nvim/cursor_shape.h +++ b/src/nvim/cursor_shape.h @@ -14,7 +14,7 @@ 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, ///< status line +SHAPE_IDX_STATUS = 10, ///< status line SHAPE_IDX_SDRAG = 11, ///< dragging a status line SHAPE_IDX_VSEP = 12, ///< A vertical separator line SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line @@ -37,7 +37,7 @@ SHAPE_VER = 2 ///< vertical bar cursor #define SHAPE_CURSOR 2 /* used for text cursor shape */ typedef struct cursor_entry { - char *full_name; ///< mode full name + 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 diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 9dff3410d6..09f016cf5a 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1000,7 +1000,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:block-Cursor/lCursor,ve:ver35-Cursor,o:hor50-Cursor,i-ci:ver25-Cursor/lCursor,r-cr:hor20-Cursor/lCursor,sm:block-Cursor-blinkwait175-blinkoff150-blinkon175"}} }, { full_name='guifont', abbreviation='gfn', diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 12281246fe..e1fec0f678 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -148,7 +148,6 @@ static void terminfo_start(UI *ui) data->ut = unibi_dummy(); } fix_terminfo(data); - // Initialize the cursor shape. // 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 -- cgit From 3a69dbfca6642463ca8e19f814f71791f66332f3 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 1 Apr 2017 22:32:16 +0200 Subject: api/cursor_style_set: mode descriptions --- src/nvim/cursor_shape.c | 44 +++++++++++++++++--------------------------- src/nvim/cursor_shape.h | 4 ++-- src/nvim/tui/tui.c | 4 ++-- 3 files changed, 21 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index c78bcbc29d..7ec70bb724 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -13,35 +13,25 @@ /// Handling of cursor and mouse pointer shapes in various modes. static 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! - { "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 }, - { "cmd_normal", - 0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE }, - { "cmd_insert", 0, - 0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE }, - { "cmd_replace", - 0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE }, - { "pending", - 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 }, - { "cmd_line", 0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE }, - { "statusline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE }, - { "drag_statusline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE }, - { "vsep", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE }, - { "vdrag", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vd", SHAPE_MOUSE }, + // 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 }, - { "match_paren", 0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR }, + { "showmatch", 0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR }, }; /// Converts cursor_shapes into a Dictionary of dictionaries diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h index 14ace2a861..0006ede31d 100644 --- a/src/nvim/cursor_shape.h +++ b/src/nvim/cursor_shape.h @@ -14,9 +14,9 @@ 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, ///< status line +SHAPE_IDX_STATUS = 10, ///< On status line SHAPE_IDX_SDRAG = 11, ///< dragging a status line -SHAPE_IDX_VSEP = 12, ///< A vertical separator 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 diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index e1fec0f678..badc0cd870 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -487,7 +487,7 @@ static void tui_cursor_style_set(UI *ui, Dictionary args) data->cursor_shapes[mode_id] = r; } - // force redrawal + // force redraw MouseMode cursor_mode = tui_mode2cursor(data->showing_mode); tui_set_cursor(ui, cursor_mode); } @@ -550,7 +550,7 @@ static void tui_set_cursor(UI *ui, MouseMode mode) default: WLOG("Unknown shape value %d", shape); break; } data->params[0].i = shape; - data->params[1].i = (c.blinkon ==0); + data->params[1].i = (c.blinkon == 0); unibi_format(vars, vars + 26, TMUX_WRAP("\x1b]50;CursorShape=%p1%d;BlinkingCursorEnabled=%p2%d\x07"), -- cgit From 16babc66870b5579f3305fa1289f25e1dc496655 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 1 Apr 2017 18:00:42 -0400 Subject: tui: Only enable/disable mouse when there's something to do (#6411) If we get a mouse_on/mouse_off event, but the mouse is already in the corresponding state, there's no need to send the event up to the terminal. Closes #4394 --- src/nvim/tui/tui.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 55936ad58d..ebdfb1e7a1 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -452,15 +452,19 @@ 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(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(ui, data->unibi_ext.disable_mouse); + data->mouse_enabled = false; + } } static void tui_mode_change(UI *ui, int mode) -- cgit From b10880dadcbd3b3ad368621f95a0f4be7e30dc0d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 2 Apr 2017 22:11:35 +0300 Subject: eval: Make writefile() able to disable fsync() --- src/nvim/eval.c | 6 +++++- src/nvim/os/fileio.c | 20 ++++++++++++-------- src/nvim/shada.c | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index f0d78a2508..8a3e3f3e22 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17421,6 +17421,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool binary = false; bool append = false; + bool do_fsync = true; if (argvars[2].v_type != VAR_UNKNOWN) { const char *const flags = tv_get_string_chk(&argvars[2]); if (flags == NULL) { @@ -17432,6 +17433,9 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (strchr(flags, 'a')) { append = true; } + if (strchr(flags, 'S')) { + do_fsync = false; + } } char buf[NUMBUFLEN]; @@ -17453,7 +17457,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (write_list(&fp, argvars[0].vval.v_list, binary)) { rettv->vval.v_number = 0; } - if ((error = file_close(&fp)) != 0) { + if ((error = file_close(&fp, do_fsync)) != 0) { emsgf(_("E80: Error when closing file %s: %s"), fname, os_strerror(error)); } diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 3c928363cc..4b7b53fc7f 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -113,27 +113,31 @@ FileDescriptor *file_open_new(int *const error, const char *const fname, /// 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; } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index f65fdaf1c0..c7b95958e0 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -811,7 +811,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)); -- cgit From 364709bedb17bfde4eb12d8f2c1427fe958dc6fc Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 00:35:29 +0300 Subject: fileio: Refactor errmsg handling Adds os_strerror() result to a number of places. Also since I could not track where err\* variables are NULL and where they are not, using macros to make sure that all three variables are set at once. Removes #ifdef UNIX around the use of os_fsync, makes it use os_close in place of close in some places. --- src/nvim/fileio.c | 171 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 94 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index bd632b2755..fb44d2cc1d 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -2258,9 +2258,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; @@ -2282,7 +2289,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() */ @@ -2577,13 +2583,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 @@ -2599,8 +2603,7 @@ buf_write ( */ c = 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) { @@ -2612,8 +2615,7 @@ buf_write ( if (perm < 0) { newfile = true; } else if (os_isdir(fname)) { - errnum = (char_u *)"E502: "; - errmsg = (char_u *)_("is a directory"); + SET_ERRMSG_NUM("E502", _("is a directory")); goto fail; } if (overwriting) { @@ -2632,11 +2634,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; } @@ -2904,23 +2904,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, @@ -2937,18 +2941,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; @@ -2963,8 +2968,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; } @@ -3028,7 +3032,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; } } @@ -3069,7 +3073,7 @@ nobackup: && !(exiting && backup != NULL)) { ml_preserve(buf, FALSE); if (got_int) { - errmsg = (char_u *)_(e_interr); + SET_ERRMSG(_(e_interr)); goto restore_backup; } } @@ -3140,8 +3144,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; } } @@ -3153,8 +3157,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; @@ -3189,11 +3193,10 @@ nobackup: if ((!newfile && os_fileinfo_hardlinks(&file_info) > 1) || (os_fileinfo_link((char *)fname, &file_info) && !os_fileinfo_id_equal(&file_info, &file_info_old))) { - errmsg = (char_u *)_("E166: Can't open linked file for writing"); - } else + SET_ERRMSG(_("E166: Can't open linked file for writing")); + } else { #endif - { - errmsg = (char_u *)_("E212: Can't open file for writing"); + SET_ERRMSG(_("E212: Can't open file for writing")); if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL && perm >= 0) { #ifdef UNIX @@ -3211,7 +3214,9 @@ nobackup: os_remove((char *)wfname); continue; } +#ifdef UNIX } +#endif } restore_backup: @@ -3253,7 +3258,7 @@ restore_backup: xfree(wfname); goto fail; } - errmsg = NULL; + SET_ERRMSG(NULL); write_info.bw_fd = fd; @@ -3373,7 +3378,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 @@ -3382,11 +3386,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. */ @@ -3416,8 +3420,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; } @@ -3454,21 +3458,25 @@ 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)"); + if (write_info.bw_conv_error_lnum == 0) { + SET_ERRMSG(_( + "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 + 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?)")); + } } /* @@ -3673,33 +3681,39 @@ nofail: #endif if (errmsg != NULL) { - int numlen = errnum != NULL ? (int)STRLEN(errnum) : 0; + const size_t numlen = (errnum != NULL ? strlen(errnum) : 0); - attr = hl_attr(HLF_E); /* set highlight for error messages */ - msg_add_fname(buf, + // Put file name in IObuff with quotes. #ifndef UNIX - sfname + msg_add_fname(buf, sfname); #else - fname + msg_add_fname(buf, 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. */ + const size_t errmsglen = strlen(errmsg); + if (STRLEN(IObuff) + errmsglen + numlen >= IOSIZE) { + IObuff[IOSIZE - errmsglen - 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); + memmove(IObuff, errnum, numlen); } - STRCAT(IObuff, errmsg); - emsg(IObuff); - if (errmsg_allocated) + xstrlcat((char *)IObuff, errmsg, IOSIZE); + if (errmsgarg != 0) { + emsgf((const char *)IObuff, os_strerror(errmsgarg)); + } else { + emsgf((const char *)IObuff); + } + 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 +3773,9 @@ nofail: got_int |= prev_got_int; return retval; +#undef SET_ERRMSG +#undef SET_ERRMSG_ARG +#undef SET_ERRMSG_NUM } /* -- cgit From 8dd9c6edd87403fb583b1e8b5567987e159fd7e2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 00:40:48 +0300 Subject: message: Do not use IObuff in emsgf --- src/nvim/message.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index 83f2735b50..4423b430a5 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -573,16 +573,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(errbuf); } static void msg_emsgf_event(void **argv) -- cgit From 8eb598c08ea51731536184a4b3e98000ce073877 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 00:44:49 +0300 Subject: fixup! --- src/nvim/message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index 4423b430a5..1d3609291a 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -583,7 +583,7 @@ bool emsgf(const char *const fmt, ...) vim_vsnprintf(errbuf, sizeof(errbuf), fmt, ap, NULL); va_end(ap); - return emsg(errbuf); + return emsg((const char_u *)errbuf); } static void msg_emsgf_event(void **argv) -- cgit From 1c41b9c77552618a5010ca69bee92033c4082748 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 01:39:09 +0300 Subject: fileio: Clean up IObuff-manipulation mess --- src/nvim/fileio.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index fb44d2cc1d..e382faf7a2 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -2259,7 +2259,7 @@ buf_write ( linenr_T lnum; long nchars; #define SET_ERRMSG_NUM(num, msg) \ - errnum = num ": ", errmsg = msg, errmsgarg = 0 + errnum = num, errmsg = msg, errmsgarg = 0 #define SET_ERRMSG_ARG(msg, error) \ errnum = NULL, errmsg = msg, errmsgarg = error #define SET_ERRMSG(msg) \ @@ -3681,29 +3681,21 @@ nofail: #endif if (errmsg != NULL) { - const size_t numlen = (errnum != NULL ? strlen(errnum) : 0); - - // Put file name in IObuff with quotes. #ifndef UNIX msg_add_fname(buf, sfname); #else msg_add_fname(buf, fname); #endif - const size_t errmsglen = strlen(errmsg); - if (STRLEN(IObuff) + errmsglen + numlen >= IOSIZE) { - IObuff[IOSIZE - errmsglen - 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, numlen); - } - xstrlcat((char *)IObuff, errmsg, IOSIZE); - if (errmsgarg != 0) { - emsgf((const char *)IObuff, os_strerror(errmsgarg)); + 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((const char *)IObuff); + emsgf(errmsg); } if (errmsg_allocated) { xfree(errmsg); @@ -3822,7 +3814,7 @@ static int set_rw_fname(char_u *fname, char_u *sfname) /* * Put file name into IObuff with quotes. */ -void msg_add_fname(buf_T *buf, char_u *fname) +static void msg_add_fname(buf_T *buf, char_u *fname) { if (fname == NULL) fname = (char_u *)"-stdin-"; -- cgit From 5dcf2804455f45eac8aad7d900bf60464a4b2888 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 02:03:05 +0300 Subject: fileio: Refactor msg_add_fname to something which needs no comments --- src/nvim/buffer.c | 4 ++-- src/nvim/fileio.c | 58 ++++++++++++++++++++++++++++++------------------------- src/nvim/os/env.c | 7 ++++--- src/nvim/path.c | 14 +++++++------- 4 files changed, 45 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index c9101c5b53..292eb03a16 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2724,7 +2724,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", @@ -2889,7 +2889,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] == ':') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index e382faf7a2..1ae73e787d 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -200,18 +200,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; @@ -1800,8 +1796,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 @@ -3531,8 +3527,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; @@ -3681,10 +3677,11 @@ nofail: #endif if (errmsg != NULL) { + // - 100 to save some space for further error message #ifndef UNIX - msg_add_fname(buf, sfname); + add_quoted_fname((char *)IObuff, IOSIZE - 100, buf, (const char *)sfname); #else - msg_add_fname(buf, fname); + add_quoted_fname((char *)IObuff, IOSIZE - 100, buf, (const char *)fname); #endif if (errnum != NULL) { if (errmsgarg != 0) { @@ -3811,16 +3808,25 @@ static int set_rw_fname(char_u *fname, char_u *sfname) return OK; } -/* - * Put file name into IObuff with quotes. - */ -static 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. diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index a10c835591..1a97adfa21 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -703,7 +703,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; @@ -717,7 +718,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; } @@ -809,7 +810,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; } diff --git a/src/nvim/path.c b/src/nvim/path.c index d0248690d9..6bf42ed2fa 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -84,15 +84,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 +100,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. @@ -174,9 +174,9 @@ const char *path_next_component(const char *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 +189,7 @@ char_u *get_past_head(char_u *path) ++retval; } - return retval; + return (char_u *)retval; } /* -- cgit From 97a7f4745dd1d75cd176dede1a4430bc4e28f8f7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 02:11:27 +0300 Subject: eval: Add s flag, use p_fs by default, error out on unknown flag --- src/nvim/eval.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8a3e3f3e22..7ab07fe6a2 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17421,20 +17421,24 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool binary = false; bool append = false; - bool do_fsync = true; + bool do_fsync = !!p_fs; if (argvars[2].v_type != VAR_UNKNOWN) { const char *const flags = tv_get_string_chk(&argvars[2]); if (flags == NULL) { return; } - if (strchr(flags, 'b')) { - binary = true; - } - if (strchr(flags, 'a')) { - append = true; - } - if (strchr(flags, 'S')) { - do_fsync = false; + 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; + } + } } } -- cgit From 2dbd49f73cba0dac8d430f86b301b6e9c15f3a7f Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 03:02:17 +0300 Subject: fileio: Save details about E212 error --- src/nvim/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 1ae73e787d..8e0e45aee6 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -3192,7 +3192,7 @@ nobackup: SET_ERRMSG(_("E166: Can't open linked file for writing")); } else { #endif - SET_ERRMSG(_("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 -- cgit From ac87c7e5ae5fc15ca97150dfce1476408804ae5a Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 3 Apr 2017 03:46:44 +0300 Subject: fileio: Fix most linter errors One error is still kept: buf_write function is too large. --- src/nvim/fileio.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 8e0e45aee6..c1b8203ed1 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -203,7 +203,7 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr) if (msg_silent != 0) { return; } - add_quoted_fname((char *)IObuff, IOSIZE - 80, buf,(const char *)name); + 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 @@ -1796,7 +1796,7 @@ failed: } if (!filtering && !(flags & READ_DUMMY)) { - add_quoted_fname((char *)IObuff, IOSIZE, curbuf,(const char *)sfname); + add_quoted_fname((char *)IObuff, IOSIZE, curbuf, (const char *)sfname); c = false; #ifdef UNIX @@ -2913,9 +2913,9 @@ buf_write ( int error; if ((error = os_close(bfd)) != 0 && errmsg == NULL) { - SET_ERRMSG_ARG(_( - "E507: Close error for backup file (add ! to override): %s"), - error); + SET_ERRMSG_ARG(_("E507: Close error for backup file " + "(add ! to override): %s"), + error); } if (write_info.bw_len < 0) { SET_ERRMSG(_( @@ -2937,7 +2937,7 @@ buf_write ( } } nobackup: - os_close(fd); /* ignore errors for closing read file */ + os_close(fd); // Ignore errors for closing read file. xfree(copybuf); if (backup == NULL && errmsg == NULL) { @@ -3458,8 +3458,7 @@ restore_backup: SET_ERRMSG(_( "E513: write error, conversion failed " "(make 'fenc' empty to override)")); - } - else { + } else { errmsg_allocated = true; SET_ERRMSG(xmalloc(300)); vim_snprintf( @@ -3527,7 +3526,7 @@ restore_backup: fname = sfname; /* use shortname now, for the messages */ #endif if (!filtering) { - add_quoted_fname((char *)IObuff, IOSIZE, buf,(const char *)fname); + add_quoted_fname((char *)IObuff, IOSIZE, buf, (const char *)fname); c = false; if (write_info.bw_conv_error) { STRCAT(IObuff, _(" CONVERSION ERROR")); -- cgit From bc6d868d00a739050b683f33994f7493cf81bd61 Mon Sep 17 00:00:00 2001 From: Yichao Zhou Date: Sun, 26 Mar 2017 03:15:52 -0700 Subject: 'listchars': `Whitespace` highlight group #6367 --- src/nvim/globals.h | 3 ++- src/nvim/option.c | 3 ++- src/nvim/screen.c | 8 ++++---- src/nvim/syntax.c | 1 + 4 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/globals.h b/src/nvim/globals.h index c15287aa38..3c705d88a5 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -464,6 +464,7 @@ typedef enum { , HLF_CUL // 'cursurline' , HLF_MC // 'colorcolumn' , HLF_QFL // selected quickfix line + , HLF_0 // Whitespace , HLF_COUNT // MUST be the last one } hlf_T; @@ -472,7 +473,7 @@ typedef enum { #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' } + 'x', 'X', '*', '#', '_', '!', '.', 'o', 'q', '0' } EXTERN int highlight_attr[HLF_COUNT]; /* Highl. attr for each context. */ EXTERN int highlight_user[9]; /* User[1-9] attributes */ diff --git a/src/nvim/option.c b/src/nvim/option.c index b3b4dc1e0a..695d0edebf 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -245,7 +245,8 @@ typedef struct vimoption { "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" /* * options[] is initialized here. diff --git a/src/nvim/screen.c b/src/nvim/screen.c index cf460adb82..d9a21aa81f 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -3409,7 +3409,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 = hl_attr(HLF_0); saved_attr2 = char_attr; // save current attr mb_c = c; if (enc_utf8 && (*mb_char2len)(c) > 1) { @@ -3424,7 +3424,7 @@ win_line ( if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') { c = lcs_trail; n_attr = 1; - extra_attr = hl_attr(HLF_8); + extra_attr = hl_attr(HLF_0); saved_attr2 = char_attr; // save current attr mb_c = c; if (enc_utf8 && (*mb_char2len)(c) > 1) { @@ -3525,8 +3525,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 = hl_attr(HLF_0); + saved_attr2 = char_attr; // save current attr mb_c = c; if (enc_utf8 && (*mb_char2len)(c) > 1) { mb_utf8 = TRUE; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index acda25e738..e36b00d770 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -5916,6 +5916,7 @@ static char *highlight_init_both[] = "default link EndOfBuffer NonText", "default link QuickFixLine Search", "default link Substitute Search", + "default link Whitespace NonText", NULL }; -- cgit From 3ccd59ee8216f3da812c5cf81eb392e6a95b539a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 3 Apr 2017 16:16:21 +0200 Subject: 'guicursor': enabled=false if 'guicursor' is empty Closes #6429 Closes #6430 --- src/nvim/api/ui.c | 6 +++--- src/nvim/cursor_shape.c | 6 ++---- src/nvim/tui/tui.c | 48 ++++++++++++++++++++++++++---------------------- src/nvim/ui.c | 3 ++- src/nvim/ui.h | 2 +- src/nvim/ui_bridge.c | 22 ++++++++++++---------- 6 files changed, 46 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index a95be0fabb..de60339e5f 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -300,11 +300,11 @@ static void remote_ui_scroll(UI *ui, int count) push_call(ui, "scroll", args); } -static void remote_ui_cursor_style_set(UI *ui, Dictionary styles) +static void remote_ui_cursor_style_set(UI *ui, bool enabled, Dictionary data) { Array args = ARRAY_DICT_INIT; - Object copy = copy_object(DICTIONARY_OBJ(styles)); - ADD(args, copy); + ADD(args, BOOLEAN_OBJ(enabled)); + ADD(args, copy_object(DICTIONARY_OBJ(data))); push_call(ui, "cursor_style_set", args); } diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index 7ec70bb724..34ee53bf75 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -89,10 +89,8 @@ 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) { + // 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) { diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index badc0cd870..f34f5f1bc4 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -84,6 +84,7 @@ typedef struct { } TUIData; static bool volatile got_winch = false; +static bool cursor_style_enabled = false; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tui/tui.c.generated.h" @@ -151,6 +152,7 @@ static void terminfo_start(UI *ui) // 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_clear_screen); // Enable bracketed paste @@ -437,11 +439,11 @@ static void tui_cursor_goto(UI *ui, int row, int col) CursorShape tui_cursor_decode_shape(const char *shape_str) { CursorShape shape = 0; - if (strcmp(shape_str, "block") == 0) { + if (strequal(shape_str, "block")) { shape = SHAPE_BLOCK; - } else if (strcmp(shape_str, "vertical") == 0) { + } else if (strequal(shape_str, "vertical")) { shape = SHAPE_VER; - } else if (strcmp(shape_str, "horizontal") == 0) { + } else if (strequal(shape_str, "horizontal")) { shape = SHAPE_HOR; } else { EMSG2(_(e_invarg2), shape_str); @@ -454,40 +456,41 @@ static cursorentry_T decode_cursor_entry(Dictionary args) cursorentry_T r; for (size_t i = 0; i < args.size; i++) { - char *keyStr = args.items[i].key.data; + char *key = args.items[i].key.data; Object value = args.items[i].value; - if (strcmp(keyStr, "cursor_shape") == 0) { + if (strequal(key, "cursor_shape")) { r.shape = tui_cursor_decode_shape(args.items[i].value.data.string.data); - } else if (strcmp(keyStr, "blinkon") == 0) { + } else if (strequal(key, "blinkon")) { r.blinkon = (int)value.data.integer; - } else if (strcmp(keyStr, "blinkoff") == 0) { + } else if (strequal(key, "blinkoff")) { r.blinkoff = (int)value.data.integer; - } else if (strcmp(keyStr, "hl_id") == 0) { + } else if (strequal(key, "hl_id")) { r.id = (int)value.data.integer; } } return r; } -static void tui_cursor_style_set(UI *ui, Dictionary args) +static void tui_cursor_style_set(UI *ui, bool enabled, Dictionary args) { + cursor_style_enabled = enabled; + if (!enabled) { + return; // Do not send cursor style control codes. + } TUIData *data = ui->data; + assert(args.size); + // Keys: as defined by `shape_table`. for (size_t i = 0; i < args.size; i++) { char *mode_name = args.items[i].key.data; const int mode_id = cursor_mode_str2int(mode_name); - - if (mode_id < 0) { - WLOG("Unknown mode '%s'", mode_name); - continue; - } + assert(mode_id >= 0); cursorentry_T r = decode_cursor_entry(args.items[i].value.data.dictionary); r.full_name = mode_name; data->cursor_shapes[mode_id] = r; } - // force redraw MouseMode cursor_mode = tui_mode2cursor(data->showing_mode); tui_set_cursor(ui, cursor_mode); } @@ -528,6 +531,9 @@ static void tui_mouse_off(UI *ui) /// @param mode one of SHAPE_XXX static void tui_set_cursor(UI *ui, MouseMode mode) { + if (!cursor_style_enabled) { + return; + } TUIData *data = ui->data; cursorentry_T c = data->cursor_shapes[mode]; int shape = c.shape; @@ -536,17 +542,15 @@ static void tui_set_cursor(UI *ui, MouseMode mode) # 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) { + if (os_getenv("KONSOLE_PROFILE_NAME") || os_getenv("KONSOLE_DBUS_SESSION")) { // Konsole uses a proprietary escape code to set the cursor shape // and does not support DECSCUSR. switch (shape) { case SHAPE_BLOCK: shape = 0; break; case SHAPE_VER: shape = 1; break; - case SHAPE_HOR: shape = 3; break; + case SHAPE_HOR: shape = 2; break; default: WLOG("Unknown shape value %d", shape); break; } data->params[0].i = shape; @@ -1102,15 +1106,15 @@ 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) { + if (strequal(name, "key_backspace")) { ILOG("libtermkey:kbs=%s", value); if (stty_erase != NULL && stty_erase[0] != 0) { return stty_erase; } - } else if (strcmp(name, "key_dc") == 0) { + } else if (strequal(name, "key_dc")) { ILOG("libtermkey:kdch1=%s", value); // Vim: "If and are now the same, redefine ." - if (stty_erase != NULL && value != NULL && strcmp(stty_erase, value) == 0) { + if (stty_erase != NULL && value != NULL && strequal(stty_erase, value)) { return stty_erase[0] == DEL ? CTRL_H_STR : DEL_STR; } } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index babb4efa96..28f71b7ef2 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -381,7 +381,8 @@ void ui_cursor_goto(int new_row, int new_col) void ui_cursor_style_set(void) { Dictionary style = cursor_shape_dict(); - UI_CALL(cursor_style_set, style); + bool enabled = (*p_guicursor != NUL); + UI_CALL(cursor_style_set, enabled, style); api_free_dictionary(style); } diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 0af0c0db65..8ffc5a45a6 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -22,7 +22,7 @@ struct ui_t { void (*clear)(UI *ui); void (*eol_clear)(UI *ui); void (*cursor_goto)(UI *ui, int row, int col); - void (*cursor_style_set)(UI *ui, Dictionary cursor_shapes); + void (*cursor_style_set)(UI *ui, bool enabled, Dictionary cursor_styles); void (*update_menu)(UI *ui); void (*busy_start)(UI *ui); void (*busy_stop)(UI *ui); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index c9bad6b254..9f780663ac 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -60,7 +60,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->bridge.clear = ui_bridge_clear; rv->bridge.eol_clear = ui_bridge_eol_clear; rv->bridge.cursor_goto = ui_bridge_cursor_goto; - rv->bridge.cursor_style_set = ui_bridge_cursor_styleset; + rv->bridge.cursor_style_set = ui_bridge_cursor_style_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; @@ -180,19 +180,21 @@ static void ui_bridge_cursor_goto_event(void **argv) ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2])); } -static void ui_bridge_cursor_styleset(UI *b, Dictionary style) +static void ui_bridge_cursor_style_set(UI *b, bool enabled, Dictionary styles) { - Object copy = copy_object(DICTIONARY_OBJ(style)); - Object *pobj = xmalloc(sizeof(copy)); - *pobj = copy; - UI_CALL(b, cursor_styleset, 2, b, pobj); + bool *enabledp = xmalloc(sizeof(*enabledp)); + Object *stylesp = xmalloc(sizeof(*stylesp)); + *enabledp = enabled; + *stylesp = copy_object(DICTIONARY_OBJ(styles)); + UI_CALL(b, cursor_style_set, 3, b, enabledp, stylesp); } -static void ui_bridge_cursor_styleset_event(void **argv) +static void ui_bridge_cursor_style_set_event(void **argv) { UI *ui = UI(argv[0]); - Object *styles = (Object *)argv[1]; - - ui->cursor_style_set(ui, styles->data.dictionary); + bool *enabled = argv[1]; + Object *styles = argv[2]; + ui->cursor_style_set(ui, *enabled, styles->data.dictionary); + xfree(enabled); api_free_object(*styles); xfree(styles); } -- cgit From e348e256f3ed93fe462971447ee79033307b2ddf Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 4 Apr 2017 02:37:43 +0200 Subject: 'guicursor': Disable by default for unknown terminals. User can still set guicursor explicitly in init.vim. Closes #5990 Closes #6403 --- src/nvim/main.c | 2 +- src/nvim/option.c | 20 +++++++++++--------- src/nvim/os/env.c | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 33e1551351..7ad42d6776 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -283,7 +283,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; diff --git a/src/nvim/option.c b/src/nvim/option.c index 695d0edebf..458d80716c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -939,11 +939,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; @@ -966,8 +963,12 @@ void set_init_2(void) 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 (!headless && !os_term_is_nice()) { + set_string_option_direct((char_u *)"guicursor", -1, (char_u *)"", + OPT_GLOBAL, SID_NONE); + } + parse_shape_opt(SHAPE_CURSOR); // set cursor shapes from 'guicursor' + (void)parse_printoptions(); // parse 'printoptions' default value } /* @@ -2842,9 +2843,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(); diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 1a97adfa21..839e0d1b51 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -889,3 +889,17 @@ bool os_setenv_append_path(const char *fname) } 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"); + return (vte_version && atoi(vte_version) >= 3900) + || NULL != os_getenv("KONSOLE_PROFILE_NAME") + || NULL != os_getenv("KONSOLE_DBUS_SESSION"); +#endif +} -- cgit From a7f34e199144bfb657c180cdc1413093fd34bdf9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 4 Apr 2017 03:38:57 +0200 Subject: options: remove 'guiheadroom' --- src/nvim/options.lua | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 09f016cf5a..4ca63f2efe 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1025,13 +1025,6 @@ return { redraw={'everything'}, enable_if=false, }, - { - full_name='guiheadroom', abbreviation='ghr', - type='number', scope={'global'}, - vi_def=true, - enable_if=false, - defaults={if_true={vi=50}} - }, { full_name='guioptions', abbreviation='go', type='string', list='flags', scope={'global'}, -- cgit From c501d7c432693705482f76a384a98b4b4c0ef1a9 Mon Sep 17 00:00:00 2001 From: Carlo Abelli Date: Thu, 6 Apr 2017 08:48:42 -0400 Subject: refactor/single-include: diff.h (#6443) --- src/nvim/CMakeLists.txt | 1 - src/nvim/diff.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 5a5ebc4415..d0f75a2b5b 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -425,7 +425,6 @@ endfunction() set(NO_SINGLE_CHECK_HEADERS cursor_shape.h - diff.h digraph.h ex_cmds.h ex_getln.h 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 -- cgit From 6a6bbbc6d8fa79a0c14fb913baa3ba2d7046419c Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 6 Apr 2017 08:54:30 -0400 Subject: vim-patch:7.4.2281 Problem: Timer test fails sometimes. Solution: Reduce minimum time by 1 msec. https://github.com/vim/vim/commit/0426bae2abede764d0dd366a28663d1c6e6ab0fe --- src/nvim/testdir/test_timers.vim | 6 +++--- src/nvim/version.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index db10f351ae..16c70b166b 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -20,7 +20,7 @@ func Test_oneshot() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') - call assert_inrange(50, 100, slept) + call assert_inrange(49, 100, slept) else call assert_inrange(20, 100, slept) endif @@ -32,7 +32,7 @@ func Test_repeat_three() let slept = WaitFor('g:val == 3') call assert_equal(3, g:val) if has('reltime') - call assert_inrange(150, 250, slept) + call assert_inrange(149, 250, slept) else call assert_inrange(80, 200, slept) endif @@ -57,7 +57,7 @@ func Test_with_partial_callback() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') - call assert_inrange(50, 130, slept) + call assert_inrange(49, 130, slept) else call assert_inrange(20, 100, slept) endif diff --git a/src/nvim/version.c b/src/nvim/version.c index ca520c7af5..3944551cb4 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -160,7 +160,7 @@ static const int included_patches[] = { 2284, 2283, // 2282 NA - // 2281 NA + 2281, 2280, 2279, // 2278 NA -- cgit From 0f99645b8faf3e5970e46c185c0cbbd7a9cfe318 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 6 Apr 2017 08:55:51 -0400 Subject: vim-patch:7.4.2304 Problem: In a timer callback the timer itself can't be found or stopped. (Thinca) Solution: Do not remove the timer from the list, remember whether it was freed. https://github.com/vim/vim/commit/417ccd7138d4d230d328de8b0d3892dd82ff1bee --- src/nvim/testdir/test_timers.vim | 15 +++++++++++++++ src/nvim/version.c | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 16c70b166b..6a8b09c898 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -125,4 +125,19 @@ func Test_paused() endif endfunc +func StopMyself(timer) + let g:called += 1 + if g:called == 2 + call timer_stop(a:timer) + endif +endfunc + +func Test_delete_myself() + let g:called = 0 + let t = timer_start(10, 'StopMyself', {'repeat': -1}) + call WaitFor('g:called == 2') + call assert_equal(2, g:called) + call assert_equal([], timer_info(t)) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index 3944551cb4..beb23090ec 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -137,7 +137,7 @@ static const int included_patches[] = { 2307, 2306, 2305, - // 2304 NA + 2304, 2303, // 2302 NA // 2301 NA -- cgit From 9edbeec07716cff5607202dbd20b81917416030f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 6 Apr 2017 08:56:53 -0400 Subject: vim-patch:7.4.2332 Problem: Crash when stop_timer() is called in a callback of a callback. Vim hangs when the timer callback uses too much time. Solution: Set tr_id to -1 when a timer is to be deleted. Don't keep calling callbacks forever. (Ozaki Kiichi) https://github.com/vim/vim/commit/75537a93e985ef32e6c267b06ce93629855dd983 --- src/nvim/testdir/test_timers.vim | 30 ++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 6a8b09c898..2a768585ce 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -140,4 +140,34 @@ func Test_delete_myself() 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/version.c b/src/nvim/version.c index beb23090ec..d16eab7201 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -109,7 +109,7 @@ static const int included_patches[] = { 2335, 2334, 2333, - // 2332 NA + 2332, 2331, 2330, 2329, -- cgit From 071f2da66bacfd5a2d4ab87bda275d3848ddcc0e Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 6 Apr 2017 08:58:18 -0400 Subject: vim-patch:7.4.2359 Problem: Memory leak in timer_start(). Solution: Check the right field to be NULL. https://github.com/vim/vim/commit/26fe0d56912e42c2b16a61b2480e19ba569aee98 --- src/nvim/testdir/test_timers.vim | 8 ++++---- src/nvim/version.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 2a768585ce..fd2b50b495 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -48,12 +48,12 @@ endfunc func Test_with_partial_callback() let g:val = 0 - let s:meow = {} - function s:meow.bite(...) - let g:val += 1 + let meow = {'one': 1} + function meow.bite(...) + let g:val += self.one endfunction - call timer_start(50, s:meow.bite) + call timer_start(50, meow.bite) let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') diff --git a/src/nvim/version.c b/src/nvim/version.c index d16eab7201..9a5d7ce169 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -82,7 +82,7 @@ static const int included_patches[] = { 2362, // 2361 NA // 2360, - // 2359 NA + 2359, // 2358 NA 2357, // 2356, -- cgit From 30e1cda8acb7bd8120348d1812cfd9ecd8be8528 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 6 Apr 2017 21:35:03 +0200 Subject: completion: fix segfault with ignorecase+infercase (#6452) Helped-by: Matthew Malcomson Closes #6451 --- src/nvim/edit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index da09aed3dc..b35504908e 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2109,7 +2109,7 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int xfree(wca); - return ins_compl_add(IObuff, len, icase, fname, NULL, true, dir, flags, + return ins_compl_add(IObuff, len, icase, fname, NULL, false, dir, flags, false); } return ins_compl_add(str, len, icase, fname, NULL, false, dir, flags, false); @@ -2146,7 +2146,7 @@ static int ins_compl_add(char_u *const str, int len, os_breakcheck(); #define FREE_CPTEXT(cptext, cptext_allocated) \ do { \ - if (cptext_allocated) { \ + if (cptext != NULL && cptext_allocated) { \ for (size_t i = 0; i < CPT_COUNT; i++) { \ xfree(cptext[i]); \ } \ -- cgit From 1813076c448f1039db33e08e83b7f1f2011db0ee Mon Sep 17 00:00:00 2001 From: Nicolas Hillegeer Date: Fri, 7 Apr 2017 12:29:17 +0200 Subject: eval: delimit string with NUL byte (#6467) A recent refactor left cpy without a NUL terminator, simplify the code instead of patching over it. Instead of plain memcpy, it'd be better to employ harder to misuse string functions made for this purpose like xstrlcpy(), but path_tail() takes char_u arguments and returns them, leading to a lot of ugly casting. Fixes #6431. --- src/nvim/eval.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7ab07fe6a2..1636b490d5 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13416,14 +13416,12 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) q = (char *)path_tail((char_u *)p); } if (q > p && !path_is_absolute_path((const char_u *)buf)) { - // Symlink is relative to directory of argument. + // 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); - cpy = xmalloc(p_len + buf_len + 1); - memcpy(cpy, p, p_len); - memcpy(path_tail((char_u *)cpy), buf, buf_len + 1); - xfree(p); - p = cpy; + p = xrealloc(p, p_len + buf_len + 1); + memcpy(path_tail((char_u *)p), buf, buf_len + 1); } else { xfree(p); p = xstrdup(buf); -- cgit From 13352c00f1909d9296c5f276a3735f5e6f231b39 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 7 Apr 2017 19:46:33 +0200 Subject: win: os_get_hostname() #5416 (#6413) --- src/nvim/mbyte.c | 51 ++++++++++++++++++++++++++------------------------- src/nvim/os/env.c | 24 ++++++++++++++++++++---- src/nvim/os/fs.c | 2 +- 3 files changed, 47 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index d96848754c..460528b85f 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1304,6 +1304,7 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, # 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 { @@ -1345,40 +1346,40 @@ int utf8_to_utf16(const char *str, WCHAR **strw) 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 = xmalloc(utf8_len); - // Convert string to UTF-8. - int r = WideCharToMultiByte(CP_UTF8, - 0, - strw, - -1, - pos, - utf8_len, - NULL, - NULL); - assert(r == utf8_len); - if (r != utf8_len) { - EMSG2("WideCharToMultiByte failed: %d", r); - } - *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; } diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 839e0d1b51..12c2da6152 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -118,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. @@ -145,10 +144,27 @@ void os_get_hostname(char *hostname, size_t size) } else { 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 } diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 3833a43f5f..c33e1140e8 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -1009,7 +1009,7 @@ char *os_resolve_shortcut(const char *fname) WCHAR *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) { -- cgit From 19044a15f9d41a7424e94fb3f0e257537e7afa5e Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 6 Apr 2017 21:21:11 +0300 Subject: strings: Replace vim_strchr implementation with a saner one Removes dead code (enc_utf8, enc_dbcs and has_mbyte now have hardcoded values), relies on libc implementation being more optimized. Also where previously negative character just would never be found it is an assertion error now. Ref #1476 --- src/nvim/strings.c | 64 ++++++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 5dcffe00e0..c4bc9b204a 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -401,54 +401,28 @@ 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. Must be a valid character. +/// +/// @return Pointer to the first byte of the found character in string or NULL +/// if it was not found. 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; - } + assert(c >= 0); + 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; } /* -- cgit From 171baaee93c8e257ef593b30c05405d03ac30c96 Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 6 Apr 2017 21:31:37 +0300 Subject: strings: Remove vim_strbyte Ref #1476 --- src/nvim/ex_cmds.c | 13 ++++++------- src/nvim/getchar.c | 4 ++-- src/nvim/mbyte.c | 6 +++--- src/nvim/regexp.c | 42 +++++++++++++++--------------------------- src/nvim/regexp_nfa.c | 13 +++---------- src/nvim/strings.c | 18 ------------------ 6 files changed, 29 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 9a847a4c0a..8485a1ca66 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -5087,14 +5087,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 diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index b83681ad01..56493a300d 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -3588,8 +3588,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); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index d96848754c..c31fee44af 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -356,10 +356,10 @@ int bomb_size(void) */ void remove_bom(char_u *s) { - char_u *p = s; + char *p = (char *)s; - while ((p = vim_strbyte(p, 0xef)) != NULL) { - if (p[1] == 0xbb && p[2] == 0xbf) { + while ((p = strchr(p, 0xef)) != NULL) { + if ((uint8_t)p[1] == 0xbb && (uint8_t)p[2] == 0xbf) { STRMOVE(p, p + 3); } else { p++; diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 9baa53d2a2..e9c9b491fd 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -3429,32 +3429,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 (!ireg_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; @@ -3484,14 +3478,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; diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 5b49ab38f0..a77978884e 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4855,17 +4855,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; } diff --git a/src/nvim/strings.c b/src/nvim/strings.c index c4bc9b204a..ada4c108cf 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -425,24 +425,6 @@ char_u *vim_strchr(const char_u *const string, const int c) } } -/* - * Version of strchr() that only works for bytes and handles unsigned char - * strings with characters above 128 correctly. It also doesn't return a - * pointer to the NUL at the end of the string. - */ -char_u *vim_strbyte(const char_u *string, int c) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE -{ - const char_u *p = string; - - while (*p != NUL) { - if (*p == c) - return (char_u *) p; - ++p; - } - return NULL; -} - /* * Search for last occurrence of "c" in "string". * Return NULL if not found. -- cgit From ac1cb1c72fa762b39ff457153c7fa6ecf1eaedc3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 6 Apr 2017 21:56:49 +0300 Subject: regexp: Refactor cstrchr Ref #1476 --- src/nvim/regexp.c | 55 +++++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index e9c9b491fd..175aa1b970 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -6287,43 +6287,38 @@ 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) - ) + if (!ireg_ic) { 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 (c > 0x80) { + const int folded_c = utf_fold(c); + for (const char_u *p = s; *p != NUL; p += utfc_ptr2len(p)) { + if (utf_fold(utf_ptr2char(p)) == folded_c) { + return (char_u *)p; + } + } + return NULL; + } - /* 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)) + int cc; + if (vim_isupper(c)) { cc = vim_tolower(c); - else if (vim_islower(c)) + } else if (vim_islower(c)) { cc = vim_toupper(c); - else + } else { return vim_strchr(s, c); + } - if (has_mbyte) { - for (p = s; *p != NUL; p += (*mb_ptr2len)(p)) { - if (enc_utf8 && c > 0x80) { - if (utf_fold(utf_ptr2char(p)) == cc) - return p; - } else if (*p == c || *p == cc) - return p; - } - } else - /* Faster version for when there are no multi-byte characters. */ - for (p = s; *p != NUL; ++p) - if (*p == c || *p == cc) - return p; - - return NULL; + char tofind[] = { (char)c, (char)cc, NUL }; + return (char_u *)strpbrk((const char *)s, tofind); } /*************************************************************** -- cgit From 20dc04470e00a369d2ba917a22b06ef2d173953f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 7 Apr 2017 16:08:58 -0400 Subject: vim-patch:8.0.0499 Problem: taglist() does not prioritize tags for a buffer. Solution: Add an optional buffer argument. (Duncan McDougall, closes vim/vim#1194) https://github.com/vim/vim/commit/c6aafbaf3ea755e3ab4ee2e3045911126a08b038 --- src/nvim/eval.c | 10 +++++++--- src/nvim/eval.lua | 2 +- src/nvim/tag.c | 10 ++++------ src/nvim/testdir/test_alot.vim | 1 + src/nvim/testdir/test_taglist.vim | 21 +++++++++++++++++++++ 5 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 src/nvim/testdir/test_taglist.vim (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1636b490d5..e15d6c0240 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8728,8 +8728,7 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) } fold_count = foldedCount(curwin, lnum, &foldinfo); if (fold_count > 0) { - text = get_foldtext(curwin, lnum, lnum + fold_count - 1, - &foldinfo, buf); + text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf); if (text == buf) text = vim_strsave(text); rettv->vval.v_string = text; @@ -16436,7 +16435,12 @@ static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - (void)get_tags(tv_list_alloc_ret(rettv), (char_u *)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); } /* diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e3c5981b32..6f876e2a96 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -300,7 +300,7 @@ 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={}, diff --git a/src/nvim/tag.c b/src/nvim/tag.c index b812dd2ffd..e4ff829807 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2797,11 +2797,9 @@ add_tag_field ( 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; @@ -2811,7 +2809,7 @@ int get_tags(list_T *list, char_u *pat) 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); diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index baf49b7ff7..99d9835996 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -26,6 +26,7 @@ source test_tabline.vim " source test_tabpage.vim source test_tagcase.vim source test_tagjump.vim +source test_taglist.vim source test_true_false.vim source test_unlet.vim source test_utf8.vim diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim new file mode 100644 index 0000000000..b89b25eae2 --- /dev/null +++ b/src/nvim/testdir/test_taglist.vim @@ -0,0 +1,21 @@ +" 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 + -- cgit From caeff6e1aff227bb5826ad575362d2a24adebaa9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 7 Apr 2017 23:18:36 +0300 Subject: regexp: Do not use locale-dependent functions in cstrchr --- src/nvim/regexp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 175aa1b970..893089f06d 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -6309,10 +6309,10 @@ static inline char_u *cstrchr(const char_u *const s, const int c) } int cc; - if (vim_isupper(c)) { - cc = vim_tolower(c); - } else if (vim_islower(c)) { - cc = vim_toupper(c); + if (ASCII_ISUPPER(c)) { + cc = TOLOWER_ASC(c); + } else if (ASCII_ISLOWER(c)) { + cc = TOUPPER_ASC(c); } else { return vim_strchr(s, c); } -- cgit From 98dd9b801281bb6eb82817ba92c4f635bb5f45e0 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 7 Apr 2017 16:18:25 -0400 Subject: vim-patch:8.0.0550 Problem: Some etags format tags file use 0x01, breaking the parsing. Solution: Use 0x02 for TAG_SEP. (James McCoy, closes vim/vim#1614) https://github.com/vim/vim/commit/9585a1655ba0d34ea88574617112093a9bd4f2e9 --- src/nvim/tag.c | 10 +++++----- src/nvim/testdir/test_taglist.vim | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index e4ff829807..f01b8b8ab1 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1847,14 +1847,14 @@ parse_line: } } } else { -#define TAG_SEP 0x01 +#define TAG_SEP 0x02 size_t tag_fname_len = STRLEN(tag_fname); // Save the tag in a buffer. - // Use 0x01 to separate fields (Can't use NUL, because the + // Use 0x02 to separate fields (Can't use NUL, because the // hash key is terminated by NUL). - // Emacs tag: - // other tag: - // without Emacs tags: + // Emacs tag: <0x02><0x02> + // other tag: <0x02><0x02> + // without Emacs tags: <0x02> // Here 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); diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim index b89b25eae2..2d1557ebd9 100644 --- a/src/nvim/testdir/test_taglist.vim +++ b/src/nvim/testdir/test_taglist.vim @@ -19,3 +19,40 @@ func Test_taglist() 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 -- cgit From 123931e65e8f6ca3ac13fff8279720c8328a018e Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 7 Apr 2017 16:38:06 -0400 Subject: lint --- src/nvim/eval.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e15d6c0240..124d6acfe9 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8729,8 +8729,9 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) fold_count = foldedCount(curwin, lnum, &foldinfo); if (fold_count > 0) { text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf); - if (text == buf) + if (text == buf) { text = vim_strsave(text); + } rettv->vval.v_string = text; } } -- cgit From acc52a953b99f78435c34337b8ca9b6716a057a1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 02:55:51 +0300 Subject: regexp: Update comment in cstrchr() --- src/nvim/regexp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 893089f06d..96884aa87f 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -6295,9 +6295,8 @@ static inline char_u *cstrchr(const char_u *const s, const int c) 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. + // 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)) { -- cgit From fd8f18bce25e6dcc66dec1fa4870a7ca5c106dec Mon Sep 17 00:00:00 2001 From: dedmass Date: Tue, 4 Apr 2017 20:30:32 -0400 Subject: refactor/single-include: cursor_shape.h #6442 --- src/nvim/CMakeLists.txt | 1 - src/nvim/cursor_shape.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index d0f75a2b5b..db3b406b4a 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -424,7 +424,6 @@ function(get_test_target prefix sfile relative_path_var target_var) endfunction() set(NO_SINGLE_CHECK_HEADERS - cursor_shape.h digraph.h ex_cmds.h ex_getln.h diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h index 0006ede31d..7cf65cba3c 100644 --- a/src/nvim/cursor_shape.h +++ b/src/nvim/cursor_shape.h @@ -1,6 +1,9 @@ #ifndef NVIM_CURSOR_SHAPE_H #define NVIM_CURSOR_SHAPE_H +#include "nvim/types.h" +#include "nvim/api/private/defs.h" + /// struct to store values from 'guicursor' and 'mouseshape' /// Indexes in shape_table[] typedef enum { -- cgit From f4e97fe49988b834fea8d8b7a62de0938325395a Mon Sep 17 00:00:00 2001 From: dedmass Date: Tue, 4 Apr 2017 20:53:26 -0400 Subject: refactor/single-include: digraph.h #6444 --- src/nvim/CMakeLists.txt | 1 - src/nvim/digraph.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index db3b406b4a..5524c4d87d 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -424,7 +424,6 @@ function(get_test_target prefix sfile relative_path_var target_var) endfunction() set(NO_SINGLE_CHECK_HEADERS - digraph.h ex_cmds.h ex_getln.h file_search.h diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h index b623969e08..d0f10eaf78 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" // for char_u +#include "nvim/ex_cmds_defs.h" // for exarg_T + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "digraph.h.generated.h" #endif -- cgit From 3d4a2ee9c72e772113e69c9928fbc58e9dc4b09b Mon Sep 17 00:00:00 2001 From: dedmass Date: Thu, 6 Apr 2017 09:12:59 -0400 Subject: refactor/single-include: ex_cmds.h #6453 --- src/nvim/CMakeLists.txt | 1 - src/nvim/ex_cmds.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 5524c4d87d..843bff3655 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -424,7 +424,6 @@ function(get_test_target prefix sfile relative_path_var target_var) endfunction() set(NO_SINGLE_CHECK_HEADERS - ex_cmds.h ex_getln.h file_search.h fold.h diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index 65bbd8a99e..792e2f772f 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -6,6 +6,8 @@ #include "nvim/os/time.h" #include "nvim/pos.h" #include "nvim/eval/typval.h" +#include "nvim/buffer_defs.h" // for buf_T and win_T +#include "nvim/ex_cmds_defs.h" // for exarg_T // flags for do_ecmd() #define ECMD_HIDE 0x01 // don't free the current buffer -- cgit From b47e1029a549d6563eeec17e099b82d781925f71 Mon Sep 17 00:00:00 2001 From: dedmass Date: Thu, 6 Apr 2017 21:56:27 -0400 Subject: refactor/single-include: move.h #6469 --- src/nvim/CMakeLists.txt | 1 - src/nvim/move.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 843bff3655..cdfc6367e5 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -438,7 +438,6 @@ set(NO_SINGLE_CHECK_HEADERS memline_defs.h menu.h misc2.h - move.h msgpack_rpc/server.h ops.h option.h diff --git a/src/nvim/move.h b/src/nvim/move.h index 3f3bf70929..1cdf1f6f52 100644 --- a/src/nvim/move.h +++ b/src/nvim/move.h @@ -2,6 +2,8 @@ #define NVIM_MOVE_H #include +#include "nvim/buffer_defs.h" // for win_T +#include "nvim/pos.h" // for linenr_T #ifdef INCLUDE_GENERATED_DECLARATIONS # include "move.h.generated.h" -- cgit From 89deb6ff223ffef5c1e93e629b4df2cf666d9cd1 Mon Sep 17 00:00:00 2001 From: dedmass Date: Thu, 6 Apr 2017 17:16:56 -0400 Subject: refactor/single-include: memline_defs.h #6465 --- src/nvim/CMakeLists.txt | 1 - src/nvim/memfile_defs.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index cdfc6367e5..4d83e9b1ea 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -435,7 +435,6 @@ set(NO_SINGLE_CHECK_HEADERS mbyte.h memfile_defs.h memline.h - memline_defs.h menu.h misc2.h msgpack_rpc/server.h diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h index cc71e1a7ff..57d8abbe30 100644 --- a/src/nvim/memfile_defs.h +++ b/src/nvim/memfile_defs.h @@ -3,8 +3,10 @@ #include #include +#include // for size_t #include "nvim/types.h" +#include "nvim/pos.h" // for linenr_T /// A block number. /// -- cgit From fd69c3f561ea8862ce4b1ff67a5650acaf5f932d Mon Sep 17 00:00:00 2001 From: dedmass Date: Thu, 6 Apr 2017 09:22:44 -0400 Subject: refactor/single-include: ex_getln.h #6454 --- src/nvim/CMakeLists.txt | 1 - src/nvim/ex_getln.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 4d83e9b1ea..3d3d30081a 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -424,7 +424,6 @@ function(get_test_target prefix sfile relative_path_var target_var) endfunction() set(NO_SINGLE_CHECK_HEADERS - ex_getln.h file_search.h fold.h getchar.h diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h index 5a1ca5213a..a29c8297d5 100644 --- a/src/nvim/ex_getln.h +++ b/src/nvim/ex_getln.h @@ -3,6 +3,9 @@ #include "nvim/eval/typval.h" #include "nvim/ex_cmds.h" +#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/os/time.h" // for Timestamp +#include "nvim/regexp_defs.h" // for regmatch_T /* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */ #define WILD_FREE 1 -- cgit From 3fd9b70c485c55adb95848aa0e2c67bfb3db786a Mon Sep 17 00:00:00 2001 From: dedmass Date: Thu, 6 Apr 2017 09:40:17 -0400 Subject: refactor/single-include: fold.h #6456 --- src/nvim/CMakeLists.txt | 1 - src/nvim/fold.h | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 3d3d30081a..24a6ec8b5e 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -425,7 +425,6 @@ endfunction() set(NO_SINGLE_CHECK_HEADERS file_search.h - fold.h getchar.h hardcopy.h if_cscope.h diff --git a/src/nvim/fold.h b/src/nvim/fold.h index 2ff10c0e91..2393f4ef47 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -1,7 +1,12 @@ #ifndef NVIM_FOLD_H #define NVIM_FOLD_H +#include // for FILE + #include "nvim/pos.h" +#include "nvim/garray.h" // for garray_T +#include "nvim/types.h" // for char_u +#include "nvim/buffer_defs.h" // for win_T /* * Info used to pass info about a fold from the fold-detection code to the -- cgit From e586047a53d4145db9c797af7f42c71c35143896 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 17:15:56 +0300 Subject: eval/decode,shada: Do not forget to clean up converters --- src/nvim/eval/decode.c | 1 + src/nvim/shada.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index fb31a65971..a4fc6c8eb1 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -892,6 +892,7 @@ json_decode_string_fail: tv_clear(&(kv_pop(stack).val)); } json_decode_string_ret: + convert_setup(&conv, NULL, NULL); kv_destroy(stack); kv_destroy(container_stack); return ret; diff --git a/src/nvim/shada.c b/src/nvim/shada.c index c7b95958e0..9ee364d962 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -709,6 +709,7 @@ static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer, static void close_sd_reader(ShaDaReadDef *const sd_reader) FUNC_ATTR_NONNULL_ALL { + convert_setup(&sd_reader->sd_conv, NULL, NULL); close_file(sd_reader->cookie); } @@ -716,6 +717,7 @@ static void close_sd_reader(ShaDaReadDef *const sd_reader) static void close_sd_writer(ShaDaWriteDef *const sd_writer) FUNC_ATTR_NONNULL_ALL { + convert_setup(&sd_writer->sd_conv, NULL, NULL); close_file(sd_writer->cookie); } -- cgit From b3587a456b4c235822006aae928667433ab85e66 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 17:18:40 +0300 Subject: shada: Initialize vimconv_T --- src/nvim/shada.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 9ee364d962..3c4fd8b992 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -800,6 +800,7 @@ static int open_shada_file_for_reading(const char *const fname, .eof = false, .fpos = 0, .cookie = file_open_new(&error, fname, kFileReadOnly, 0), + .sd_conv.vc_type = CONV_NONE, }; if (sd_reader->cookie == NULL) { return error; @@ -2939,6 +2940,7 @@ int shada_write_file(const char *const file, bool nomerge) .write = &write_file, .close = &close_sd_writer, .error = NULL, + .sd_conv.vc_type = CONV_NONE, }; ShaDaReadDef sd_reader = { .close = NULL }; -- cgit From 6006cb74ef7c43b58e8c06e5ecaa5823247b970a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 17:36:02 +0300 Subject: eval/decode: Omit calling convert_setup for each string Uses the same trick eval/encode does. --- src/nvim/eval/decode.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index a4fc6c8eb1..e8c06b2927 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -606,6 +606,17 @@ parse_json_number_ret: } \ } 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 UTF-8 to last_p_enc +static vimconv_T p_enc_conv = { + .vc_type = CONV_NONE, +}; + /// Convert JSON string into VimL object /// /// @param[in] buf String to convert. UTF-8 encoding is assumed. @@ -626,9 +637,12 @@ 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; + if (last_p_enc != (const void *)p_enc) { + p_enc_conv.vc_type = CONV_NONE; + convert_setup(&p_enc_conv, (char_u *)"utf-8", p_enc); + p_enc_conv.vc_fail = true; + last_p_enc = p_enc; + } int ret = OK; ValuesStack stack = KV_INITIAL_VALUE; ContainerStack container_stack = KV_INITIAL_VALUE; @@ -774,9 +788,9 @@ json_decode_string_cycle_start: break; } case '"': { - if (parse_json_string(&conv, buf, buf_len, &p, &stack, &container_stack, - &next_map_special, &didcomma, &didcolon) - == FAIL) { + if (parse_json_string( + &p_enc_conv, buf, buf_len, &p, &stack, &container_stack, + &next_map_special, &didcomma, &didcolon) == FAIL) { // Error message was already given goto json_decode_string_fail; } @@ -892,7 +906,6 @@ json_decode_string_fail: tv_clear(&(kv_pop(stack).val)); } json_decode_string_ret: - convert_setup(&conv, NULL, NULL); kv_destroy(stack); kv_destroy(container_stack); return ret; -- cgit From e81469522371837615d2e2ffbd578ef44f883d2a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 18:03:56 +0300 Subject: eval/*code,shada: Drop support for converting UTF-8 from/to p_enc Not needed any longer since p_enc is always utf-8. --- src/nvim/eval/decode.c | 39 +-------- src/nvim/eval/encode.c | 56 +++--------- src/nvim/shada.c | 234 +++++++------------------------------------------ 3 files changed, 45 insertions(+), 284 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index e8c06b2927..c7ca3a8ce5 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -222,8 +222,6 @@ static inline int json_decoder_pop(ValuesStackItem obj, /// 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 '"'. @@ -240,8 +238,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, @@ -416,20 +413,6 @@ 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 = tv_list_alloc(); @@ -606,17 +589,6 @@ parse_json_number_ret: } \ } 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 UTF-8 to last_p_enc -static vimconv_T p_enc_conv = { - .vc_type = CONV_NONE, -}; - /// Convert JSON string into VimL object /// /// @param[in] buf String to convert. UTF-8 encoding is assumed. @@ -637,12 +609,7 @@ int json_decode_string(const char *const buf, const size_t buf_len, EMSG(_("E474: Attempt to decode a blank string")); return FAIL; } - if (last_p_enc != (const void *)p_enc) { - p_enc_conv.vc_type = CONV_NONE; - convert_setup(&p_enc_conv, (char_u *)"utf-8", p_enc); - p_enc_conv.vc_fail = true; - last_p_enc = p_enc; - } + assert(STRCMP(p_enc, "utf-8") == 0); int ret = OK; ValuesStack stack = KV_INITIAL_VALUE; ContainerStack container_stack = KV_INITIAL_VALUE; @@ -789,7 +756,7 @@ json_decode_string_cycle_start: } case '"': { if (parse_json_string( - &p_enc_conv, buf, buf_len, &p, &stack, &container_stack, + buf, buf_len, &p, &stack, &container_stack, &next_map_special, &didcomma, &didcolon) == FAIL) { // Error message was already given goto json_decode_string_fail; diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 26f9aaa27d..b64217f969 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -11,7 +11,7 @@ #include #include "nvim/eval/encode.h" -#include "nvim/buffer_defs.h" // vimconv_T +#include "nvim/buffer_defs.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/garray.h" @@ -29,10 +29,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", @@ -537,17 +533,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", @@ -579,33 +564,16 @@ 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; - } + assert(STRCMP(p_enc, "utf-8") == 0); 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)); @@ -636,7 +604,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) @@ -666,7 +634,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[]) { diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 3c4fd8b992..cfe0bd8774 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -73,15 +73,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_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)) @@ -413,8 +408,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; @@ -435,8 +428,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 @@ -709,7 +700,6 @@ static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer, static void close_sd_reader(ShaDaReadDef *const sd_reader) FUNC_ATTR_NONNULL_ALL { - convert_setup(&sd_reader->sd_conv, NULL, NULL); close_file(sd_reader->cookie); } @@ -717,7 +707,6 @@ static void close_sd_reader(ShaDaReadDef *const sd_reader) static void close_sd_writer(ShaDaWriteDef *const sd_writer) FUNC_ATTR_NONNULL_ALL { - convert_setup(&sd_writer->sd_conv, NULL, NULL); close_file(sd_writer->cookie); } @@ -800,13 +789,12 @@ static int open_shada_file_for_reading(const char *const fname, .eof = false, .fpos = 0, .cookie = file_open_new(&error, fname, kFileReadOnly, 0), - .sd_conv.vc_type = CONV_NONE, }; if (sd_reader->cookie == NULL) { return error; } - convert_setup(&sd_reader->sd_conv, "utf-8", p_enc); + assert(STRCMP(p_enc, "utf-8") == 0); return 0; } @@ -1902,127 +1890,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); - tv_clear(&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[0]))); - 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; } @@ -2559,11 +2444,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 { - tv_copy(&vartv, &tgttv); - } + tv_copy(&vartv, &tgttv); ShaDaWriteResult spe_ret; if ((spe_ret = shada_pack_entry(packer, (ShadaEntry) { .type = kSDItemVariable, @@ -2814,9 +2695,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; \ } \ @@ -2826,8 +2706,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; } @@ -2835,8 +2715,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; \ } \ @@ -2863,9 +2743,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; } @@ -2889,8 +2768,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) { @@ -2940,7 +2819,6 @@ int shada_write_file(const char *const file, bool nomerge) .write = &write_file, .close = &close_sd_writer, .error = NULL, - .sd_conv.vc_type = CONV_NONE, }; ShaDaReadDef sd_reader = { .close = NULL }; @@ -3042,7 +2920,7 @@ shada_write_file_nomerge: {} verbose_leave(); } - convert_setup(&sd_writer.sd_conv, p_enc, "utf-8"); + assert(STRCMP(p_enc, "utf-8") == 0); const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge ? NULL @@ -3331,29 +3209,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 " " \ @@ -3431,10 +3286,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 { \ @@ -3807,30 +3659,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; @@ -3863,16 +3699,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); - tv_clear(&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"); -- cgit From ab19fa155203a4071cb8e780db7d3480b562aee0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 19:11:42 +0300 Subject: *: Fix linter errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops comments `// for …` that do not pass linter for them being unmaintainable and fast to becoming incomplete or even incorrect. Mention @dedmass --- src/nvim/digraph.h | 4 ++-- src/nvim/eval/decode.c | 6 +++--- src/nvim/ex_cmds.h | 4 ++-- src/nvim/ex_getln.h | 6 +++--- src/nvim/fold.h | 8 ++++---- src/nvim/memfile_defs.h | 4 ++-- src/nvim/move.h | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h index d0f10eaf78..1b73ccaf3f 100644 --- a/src/nvim/digraph.h +++ b/src/nvim/digraph.h @@ -1,8 +1,8 @@ #ifndef NVIM_DIGRAPH_H #define NVIM_DIGRAPH_H -#include "nvim/types.h" // for char_u -#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/types.h" +#include "nvim/ex_cmds_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "digraph.h.generated.h" diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index c7ca3a8ce5..f9889ca547 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -755,9 +755,9 @@ json_decode_string_cycle_start: break; } case '"': { - if (parse_json_string( - buf, buf_len, &p, &stack, &container_stack, - &next_map_special, &didcomma, &didcolon) == FAIL) { + if (parse_json_string(buf, buf_len, &p, &stack, &container_stack, + &next_map_special, &didcomma, &didcolon) + == FAIL) { // Error message was already given goto json_decode_string_fail; } diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index 792e2f772f..b564cde56c 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -6,8 +6,8 @@ #include "nvim/os/time.h" #include "nvim/pos.h" #include "nvim/eval/typval.h" -#include "nvim/buffer_defs.h" // for buf_T and win_T -#include "nvim/ex_cmds_defs.h" // for exarg_T +#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_getln.h b/src/nvim/ex_getln.h index a29c8297d5..051564fbe1 100644 --- a/src/nvim/ex_getln.h +++ b/src/nvim/ex_getln.h @@ -3,9 +3,9 @@ #include "nvim/eval/typval.h" #include "nvim/ex_cmds.h" -#include "nvim/ex_cmds_defs.h" // for exarg_T -#include "nvim/os/time.h" // for Timestamp -#include "nvim/regexp_defs.h" // for regmatch_T +#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/fold.h b/src/nvim/fold.h index 2393f4ef47..f35b328fb1 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -1,12 +1,12 @@ #ifndef NVIM_FOLD_H #define NVIM_FOLD_H -#include // for FILE +#include #include "nvim/pos.h" -#include "nvim/garray.h" // for garray_T -#include "nvim/types.h" // for char_u -#include "nvim/buffer_defs.h" // for win_T +#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/memfile_defs.h b/src/nvim/memfile_defs.h index 57d8abbe30..b3c2f3564c 100644 --- a/src/nvim/memfile_defs.h +++ b/src/nvim/memfile_defs.h @@ -3,10 +3,10 @@ #include #include -#include // for size_t +#include #include "nvim/types.h" -#include "nvim/pos.h" // for linenr_T +#include "nvim/pos.h" /// A block number. /// diff --git a/src/nvim/move.h b/src/nvim/move.h index 1cdf1f6f52..00fbcc580f 100644 --- a/src/nvim/move.h +++ b/src/nvim/move.h @@ -2,8 +2,8 @@ #define NVIM_MOVE_H #include -#include "nvim/buffer_defs.h" // for win_T -#include "nvim/pos.h" // for linenr_T +#include "nvim/buffer_defs.h" +#include "nvim/pos.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "move.h.generated.h" -- cgit From cd0a436622d0eeafcbc79e0a6e53088b881ab5b1 Mon Sep 17 00:00:00 2001 From: dedmass Date: Thu, 6 Apr 2017 17:06:35 -0400 Subject: refactor/single-include Closes #6463 refactor/single-include: file_search.h Closes #6455 refactor/single-include: hardcopy.h Closes #6457 refactor/single-include: if_cscope.h Closes #6458 refactor/single-include: mark.h Closes #6461 refactor/single-include: mbyte.h Closes #6462 refactor/single-include: memline.h Closes #6464 refactor/single-include: menu.h Closes #6468 refactor/single-include: ops.h Closes #6470 --- src/nvim/CMakeLists.txt | 9 --------- src/nvim/file_search.h | 5 +++++ src/nvim/hardcopy.h | 4 ++++ src/nvim/if_cscope.h | 3 +++ src/nvim/mark.h | 1 + src/nvim/mbyte.h | 1 + src/nvim/memline.h | 2 ++ src/nvim/menu.h | 5 +++++ src/nvim/ops.h | 2 ++ 9 files changed, 23 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 24a6ec8b5e..e0f4944762 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -424,19 +424,10 @@ function(get_test_target prefix sfile relative_path_var target_var) endfunction() set(NO_SINGLE_CHECK_HEADERS - file_search.h getchar.h - hardcopy.h - if_cscope.h if_cscope_defs.h - mark.h - mbyte.h - memfile_defs.h - memline.h - menu.h misc2.h msgpack_rpc/server.h - ops.h option.h os/shell.h os_unix.h 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 // 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/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 +#include // 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/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/mark.h b/src/nvim/mark.h index efba9708db..c22a102926 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -8,6 +8,7 @@ #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_) \ diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index 3565202466..ad9e38004c 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -7,6 +7,7 @@ #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". 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/menu.h b/src/nvim/menu.h index 3266c511b4..a84b7d812e 100644 --- a/src/nvim/menu.h +++ b/src/nvim/menu.h @@ -1,6 +1,11 @@ #ifndef NVIM_MENU_H #define NVIM_MENU_H +#include // 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 */ #define MENU_INDEX_INVALID -1 #define MENU_INDEX_NORMAL 0 diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 13d0142343..a8867e02ea 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -8,6 +8,8 @@ #include "nvim/types.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); -- cgit From 7701014b659d3505c6d4f0de95c06042155c98d1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 20:22:46 +0300 Subject: *: Remove useless asserts --- src/nvim/eval/decode.c | 1 - src/nvim/eval/encode.c | 1 - src/nvim/shada.c | 2 -- 3 files changed, 4 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index f9889ca547..a7dc6b205d 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -609,7 +609,6 @@ int json_decode_string(const char *const buf, const size_t buf_len, EMSG(_("E474: Attempt to decode a blank string")); return FAIL; } - assert(STRCMP(p_enc, "utf-8") == 0); int ret = OK; ValuesStack stack = KV_INITIAL_VALUE; ContainerStack container_stack = KV_INITIAL_VALUE; diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index b64217f969..d74913a481 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -564,7 +564,6 @@ static inline int convert_to_json_string(garray_T *const gap, } else { size_t utf_len = len; char *tofree = NULL; - assert(STRCMP(p_enc, "utf-8") == 0); size_t str_len = 0; // Encode character as \uNNNN if // 1. It is an ASCII control character (0x0 .. 0x1F; 0x7F not diff --git a/src/nvim/shada.c b/src/nvim/shada.c index cfe0bd8774..8c5d6dff65 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -2920,8 +2920,6 @@ shada_write_file_nomerge: {} verbose_leave(); } - assert(STRCMP(p_enc, "utf-8") == 0); - const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge ? NULL : &sd_reader)); -- cgit From 7b6b629e1a1e3c9f49f75f3bf2c53bb76f77e209 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 20:30:26 +0300 Subject: api: Add FUNC_API_SINCE(1) to new functions --- src/nvim/api/vim.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 511c87f408..05317b8d69 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -844,6 +844,7 @@ static void write_msg(String message, bool to_err) /// /// @return its argument. Object _vim_id(Object obj) + FUNC_API_SINCE(1) { return copy_object(obj); } @@ -857,6 +858,7 @@ Object _vim_id(Object obj) /// /// @return its argument. Array _vim_id_array(Array arr) + FUNC_API_SINCE(1) { return copy_object(ARRAY_OBJ(arr)).data.array; } @@ -870,6 +872,7 @@ Array _vim_id_array(Array arr) /// /// @return its argument. Dictionary _vim_id_dictionary(Dictionary dct) + FUNC_API_SINCE(1) { return copy_object(DICTIONARY_OBJ(dct)).data.dictionary; } @@ -883,6 +886,7 @@ Dictionary _vim_id_dictionary(Dictionary dct) /// /// @return its argument. Float _vim_id_float(Float flt) + FUNC_API_SINCE(1) { return flt; } -- cgit From a40a969e9a4776f1e274dcf0e59c8f1ec1770ca0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 20:33:48 +0300 Subject: api: Rename _vim_id functions to nvim__id --- src/nvim/api/vim.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 05317b8d69..9ee3827040 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -843,7 +843,7 @@ static void write_msg(String message, bool to_err) /// @param[in] obj Object to return. /// /// @return its argument. -Object _vim_id(Object obj) +Object nvim__id(Object obj) FUNC_API_SINCE(1) { return copy_object(obj); @@ -857,7 +857,7 @@ Object _vim_id(Object obj) /// @param[in] arr Array to return. /// /// @return its argument. -Array _vim_id_array(Array arr) +Array nvim__id_array(Array arr) FUNC_API_SINCE(1) { return copy_object(ARRAY_OBJ(arr)).data.array; @@ -871,7 +871,7 @@ Array _vim_id_array(Array arr) /// @param[in] dct Dictionary to return. /// /// @return its argument. -Dictionary _vim_id_dictionary(Dictionary dct) +Dictionary nvim__id_dictionary(Dictionary dct) FUNC_API_SINCE(1) { return copy_object(DICTIONARY_OBJ(dct)).data.dictionary; @@ -885,7 +885,7 @@ Dictionary _vim_id_dictionary(Dictionary dct) /// @param[in] flt Value to return. /// /// @return its argument. -Float _vim_id_float(Float flt) +Float nvim__id_float(Float flt) FUNC_API_SINCE(1) { return flt; -- cgit From 0f4b4c7529d6699bcae5c943a4bc27827c9aa8d6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 18:23:02 +0300 Subject: headers: Remove useless HAVE_CONFIG_H macros We do not have non-cmake build options, cmake always does configure_file. --- src/nvim/iconv.h | 4 +--- src/nvim/vim.h | 10 ++++------ 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src') 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/vim.h b/src/nvim/vim.h index cc0587fb88..d92115ecdf 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -13,18 +13,16 @@ /* ============ 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 */ -- cgit From 8e519a22ddcad6a38d966a7c340c9fd77d72f392 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 8 Apr 2017 18:51:29 +0300 Subject: vim.h: Remove strange comments --- src/nvim/vim.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/nvim/vim.h b/src/nvim/vim.h index d92115ecdf..172e62b039 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -11,8 +11,6 @@ #define RUNTIME_DIRNAME "runtime" /* end */ -/* ============ the header file puzzle (ca. 50-100 pieces) ========= */ - #include "auto/config.h" #define HAVE_PATHDEF @@ -44,11 +42,6 @@ enum { NUMBUFLEN = 65 }; #include "nvim/keymap.h" #include "nvim/macros.h" - - - -/* ================ end of the header file puzzle =============== */ - #include "nvim/gettext.h" /* special attribute addition: Put message in history */ -- cgit From 3a6b8c28c813f8e65851c8e89c7cf56b4d6cf03f Mon Sep 17 00:00:00 2001 From: Nikolai Aleksandrovich Pavlov Date: Sun, 9 Apr 2017 04:28:48 +0300 Subject: cmake: Use archive instead of downloading *.json files (#6482) --- src/nvim/CMakeLists.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index e0f4944762..1daa5dc3c4 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -41,7 +41,7 @@ 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 "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/errors.tar.gz") +set(LINT_SUPPRESSES_URL "${LINT_SUPPRESS_URL_BASE}/errors.tar.gz") include_directories(${GENERATED_DIR}) include_directories(${CACHED_GENERATED_DIR}) @@ -486,6 +486,20 @@ function(add_download output url allow_failure) ) endfunction() +include(ExternalProject) +ExternalProject_Add( + clint-error-files + PREFIX "${LINT_SUPPRESSES_ROOT}" + URL "${LINT_SUPPRESSES_URL}" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + BUILD_IN_SOURCE 1 + INSTALL_COMMAND + "${CMAKE_COMMAND}" + -DTARGET=${LINT_SUPPRESSES_ROOT} + -P "${PROJECT_SOURCE_DIR}/cmake/InstallClintErrors.cmake" +) + add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL} off) set(LINT_NVIM_REL_SOURCES) @@ -494,14 +508,13 @@ foreach(sfile ${LINT_NVIM_SOURCES}) set(suppress_file ${LINT_SUPPRESSES_ROOT}/${suffix}.json) set(suppress_url "${LINT_SUPPRESS_URL_BASE}/${suffix}.json") set(rsfile src/nvim/${r}) - add_download(${suppress_file} ${suppress_url} on) 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} ${suppress_file} + DEPENDS ${LINT_PRG} ${sfile} clint-error-files ) list(APPEND LINT_TARGETS ${touch_file}) list(APPEND LINT_NVIM_REL_SOURCES ${rsfile}) -- cgit From c8243ad071f6cfcb9650ee00c53feadaaf7d90d5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 05:18:09 +0300 Subject: cmake: Do not build clint-error-files by default --- src/nvim/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 1daa5dc3c4..6a4fa7eadb 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -491,6 +491,7 @@ ExternalProject_Add( clint-error-files PREFIX "${LINT_SUPPRESSES_ROOT}" URL "${LINT_SUPPRESSES_URL}" + EXCLUDE_FROM_ALL 1 CONFIGURE_COMMAND "" BUILD_COMMAND "" BUILD_IN_SOURCE 1 -- cgit From b99cac277812d337e8a5f1bc6a182e62f1e8c448 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 06:17:02 +0300 Subject: cmake: Do not use ExternalProject Necessary argument (EXCLUDE_FROM_ALL) only appears in 3.1.0. --- src/nvim/CMakeLists.txt | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 6a4fa7eadb..cb003c2026 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -42,6 +42,9 @@ 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") include_directories(${GENERATED_DIR}) include_directories(${CACHED_GENERATED_DIR}) @@ -50,6 +53,8 @@ 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 NVIM_SOURCES *.c) file(GLOB NVIM_HEADERS *.h) @@ -486,19 +491,18 @@ function(add_download output url allow_failure) ) endfunction() -include(ExternalProject) -ExternalProject_Add( - clint-error-files - PREFIX "${LINT_SUPPRESSES_ROOT}" - URL "${LINT_SUPPRESSES_URL}" - EXCLUDE_FROM_ALL 1 - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - BUILD_IN_SOURCE 1 - INSTALL_COMMAND - "${CMAKE_COMMAND}" +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 "${PROJECT_SOURCE_DIR}/cmake/InstallClintErrors.cmake" + -P ${LINT_SUPPRESSES_INSTALL_SCRIPT} + DEPENDS + ${LINT_SUPPRESSES_ARCHIVE} ${LINT_SUPPRESSES_INSTALL_SCRIPT} ) add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL} off) @@ -515,7 +519,7 @@ foreach(sfile ${LINT_NVIM_SOURCES}) COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} ${rsfile} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -E touch ${touch_file} - DEPENDS ${LINT_PRG} ${sfile} clint-error-files + DEPENDS ${LINT_PRG} ${sfile} ${LINT_SUPPRESSES_TOUCH_FILE} ) list(APPEND LINT_TARGETS ${touch_file}) list(APPEND LINT_NVIM_REL_SOURCES ${rsfile}) -- cgit From fb66a7c69ef061fd2da12df8bca47592df25438f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 8 Apr 2017 21:22:11 -0400 Subject: vim-patch:8.0.0377 Problem: Possible overflow when reading corrupted undo file. Solution: Check if allocated size is not too big. (King) https://github.com/vim/vim/commit/3eb1637b1bba19519885dd6d377bd5596e91d22c CVE-2017-6349 --- src/nvim/undo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 4d4e8d9bb9..83c171d66a 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #include @@ -1400,7 +1401,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; -- cgit From ad66826abee14009abddfbef3e6088afc773ab9d Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 8 Apr 2017 21:56:02 -0400 Subject: vim-patch:8.0.0378 Problem: Another possible overflow when reading corrupted undo file. Solution: Check if allocated size is not too big. (King) https://github.com/vim/vim/commit/0c8485f0e4931463c0f7986e1ea84a7d79f10c75 CVE-2017-6350 --- src/nvim/undo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 83c171d66a..571ad7204f 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -967,12 +967,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; -- cgit From b338bb9d6c331fa4a45fbbeb7da3210f30f31702 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 9 Apr 2017 00:45:19 -0400 Subject: vim-patch:8.0.0322 Problem: Possible overflow with spell file where the tree length is corrupted. Solution: Check for an invalid length (suggested by shqking) https://github.com/vim/vim/commit/399c297aa93afe2c0a39e2a1b3f972aebba44c9d CVE-2017-5953 --- src/nvim/spellfile.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 4d7ff558ad..81000b95f5 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1572,6 +1572,10 @@ spell_read_tree ( int len = get4c(fd); if (len < 0) return SP_TRUNCERROR; + if (len >= 0x3ffffff) { + // Invalid length, multiply with sizeof(int) would overflow. + return SP_FORMERROR; + } if (len > 0) { // Allocate the byte array. bp = xmalloc(len); -- cgit From 4af6c60826b4cb939fd9b7fe67a0b03e86d72bfc Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 9 Apr 2017 00:46:52 -0400 Subject: vim-patch:8.0.0376 Problem: Size computations in spell file reading are not exactly right. Solution: Make "len" a "long" and check with LONG_MAX. https://github.com/vim/vim/commit/6d3c8586fc81b022e9f06c611b9926108fb878c7 --- src/nvim/spellfile.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 81000b95f5..a6cee59795 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -223,6 +223,7 @@ // few bytes as possible, see offset2bytes()) #include +#include #include #include "nvim/vim.h" @@ -1569,10 +1570,10 @@ spell_read_tree ( // The tree size was computed when writing the file, so that we can // allocate it as one long block. - int len = get4c(fd); + long len = get4c(fd); if (len < 0) return SP_TRUNCERROR; - if (len >= 0x3ffffff) { + if ((size_t)len >= SIZE_MAX / sizeof(int)) { // Invalid length, multiply with sizeof(int) would overflow. return SP_FORMERROR; } -- cgit From 06a96df510e1fa8d77d21a8120e97342d04be15f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 9 Apr 2017 01:17:15 -0400 Subject: lint --- src/nvim/spellfile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index a6cee59795..bbef1f5032 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1571,8 +1571,9 @@ spell_read_tree ( // The tree size was computed when writing the file, so that we can // allocate it as one long block. long len = get4c(fd); - if (len < 0) + 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; -- cgit From 8d982ab52269e8adccbc21cc0d6f8ab3b817bf6e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 20:55:48 +0300 Subject: coverity/13686: Do not allow NUL byte in precondition regex Before this commit it emitted e_spell_trunc in the first case and treated file as completely valid on the second. While first is fine (both errors are actually valid, though old error is probably better), second results in incorrect regex used. --- src/nvim/spellfile.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index bbef1f5032..2c0db0694a 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -267,7 +267,7 @@ #define SAL_REM_ACCENTS 4 #define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file -#define VIMSPELLMAGICL 8 +#define VIMSPELLMAGICL (sizeof(VIMSPELLMAGIC) - 1) #define VIMSPELLVERSION 50 // Section IDs. Only renumber them when VIMSPELLVERSION changes! @@ -516,7 +516,6 @@ spell_load_file ( FILE *fd; char_u buf[VIMSPELLMAGICL]; char_u *p; - int i; int n; int len; char_u *save_sourcing_name = sourcing_name; @@ -558,8 +557,9 @@ spell_load_file ( sourcing_lnum = 0; //
: - for (i = 0; i < VIMSPELLMAGICL; ++i) + for (size_t i = 0; i < VIMSPELLMAGICL; i++) { buf[i] = getc(fd); // + } if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) { EMSG(_("E757: This does not look like a spell file")); goto endFAIL; @@ -983,35 +983,36 @@ static int read_charflags_section(FILE *fd) // 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]; - // ... - cnt = get2c(fd); // - if (cnt <= 0) + const int cnt = get2c(fd); // + if (cnt <= 0) { return SP_FORMERROR; + } lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *)); lp->sl_prefixcnt = cnt; - for (i = 0; i < cnt; ++i) { + for (int i = 0; i < cnt; ++i) { // : - n = getc(fd); // - if (n < 0 || n >= MAXWLEN) + const int n = getc(fd); // + if (n < 0 || n >= MAXWLEN) { return SP_FORMERROR; + } // When 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); // - *p = NUL; - lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING); + char buf[MAXWLEN + 1]; + buf[0] = '^'; // always match at one position only + const size_t read_byte = fread(buf + 1, 1, (size_t)n, fd); + if (read_byte != (size_t)n) { + return feof(fd) ? SP_FORMERROR : SP_OTHERERROR; + } + if (memchr(buf + 1, NUL, (size_t)n)) { + return SP_FORMERROR; + } + buf[n + 1] = NUL; + lp->sl_prefprog[i] = vim_regcomp((char_u *)buf, RE_MAGIC | RE_STRING); } } return 0; -- cgit From 5b4f07ee86194a7c6032991102c96387581029c9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 21:47:45 +0300 Subject: spellfile: Use old error This makes first test not actually show any change in behaviour. --- src/nvim/spellfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 2c0db0694a..4909b7b14e 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1006,7 +1006,7 @@ static int read_prefcond_section(FILE *fd, slang_T *lp) buf[0] = '^'; // always match at one position only const size_t read_byte = fread(buf + 1, 1, (size_t)n, fd); if (read_byte != (size_t)n) { - return feof(fd) ? SP_FORMERROR : SP_OTHERERROR; + return feof(fd) ? SP_TRUNCERROR : SP_OTHERERROR; } if (memchr(buf + 1, NUL, (size_t)n)) { return SP_FORMERROR; -- cgit From ecce981dba367d61be170b535083691dd9c40cd2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 22:02:26 +0300 Subject: coverity/13687: Do not allow NUL byte in region names --- src/nvim/spellfile.c | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 4909b7b14e..97a82582c0 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -494,6 +494,41 @@ typedef struct spellinfo_S { # 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. +/// +/// @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) \ + 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) { \ + 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) \ + 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); \ + if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \ + return SP_FORMERROR; \ + } \ + } while (0) + // Load one spell file and store the info into a slang_T. // // This is invoked in three ways: @@ -935,12 +970,10 @@ static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp) // Return SP_*ERROR flags. static int read_region_section(FILE *fd, slang_T *lp, int len) { - int i; - - if (len > 16) + if (len > 16) { return SP_FORMERROR; - for (i = 0; i < len; ++i) - lp->sl_regions[i] = getc(fd); // + } + SPELL_READ_NONNUL_BYTES((char *)lp->sl_regions, (size_t)len, fd); lp->sl_regions[len] = NUL; return 0; } @@ -1004,13 +1037,7 @@ static int read_prefcond_section(FILE *fd, slang_T *lp) if (n > 0) { char buf[MAXWLEN + 1]; buf[0] = '^'; // always match at one position only - const size_t read_byte = fread(buf + 1, 1, (size_t)n, fd); - if (read_byte != (size_t)n) { - return feof(fd) ? SP_TRUNCERROR : SP_OTHERERROR; - } - if (memchr(buf + 1, NUL, (size_t)n)) { - return SP_FORMERROR; - } + 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); } -- cgit From 8f75b67c0733f09b8bc1d99235eb3231abc6500c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 22:16:26 +0300 Subject: coverity/13688: Check for NUL bytes in salfrom --- src/nvim/spellfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 97a82582c0..8756bee21c 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1157,8 +1157,8 @@ static int read_sal_section(FILE *fd, slang_T *slang) 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); // + SPELL_READ_NONNUL_BYTES((char *)p, (size_t)ccnt, fd); // + p += ccnt; *p++ = NUL; // -- cgit From 35584594f5cfd46e9a56d9bc3473244c437a944a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 22:30:48 +0300 Subject: coverity/13689: Check file header with memcmp Not that it is actually useful (would fail in any case), but should fix coverity report. --- src/nvim/spellfile.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 8756bee21c..9943a71a7c 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -225,6 +225,7 @@ #include #include #include +#include #include "nvim/vim.h" #include "nvim/spell_defs.h" @@ -529,6 +530,26 @@ typedef struct spellinfo_S { } \ } 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: @@ -549,7 +570,6 @@ spell_load_file ( ) { FILE *fd; - char_u buf[VIMSPELLMAGICL]; char_u *p; int n; int len; @@ -592,12 +612,20 @@ spell_load_file ( sourcing_lnum = 0; //
: - for (size_t i = 0; i < VIMSPELLMAGICL; i++) { - buf[i] = getc(fd); // - } - if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) { - EMSG(_("E757: This does not look like a spell file")); - goto endFAIL; + 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); // if (c < VIMSPELLVERSION) { -- cgit From aa857f9e481770059642b9286b66c75b1d9bd758 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 22:33:45 +0300 Subject: spellfile: Fix memory leak --- src/nvim/spellfile.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 9943a71a7c..d34c3a8ba1 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -500,16 +500,18 @@ typedef struct spellinfo_S { /// @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) \ +#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) @@ -519,13 +521,14 @@ typedef struct spellinfo_S { /// @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) \ +#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); \ + 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) @@ -543,7 +546,7 @@ 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); + SPELL_READ_BYTES(buf, VIMSPELLMAGICL, fd, ); if (memcmp(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) { return SP_FORMERROR; } @@ -1001,7 +1004,7 @@ 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); + SPELL_READ_NONNUL_BYTES((char *)lp->sl_regions, (size_t)len, fd, ); lp->sl_regions[len] = NUL; return 0; } @@ -1065,7 +1068,7 @@ static int read_prefcond_section(FILE *fd, slang_T *lp) 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); + 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); } @@ -1185,7 +1188,8 @@ static int read_sal_section(FILE *fd, slang_T *slang) if (i < ccnt) // store the char we got while checking for end of sm_lead *p++ = c; - SPELL_READ_NONNUL_BYTES((char *)p, (size_t)ccnt, fd); // + SPELL_READ_NONNUL_BYTES( // + (char *)p, (size_t)ccnt, fd, xfree(smp->sm_lead)); p += ccnt; *p++ = NUL; -- cgit From eb3663eb1000bdf9b5c754614921001b21a2cf03 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 22:39:23 +0300 Subject: spellfile: Fix clint errors --- src/nvim/spellfile.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index d34c3a8ba1..f4acb37a7a 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -546,7 +546,7 @@ 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, ); + SPELL_READ_BYTES(buf, VIMSPELLMAGICL, fd, ;); if (memcmp(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) { return SP_FORMERROR; } @@ -1004,7 +1004,7 @@ 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, ); + SPELL_READ_NONNUL_BYTES((char *)lp->sl_regions, (size_t)len, fd, ;); lp->sl_regions[len] = NUL; return 0; } @@ -1056,7 +1056,7 @@ static int read_prefcond_section(FILE *fd, slang_T *lp) lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *)); lp->sl_prefixcnt = cnt; - for (int i = 0; i < cnt; ++i) { + for (int i = 0; i < cnt; i++) { // : const int n = getc(fd); // if (n < 0 || n >= MAXWLEN) { @@ -1068,7 +1068,7 @@ static int read_prefcond_section(FILE *fd, slang_T *lp) 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, ); + 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); } -- cgit From fa7ace446e724f888c815fe177c7b6e7b8057b7d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 23:38:05 +0300 Subject: coverity/56795: Fix NULL dereference in :syn keyword non-printable Bug was introduced 3 years earlier, in 13848aa: NULL keyword_copy was incorrectly treated as an indicator of OOM. --- src/nvim/syntax.c | 124 +++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index e36b00d770..1ed65ec52a 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -4246,83 +4246,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) -- cgit From ebe50519775081565b66e18a471473e46f713442 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 9 Apr 2017 23:46:38 +0300 Subject: spellfile: Fix SAL sections reading --- src/nvim/spellfile.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index f4acb37a7a..1da71dc4f9 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1123,7 +1123,6 @@ static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first) // Return SP_*ERROR flags. static int read_sal_section(FILE *fd, slang_T *slang) { - int i; int cnt; garray_T *gap; salitem_T *smp; @@ -1133,13 +1132,16 @@ static int read_sal_section(FILE *fd, slang_T *slang) slang->sl_sofo = false; - i = getc(fd); // - if (i & SAL_F0LLOWUP) + const int flags = getc(fd); // + if (flags & SAL_F0LLOWUP) { slang->sl_followup = true; - if (i & SAL_COLLAPSE) + } + if (flags & SAL_COLLAPSE) { slang->sl_collapse = true; - if (i & SAL_REM_ACCENTS) + } + if (flags & SAL_REM_ACCENTS) { slang->sl_rem_accents = true; + } cnt = get2c(fd); // if (cnt < 0) @@ -1159,7 +1161,8 @@ static int read_sal_section(FILE *fd, slang_T *slang) smp->sm_lead = p; // Read up to the first special char into sm_lead. - for (i = 0; i < ccnt; ++i) { + int i = 0; + for (; i < ccnt; ++i) { c = getc(fd); // if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) break; @@ -1185,12 +1188,17 @@ static int read_sal_section(FILE *fd, slang_T *slang) // Any following chars go in sm_rules. smp->sm_rules = p; - if (i < ccnt) + if (i < ccnt) { // store the char we got while checking for end of sm_lead *p++ = c; - SPELL_READ_NONNUL_BYTES( // - (char *)p, (size_t)ccnt, fd, xfree(smp->sm_lead)); - p += ccnt; + } + i++; + if (i < ccnt) { + SPELL_READ_NONNUL_BYTES( // + (char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead)); + p += (ccnt - i); + i = ccnt; + } *p++ = NUL; // -- cgit From 1b66ed890b6e1444b6be113bc5572f1baf82db6c Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 10 Apr 2017 02:53:00 +0300 Subject: cmake: Do not forget to actually create a touch file for errors.tar.gz --- src/nvim/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index cb003c2026..a91657f1bd 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -501,6 +501,7 @@ add_custom_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} ) -- cgit From db9ef6263ec5b7885782ccf0a93e06b0c71f6944 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 8 Apr 2017 16:45:38 +0200 Subject: mbyte: replace vim_tolower with mb_tolower handling locale correctly --- src/nvim/charset.c | 69 +++----------------------------------------------- src/nvim/edit.c | 22 ++++++++-------- src/nvim/eval.c | 2 +- src/nvim/ex_getln.c | 4 +-- src/nvim/file_search.c | 2 +- src/nvim/macros.h | 2 +- src/nvim/mbyte.c | 17 ++++++++----- src/nvim/message.c | 4 +-- src/nvim/ops.c | 10 ++++---- src/nvim/path.c | 4 +-- src/nvim/regexp.c | 34 ++++++++++++------------- src/nvim/regexp_nfa.c | 20 +++++++-------- src/nvim/search.c | 4 +-- src/nvim/spell.c | 14 +++++----- src/nvim/spell_defs.h | 4 +-- src/nvim/strings.c | 2 +- 16 files changed, 79 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 99d3e2dd88..645139f696 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -212,8 +212,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 @@ -417,11 +417,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); @@ -1506,67 +1506,6 @@ 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 -/// -/// @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); -} - /// Skip over text until ' ' or '\t' or NUL /// /// @param[in] p Text to skip over. diff --git a/src/nvim/edit.c b/src/nvim/edit.c index b35504908e..aa254b0577 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2037,12 +2037,12 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int } else { c = *(p++); } - if (vim_islower(c)) { + if (mb_islower(c)) { has_lower = true; - if (vim_isupper(wca[i])) { + if (mb_isupper(wca[i])) { // Rule 1 is satisfied. for (i = actual_compl_length; i < actual_len; i++) { - wca[i] = vim_tolower(wca[i]); + wca[i] = mb_tolower(wca[i]); } break; } @@ -2062,14 +2062,14 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int } else { c = *(p++); } - if (was_letter && vim_isupper(c) && vim_islower(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] = vim_toupper(wca[i]); + wca[i] = mb_toupper(wca[i]); } break; } - was_letter = vim_islower(c) || vim_isupper(c); + was_letter = mb_islower(c) || mb_isupper(c); } } @@ -2082,10 +2082,10 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int } else { c = *(p++); } - if (vim_islower(c)) { - wca[i] = vim_tolower(wca[i]); - } else if (vim_isupper(c)) { - wca[i] = vim_toupper(wca[i]); + if (mb_islower(c)) { + wca[i] = mb_tolower(wca[i]); + } else if (mb_isupper(c)) { + wca[i] = mb_toupper(wca[i]); } } } @@ -2302,7 +2302,7 @@ static void ins_compl_longest_match(compl_T *match) c1 = *p; c2 = *s; } - if (match->cp_icase ? (vim_tolower(c1) != vim_tolower(c2)) + if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2)) : (c1 != c2)) break; if (has_mbyte) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 124d6acfe9..c1ee33b06a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16802,7 +16802,7 @@ static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr) int c, lc; c = utf_ptr2char(p); - lc = utf_tolower(c); + lc = mb_tolower(c); l = utf_ptr2len(p); /* TODO: reallocate string when byte count changes. */ if (utf_char2len(lc) == l) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 8810204c03..9d74f554ba 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1231,7 +1231,7 @@ static int command_line_handle_key(CommandLineState *s) // 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); + s->c = mb_tolower(s->c); } if (s->c != NUL) { @@ -3018,7 +3018,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) { diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 9592235905..db745bdd15 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1057,7 +1057,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; } diff --git a/src/nvim/macros.h b/src/nvim/macros.h index a8df6322cf..22fd48de9d 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -62,7 +62,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 diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 460528b85f..5f5abbeac5 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1174,11 +1174,16 @@ int utf_fold(int a) return utf_convert(a, foldCase, ARRAY_SIZE(foldCase)); } +// 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 utf_toupper(int a) +int mb_toupper(int a) { /* If 'casemap' contains "keepascii" use ASCII style toupper(). */ if (a < 128 && (cmp_flags & CMP_KEEPASCII)) @@ -1198,17 +1203,17 @@ 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; + 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) +int mb_tolower(int a) { /* If 'casemap' contains "keepascii" use ASCII style tolower(). */ if (a < 128 && (cmp_flags & CMP_KEEPASCII)) @@ -1228,9 +1233,9 @@ 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(const char_u *s1, const char_u *s2, size_t n1, diff --git a/src/nvim/message.c b/src/nvim/message.c index 1d3609291a..2cc426cf42 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2731,7 +2731,7 @@ do_dialog ( } /* Make the character lowercase, as chars in "hotkeys" are. */ - c = vim_tolower(c); + c = mb_tolower(c); retval = 1; for (i = 0; hotkeys[i]; ++i) { if (has_mbyte) { @@ -2777,7 +2777,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); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 68ef27222c..c5b7e65983 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1956,16 +1956,16 @@ 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 (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)) { + 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); + nc = mb_tolower(c); } if (nc != c) { if (enc_utf8 && (c >= 0x80 || nc >= 0x80)) { @@ -3327,7 +3327,7 @@ void ex_display(exarg_T *eap) get_clipboard(name, &yb, true); - if (name == vim_tolower(redir_reg) + if (name == mb_tolower(redir_reg) || (redir_reg == '"' && yb == y_previous)) continue; /* do not list register being written to, the * pointer can be freed */ diff --git a/src/nvim/path.c b/src/nvim/path.c index 6bf42ed2fa..781522f63f 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1853,7 +1853,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 == '\\') @@ -1864,7 +1864,7 @@ 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) + return p_fic ? mb_toupper(c1) - mb_toupper(c2) : c1 - c2; /* no match */ } diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 9baa53d2a2..7e2fc261f2 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -2350,7 +2350,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); } } @@ -2376,7 +2376,7 @@ collection: break; case CLASS_UPPER: for (cu = 1; cu <= 255; cu++) { - if (vim_isupper(cu)) { + if (mb_isupper(cu)) { regmbc(cu); } } @@ -3474,7 +3474,7 @@ static long bt_regexec_both(char_u *line, || (ireg_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; @@ -4155,7 +4155,7 @@ regmatch ( if (*opnd != *reginput && (!ireg_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 @@ -4573,10 +4573,10 @@ regmatch ( if (OP(next) == EXACTLY) { rst.nextb = *OPERAND(next); if (ireg_ic) { - if (vim_isupper(rst.nextb)) - rst.nextb_ic = vim_tolower(rst.nextb); + if (mb_isupper(rst.nextb)) + rst.nextb_ic = mb_tolower(rst.nextb); else - rst.nextb_ic = vim_toupper(rst.nextb); + rst.nextb_ic = mb_toupper(rst.nextb); } else rst.nextb_ic = rst.nextb; } else { @@ -5339,8 +5339,8 @@ do_class: * 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); + cu = mb_toupper(*opnd); + cl = mb_tolower(*opnd); while (count < maxcount && (*scan == cu || *scan == cl)) { count++; scan++; @@ -6314,10 +6314,10 @@ static char_u *cstrchr(char_u *s, int 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 (mb_isupper(c)) + cc = mb_tolower(c); + else if (mb_islower(c)) + cc = mb_toupper(c); else return vim_strchr(s, c); @@ -6348,28 +6348,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; } diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 5b49ab38f0..1d57595cbe 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4373,7 +4373,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; @@ -4391,7 +4391,7 @@ 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: @@ -4892,7 +4892,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 && (!ireg_ic || mb_tolower(c1) != mb_tolower(c2))) || c1_len != c2_len) { match = false; break; @@ -5585,11 +5585,11 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, break; } if (ireg_ic) { - int curc_low = vim_tolower(curc); + int curc_low = mb_tolower(curc); int done = FALSE; for (; c1 <= c2; ++c1) - if (vim_tolower(c1) == curc_low) { + if (mb_tolower(c1) == curc_low) { result = result_if_matched; done = TRUE; break; @@ -5599,8 +5599,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, } } else if (state->c < 0 ? check_char_class(state->c, curc) : (curc == state->c - || (ireg_ic && vim_tolower(curc) - == vim_tolower(state->c)))) { + || (ireg_ic && mb_tolower(curc) + == mb_tolower(state->c)))) { result = result_if_matched; break; } @@ -6004,7 +6004,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, result = (c == curc); if (!result && ireg_ic) - result = vim_tolower(c) == vim_tolower(curc); + result = mb_tolower(c) == mb_tolower(curc); // If ireg_icombine is not set only skip over the character // itself. When it is set skip over composing characters. @@ -6152,8 +6152,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 && (!ireg_ic || mb_tolower(c) + != mb_tolower(prog->regstart))) { #ifdef REGEXP_DEBUG fprintf(log_fd, " Skipping start state, regstart does not match\n"); diff --git a/src/nvim/search.c b/src/nvim/search.c index c5c92b41c5..4f060b2b8b 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -336,7 +336,7 @@ int pat_has_uppercase(char_u *pat) int l; if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { - if (enc_utf8 && utf_isupper(utf_ptr2char(p))) + if (enc_utf8 && mb_isupper(utf_ptr2char(p))) return TRUE; p += l; } else if (*p == '\\') { @@ -348,7 +348,7 @@ int pat_has_uppercase(char_u *pat) p += 2; else p += 1; - } else if (vim_isupper(*p)) + } else if (mb_isupper(*p)) return TRUE; else ++p; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index d4f49bffb2..99661d0ef5 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2545,10 +2545,10 @@ void init_spell_chartab(void) } else if (enc_utf8) { for (i = 128; i < 256; ++i) { int f = utf_fold(i); - int u = utf_toupper(i); + int u = mb_toupper(i); - spelltab.st_isu[i] = utf_isupper(i); - spelltab.st_isw[i] = spelltab.st_isu[i] || utf_islower(i); + 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. @@ -2558,13 +2558,13 @@ void init_spell_chartab(void) } else { // Rough guess: use locale-dependent library functions. for (i = 128; i < 256; ++i) { - if (vim_isupper(i)) { + if (mb_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_fold[i] = mb_tolower(i); + } else if (mb_islower(i)) { spelltab.st_isw[i] = true; - spelltab.st_upper[i] = vim_toupper(i); + spelltab.st_upper[i] = mb_toupper(i); } } } diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index c54a7f5390..ddd54c724e 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -265,11 +265,11 @@ typedef struct trystate_S { : (c) < \ 256 ? (int)spelltab.st_fold[c] : (int)towlower(c)) -#define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(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 ? utf_isupper(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 diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 5dcffe00e0..e7c0fb8a7d 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -309,7 +309,7 @@ char *strup_save(const char *const orig) if (enc_utf8) { int c = utf_ptr2char((const char_u *)p); - int uc = utf_toupper(c); + int uc = mb_toupper(c); // Reallocate string when byte count changes. This is rare, // thus it's OK to do another malloc()/free(). -- cgit From 4c857dae1169f3b8c7b6a9740f50acfd3c16858d Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 9 Apr 2017 09:29:00 +0200 Subject: vim-patch:8.0.0243 Problem: When making a character lower case with tolower() changes the byte cound, it is not made lower case. Solution: Add strlow_save(). (Dominique Pelle, closes vim/vim#1406) https://github.com/vim/vim/commit/cc5b22b3bfdc0e9e835cf7871166badda31447bd Join almost identical strup_save and strlow_save functions to one Function. --- src/nvim/eval.c | 26 +------ src/nvim/strings.c | 51 ++++++------- src/nvim/testdir/test_functions.vim | 144 ++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c1ee33b06a..ed07de51c8 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16791,30 +16791,8 @@ void timer_teardown(void) */ static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u *p = (char_u *)xstrdup(tv_get_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 = mb_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); } /* @@ -16823,7 +16801,7 @@ 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 = (char_u *)strup_save(tv_get_string(&argvars[0])); + rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]), true); } /* diff --git a/src/nvim/strings.c b/src/nvim/strings.c index e7c0fb8a7d..87e066d80a 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -291,14 +291,15 @@ void vim_strup(char_u *p) } } -/// Make given string all upper-case +/// Make given string all upper-case or all lower-case /// -/// Handels multi-byte characters as good as possible. +/// 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 *strup_save(const char *const orig) +char *strcase_save(const char *const orig, bool upper) FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL { char *res = xstrdup(orig); @@ -307,33 +308,25 @@ char *strup_save(const char *const orig) while (*p != NUL) { int l; - if (enc_utf8) { - int c = utf_ptr2char((const char_u *)p); - int uc = mb_toupper(c); - - // 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; - } else if (has_mbyte && (l = (*mb_ptr2len)((const char_u *)p)) > 1) { - p += l; // Skip multi-byte character. - } else { - // note that toupper() can be a macro - *p = (char)(uint8_t)TOUPPER_LOC(*p); - p++; + int c = utf_ptr2char((const char_u *)p); + int uc = upper ? mb_toupper(c) : mb_tolower(c); + + // 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; diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 81cb6314ce..3c258299c1 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -29,3 +29,147 @@ func Test_setbufvar_options() 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 + + -- cgit From acc06b0b7b99925d7567d2e79c2f5e88434edae8 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 9 Apr 2017 09:40:12 +0200 Subject: vim-patch:8.0.0552 Problem: Toupper and tolower don't work properly for Turkish when 'casemap' is empty. (Bjorn Linse) Solution: Check the 'casemap' options when deciding how to upper/lower case. https://github.com/vim/vim/commit/3317d5ebbe8304da82b8088446060afcae0012af vim-patch:8.0.0553 Problem: Toupper/tolower test with Turkish locale fails on Mac. Solution: Skip the test on Mac. https://github.com/vim/vim/commit/9f4de1f5435b900e43e19766da1a5bed4686cf44 vim-patch:8.0.0554 Problem: Toupper and tolower don't work properly for Turkish when 'casemap' contains "keepascii". (Bjorn Linse) Solution: When 'casemap' contains "keepascii" use ASCII toupper/tolower. https://github.com/vim/vim/commit/1cc482069a3407132aeb43a55d6dc284153e79c7 vim-patch:8.0.0555 Problem: Toupper/tolower test fails on OSX without Darwin. Solution: Skip that part of the test also for OSX. (Kazunobu Kuriyama) https://github.com/vim/vim/commit/d2381a2cadb9ef359ad5efb916734c635b29bd13 --- src/nvim/testdir/test_normal.vim | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src') diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index a22dca35cc..c529971528 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -1606,6 +1606,40 @@ fun! Test_normal30_changecase() norm! V~ call assert_equal('THIS IS A simple test: äüöss', getline('.')) + " Turkish ASCII turns to multi-byte. On Mac the Turkish locale is available + " but toupper()/tolower() don't do the right thing. + if !has('mac') && !has('osx') + try + lang tr_TR.UTF-8 + set casemap= + 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")) + + 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 + endif + " clean up bw! endfunc -- cgit From c1cf03398143f4dc0ac9155988edad349d24deca Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 9 Apr 2017 10:08:26 +0200 Subject: lint: fix clint errors around mb_tolower calls --- src/nvim/edit.c | 3 ++- src/nvim/eval.c | 6 ++++-- src/nvim/mbyte.c | 14 +++++--------- src/nvim/message.c | 2 +- src/nvim/ops.c | 17 ++++++++++------- src/nvim/path.c | 2 +- src/nvim/regexp.c | 17 ++++++++++------- src/nvim/regexp_nfa.c | 14 +++++++++----- src/nvim/search.c | 25 ++++++++++++++----------- src/nvim/spell.c | 44 ++++++++++++-------------------------------- 10 files changed, 68 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index aa254b0577..fe00027dec 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2303,8 +2303,9 @@ static void ins_compl_longest_match(compl_T *match) c2 = *s; } if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2)) - : (c1 != c2)) + : (c1 != c2)) { break; + } if (has_mbyte) { mb_ptr_adv(p); mb_ptr_adv(s); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ed07de51c8..0663e19b9a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16792,7 +16792,8 @@ void timer_teardown(void) static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr) { rettv->v_type = VAR_STRING; - rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]), false); + rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]), + false); } /* @@ -16801,7 +16802,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 = (char_u *)strcase_save(tv_get_string(&argvars[0]), true); + rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]), + true); } /* diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 5f5abbeac5..b18459a2b5 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1179,10 +1179,8 @@ int utf_fold(int a) // 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. - */ +/// 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(). */ @@ -1205,14 +1203,12 @@ int mb_toupper(int a) bool mb_islower(int a) { - /* German sharp s is lower case but has no upper case equivalent. */ + // 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. - */ +/// 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(). */ diff --git a/src/nvim/message.c b/src/nvim/message.c index 2cc426cf42..3e4a1e10b6 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2730,7 +2730,7 @@ do_dialog ( break; } - /* Make the character lowercase, as chars in "hotkeys" are. */ + // Make the character lowercase, as chars in "hotkeys" are. c = mb_tolower(c); retval = 1; for (i = 0; hotkeys[i]; ++i) { diff --git a/src/nvim/ops.c b/src/nvim/ops.c index c5b7e65983..f11d6b69b2 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1957,15 +1957,17 @@ int swapchar(int op_type, pos_T *pos) return FALSE; nc = c; if (mb_islower(c)) { - if (op_type == OP_ROT13) + if (op_type == OP_ROT13) { nc = ROT13(c, 'a'); - else if (op_type != OP_LOWER) + } else if (op_type != OP_LOWER) { nc = mb_toupper(c); + } } else if (mb_isupper(c)) { - if (op_type == OP_ROT13) + if (op_type == OP_ROT13) { nc = ROT13(c, 'A'); - else if (op_type != OP_UPPER) + } else if (op_type != OP_UPPER) { nc = mb_tolower(c); + } } if (nc != c) { if (enc_utf8 && (c >= 0x80 || nc >= 0x80)) { @@ -3328,9 +3330,10 @@ void ex_display(exarg_T *eap) get_clipboard(name, &yb, true); if (name == mb_tolower(redir_reg) - || (redir_reg == '"' && yb == y_previous)) - continue; /* do not list register being written to, the - * pointer can be freed */ + || (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'); diff --git a/src/nvim/path.c b/src/nvim/path.c index 781522f63f..205fc2ed62 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1865,7 +1865,7 @@ int pathcmp(const char *p, const char *q, int maxlen) if (vim_ispathsep(c2)) return 1; return p_fic ? mb_toupper(c1) - mb_toupper(c2) - : c1 - c2; /* no match */ + : c1 - c2; // no match } i += MB_PTR2LEN((char_u *)p + i); diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 7e2fc261f2..4b5e17b00b 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -4573,12 +4573,14 @@ regmatch ( if (OP(next) == EXACTLY) { rst.nextb = *OPERAND(next); if (ireg_ic) { - if (mb_isupper(rst.nextb)) + if (mb_isupper(rst.nextb)) { rst.nextb_ic = mb_tolower(rst.nextb); - else + } else { rst.nextb_ic = mb_toupper(rst.nextb); - } else + } + } else { rst.nextb_ic = rst.nextb; + } } else { rst.nextb = NUL; rst.nextb_ic = NUL; @@ -6312,14 +6314,15 @@ static char_u *cstrchr(char_u *s, int 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) + if (c > 0x80) { cc = utf_fold(c); - else if (mb_isupper(c)) + } else if (mb_isupper(c)) { cc = mb_tolower(c); - else if (mb_islower(c)) + } else if (mb_islower(c)) { cc = mb_toupper(c); - else + } else { return vim_strchr(s, c); + } if (has_mbyte) { for (p = s; *p != NUL; p += (*mb_ptr2len)(p)) { diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 1d57595cbe..caf26fdd35 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4391,8 +4391,9 @@ static int check_char_class(int class, int c) return OK; break; case NFA_CLASS_UPPER: - if (mb_isupper(c)) + if (mb_isupper(c)) { return OK; + } break; case NFA_CLASS_XDIGIT: if (ascii_isxdigit(c)) @@ -5586,16 +5587,18 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, } if (ireg_ic) { int curc_low = mb_tolower(curc); - int done = FALSE; + int done = false; - for (; c1 <= c2; ++c1) + 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 @@ -6003,8 +6006,9 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, #endif result = (c == curc); - if (!result && ireg_ic) + if (!result && ireg_ic) { result = mb_tolower(c) == mb_tolower(curc); + } // If ireg_icombine is not set only skip over the character // itself. When it is set skip over composing characters. diff --git a/src/nvim/search.c b/src/nvim/search.c index 4f060b2b8b..91a558045f 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -335,23 +335,26 @@ int pat_has_uppercase(char_u *pat) while (*p != NUL) { int l; - if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { - if (enc_utf8 && mb_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 (mb_isupper(*p)) - return TRUE; - else - ++p; + } + } else if (mb_isupper(*p)) { + return true; + } else { + p++; + } } return FALSE; } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 99661d0ef5..18febda1d8 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2526,8 +2526,7 @@ 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. @@ -2537,36 +2536,17 @@ 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 = mb_toupper(i); - - 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; - } - } else { - // Rough guess: use locale-dependent library functions. - for (i = 128; i < 256; ++i) { - if (mb_isupper(i)) { - spelltab.st_isw[i] = true; - spelltab.st_isu[i] = true; - spelltab.st_fold[i] = mb_tolower(i); - } else if (mb_islower(i)) { - spelltab.st_isw[i] = true; - spelltab.st_upper[i] = mb_toupper(i); - } - } + for (i = 128; i < 256; i++) { + int f = utf_fold(i); + int u = mb_toupper(i); + + 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; } } -- cgit From f3093bc508631930d41e9603b43687f4e51af2b3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 10 Apr 2017 23:10:01 +0300 Subject: api: Bump nvim__*id functions since value --- src/nvim/api/vim.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 9ee3827040..0056ea1725 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -844,7 +844,7 @@ static void write_msg(String message, bool to_err) /// /// @return its argument. Object nvim__id(Object obj) - FUNC_API_SINCE(1) + FUNC_API_SINCE(2) { return copy_object(obj); } @@ -858,7 +858,7 @@ Object nvim__id(Object obj) /// /// @return its argument. Array nvim__id_array(Array arr) - FUNC_API_SINCE(1) + FUNC_API_SINCE(2) { return copy_object(ARRAY_OBJ(arr)).data.array; } @@ -872,7 +872,7 @@ Array nvim__id_array(Array arr) /// /// @return its argument. Dictionary nvim__id_dictionary(Dictionary dct) - FUNC_API_SINCE(1) + FUNC_API_SINCE(2) { return copy_object(DICTIONARY_OBJ(dct)).data.dictionary; } @@ -886,7 +886,7 @@ Dictionary nvim__id_dictionary(Dictionary dct) /// /// @return its argument. Float nvim__id_float(Float flt) - FUNC_API_SINCE(1) + FUNC_API_SINCE(2) { return flt; } -- cgit From 57308c4f82aa18b4c6a1af76d224c40e442c9a1e Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 10 Apr 2017 23:22:59 +0300 Subject: eval/decode: Include header needed for TriState --- src/nvim/eval/decode.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/eval/decode.h b/src/nvim/eval/decode.h index c8e7a189e3..77fc4c78c2 100644 --- a/src/nvim/eval/decode.h +++ b/src/nvim/eval/decode.h @@ -6,6 +6,7 @@ #include #include "nvim/eval/typval.h" +#include "nvim/globals.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/decode.h.generated.h" -- cgit From 1751ec192d860f2591d18c4aad4248b5ab786cec Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 11 Apr 2017 01:05:56 +0300 Subject: viml/executor: Fix check-single-includes --- src/nvim/viml/executor/executor.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nvim/viml/executor/executor.h b/src/nvim/viml/executor/executor.h index 85cb3550e7..648bb73785 100644 --- a/src/nvim/viml/executor/executor.h +++ b/src/nvim/viml/executor/executor.h @@ -5,6 +5,8 @@ #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; -- cgit From f98a3d85ed2f34a62300097fd30b393a3b3be393 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 11 Apr 2017 01:09:36 +0300 Subject: lua: Move files from src/nvim/viml/executor to src/nvim/lua --- src/nvim/CMakeLists.txt | 7 +- src/nvim/eval.c | 2 +- src/nvim/ex_docmd.c | 2 +- src/nvim/lua/converter.c | 1194 ++++++++++++++++++++++++++++++++++++ src/nvim/lua/converter.h | 15 + src/nvim/lua/executor.c | 576 +++++++++++++++++ src/nvim/lua/executor.h | 25 + src/nvim/lua/vim.lua | 2 + src/nvim/viml/executor/converter.c | 1194 ------------------------------------ src/nvim/viml/executor/converter.h | 15 - src/nvim/viml/executor/executor.c | 576 ----------------- src/nvim/viml/executor/executor.h | 25 - src/nvim/viml/executor/vim.lua | 2 - 13 files changed, 1817 insertions(+), 1818 deletions(-) create mode 100644 src/nvim/lua/converter.c create mode 100644 src/nvim/lua/converter.h create mode 100644 src/nvim/lua/executor.c create mode 100644 src/nvim/lua/executor.h create mode 100644 src/nvim/lua/vim.lua delete mode 100644 src/nvim/viml/executor/converter.c delete mode 100644 src/nvim/viml/executor/converter.h delete mode 100644 src/nvim/viml/executor/executor.c delete mode 100644 src/nvim/viml/executor/executor.h delete mode 100644 src/nvim/viml/executor/vim.lua (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index cec9a09141..1401029cf5 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -33,8 +33,8 @@ set(OPTIONS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genoptions.lua) set(UNICODE_TABLES_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genunicodetables.lua) set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode) set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h) -set(VIM_MODULE_FILE ${GENERATED_DIR}/viml/executor/vim_module.generated.h) -set(VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/viml/executor/vim.lua) +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 ${PROJECT_SOURCE_DIR}/scripts/gencharblob.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") @@ -72,8 +72,7 @@ foreach(subdir tui event eval - viml - viml/executor + lua ) if(${subdir} MATCHES "tui" AND NOT FEAT_TUI) continue() diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 75cd100061..e60cc4e218 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -94,7 +94,7 @@ #include "nvim/lib/kvec.h" #include "nvim/lib/khash.h" #include "nvim/lib/queue.h" -#include "nvim/viml/executor/executor.h" +#include "nvim/lua/executor.h" #include "nvim/eval/typval.h" #include "nvim/eval/executor.h" #include "nvim/eval/gc.h" diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index e44d759e04..b7bf6b4728 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -67,7 +67,7 @@ #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" #include "nvim/shada.h" -#include "nvim/viml/executor/executor.h" +#include "nvim/lua/executor.h" #include "nvim/globals.h" static int quitmore = 0; diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c new file mode 100644 index 0000000000..348315124b --- /dev/null +++ b/src/nvim/lua/converter.c @@ -0,0 +1,1194 @@ +#include +#include +#include +#include +#include +#include + +#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; +} + +#define NLUA_PUSH_HANDLE(lstate, type, idx) \ + do { \ + lua_pushnumber(lstate, (lua_Number)(idx)); \ + } while (0) + +#define NLUA_POP_HANDLE(lstate, type, stack_idx, idx) \ + do { \ + idx = (type)lua_tonumber(lstate, stack_idx); \ + } while (0) + +/// 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 \ +{ \ + NLUA_PUSH_HANDLE(lstate, type, 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, Validation, "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, Validation, "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, Exception, "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, Validation, "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, Validation, "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 (err->set) { + 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 (!err->set) { + ret.items[i].value = nlua_pop_Object(lstate, err); + // stack: dict, key + } else { + lua_pop(lstate, 1); + // stack: dict, key + } + + if (err->set) { + 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 (!err->set && kv_size(stack)) { + if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { + api_set_error(err, Exception, "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, Validation, "Cannot convert given lua table"); + break; + } + default: { + assert(false); + } + } + break; + } + default: { + api_set_error(err, Validation, "Cannot convert given lua type"); + break; + } + } + if (!cur.container) { + lua_pop(lstate, 1); + } + } + kv_destroy(stack); + if (err->set) { + 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; \ + NLUA_POP_HANDLE(lstate, type, -1, ret); \ + 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..49f6ac4016 --- /dev/null +++ b/src/nvim/lua/converter.h @@ -0,0 +1,15 @@ +#ifndef NVIM_VIML_EXECUTOR_CONVERTER_H +#define NVIM_VIML_EXECUTOR_CONVERTER_H + +#include +#include +#include + +#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_VIML_EXECUTOR_CONVERTER_H diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c new file mode 100644 index 0000000000..7cf326aef5 --- /dev/null +++ b/src/nvim/lua/executor.c @@ -0,0 +1,576 @@ +#include +#include +#include + +#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/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 "" + +/// 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. +static lua_State *init_lua(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; +} + +static lua_State *global_lstate = NULL; + +/// 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 +{ + if (global_lstate == NULL) { + global_lstate = init_lua(); + } + + NLUA_CALL_C_FUNCTION_2(global_lstate, 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; +} + +/// 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( + ""); + } + 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 (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 +{ + if (global_lstate == NULL) { + global_lstate = init_lua(); + } + + NLUA_CALL_C_FUNCTION_3(global_lstate, nlua_eval_lua_string, 0, + (void *)&str, arg, ret_tv); +} + +/// 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 (global_lstate == NULL) { + global_lstate = init_lua(); + } + 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(global_lstate, 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 +{ + if (global_lstate == NULL) { + global_lstate = init_lua(); + } + NLUA_CALL_C_FUNCTION_1(global_lstate, 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..22e55a56d3 --- /dev/null +++ b/src/nvim/lua/executor.h @@ -0,0 +1,25 @@ +#ifndef NVIM_VIML_EXECUTOR_EXECUTOR_H +#define NVIM_VIML_EXECUTOR_EXECUTOR_H + +#include + +#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_VIML_EXECUTOR_EXECUTOR_H diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua new file mode 100644 index 0000000000..8d1c5bdf4f --- /dev/null +++ b/src/nvim/lua/vim.lua @@ -0,0 +1,2 @@ +-- TODO(ZyX-I): Create compatibility layer. +return {} diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c deleted file mode 100644 index 425a38538d..0000000000 --- a/src/nvim/viml/executor/converter.c +++ /dev/null @@ -1,1194 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#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/viml/executor/converter.h" -#include "nvim/viml/executor/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 "viml/executor/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; -} - -#define NLUA_PUSH_HANDLE(lstate, type, idx) \ - do { \ - lua_pushnumber(lstate, (lua_Number)(idx)); \ - } while (0) - -#define NLUA_POP_HANDLE(lstate, type, stack_idx, idx) \ - do { \ - idx = (type)lua_tonumber(lstate, stack_idx); \ - } while (0) - -/// 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 \ -{ \ - NLUA_PUSH_HANDLE(lstate, type, 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, Validation, "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, Validation, "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, Exception, "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, Validation, "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, Validation, "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 (err->set) { - 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 (!err->set) { - ret.items[i].value = nlua_pop_Object(lstate, err); - // stack: dict, key - } else { - lua_pop(lstate, 1); - // stack: dict, key - } - - if (err->set) { - 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 (!err->set && kv_size(stack)) { - if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { - api_set_error(err, Exception, "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, Validation, "Cannot convert given lua table"); - break; - } - default: { - assert(false); - } - } - break; - } - default: { - api_set_error(err, Validation, "Cannot convert given lua type"); - break; - } - } - if (!cur.container) { - lua_pop(lstate, 1); - } - } - kv_destroy(stack); - if (err->set) { - 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; \ - NLUA_POP_HANDLE(lstate, type, -1, ret); \ - 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/viml/executor/converter.h b/src/nvim/viml/executor/converter.h deleted file mode 100644 index dbbaaebf6b..0000000000 --- a/src/nvim/viml/executor/converter.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef NVIM_VIML_EXECUTOR_CONVERTER_H -#define NVIM_VIML_EXECUTOR_CONVERTER_H - -#include -#include -#include - -#include "nvim/api/private/defs.h" -#include "nvim/func_attr.h" -#include "nvim/eval.h" - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "viml/executor/converter.h.generated.h" -#endif -#endif // NVIM_VIML_EXECUTOR_CONVERTER_H diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c deleted file mode 100644 index 826460772e..0000000000 --- a/src/nvim/viml/executor/executor.c +++ /dev/null @@ -1,576 +0,0 @@ -#include -#include -#include - -#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/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/viml/executor/executor.h" -#include "nvim/viml/executor/converter.h" - -typedef struct { - Error err; - String lua_err_str; -} LuaError; - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "viml/executor/vim_module.generated.h" -# include "viml/executor/executor.c.generated.h" -#endif - -/// Name of the run code for use in messages -#define NLUA_EVAL_NAME "" - -/// 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. -static lua_State *init_lua(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; -} - -static lua_State *global_lstate = NULL; - -/// 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 -{ - if (global_lstate == NULL) { - global_lstate = init_lua(); - } - - NLUA_CALL_C_FUNCTION_2(global_lstate, 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; -} - -/// 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( - ""); - } - 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 (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 -{ - if (global_lstate == NULL) { - global_lstate = init_lua(); - } - - NLUA_CALL_C_FUNCTION_3(global_lstate, nlua_eval_lua_string, 0, - (void *)&str, arg, ret_tv); -} - -/// 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 (global_lstate == NULL) { - global_lstate = init_lua(); - } - 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(global_lstate, 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 -{ - if (global_lstate == NULL) { - global_lstate = init_lua(); - } - NLUA_CALL_C_FUNCTION_1(global_lstate, nlua_exec_lua_file, 0, - (void *)eap->arg); -} diff --git a/src/nvim/viml/executor/executor.h b/src/nvim/viml/executor/executor.h deleted file mode 100644 index 648bb73785..0000000000 --- a/src/nvim/viml/executor/executor.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef NVIM_VIML_EXECUTOR_EXECUTOR_H -#define NVIM_VIML_EXECUTOR_EXECUTOR_H - -#include - -#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 "viml/executor/executor.h.generated.h" -#endif -#endif // NVIM_VIML_EXECUTOR_EXECUTOR_H diff --git a/src/nvim/viml/executor/vim.lua b/src/nvim/viml/executor/vim.lua deleted file mode 100644 index 8d1c5bdf4f..0000000000 --- a/src/nvim/viml/executor/vim.lua +++ /dev/null @@ -1,2 +0,0 @@ --- TODO(ZyX-I): Create compatibility layer. -return {} -- cgit From 0c5e359cb502cc858892930bcc8dbfadcdf09bd3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 11 Apr 2017 01:32:35 +0300 Subject: cmake: Append lua include also to single-includes targets --- src/nvim/CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 1401029cf5..7111e4aa81 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -358,12 +358,12 @@ target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) install_helper(TARGETS nvim) if(PREFER_LUAJIT) - set_property(TARGET nvim APPEND PROPERTY - INCLUDE_DIRECTORIES ${LUAJIT_INCLUDE_DIRS}) + set(LUA_PREFERRED_INCLUDE_DIRS ${LUAJIT_INCLUDE_DIRS}) else() - set_property(TARGET nvim APPEND PROPERTY - INCLUDE_DIRECTORIES ${LUA_INCLUDE_DIRS}) + set(LUA_PREFERRED_INCLUDE_DIRS ${LUA_INCLUDE_DIRS}) endif() +set_property(TARGET nvim APPEND PROPERTY + INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS}) if(WIN32) # Copy DLLs and third-party tools to bin/ and install them along with nvim @@ -540,6 +540,10 @@ foreach(hfile ${NVIM_HEADERS}) ${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) -- cgit From 4a63d9e5f88feb16ec513b8dba1f8d02bd2ff4d6 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sun, 9 Apr 2017 12:31:54 +0900 Subject: win: mch_open_rw: specify S_IWRITE #6487 On Windows, `mch_open_rw` is not actually doing what it claims. This manifests as "E301: Oops, lost the swap file !!!" when filename is changed with :file {name}. Steps to reproduce (covered by test/functional/ex_cmds/file_spec.lua): nvim -u NONE :edit test :file test2 E301 Oops, lost the swap file!!! From libuv/src/win/fs.c: void fs__open(uv_fs_t* req) { ... attributes |= FILE_ATTRIBUTE_NORMAL; if (flags & _O_CREAT) { if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) { attributes |= FILE_ATTRIBUTE_READONLY; } } --- src/nvim/macros.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/macros.h b/src/nvim/macros.h index 22fd48de9d..9131f8be84 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -120,8 +120,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)) -- cgit From 9bf15ca3fa2aa5f1a533b7b1598b6e3937fb1b17 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 11 Apr 2017 10:18:53 +0300 Subject: lua: Fix header guards --- src/nvim/lua/converter.h | 6 +++--- src/nvim/lua/executor.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h index 49f6ac4016..542c56ea3e 100644 --- a/src/nvim/lua/converter.h +++ b/src/nvim/lua/converter.h @@ -1,5 +1,5 @@ -#ifndef NVIM_VIML_EXECUTOR_CONVERTER_H -#define NVIM_VIML_EXECUTOR_CONVERTER_H +#ifndef NVIM_LUA_CONVERTER_H +#define NVIM_LUA_CONVERTER_H #include #include @@ -12,4 +12,4 @@ #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/converter.h.generated.h" #endif -#endif // NVIM_VIML_EXECUTOR_CONVERTER_H +#endif // NVIM_LUA_CONVERTER_H diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index 22e55a56d3..0cbf290f64 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -1,5 +1,5 @@ -#ifndef NVIM_VIML_EXECUTOR_EXECUTOR_H -#define NVIM_VIML_EXECUTOR_EXECUTOR_H +#ifndef NVIM_LUA_EXECUTOR_H +#define NVIM_LUA_EXECUTOR_H #include @@ -22,4 +22,4 @@ void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/executor.h.generated.h" #endif -#endif // NVIM_VIML_EXECUTOR_EXECUTOR_H +#endif // NVIM_LUA_EXECUTOR_H -- cgit From a8ade2441d41289581628118a88c260c3ebb3fa5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 11 Apr 2017 10:37:14 +0300 Subject: lua/converter: Remove useless macros --- src/nvim/lua/converter.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 348315124b..80d9096212 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -542,16 +542,6 @@ bool nlua_push_typval(lua_State *lstate, typval_T *const tv) return true; } -#define NLUA_PUSH_HANDLE(lstate, type, idx) \ - do { \ - lua_pushnumber(lstate, (lua_Number)(idx)); \ - } while (0) - -#define NLUA_POP_HANDLE(lstate, type, stack_idx, idx) \ - do { \ - idx = (type)lua_tonumber(lstate, stack_idx); \ - } while (0) - /// Push value which is a type index /// /// Used for all “typed” tables: i.e. for all tables which represent VimL @@ -676,7 +666,7 @@ void nlua_push_Array(lua_State *lstate, const Array array) void nlua_push_##type(lua_State *lstate, const type item) \ FUNC_ATTR_NONNULL_ALL \ { \ - NLUA_PUSH_HANDLE(lstate, type, item); \ + lua_pushnumber(lstate, (lua_Number)(item)); \ } GENERATE_INDEX_FUNCTION(Buffer) @@ -1135,7 +1125,7 @@ type nlua_pop_##type(lua_State *lstate, Error *err) \ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \ { \ type ret; \ - NLUA_POP_HANDLE(lstate, type, -1, ret); \ + ret = (type)lua_tonumber(lstate, -1); \ lua_pop(lstate, 1); \ return ret; \ } -- cgit From 2d72d85b23761383ac7838faed2f7b53bdce8817 Mon Sep 17 00:00:00 2001 From: Felipe Oliveira Carvalho Date: Tue, 11 Apr 2017 22:44:48 +0200 Subject: refactor: pos_T macros to functions (#6496) --- src/nvim/charset.c | 3 ++- src/nvim/ex_getln.c | 1 + src/nvim/indent.c | 3 ++- src/nvim/indent_c.c | 1 + src/nvim/macros.h | 19 ------------------- src/nvim/mark.h | 40 ++++++++++++++++++++++++++++++++++++++++ src/nvim/screen.c | 1 + src/nvim/spell.c | 1 + 8 files changed, 48 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 645139f696..3037cfe669 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -15,6 +15,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" @@ -1366,7 +1367,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 { diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 9d74f554ba..0b6036ace9 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -30,6 +30,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" diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 7f31bb8c5c..8fbad38495 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -7,6 +7,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" @@ -598,7 +599,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 4a73fbaf61..8f5547544d 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -10,6 +10,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" diff --git a/src/nvim/macros.h b/src/nvim/macros.h index 9131f8be84..b816b34b39 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -28,25 +28,6 @@ /// @return `s, sizeof(s) - 1` #define S_LEN(s) (s), (sizeof(s) - 1) -/* - * Position comparisons - */ -# define lt(a, b) (((a).lnum != (b).lnum) \ - ? (a).lnum < (b).lnum \ - : (a).col != (b).col \ - ? (a).col < (b).col \ - : (a).coladd < (b).coladd) -# define ltp(a, b) (((a)->lnum != (b)->lnum) \ - ? (a)->lnum < (b)->lnum \ - : (a)->col != (b)->col \ - ? (a)->col < (b)->col \ - : (a)->coladd < (b)->coladd) -# define equalpos(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && \ - ((a).coladd == (b).coladd)) -# define clearpos(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0; } - -#define ltoreq(a, b) (lt(a, b) || equalpos(a, b)) - /* * lineempty() - return TRUE if the line is empty */ diff --git a/src/nvim/mark.h b/src/nvim/mark.h index c22a102926..a356c1f398 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -4,6 +4,7 @@ #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" @@ -75,6 +76,45 @@ 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/screen.c b/src/nvim/screen.c index d9a21aa81f..febca105e9 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -102,6 +102,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" diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 18febda1d8..17016be35f 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -92,6 +92,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" -- cgit From 1bd39fb8d009f5ff62023d0f2fe86bbcdaeb3abc Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 11 Apr 2017 23:59:05 +0300 Subject: api: Remove FUNC_API_SINCE for nvim__ functions --- src/nvim/api/vim.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 0056ea1725..1d44e779c7 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -844,7 +844,6 @@ static void write_msg(String message, bool to_err) /// /// @return its argument. Object nvim__id(Object obj) - FUNC_API_SINCE(2) { return copy_object(obj); } @@ -858,7 +857,6 @@ Object nvim__id(Object obj) /// /// @return its argument. Array nvim__id_array(Array arr) - FUNC_API_SINCE(2) { return copy_object(ARRAY_OBJ(arr)).data.array; } @@ -872,7 +870,6 @@ Array nvim__id_array(Array arr) /// /// @return its argument. Dictionary nvim__id_dictionary(Dictionary dct) - FUNC_API_SINCE(2) { return copy_object(DICTIONARY_OBJ(dct)).data.dictionary; } @@ -886,7 +883,6 @@ Dictionary nvim__id_dictionary(Dictionary dct) /// /// @return its argument. Float nvim__id_float(Float flt) - FUNC_API_SINCE(2) { return flt; } -- cgit From 1d7fde39a6927d01de74aefb540ad445bfdfbfda Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 12 Apr 2017 00:31:01 +0300 Subject: api/buffer: Validate replacement array in a separate cycle Should not really change anything, but code should be more efficient by using more optimized libc functions (memchrsub is not libc, but it uses memchr) in place of a cycle. --- src/nvim/api/buffer.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 611f29f1f2..0a7b7982e2 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -292,6 +292,23 @@ void nvim_buf_set_lines(uint64_t channel_id, return; } + for (size_t i = 0; i < replacement.size; i++) { + if (replacement.items[i].type != kObjectTypeString) { + api_set_error(err, + Validation, + _("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, Validation, _("string cannot contain newlines")); + return; + } + } + } + win_T *save_curwin = NULL; tabpage_T *save_curtab = NULL; size_t new_len = replacement.size; @@ -300,26 +317,12 @@ void nvim_buf_set_lines(uint64_t channel_id, 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 != VIML_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(); -- cgit From d6e5f94ae945308d96be414c9c1fb3f0ae71355e Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 24 Mar 2017 02:54:50 +0100 Subject: win: defaults: 'shellredir', 'shellxquote', 'shellxescape' --- src/nvim/misc1.c | 6 +++--- src/nvim/options.lua | 18 +++++++++++++++--- src/nvim/os/shell.c | 2 -- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 0b74b4437e..8d93505be3 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2678,7 +2678,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; @@ -2686,8 +2687,7 @@ 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); + smsg(_("Calling shell to execute: \"%s\""), cmd == NULL ? p_sh : cmd); ui_putc('\n'); verbose_leave(); } diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 4ca63f2efe..774c39808f 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2051,7 +2051,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', @@ -2073,7 +2077,11 @@ return { secure=true, vi_def=true, varname='p_sxq', - defaults={if_true={vi=""}} + defaults={ + condition='WIN32', + if_true={vi="("}, + if_false={vi=""} + } }, { full_name='shellxescape', abbreviation='sxe', @@ -2081,7 +2089,11 @@ return { secure=true, vi_def=true, varname='p_sxe', - defaults={if_true={vi=""}} + defaults={ + condition='WIN32', + if_true={vi='"&|<>()@^'}, + if_false={vi=""} + } }, { full_name='shiftround', abbreviation='sr', diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index b449cc3d5a..5cc9d4b79b 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -124,11 +124,9 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args) } size_t nread; - 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) { -- cgit From f7611d74e73329a4192666ff59911ff214f462ab Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 24 Mar 2017 14:42:42 +0100 Subject: win: vim_strsave_shellescape: Handle 'shellslash'. From Vim, misc2.c:vim_strsave_shellescape --- src/nvim/strings.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 87e066d80a..8a1a3beddd 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -198,8 +198,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 */ @@ -216,10 +224,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++ = '\\'; @@ -246,7 +269,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; -- cgit From f3cc843755a6d638ada77dc31721aa53b3ff2364 Mon Sep 17 00:00:00 2001 From: Rui Abreu Ferreira Date: Tue, 28 Mar 2017 16:03:53 +0100 Subject: win: libuv_process_spawn(): special-case cmd.exe Disable CommandLineToArgvW-standard quoting for cmd.exe. libuv assumes spawned processes follow the convention expected by CommandLineToArgvW(). But cmd.exe is non-conformant, so for cmd.exe: - With system([]), the caller has full control (and responsibility) to quote arguments correctly. - With system(''), shell* options are used. libuv quoting is disabled if argv[0] is: - cmd.exe - cmd - $COMSPEC resolving to a path with filename cmd.exe Closes #6329 References #6387 --- src/nvim/event/libuv_process.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index 3da0c386b4..ab69bea04c 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -8,6 +8,8 @@ #include "nvim/event/process.h" #include "nvim/event/libuv_process.h" #include "nvim/log.h" +#include "nvim/path.h" +#include "nvim/os/os.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/libuv_process.c.generated.h" @@ -24,6 +26,26 @@ int libuv_process_spawn(LibuvProcess *uvproc) if (proc->detach) { uvproc->uvopts.flags |= UV_PROCESS_DETACHED; } +#ifdef WIN32 + // libuv assumes spawned processes follow the convention from + // CommandLineToArgvW(), cmd.exe does not. Disable quoting since it will + // result in unexpected behaviour, the caller is left with the responsibility + // to quote arguments accordingly. system('') has shell* options for this. + // + // Disable quoting for cmd, cmd.exe and $COMSPEC with a cmd.exe filename + bool is_cmd = STRICMP(proc->argv[0], "cmd.exe") == 0 + || STRICMP(proc->argv[0], "cmd") == 0; + if (!is_cmd) { + const char_u *comspec = (char_u *)os_getenv("COMSPEC"); + const char_u *comspecshell = path_tail((char_u *)proc->argv[0]); + is_cmd = comspec != NULL && STRICMP(proc->argv[0], comspec) == 0 + && STRICMP("cmd.exe", (char *)comspecshell) == 0; + } + + if (is_cmd) { + uvproc->uvopts.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; + } +#endif uvproc->uvopts.exit_cb = exit_cb; uvproc->uvopts.cwd = proc->cwd; uvproc->uvopts.env = NULL; -- cgit From d31d177a0c2c9997c2cdb04975bc3354b9a23fb8 Mon Sep 17 00:00:00 2001 From: Rui Abreu Ferreira Date: Thu, 30 Mar 2017 23:41:52 +0100 Subject: win: default shellxescape, shellxquote to empty Calling cmd.exe in Windows follows a very different pattern from Vim. The primary difference is that Vim does a nested call to cmd.exe, e.g. the following call in Vim system('echo a 2>&1') spawns the following processes "C:\Program Files (x86)\Vim\vim80\vimrun" -s C:\Windows\system32\cmd.exe /c (echo a 2^>^&1 ^>C:\Users\dummy\AppData\Local\Temp\VIoC169.tmp 2^>^&1) C:\Windows\system32\cmd.exe /c C:\Windows\system32\cmd.exe /c (echo a 2^>^&1 ^>C:\Users\dummy\AppData\Local\Temp\VIo3C6C.tmp 2^>^&1) C:\Windows\system32\cmd.exe /c (echo a 2>&1 >C:\Users\dummy\AppData\Local\Temp\VIo3C6C.tmp 2>&1) The escaping with ^ is needed because cmd.exe calls itself and needs to preserve the special metacharacters for the last call. However in nvim no nested call is made, system('') spawns a single cmd.exe process. Setting shellxescape to "" disables escaping with ^. The previous default for shellxquote=( wrapped any command in parenthesis, in Vim this is more meaningful due to the use of tempfiles to store the output and redirection (also see &shellquote). There is a slight benefit in having the default be empty because some expressions that run in console will not run within parens e.g. due to unbalanced double quotes system('echo "a b') --- src/nvim/options.lua | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 774c39808f..4e7be63b63 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2077,11 +2077,7 @@ return { secure=true, vi_def=true, varname='p_sxq', - defaults={ - condition='WIN32', - if_true={vi="("}, - if_false={vi=""} - } + defaults={if_true={vi=""}} }, { full_name='shellxescape', abbreviation='sxe', @@ -2089,11 +2085,7 @@ return { secure=true, vi_def=true, varname='p_sxe', - defaults={ - condition='WIN32', - if_true={vi='"&|<>()@^'}, - if_false={vi=""} - } + defaults={if_true={vi=""}} }, { full_name='shiftround', abbreviation='sr', -- cgit From 7c4e5dfd2722b8c25641cbbc66c5b0133d0e2f03 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 12 Apr 2017 01:35:17 +0200 Subject: win: os_shell_is_cmdexe() + tests --- src/nvim/event/libuv_process.c | 20 +++----------------- src/nvim/memory.c | 7 +++++++ src/nvim/os/env.c | 22 ++++++++++++++++++---- 3 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index ab69bea04c..f5a41d151b 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -8,7 +8,6 @@ #include "nvim/event/process.h" #include "nvim/event/libuv_process.h" #include "nvim/log.h" -#include "nvim/path.h" #include "nvim/os/os.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -27,22 +26,9 @@ int libuv_process_spawn(LibuvProcess *uvproc) uvproc->uvopts.flags |= UV_PROCESS_DETACHED; } #ifdef WIN32 - // libuv assumes spawned processes follow the convention from - // CommandLineToArgvW(), cmd.exe does not. Disable quoting since it will - // result in unexpected behaviour, the caller is left with the responsibility - // to quote arguments accordingly. system('') has shell* options for this. - // - // Disable quoting for cmd, cmd.exe and $COMSPEC with a cmd.exe filename - bool is_cmd = STRICMP(proc->argv[0], "cmd.exe") == 0 - || STRICMP(proc->argv[0], "cmd") == 0; - if (!is_cmd) { - const char_u *comspec = (char_u *)os_getenv("COMSPEC"); - const char_u *comspecshell = path_tail((char_u *)proc->argv[0]); - is_cmd = comspec != NULL && STRICMP(proc->argv[0], comspec) == 0 - && STRICMP("cmd.exe", (char *)comspecshell) == 0; - } - - if (is_cmd) { + // 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 diff --git a/src/nvim/memory.c b/src/nvim/memory.c index b4fdd86a6d..85ec916ba0 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -495,6 +495,13 @@ bool strequal(const char *a, const char *b) 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. diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 12c2da6152..ad51e598c1 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -1,11 +1,8 @@ -// env.c -- environment variable access +// Environment inspection #include - #include -// 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" @@ -919,3 +916,20 @@ bool os_term_is_nice(void) || NULL != os_getenv("KONSOLE_DBUS_SESSION"); #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)); +} -- cgit From 45b5ebea9ddf029b3453ab21d20ae41f32c8de97 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 14 Apr 2017 17:41:59 +0200 Subject: perf: tv_clear(): Cache gettext() result. (#6519) Closes #6437 --- src/nvim/eval/typval.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 779bb18175..eb6db9547b 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1837,9 +1837,12 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, /// @param[in,out] tv Value to free. void tv_clear(typval_T *const tv) { + static char *objname = NULL; // cached because gettext() is slow. #6437 + if (objname == NULL) { + objname = xstrdup(_("tv_clear() argument")); + } if (tv != NULL && tv->v_type != VAR_UNKNOWN) { - const int evn_ret = encode_vim_to_nothing(NULL, tv, - _("tv_clear() argument")); + const int evn_ret = encode_vim_to_nothing(NULL, tv, objname); (void)evn_ret; assert(evn_ret == OK); } -- cgit From b2942d1e729c4cfa8ec9d3bedcdc7ad838a689ef Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 13 Apr 2017 19:16:32 +0300 Subject: eval: Change the point at which arg_errmsg and its length are changed Ref #6437 --- src/nvim/eval.c | 130 +++++++++++++++++++++++++++---------------------- src/nvim/eval/typval.c | 22 ++++++--- src/nvim/eval/typval.h | 11 +++++ 3 files changed, 98 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0663e19b9a..e81378bcaa 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2378,9 +2378,9 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, &tv, &di, true, false) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, (const char *)lp->ll_name, - STRLEN(lp->ll_name)) + TV_CSTRING) && !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name, - STRLEN(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); } @@ -2393,7 +2393,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, } else if (tv_check_lock(lp->ll_newkey == NULL ? lp->ll_tv->v_lock : lp->ll_tv->vval.v_dict->dv_lock, - (const char *)lp->ll_name, STRLEN(lp->ll_name))) { + (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; @@ -2402,7 +2402,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, 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, (const char *)lp->ll_name, - STRLEN(lp->ll_name))) { + TV_CSTRING)) { return; } ri = ri->li_next; @@ -2992,14 +2992,14 @@ int do_unlet(const char *const name, const size_t name_len, const int forceit) } if (hi != NULL && !HASHITEM_EMPTY(hi)) { dictitem_T *const di = TV_DICT_HI2DI(hi); - if (var_check_fixed(di->di_flags, (const char *)name, STRLEN(name)) - || var_check_ro(di->di_flags, (const char *)name, STRLEN(name)) - || tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { + 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, (const char *)name, STRLEN(name))) { + || tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) { return FAIL; } @@ -6553,10 +6553,8 @@ 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) { - const char *const arg_errmsg = _("add() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); if ((l = argvars[0].vval.v_list) != NULL - && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { + && !tv_check_lock(l->lv_lock, "add() argument", TV_TRANSLATE)) { tv_list_append_tv(l, &argvars[1]); tv_copy(&argvars[0], rettv); } @@ -8152,7 +8150,6 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) { const char *const arg_errmsg = N_("extend() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) { long before; @@ -8161,13 +8158,13 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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, arg_errmsg_len); + 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, arg_errmsg_len)) { + } else if (!tv_check_lock(l1->lv_lock, arg_errmsg, TV_TRANSLATE)) { listitem_T *item; if (argvars[2].v_type != VAR_UNKNOWN) { before = tv_get_number_chk(&argvars[2], &error); @@ -8195,13 +8192,13 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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, arg_errmsg_len); + 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, arg_errmsg_len)) { + } 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) { @@ -8349,20 +8346,19 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) int todo; char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); const char *const arg_errmsg = (map - ? _("map() argument") - : _("filter() argument")); - const size_t arg_errmsg_len = strlen(arg_errmsg); + ? 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, arg_errmsg_len))) { + || (!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, arg_errmsg_len))) { + || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE))) { return; } } else { @@ -8395,8 +8391,8 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) di = TV_DICT_HI2DI(hi); if (map - && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, arg_errmsg_len) - || var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len))) { + && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TV_TRANSLATE) + || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE))) { break; } @@ -8407,8 +8403,8 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) break; } if (!map && rem) { - if (var_check_fixed(di->di_flags, arg_errmsg, arg_errmsg_len) - || var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len)) { + if (var_check_fixed(di->di_flags, arg_errmsg, TV_TRANSLATE) + || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE)) { break; } tv_dict_item_remove(d, di); @@ -8421,7 +8417,7 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) for (li = l->lv_first; li != NULL; li = nli) { if (map - && tv_check_lock(li->li_tv.v_lock, arg_errmsg, arg_errmsg_len)) { + && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TV_TRANSLATE)) { break; } nli = li->li_next; @@ -11158,13 +11154,12 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) { list_T *l; bool error = false; - const char *const arg_errmsg = _("insert() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); 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, arg_errmsg, arg_errmsg_len)) { + && !tv_check_lock(l->lv_lock, N_("insert() argument"), + TV_TRANSLATE)) { long before = 0; if (argvars[2].v_type != VAR_UNKNOWN) { before = tv_get_number_chk(&argvars[2], &error); @@ -13205,21 +13200,20 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) long end; dict_T *d; dictitem_T *di; - const char *const arg_errmsg = _("remove() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); + 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, arg_errmsg_len)) { + && !tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE)) { const char *key = tv_get_string_chk(&argvars[1]); if (key != NULL) { di = tv_dict_find(d, key, -1); if (di == NULL) { EMSG2(_(e_dictkey), key); - } else if (!var_check_fixed(di->di_flags, arg_errmsg, arg_errmsg_len) - && !var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len)) { + } 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; di->di_tv = TV_INITIAL_VALUE; tv_dict_item_remove(d, di); @@ -13232,7 +13226,7 @@ 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, arg_errmsg_len)) { + && !tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE)) { bool error = false; idx = tv_get_number_chk(&argvars[1], &error); @@ -13503,14 +13497,12 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - const char *const arg_errmsg = _("reverse() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); - 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, arg_errmsg, arg_errmsg_len)) { + && !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; @@ -15202,16 +15194,14 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) sortinfo = &info; const char *const arg_errmsg = (sort - ? _("sort() argument") - : _("uniq() argument")); - const size_t arg_errmsg_len = strlen(arg_errmsg); + ? 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, arg_errmsg, arg_errmsg_len)) { + if (l == NULL || tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE)) { goto theend; } rettv->vval.v_list = l; @@ -18876,24 +18866,37 @@ static void set_var(const char *name, const size_t name_len, typval_T *const tv, /// /// @param[in] flags di_flags attribute value. /// @param[in] name Variable name, for use in error message. -/// @param[in] name_len Variable name length. +/// @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. /// /// @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 *const name, - const size_t name_len) +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) { - emsgf(_(e_readonlyvar), (int)name_len, 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) { - emsgf(_("E794: Cannot set variable in the sandbox: \"%.*s\""), - (int)name_len, 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; } /// Check whether variable is fixed (DI_FLAGS_FIX) @@ -18902,14 +18905,23 @@ bool var_check_ro(const int flags, const char *const name, /// /// @param[in] flags di_flags attribute value. /// @param[in] name Variable name, for use in error message. -/// @param[in] name_len Variable name length. +/// @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. /// /// @return True if variable is fixed, false otherwise. -static bool var_check_fixed(const int flags, const char *const name, - const size_t name_len) +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) { + 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; } @@ -19716,12 +19728,12 @@ void ex_function(exarg_T *eap) } if (fudi.fd_di == NULL) { if (tv_check_lock(fudi.fd_dict->dv_lock, (const char *)eap->arg, - STRLEN(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, (const char *)eap->arg, - STRLEN(eap->arg))) { + TV_CSTRING)) { // Can't change an existing function if it is locked goto erret; } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index eb6db9547b..c29c67124f 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2045,11 +2045,14 @@ bool tv_islocked(const typval_T *const tv) /// /// @param[in] lock Lock status. /// @param[in] name Variable name, used in the error message. -/// @param[in] name_len Variable name length. +/// @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. /// /// @return true if variable is locked, false otherwise. -bool tv_check_lock(const VarLockStatus lock, const char *const name, - const size_t name_len) +bool tv_check_lock(const VarLockStatus lock, const char *name, + size_t name_len) FUNC_ATTR_WARN_UNUSED_RESULT { const char *error_message = NULL; @@ -2068,10 +2071,17 @@ bool tv_check_lock(const VarLockStatus lock, const char *const name, } assert(error_message != NULL); - const char *const unknown_name = _("Unknown"); + 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), (name != NULL ? name_len : strlen(unknown_name)), - (name != NULL ? name : unknown_name)); + emsgf(_(error_message), (int)name_len, name); return true; } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 7eab22bc12..df46222067 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -423,6 +423,17 @@ 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 INCLUDE_GENERATED_DECLARATIONS # include "eval/typval.h.generated.h" #endif -- cgit From 276ee1f7fb989b931a9ddfabfd4aaf1782bcbb77 Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 13 Apr 2017 23:42:51 +0300 Subject: eval: Add comment regarding why special values are needed --- src/nvim/eval.c | 12 ++++++++++++ src/nvim/eval/typval.c | 6 ++++++ 2 files changed, 18 insertions(+) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e81378bcaa..281b80a915 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -18871,6 +18871,12 @@ static void set_var(const char *name, const size_t name_len, typval_T *const tv, /// 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, @@ -18910,6 +18916,12 @@ bool var_check_ro(const int flags, const char *name, /// 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) diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index c29c67124f..b70554c1ef 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2050,6 +2050,12 @@ bool tv_islocked(const typval_T *const tv) /// 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) -- cgit From b54e5c220f0b1bff31ce65c6988f70cbb9780b5e Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 14 Apr 2017 00:12:05 +0300 Subject: unittests: Add a test for TV_CSTRING MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not using enum{} because SIZE_MAX exceeds integer and I do not really like how enum definition is described in C99: 1. Even though all values must fit into the chosen type (6.7.2.2, p 4) the type to choose is still implementation-defined. 2. 6.4.4.3 explicitly states that “an identifier declared as an enumeration constant has type `int`”. So it looks like “no matter what type was chosen for enumeration, constants will be integers”. Yet the following simple program: #include #include #include enum { X=SIZE_MAX }; int main(int argc, char **argv) { printf("x:%zu m:%zu t:%zu v:%zu", sizeof(X), sizeof(SIZE_MAX), sizeof(size_t), (size_t)X); } yields one of the following using different compilers: - clang/gcc/pathcc: `x:8 m:8 t:8 v:18446744073709551615` - pcc/tcc: `x:4 m:8 t:8 v:1844674407370955161` If I remove the cast of X to size_t then pcc/tcc both yield `x:4 m:8 t:8 v:4294967295`, other compilers’ output does not change. All compilers were called with `$compiler -std=c99 -xc -` (feeding program from echo), except for `tcc` which has missing `-std=c99`. `pcc` seems to ignore the argument though: it is perfectly fine with `-std=c1000`. --- src/nvim/eval/typval.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index df46222067..0f659727ee 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -17,6 +17,7 @@ #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 int varnumber_T; @@ -434,6 +435,12 @@ static inline bool tv_is_func(const typval_T tv) /// 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 -- cgit From 31fd6d4bbf80d0f50893ab6144aa5eb70c95c351 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 14 Apr 2017 23:57:44 +0300 Subject: eval/typval: Do not translate tv_clear argument, this is useless --- src/nvim/eval/typval.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index b70554c1ef..d5177138b0 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1799,11 +1799,13 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, #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 @@ -1837,12 +1839,14 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, /// @param[in,out] tv Value to free. void tv_clear(typval_T *const tv) { - static char *objname = NULL; // cached because gettext() is slow. #6437 - if (objname == NULL) { - objname = xstrdup(_("tv_clear() argument")); - } if (tv != NULL && tv->v_type != VAR_UNKNOWN) { - const int evn_ret = encode_vim_to_nothing(NULL, tv, objname); + // 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); } -- cgit From c289986c89dd0189ed8ab709bf2eb822c493542a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 00:08:50 +0300 Subject: eval/encode: Do translate “… argument” strings, but only in conv_error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/eval/encode.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index d74913a481..c058c3a9c0 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -179,9 +179,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; } @@ -790,7 +790,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; @@ -818,7 +818,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); } @@ -841,7 +841,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); } -- cgit From 12fc1defd6a1b13d1f801173e0b6a1cef28527ae Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 15 Apr 2017 11:19:40 +0200 Subject: ops: fix i with multi-byte text (#6524) --- src/nvim/getchar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index b83681ad01..3b248c4bc6 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -302,13 +302,13 @@ static void add_num_buff(buffheader_T *buf, long n) */ static void add_char_buff(buffheader_T *buf, int c) { - char bytes[MB_MAXBYTES + 1]; + uint8_t bytes[MB_MAXBYTES + 1]; int len; if (IS_SPECIAL(c)) { len = 1; } else { - len = (*mb_char2bytes)(c, (char_u *)bytes); + len = mb_char2bytes(c, bytes); } for (int i = 0; i < len; i++) { -- cgit From a8f7872f445a9ec18be40b203a65d809adb05cd1 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 15 Apr 2017 08:50:43 -0400 Subject: test_timers.vim: Adjust timing to handle difference in implementation --- src/nvim/testdir/test_timers.vim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index fd2b50b495..d377062780 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -20,7 +20,7 @@ func Test_oneshot() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') - call assert_inrange(49, 100, slept) + call assert_inrange(40, 100, slept) else call assert_inrange(20, 100, slept) endif @@ -32,7 +32,7 @@ func Test_repeat_three() let slept = WaitFor('g:val == 3') call assert_equal(3, g:val) if has('reltime') - call assert_inrange(149, 250, slept) + call assert_inrange(120, 250, slept) else call assert_inrange(80, 200, slept) endif @@ -57,7 +57,7 @@ func Test_with_partial_callback() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') - call assert_inrange(49, 130, slept) + call assert_inrange(40, 130, slept) else call assert_inrange(20, 100, slept) endif @@ -119,7 +119,7 @@ func Test_paused() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') - call assert_inrange(0, 30, slept) + call assert_inrange(0, 60, slept) else call assert_inrange(0, 10, slept) endif -- cgit From c70ab1a2e2d78832e0246bd64c53c8b92912f0ef Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 15 Apr 2017 15:06:50 +0200 Subject: test: make locale dependent oldtest more reliable (#6526) --- src/nvim/testdir/test_normal.vim | 42 ++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index c529971528..6261625801 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -1606,12 +1606,13 @@ fun! Test_normal30_changecase() norm! V~ call assert_equal('THIS IS A simple test: äüöss', getline('.')) - " Turkish ASCII turns to multi-byte. On Mac the Turkish locale is available - " but toupper()/tolower() don't do the right thing. - if !has('mac') && !has('osx') - try - lang tr_TR.UTF-8 - set casemap= + " 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)) @@ -1621,8 +1622,7 @@ fun! Test_normal30_changecase() 1normal guu call assert_equal("i\u0131", getline(1)) call assert_equal("i\u0131", tolower("iI")) - - set casemap& + elseif iupper == "I" call setline(1, 'iI') 1normal gUU call assert_equal("II", getline(1)) @@ -1632,13 +1632,25 @@ fun! Test_normal30_changecase() 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 - endif + 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! -- cgit From 0dddd8a27caac1060dedbe55b285e3564e81e995 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:13:43 +0300 Subject: os/fileio: Remove FUNC_ATTR_MALLOC for file_open_new fp contains pointer to rbuffer --- src/nvim/os/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 4b7b53fc7f..3c47c66196 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -100,7 +100,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) { -- cgit From b08b71c7288ed7bbeae6066ab36a1366d0673bf5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:16:00 +0300 Subject: eval/typval: Remove FUNC_ATTR_MALLOC from tv_list_alloc Allocated list points to previously allocated list. Allocated list is saved to gc_first_list. --- src/nvim/eval/typval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index eb6db9547b..14db330dba 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -136,7 +136,7 @@ void tv_list_watch_fix(list_T *const l, const listitem_T *const item) /// /// @return [allocated] new list. list_T *tv_list_alloc(void) - FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC + FUNC_ATTR_NONNULL_RET { list_T *const list = xcalloc(1, sizeof(list_T)); -- cgit From b9004d744811f530922fbb194ea02033d332f375 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:16:40 +0300 Subject: eval/typval: Remove FUNC_ATTR_MALLOC from tv_dict_item_copy Allocated storage may receive pointer to the list after tv_copy(). --- src/nvim/eval/typval.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 14db330dba..4d1400484a 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1011,7 +1011,6 @@ void tv_dict_item_free(dictitem_T *const item) /// @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 - FUNC_ATTR_MALLOC { dictitem_T *const new_di = tv_dict_item_alloc((const char *)di->di_key); tv_copy(&di->di_tv, &new_di->di_tv); -- cgit From af3579d5f7bc86a25fd73e94c6de0e73ae9d8e12 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:18:25 +0300 Subject: eval/typval: Remove FUNC_ATTR_MALLOC from tv_dict_alloc Allocated dict points to previously allocated dict. Queue in allocated dict points to itself. Hashtab in allocated dict points to inside itself. Allocated dict is saved to gc_first_dict. --- src/nvim/eval/typval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 4d1400484a..9e954be9b3 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1039,7 +1039,7 @@ void tv_dict_item_remove(dict_T *const dict, dictitem_T *const item) /// /// @return [allocated] new dictionary. dict_T *tv_dict_alloc(void) - FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { dict_T *const d = xmalloc(sizeof(dict_T)); -- cgit From 82ba2891ae905fabacafc58daebedc80533b8334 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:19:22 +0300 Subject: eval/typval: Remove FUNC_ATTR_MALLOC from tv_list_alloc_ret Same as tv_list_alloc, but additionally ret_tv receives pointer to the newly allocated list. --- src/nvim/eval/typval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 9e954be9b3..70ec3dfe39 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1576,7 +1576,7 @@ void tv_dict_set_keys_readonly(dict_T *const dict) /// /// @return [allocated] pointer to the created list. list_T *tv_list_alloc_ret(typval_T *const ret_tv) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC + FUNC_ATTR_NONNULL_ALL { list_T *const l = tv_list_alloc(); ret_tv->vval.v_list = l; -- cgit From d191ba1db38cf4bad3e4ed3e3346f3f8a9c015cf Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:23:00 +0300 Subject: option: Remove FUNC_ATTR_MALLOC from get_winbuf_options Same as tv_dict_alloc() and additionally it saves some strings inside a dictionary. --- src/nvim/option.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 458d80716c..0070a0056d 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -6974,7 +6974,7 @@ bool signcolumn_on(win_T *wp) /// Get window or buffer local options dict_T *get_winbuf_options(const int bufopt) - FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC + FUNC_ATTR_WARN_UNUSED_RESULT { dict_T *const d = tv_dict_alloc(); -- cgit From ac47e64ecad6b21d4d29066b37ab4018fcd8da48 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:25:00 +0300 Subject: ops: Remove FUNC_ATTR_MALLOC from copy_register Returned storage has a pointer to a newly allocated array. --- src/nvim/ops.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index f11d6b69b2..5212ec45ab 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -802,7 +802,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); -- cgit From d76a13bb65574f4811313ada6454f7d34cde2a2c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 15 Apr 2017 19:39:53 +0300 Subject: os/shell: Remove FUNC_ATTR_MALLOC from shell_build_argv Returns an array of allocated strings. --- src/nvim/os/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 5cc9d4b79b..29c0431521 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -47,7 +47,7 @@ typedef struct { /// @param extra_args Extra arguments to the shell, or NULL. /// @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)); -- cgit From ec0fabd4d5129c7293c8b8fcf0d0946ae5bd5fd4 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Sat, 15 Apr 2017 18:45:47 +0200 Subject: eval.c: Code style fixes --- src/nvim/eval.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6a18baf2e2..33a553436f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16696,11 +16696,11 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type != VAR_UNKNOWN) { if (argvars[0].v_type != VAR_NUMBER) { EMSG(_(e_number_exp)); - } else { - timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); - if (timer != NULL && !timer->stopped) { - add_timer_info(rettv, timer); - } + 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); @@ -16712,12 +16712,12 @@ static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr) { if (argvars[0].v_type != VAR_NUMBER) { EMSG(_(e_number_exp)); - } else { - 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; - } + 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; } } @@ -16790,7 +16790,7 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr) { - timer_teardown(); + timer_stop_all(); } // invoked on the main loop @@ -16853,7 +16853,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, { @@ -16861,6 +16861,11 @@ void timer_teardown(void) }) } +void timer_teardown(void) +{ + timer_stop_all(); +} + /* * "tolower(string)" function */ -- cgit From 33952a7661927f875ebf40a60e236831c789de58 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 18:53:02 +0300 Subject: *: Silence some false positives --- src/nvim/api/private/helpers.h | 1 + src/nvim/buffer.h | 3 ++- src/nvim/eval/typval_encode.c.h | 4 ++-- src/nvim/globals.h | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 9fe8c351cf..20b4015fb5 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -8,6 +8,7 @@ #include "nvim/memory.h" #include "nvim/lib/kvec.h" +// -V:api_set_error:618 #define api_set_error(err, errtype, ...) \ do { \ snprintf((err)->msg, \ diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h index 016c5ce3b7..39b9faf8b1 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -103,7 +103,8 @@ static inline void buf_set_changedtick(buf_T *const buf, const int changedtick) assert(changedtick_di->di_flags == (DI_FLAGS_RO|DI_FLAGS_FIX)); # endif assert(changedtick_di == (dictitem_T *)&buf->changedtick_di); - assert(&buf->b_changedtick == &buf->changedtick_di.di_tv.vval.v_number); + assert(&buf->b_changedtick // -V501 + == &buf->changedtick_di.di_tv.vval.v_number); #endif buf->b_changedtick = changedtick; } diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index ad54eef4a0..3487880bd2 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -611,7 +611,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( @@ -814,6 +814,6 @@ 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/globals.h b/src/nvim/globals.h index 3c705d88a5..df9f418951 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -548,6 +548,7 @@ EXTERN win_T *prevwin INIT(= NULL); /* previous window */ FOR_ALL_TABS(tp) \ FOR_ALL_WINDOWS_IN_TAB(wp, tp) +// -V:FOR_ALL_WINDOWS_IN_TAB:501 # define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \ for (win_T *wp = ((tp) == curtab) \ ? firstwin : (tp)->tp_firstwin; wp != NULL; wp = wp->w_next) -- cgit From a096766ee3edc1197039d236c3a5c42365d60d4d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:27:17 +0300 Subject: diff: Silence -V519 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not exactly a false positive, but previous assignment is a part of the pattern “change global, run code which uses it, change global back”. --- src/nvim/diff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index ff76abc01f..49574fbbfc 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1076,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) { -- cgit From 2901921a1b5bf72cb404fed0ed0510124eaf6e8b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:30:18 +0300 Subject: digraph: Ignore false positive Reversed order is intentional, digraphs allow swapping characters. --- src/nvim/digraph.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 560205fe7d..fb4a8c6d0d 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1569,7 +1569,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; -- cgit From 4f0fc1f06a6b551c081f1e4abf1a119588c6a386 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:32:38 +0300 Subject: digraph: Fix errors due to has_mbyte and friends being fixed --- src/nvim/digraph.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index fb4a8c6d0d..66fb525920 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1676,11 +1676,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) { @@ -1701,15 +1697,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++ = ' '; -- cgit From 9e9ba14e0e443beff4c1418cdaff412c394852c0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:38:16 +0300 Subject: edit: Fix strange code Based on the flow it looks like ptr could not be NULL here: if ptr_arg is NULL ptr is compl_leader, if compl_leader is NULL function exits. This also applies to Vim as far as I see. --- src/nvim/edit.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index fe00027dec..1ca5424736 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -3427,10 +3427,11 @@ 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); + } + assert(ptr != NULL); + AppendToRedobuffLit(ptr + len, -1); } /* -- cgit From fb4754104b50baa0eb489e5c9b50c1d37523f2d3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:39:55 +0300 Subject: macros: Fix excessive check --- src/nvim/macros.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/macros.h b/src/nvim/macros.h index b816b34b39..214af82422 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -75,7 +75,7 @@ do { \ if (*p_langmap \ && (condition) \ - && (p_lrm || (!p_lrm && KeyTyped)) \ + && (p_lrm || KeyTyped) \ && !KeyStuffed \ && (c) >= 0) \ { \ -- cgit From dd5b0cc17a1ec6925c6cd7a5be23eb78bf953f76 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:50:23 +0300 Subject: edit: Copy assert to before the warning --- src/nvim/edit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 1ca5424736..51d0847bc7 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -3419,6 +3419,7 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg) else return; /* nothing to do */ } + assert(ptr != NULL); if (compl_orig_text != NULL) { p = compl_orig_text; for (len = 0; p[len] != NUL && p[len] == ptr[len]; ++len) -- cgit From d70a0f6895048a3dcb5ec841afd01daee4866be4 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:51:35 +0300 Subject: eval/typval_encode: Silence then/else equivalence warning --- src/nvim/eval/typval_encode.c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index 3487880bd2..b4a70fb188 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -489,7 +489,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); -- cgit From 05c1829a8ccf2df07927bec502467faa443d90d8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:55:49 +0300 Subject: eval: Silence eap->skip false positives `lnum` starts at `eap->line2` in case of skipping, so cycle is always run at least once. --- src/nvim/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 772994de31..49e3590185 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2747,7 +2747,7 @@ void ex_call(exarg_T *eap) } else lnum = eap->line1; for (; lnum <= eap->line2; ++lnum) { - if (!eap->skip && eap->addr_count > 0) { + if (!eap->skip && eap->addr_count > 0) { // -V560 curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; curwin->w_cursor.coladd = 0; @@ -2768,7 +2768,7 @@ void ex_call(exarg_T *eap) } tv_clear(&rettv); - if (doesrange || eap->skip) { + if (doesrange || eap->skip) { // -V560 break; } -- cgit From 97a1ccf8e7470d8c781c86253f8a7795fe50dc50 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:56:55 +0300 Subject: eval: Fix V547: `d == NULL` was already checked at line 2986 --- src/nvim/eval.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 49e3590185..4cc400799d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2999,8 +2999,7 @@ int do_unlet(const char *const name, const size_t name_len, const int forceit) return FAIL; } - if (d == NULL - || tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { + if (tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { return FAIL; } -- cgit From 7c9e3d6cadb441aaa40c8539de41e302228196a9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:02:06 +0300 Subject: eval: Refactor f_char2nr With has_mbyte equal to 1 and &encoding always UTF-8 second argument is no longer useful: utf_ptr2char is the same as mb_ptr2char. Also changes function behaviour a bit: now if second argument is not a number it immediately returns with error, without bothering to get a character. --- src/nvim/eval.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4cc400799d..bfc9f6eaa6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7305,18 +7305,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 = tv_get_number_chk(&argvars[1], NULL); + if (argvars[1].v_type != VAR_UNKNOWN) { + if (!tv_check_num(&argvars[1])) { + return; } - - rettv->vval.v_number = (utf8 ? *utf_ptr2char : *mb_ptr2char)( - (const char_u *)tv_get_string(&argvars[0])); - } else { - rettv->vval.v_number = (uint8_t)(tv_get_string(&argvars[0])[0]); } + + rettv->vval.v_number = utf_ptr2char( + (const char_u *)tv_get_string(&argvars[0])); } /* -- cgit From 31190879cc85cb3e8a056d544ea0c3ed63ce21df Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:07:54 +0300 Subject: eval: Fix useless NULL check partial_name() as it is written now really cannot return NULL --- src/nvim/eval.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index bfc9f6eaa6..f8afc03c1c 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8977,13 +8977,10 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (strcmp(what, "func") == 0 || strcmp(what, "name") == 0) { rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING); const char *const n = (const char *)partial_name(pt); - if (n == NULL) { - rettv->vval.v_string = NULL; - } else { - rettv->vval.v_string = (char_u *)xstrdup(n); - if (rettv->v_type == VAR_FUNC) { - func_ref(rettv->vval.v_string); - } + 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) { rettv->v_type = VAR_DICT; -- cgit From 3c5f4b382f62d9f3cf5d54720592ff75d3a1f86d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:08:56 +0300 Subject: eval: Silence octal constant warning --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index f8afc03c1c..a259bbf0eb 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12538,7 +12538,7 @@ static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int prot = 0755; + int prot = 0755; // -V536 rettv->vval.v_number = FAIL; if (check_restricted() || check_secure()) -- cgit From fbdef2e6f2d65d3cc6f3c8a8dcd8b3cddf41c474 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:16:32 +0300 Subject: eval: Refactor nr2char() Adds error messages, checks type and ignores the second argument. Currently utf_char2bytes is able to handle any 31-bit character, not limited by a unicode range. So checking for INT_MAX and not for something else: function yet uses `int`. --- src/nvim/eval.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a259bbf0eb..71af801986 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12763,25 +12763,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) { - utf8 = tv_get_number_chk(&argvars[1], NULL); - } - if (utf8) { - buf[(*utf_char2bytes)((int)tv_get_number(&argvars[0]), buf)] = NUL; - } else { - buf[(*mb_char2bytes)((int)tv_get_number(&argvars[0]), buf)] = NUL; + if (argvars[1].v_type != VAR_UNKNOWN) { + if (!tv_check_num(&argvars[1])) { + return; } - } else { - buf[0] = (char_u)tv_get_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 could not be less then zero")); + return; + } + if (num > INT_MAX) { + emsgf(_("E5071: Character number could not be greater then 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); } /* -- cgit From 787d71a3afbe619a301ba7898e2c43fdcffdc8ec Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:19:10 +0300 Subject: eval: Fix condition in f_serverstop --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 71af801986..2a725c49f7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14306,7 +14306,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; } -- cgit From 9b1dd084257fc2b5f50e29b283be698c13d4a509 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:20:38 +0300 Subject: eval: Remove unneeded varp check --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2a725c49f7..6e204be481 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14330,7 +14330,7 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; bool error = false; -- cgit From 9dd1926df01a27c913dd19ef0a4f79d06842508a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:20:53 +0300 Subject: eval: Remove unneeded varp check --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6e204be481..30b776c887 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14874,7 +14874,7 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *const varname = tv_get_string_chk(&argvars[1]); typval_T *const varp = &argvars[2]; - if (varname != NULL && varp != NULL && tp != NULL) { + if (varname != NULL && tp != NULL) { tabpage_T *const save_curtab = curtab; goto_tabpage_tp(tp, false, false); -- cgit From 1bc080078793aafcecfae95620f6dac917c737dc Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:22:12 +0300 Subject: eval: Remove unneeded !eap->skip check Already checked in the outer if(). --- src/nvim/eval.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 30b776c887..67d5465896 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -19462,8 +19462,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 -- cgit From c5010c98ae8532f7f2778ce0e89a01d9e1ca68f9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:22:58 +0300 Subject: eval: Fix position of buf declaration --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 67d5465896..cf55b42bdf 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -21048,8 +21048,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, char *s = tofree; emsg_off--; if (s != NULL) { + char buf[MSG_BUF_LEN]; if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) { - char buf[MSG_BUF_LEN]; trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN, sizeof(buf)); s = buf; -- cgit From d766607dc9e3c54a7575102ecf025eb184d9f648 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:24:30 +0300 Subject: farsi: Simplify condition --- src/nvim/farsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c index e7e93f756f..2d37d1284e 100644 --- a/src/nvim/farsi.c +++ b/src/nvim/farsi.c @@ -321,7 +321,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 { -- cgit From a894c82defc00fcd0ed14a6d157130d9dc63f314 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:25:00 +0300 Subject: ex_docmd: Remove excessive assignment --- src/nvim/ex_docmd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 0fd4ae48be..3d1136b7ac 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1304,7 +1304,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(). */ -- cgit From 87e107d92143e108ec3ec5f91851ca3cb3768175 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:27:20 +0300 Subject: ex_docmd: Remove :Ni! easter egg --- src/nvim/ex_docmd.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3d1136b7ac..60d3bb07a3 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1726,11 +1726,7 @@ 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")); @@ -4961,20 +4957,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) -- cgit From fe01e9c947b8c2fcb328e79b8b91ceebfd8c04cc Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:27:47 +0300 Subject: ex_docmd: Remove unneeded if() --- src/nvim/ex_docmd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 60d3bb07a3..0e399c9fb3 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4097,12 +4097,11 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) options += WILD_ICASE; p = ExpandOne(&xpc, eap->arg, NULL, options, WILD_EXPAND_FREE); - if (p == NULL) + 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; -- cgit From d88ae748b51963d0188fe41f0abd6ea208bd2eef Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:29:19 +0300 Subject: getchar: Fix if block indentation --- src/nvim/getchar.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 3b248c4bc6..e056ff488c 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1849,11 +1849,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; + } + } } } -- cgit From e3de83a8291cf0ef1481a2631dda04b37b6e3412 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:32:10 +0300 Subject: hardcopy: Remove unneeded prt_do_conv assignment --- src/nvim/hardcopy.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 4cb05ffc12..b2cbe30a43 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -2576,13 +2576,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; -- cgit From 0f7c260cd873c996da9badb42b9135cd15bee285 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:39:57 +0300 Subject: fileio: Simlify help files encoding detection Most of code is dead when enc_utf8 is always true. Given that `c` is being reused for other purposes I left it set to 1 just in case. --- src/nvim/fileio.c | 43 ++++++++----------------------------------- 1 file changed, 8 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index c1b8203ed1..74fa5aa1de 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -730,43 +730,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; -- cgit From 2394c9f2b79e5c9c121c21dcb324f9c18b473853 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:47:06 +0300 Subject: memline: Silence “buffer underflow” warning, looks like false positive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/memline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 5ea2397db3..45e16554e6 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -616,7 +616,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 } /* -- cgit From 10ce00efa8c9d4e9f2b588063ce04f7d49050d8b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:55:29 +0300 Subject: memline: Fix “NULL pointer dereference” warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was actually a false positive indicating always-true condition, not real dereference. --- src/nvim/memline.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 45e16554e6..b31ca136dd 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -3362,29 +3362,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) -- cgit From 083792e1374100f1b0c48c72987935f56ebbd8ad Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:56:30 +0300 Subject: message: Remove some enc_utf8/… checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/message.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index 3e4a1e10b6..91dfc79e38 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1165,15 +1165,9 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr) * 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((char_u *)str, len + 1); - } else if (has_mbyte) { - mb_l = (*mb_ptr2len)((char_u *)str); - } else { - mb_l = 1; - } - if (has_mbyte && mb_l > 1) { + // 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. -- cgit From 0718d0e6d44536547dac2248c65b15547e56fc10 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:58:19 +0300 Subject: message: Some more has_mbyte/enc_utf8 removal --- src/nvim/message.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index 91dfc79e38..42e1fd1cf9 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1657,16 +1657,13 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, // 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((char_u *)s, l, attr); + if (maxlen >= 0) { + // Avoid including composing chars after the end. + l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); } else { - msg_screen_putchar(*s++, attr); + l = utfc_ptr2len(s); } + s = screen_puts_mbyte((char_u *)s, l, attr); did_last_char = true; } else { did_last_char = false; -- cgit From dc523eed8ec2ea238dde21f39fdbb6343227c16e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:59:44 +0300 Subject: fileio: Silence “!= identical subexpressions” warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/os/fileio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 3c47c66196..27eb448c3d 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -47,6 +47,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname, 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) { \ -- cgit From 84aa457ccdf88baeee1e87ba763fafe0ff77095e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:02:43 +0300 Subject: os/env: Fix “invalid pointer to local” false positive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/os/env.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index ad51e598c1..f3187de182 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -641,7 +641,7 @@ char *vim_getenv(const char *name) exe_name, "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR, MAXPATHL) == OK) { - vim_path = exe_name; + vim_path = exe_name; // -V507 } } } @@ -675,6 +675,7 @@ char *vim_getenv(const char *name) vim_path = NULL; } } + assert(vim_path != exe_name); } #ifdef HAVE_PATHDEF -- cgit From cdbfff077b23d666036bd9967756938df9044b38 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:05:50 +0300 Subject: ops: Silence “counter not used in loop” false positive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 5212ec45ab..6ea3a45049 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2785,7 +2785,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) { -- cgit From 54bd78b8a8d212a0278b1d9517dd0dcc4df79a0b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:06:22 +0300 Subject: normal: Remove unneeded assignment --- src/nvim/normal.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 388ddfc8bb..1809b98586 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -694,7 +694,6 @@ static void normal_get_additional_char(NormalState *s) if (langmap_active) { // Undo the decrement done above no_mapping++; - State = NORMAL_BUSY; } State = NORMAL_BUSY; s->need_flushbuf |= add_to_showcmd(*cp); -- cgit From b5db7cde366ae159aee6826167b68c3aff0cdf19 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:08:12 +0300 Subject: normal: Clarify the code Current variant works only because of PUT_FIXINDENT being equal to true. --- src/nvim/normal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 1809b98586..d7c7c7d48c 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -2336,7 +2336,8 @@ do_mouse ( if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) insert_reg(regname, true); else { - do_put(regname, NULL, BACKWARD, 1L, fixindent | PUT_CURSEND); + 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); @@ -2688,7 +2689,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 -- cgit From aa3b1f695f699e189d5190c57e6c5e2bce4b0c9e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:09:31 +0300 Subject: normal: Add figure braces so that code is clearer --- src/nvim/normal.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index d7c7c7d48c..9340a45f62 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -7613,11 +7613,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) == false) { + clearopbeep(cap->oap); + } + } } } -- cgit From be9d98cb45aab402b7666776ad1288b9a79bb0c1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:10:40 +0300 Subject: quickfix: Remove unneeded condition fmt_ptr was checked for being NULL in if() condition earlier. --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 4fa5c85abd..33b832c033 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -856,7 +856,7 @@ restofline: if (fmt_ptr == NULL) { qi->qf_multiline = qi->qf_multiignore = false; } - } else if (fmt_ptr != NULL) { + } else { // honor %> item if (fmt_ptr->conthere) { fmt_start = fmt_ptr; -- cgit From 4e7150ee94d967ff51cbef24a7e18f71290ed9a2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:11:37 +0300 Subject: quicfix: Remove duplicate condition --- src/nvim/quickfix.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 33b832c033..af055e9b75 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3284,7 +3284,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); @@ -3341,7 +3340,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); -- cgit From b396a3f72edb3fb345e516a12b92991b249da572 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:13:49 +0300 Subject: quicfix: Avoid possible NULL dereference --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index af055e9b75..1241841885 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -984,7 +984,7 @@ qf_init_ext( } // Use the local value of 'errorformat' if it's set. - if (errorformat == p_efm && tv == NULL && *buf->b_p_efm != NUL) { + if (errorformat == p_efm && tv == NULL && buf && *buf->b_p_efm != NUL) { efm = buf->b_p_efm; } else { efm = errorformat; -- cgit From a65867542d291cda6cdd68e56e0d5d3866dbbb72 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:17:08 +0300 Subject: screen: Remove unneeded check --- src/nvim/screen.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index febca105e9..79596f73cd 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1016,9 +1016,7 @@ 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 (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 -- cgit From 7cf4b0ac06c7d6675a05924b6aff3850fde3bcf2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:18:00 +0300 Subject: screen: Silence “buffer underflow” warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 79596f73cd..cf116e1930 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2447,7 +2447,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; } } -- cgit From 48ad8e0ff1ba721a5607c20f48e813400041299c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:22:02 +0300 Subject: screen: Silence NULL dereference false positive Based on the loop condition when shl_flag is true cur != NULL. --- src/nvim/screen.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index cf116e1930..db757a54f5 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2579,13 +2579,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; @@ -5536,13 +5537,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)) { -- cgit From e131194db71c5fc20148ea6e463de997917f6c0a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:22:46 +0300 Subject: screen: Remove unneeded condition Already checked in outer if() --- src/nvim/screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index db757a54f5..431f74508d 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2784,8 +2784,8 @@ 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 (wp->w_p_bri && row != startrow && filler_lines == 0) { + char_attr = 0; // was: hl_attr(HLF_AT); if (diff_hlf != (hlf_T)0) { char_attr = hl_attr(diff_hlf); -- cgit From c0cbc507202231d5dd9c5c8669e6116f3344d535 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:26:07 +0300 Subject: screen: Remove another portion of has_mbyte/friends-checking stuff --- src/nvim/screen.c | 95 +++++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 431f74508d..66b52c3b25 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -5330,43 +5330,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; } } @@ -5374,16 +5370,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; @@ -6103,8 +6094,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 @@ -6189,13 +6179,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)); } } } -- cgit From 316789e14c3910c0b4c5dd710a1c82ebd7b01ac2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:33:10 +0300 Subject: tag: Silence “buffer underflow” warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/tag.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index f01b8b8ab1..1ce2a4e2eb 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1222,9 +1222,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 -- cgit From 76783963ebc90ca565311489bb2206b208d2e147 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:34:15 +0300 Subject: tag: Fix “initialized twice successively” false positive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/tag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 1ce2a4e2eb..0c7244cbb3 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2534,7 +2534,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 -- cgit From 69ebfb8d8ea26061a4fbfe9ee07d7bfff49e6a2b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:35:50 +0300 Subject: regexp: Fix warning about octal constant --- src/nvim/regexp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 4b5e17b00b..e15a2eebe5 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -2398,7 +2398,7 @@ collection: regc('\b'); break; case CLASS_ESCAPE: - regc('\033'); + regc(ESC); break; } } else { -- cgit From b7118a008af1f0a15f7cfbe070a1f590310cc7b5 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:36:53 +0300 Subject: regexp: Remove another has_mbyte/…-checking stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/regexp.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index e15a2eebe5..284cb27c40 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -2923,13 +2923,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; -- cgit From 30561afe4128ab0c5371af00641d5c5a682d6270 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:38:06 +0300 Subject: regexp: Silence octal constant warning --- src/nvim/regexp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 284cb27c40..7be89c2d7e 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -3047,7 +3047,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; -- cgit From 372b6af8ea09bced16e8c793cbab304d2393bfa6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:41:55 +0300 Subject: regexp_nfa: Remove another has_mbyte/…-checking code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/regexp_nfa.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index caf26fdd35..67a405daf5 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -2772,15 +2772,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; } -- cgit From 9d302c60f084c33c05b758cae12cc2dfa775e48e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 21:42:20 +0300 Subject: regexp_nfa: Remove octal constant --- src/nvim/regexp_nfa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 67a405daf5..506e6277e9 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4407,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: -- cgit From 58300d70d26969546e204983f8b4e505771ec8dd Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 22:20:19 +0300 Subject: *: Fix linter errors --- src/nvim/eval.c | 9 +++++---- src/nvim/ex_docmd.c | 3 +-- src/nvim/normal.c | 6 +++--- src/nvim/screen.c | 10 ++++------ 4 files changed, 13 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index cf55b42bdf..7c5b23f567 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2742,11 +2742,12 @@ 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) { + } + for (; lnum <= eap->line2; lnum++) { if (!eap->skip && eap->addr_count > 0) { // -V560 curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 0e399c9fb3..17b3b512ef 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4095,8 +4095,7 @@ 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); + p = ExpandOne(&xpc, eap->arg, NULL, options, WILD_EXPAND_FREE); if (p == NULL) { return FAIL; } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 9340a45f62..7f087dcd20 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -2333,9 +2333,9 @@ 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 { + } else { do_put(regname, NULL, BACKWARD, 1L, (fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND); @@ -7616,7 +7616,7 @@ static void nv_record(cmdarg_T *cap) } else { // (stop) recording into a named register, unless executing a // register. - if (!Exec_reg && do_record(cap->nchar) == false) { + if (!Exec_reg && do_record(cap->nchar) == FAIL) { clearopbeep(cap->oap); } } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 66b52c3b25..a8993be4e5 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1017,11 +1017,9 @@ static void win_update(win_T *wp) if (VIsual_active) { 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 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; @@ -5349,7 +5347,7 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) nc1 = NUL; } else { nc = utfc_ptr2char_len(ptr + mbyte_blen, pcc, - (int)((text + len) - ptr - mbyte_blen)); + (int)((text + len) - ptr - mbyte_blen)); nc1 = pcc[0]; } pc = prev_c; -- cgit From 2eb9150a4fcb8f43599e5f470cbcb3a12195d910 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 23:58:32 +0300 Subject: buffer: Adjust where do_buffer call is located It is located there in Vim, but in dd7657c1605246e8f7ade35184069a09dc254e84 position was for some reason swapped. --- src/nvim/buffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 292eb03a16..e48b7846ae 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -741,12 +741,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); 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; -- cgit From 263849b2dd4dc98bbe0870f5654c77809caeb965 Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Sun, 16 Apr 2017 20:15:50 +0100 Subject: fold: foldMoveRange(): fix :move bug #6534 Closes #6540 In #6221 there was a mistake in calculating which folds need to be re-ordered. When there are no folds after those that have been adjusted, then `move_end` remains 0. This results in reverse_fold_order() swapping folds that have been adjusted with uninitialised folds in the remainder of the grow array. Add a check in foldMoveRange() to account for this case. --- src/nvim/fold.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/fold.c b/src/nvim/fold.c index d810aee0ce..34db4d2171 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -2765,10 +2765,13 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2, } dest_index = FOLD_INDEX(fp, gap); - // All folds are now correct, but they are not necessarily in the correct - // order. - // We have to swap folds in the range [move_end, dest_index) with those in - // the range [move_start, move_end). + // 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); -- cgit From 3345382cc2afd3b3a027d9abb5c101507ebb57d7 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Mon, 17 Apr 2017 00:00:04 +0200 Subject: highlight: default Cursor to guibg=fg, guifg=bg Closes #6508 --- src/nvim/syntax.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 1ed65ec52a..d5ff3707e8 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -5898,6 +5898,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", -- cgit From 14b1becb5466003a65fa6be0517352abb7bc0f42 Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Wed, 19 Apr 2017 03:20:05 +0300 Subject: doc: fix typo (#6504) --- src/nvim/buffer.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index e48b7846ae..1f44e1adb0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1839,9 +1839,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; @@ -2339,9 +2337,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; -- cgit From c2f3e361c52ec4e7149ea1d8c6a1202e0873da8e Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 19 Apr 2017 19:11:50 +0300 Subject: *: Add comment to all C files --- src/nvim/api/buffer.c | 3 +++ src/nvim/api/private/dispatch.c | 3 +++ src/nvim/api/private/handle.c | 3 +++ src/nvim/api/private/helpers.c | 3 +++ src/nvim/api/tabpage.c | 3 +++ src/nvim/api/ui.c | 3 +++ src/nvim/api/vim.c | 3 +++ src/nvim/api/window.c | 3 +++ src/nvim/arabic.c | 3 +++ src/nvim/buffer.c | 3 +++ src/nvim/charset.c | 3 +++ src/nvim/cursor.c | 3 +++ src/nvim/cursor_shape.c | 3 +++ src/nvim/diff.c | 3 +++ src/nvim/digraph.c | 3 +++ src/nvim/edit.c | 3 +++ src/nvim/eval.c | 3 +++ src/nvim/eval/decode.c | 3 +++ src/nvim/eval/encode.c | 3 +++ src/nvim/eval/executor.c | 3 +++ src/nvim/eval/gc.c | 3 +++ src/nvim/eval/typval.c | 3 +++ src/nvim/event/libuv_process.c | 3 +++ src/nvim/event/loop.c | 3 +++ src/nvim/event/multiqueue.c | 3 +++ src/nvim/event/process.c | 3 +++ src/nvim/event/rstream.c | 3 +++ src/nvim/event/signal.c | 3 +++ src/nvim/event/socket.c | 3 +++ src/nvim/event/stream.c | 3 +++ src/nvim/event/time.c | 3 +++ src/nvim/event/wstream.c | 3 +++ src/nvim/ex_cmds.c | 3 +++ src/nvim/ex_cmds2.c | 3 +++ src/nvim/ex_docmd.c | 3 +++ src/nvim/ex_eval.c | 3 +++ src/nvim/ex_getln.c | 3 +++ src/nvim/farsi.c | 3 +++ src/nvim/file_search.c | 3 +++ src/nvim/fileio.c | 3 +++ src/nvim/fold.c | 3 +++ src/nvim/garray.c | 3 +++ src/nvim/getchar.c | 3 +++ src/nvim/hardcopy.c | 3 +++ src/nvim/hashtab.c | 3 +++ src/nvim/if_cscope.c | 3 +++ src/nvim/indent.c | 3 +++ src/nvim/indent_c.c | 3 +++ src/nvim/keymap.c | 3 +++ src/nvim/log.c | 3 +++ src/nvim/main.c | 3 +++ src/nvim/map.c | 3 +++ src/nvim/mark.c | 3 +++ src/nvim/mbyte.c | 3 +++ src/nvim/memfile.c | 3 +++ src/nvim/memline.c | 3 +++ src/nvim/memory.c | 3 +++ src/nvim/menu.c | 3 +++ src/nvim/message.c | 3 +++ src/nvim/misc1.c | 3 +++ src/nvim/mouse.c | 3 +++ src/nvim/move.c | 3 +++ src/nvim/msgpack_rpc/channel.c | 3 +++ src/nvim/msgpack_rpc/helpers.c | 3 +++ src/nvim/msgpack_rpc/server.c | 3 +++ src/nvim/normal.c | 3 +++ src/nvim/ops.c | 3 +++ src/nvim/option.c | 3 +++ src/nvim/os/dl.c | 3 +++ src/nvim/os/env.c | 3 +++ src/nvim/os/fileio.c | 3 +++ src/nvim/os/fs.c | 3 +++ src/nvim/os/input.c | 3 +++ src/nvim/os/mem.c | 3 +++ src/nvim/os/pty_process_unix.c | 3 +++ src/nvim/os/shell.c | 3 +++ src/nvim/os/signal.c | 3 +++ src/nvim/os/stdpaths.c | 3 +++ src/nvim/os/time.c | 3 +++ src/nvim/os/users.c | 3 +++ src/nvim/os_unix.c | 3 +++ src/nvim/path.c | 3 +++ src/nvim/popupmnu.c | 3 +++ src/nvim/profile.c | 3 +++ src/nvim/quickfix.c | 3 +++ src/nvim/rbuffer.c | 3 +++ src/nvim/regexp.c | 3 +++ src/nvim/regexp_nfa.c | 3 +++ src/nvim/screen.c | 3 +++ src/nvim/search.c | 3 +++ src/nvim/sha256.c | 3 +++ src/nvim/shada.c | 3 +++ src/nvim/spell.c | 3 +++ src/nvim/spellfile.c | 3 +++ src/nvim/state.c | 3 +++ src/nvim/strings.c | 3 +++ src/nvim/syntax.c | 3 +++ src/nvim/tag.c | 3 +++ src/nvim/terminal.c | 3 +++ src/nvim/testdir/samples/memfile_test.c | 3 +++ src/nvim/tui/input.c | 3 +++ src/nvim/tui/tui.c | 3 +++ src/nvim/ugrid.c | 3 +++ src/nvim/ui.c | 3 +++ src/nvim/ui_bridge.c | 3 +++ src/nvim/undo.c | 3 +++ src/nvim/version.c | 3 +++ src/nvim/window.c | 3 +++ 108 files changed, 324 insertions(+) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 26f9a6f592..1b3592679b 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 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 #include #include 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 #include diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index fe15b28041..5877b848fc 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 #include #include diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index 0f0c33f621..29592408fc 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 #include #include diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index de60339e5f..3cc2870792 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 #include #include diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 6926436d2f..e5ef4a35c1 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 #include #include diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 3c564ada99..e1bb70ee0d 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 #include #include 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/buffer.c b/src/nvim/buffer.c index 1f44e1adb0..46f2cdac79 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 */ diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 3037cfe669..ee58e0af91 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. diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 45abd314fc..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 #include diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index 34ee53bf75..24a5672d0f 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 #include #include "nvim/vim.h" diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 49574fbbfc..0bd3f59cf2 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. diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 66fb525920..32e71f61f7 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 diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 51d0847bc7..678fa851eb 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 */ diff --git a/src/nvim/eval.c b/src/nvim/eval.c index dcbd7ab152..16f054957f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.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 + /* * eval.c: Expression evaluation. */ diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index a7dc6b205d..8905317f15 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.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 #include diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index d74913a481..e32f893faa 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. diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index ec6c86ac64..91bb61323f 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.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/eval/typval.h" #include "nvim/eval/executor.h" #include "nvim/eval.h" diff --git a/src/nvim/eval/gc.c b/src/nvim/eval/gc.c index 5ce52ddd70..2bbf78d827 100644 --- a/src/nvim/eval/gc.c +++ b/src/nvim/eval/gc.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/eval/typval.h" #include "nvim/eval/gc.h" diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 70ec3dfe39..a57dd42f6e 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.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 #include #include diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index f5a41d151b..3116adbde8 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 #include diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 0e1775d01b..6963978581 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 #include diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 79b4dd9458..a17bae31e3 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. // diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 4429a65f92..ffda10a494 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 #include diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 2737dad305..854af474b2 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 #include #include 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 #include "nvim/event/loop.h" diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 8f9327f3d4..e536d79a2a 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 #include diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 26083c20f4..860a957b3e 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.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 #include #include 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 #include diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index fc7aad8eb9..f453e5898d 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 #include #include diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 9a847a4c0a..117ef6a507 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 */ diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index eeace789b2..a1a32d9f52 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 diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 17b3b512ef..7568d71ac0 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. */ diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 65112c4dd8..5d664b94a8 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.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 + // TODO(ZyX-I): move to eval/executor /// @file ex_eval.c diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 0b6036ace9..1affdb2fe7 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. */ diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c index 2d37d1284e..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 diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index db745bdd15..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: diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 74fa5aa1de..3e062aecc0 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 */ diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 34db4d2171..2aa9a9cb5e 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 /* 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/getchar.c b/src/nvim/getchar.c index e056ff488c..9d32df5a68 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 * diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index b2cbe30a43..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 */ diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 354c9718ba..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. diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index b647b8146a..e1c7df9175 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 * Ported to Win32 by Sergey Khorev diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 8fbad38495..5471b41b2c 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 #include #include diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 8f5547544d..4806f46705 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 #include #include diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 72b0d0aa40..0fe2ffe6f2 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 #include #include diff --git a/src/nvim/log.c b/src/nvim/log.c index bbb4dfb944..d059e28d5d 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.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 #include #include diff --git a/src/nvim/main.c b/src/nvim/main.c index 7ad42d6776..1095d4d3b5 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + #define EXTERN #include #include diff --git a/src/nvim/map.c b/src/nvim/map.c index 73af487f90..54a9e559af 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 #include #include diff --git a/src/nvim/mark.c b/src/nvim/mark.c index ae94ec7ecd..675fe4d57f 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 */ diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index b18459a2b5..b21ec944c1 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 /// diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 5d6639c4d0..efaf1f94c5 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. /// diff --git a/src/nvim/memline.c b/src/nvim/memline.c index b31ca136dd..40a6761225 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) diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 85ec916ba0..0ee4776581 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 diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 529978e3f0..4e621b49c1 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 diff --git a/src/nvim/message.c b/src/nvim/message.c index 42e1fd1cf9..146937c25a 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 */ diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 8d93505be3..6de74fddf2 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 */ diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 2ebe199f47..6088488388 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 #include "nvim/mouse.h" diff --git a/src/nvim/move.c b/src/nvim/move.c index 4feabf624b..d5be4cb8c3 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. * diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 259dcc523c..b2c6ef852c 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 #include #include diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 4d8a9984e1..967ce31c1b 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 #include #include diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index d7c2926a0f..b6958088ca 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 #include #include diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 7f087dcd20..51da9429b6 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 diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6ea3a45049..c77781b1d1 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 diff --git a/src/nvim/option.c b/src/nvim/option.c index 0070a0056d..bade4af8e3 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.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 + // 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. 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 diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index f3187de182..72bd0bf788 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.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 + // Environment inspection #include diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 27eb448c3d..4309ac723c 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 diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index c33e1140e8..c39ff5d358 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 #include diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 5f0f2ec677..80457eaa14 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 #include #include 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 diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index 71a5e13de5..eb9335b03c 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 #include diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 29c0431521..fc8ab7dc8f 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 #include #include 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 #include 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 #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 #include #include 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 diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index acd86f06dc..c5a42204be 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, ...) * diff --git a/src/nvim/path.c b/src/nvim/path.c index 205fc2ed62..12952f49db 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 #include #include diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 6346951c05..6e81c5a171 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) 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 #include #include diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 1241841885..112498ae20 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 */ 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 #include #include diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 7be89c2d7e..7a00ee27bb 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() * diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 506e6277e9..139772d51e 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. * diff --git a/src/nvim/screen.c b/src/nvim/screen.c index a8993be4e5..818c2c577d 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 * diff --git a/src/nvim/search.c b/src/nvim/search.c index 91a558045f..c662e3ba40 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 */ diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c index c72dafd08e..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 diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 8c5d6dff65..a6d8cb6563 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 #include #include diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 17016be35f..25ae562e65 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.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 + // spell.c: code for spell checking // // See spellfile.c for the Vim spell file format. diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 1da71dc4f9..d34d69b3a4 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.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 + // spellfile.c: code for reading and writing spell files. // // See spell.c for information about spell checking. diff --git a/src/nvim/state.c b/src/nvim/state.c index 44c6441e40..210708c3f4 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.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 #include "nvim/lib/kvec.h" diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 8a1a3beddd..743b43c2e5 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.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 #include #include diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index d5ff3707e8..ce48547163 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 */ diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 0c7244cbb3..b8b86bf979 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 */ diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 85c4950b42..19b9bdc19f 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.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 + // VT220/xterm-like terminal emulator. // Powered by libvterm http://www.leonerd.org.uk/code/libvterm // diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c index 0fa1e14c40..3c8f108255 100644 --- a/src/nvim/testdir/samples/memfile_test.c +++ b/src/nvim/testdir/samples/memfile_test.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 + /* vi:set ts=8 sts=4 sw=4 noet: * * VIM - Vi IMproved by Bram Moolenaar diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 8e5adb14f9..3f2ccd4746 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" diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index f34f5f1bc4..941fdb2570 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 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 #include #include diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 28f71b7ef2..cfa186987c 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 #include #include diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 9f780663ac..2c70b46c14 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. diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 571ad7204f..290d5d7553 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 * diff --git a/src/nvim/version.c b/src/nvim/version.c index 9a5d7ce169..29ce741ba0 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. diff --git a/src/nvim/window.c b/src/nvim/window.c index 6020159af9..60bba19b07 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 #include #include -- cgit From d194380de93023c8901eb77b2820b0f74e8a5283 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 16 Apr 2017 17:42:41 +0200 Subject: vim-patch:e4a3bcf28d92 Updated runtime files. Add Scala files. https://github.com/vim/vim/commit/e4a3bcf28d92d0bde9ca227ccb40d401038185e5 --- src/nvim/po/fi.po | 7869 +++++++++++++++++++++++++---------------------------- 1 file changed, 3774 insertions(+), 4095 deletions(-) (limited to 'src') diff --git a/src/nvim/po/fi.po b/src/nvim/po/fi.po index d30faeb554..d817144151 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 +# 2007-2016, Flammie Pirinen # -# Vimin kyttjt on nrttej. Sanasto on jargonia :-p -# -# Lhinn latin-1:t, sill vim pit portata ilmeisen obskuureille -# alustoille. Mys: pluralit puuttuu, ohjelman kyttliittymn fontti -# tasavlinen, 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 nkymst: 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 \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 \n" "Language-Team: Finnish \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 perss" +#~ 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 \"%s\" doesn't exist" +#~ 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: Mitn 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, kytetn 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 % does not exist" -msgstr "E86: Puskuria % 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: Ensimmisen 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 % (add ! to override)" msgstr "" -"E89: Puskurin % 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 % not found" -msgstr "E92: Puskuria % ei lydy" +#, fuzzy, c-format +#~ msgid "E92: Buffer % 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 tsm 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 tsm yhteenkn puskuriin" +msgstr "E94: %s ei täsmää yhteenkään puskuriin" -#: ../buffer.c:2161 -#, c-format -msgid "line %" -msgstr "rivi %" +#, fuzzy, c-format +#~ msgid "line %" +#~ 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 "% lines --%d%%--" -msgstr "% rivi --%d %%--" +#, fuzzy, c-format +#~ msgid "% lines --%d%%--" +#~ msgstr "%ld riviä --%d %%--" -#: ../buffer.c:2530 -#, c-format -msgid "line % of % --%d%%-- col " -msgstr "rivi %/% --%d %%-- sarake " +#, fuzzy, c-format +#~ msgid "line % of % --%d%%-- col " +#~ msgstr "rivi %ld/%ld --%d %%-- sarake " -#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554 msgid "[No Name]" -msgstr "[Nimetn]" +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=% id=%d name=%s" -msgstr " rivi=% id=%d nimi=%s" +#, fuzzy, c-format +#~ msgid " line=% 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 % buffers" -msgstr "E96: Ei voi diffata enemp kuin % puskuria" +#, fuzzy, c-format +#~ msgid "E96: Cannot diff more than % 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 vliaikaistiedostoja" +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: Tm 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: Yksikn 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: Yksikn 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, kytettvn 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 lydy" +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 kytt digraafissa" +msgstr "E104: Escapea ei voi käyttää digraafissa" -#: ../digraph.c:1760 msgid "E544: Keymap file not found" -msgstr "E544: Nppinkarttaa ei lydy" +msgstr "E544: Näppäinkarttaa ei löydy" -#: ../digraph.c:1785 msgid "E105: Using :loadkeymap not in a sourced file" -msgstr "E105: Kytetn :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 " Avainsanatydennys (^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 " Tysrivitydennys (^L^N^P)" +msgstr " Täysrivitäydennys (^L^N^P)" -#: ../edit.c:86 msgid " File name completion (^F^N^P)" -msgstr " Tiedostonimitydennys (^F^N^P)" +msgstr " Tiedostonimitäydennys (^F^N^P)" -#: ../edit.c:87 msgid " Tag completion (^]^N^P)" -msgstr " Tgitydennys (^]^N^P)" +msgstr " Tägitäydennys (^]^N^P)" -#: ../edit.c:88 msgid " Path pattern completion (^N^P)" -msgstr " Polkukuviotydennys (^N^P)" +msgstr " Polkukuviotäydennys (^N^P)" -#: ../edit.c:89 msgid " Definition completion (^D^N^P)" -msgstr " Mritelmtydennys (^D^N^P)" +msgstr " Määritelmätäydennys (^D^N^P)" -#: ../edit.c:91 msgid " Dictionary completion (^K^N^P)" -msgstr " Sanakirjatydennys (^K^N^P)" +msgstr " Sanakirjatäydennys (^K^N^P)" -#: ../edit.c:92 msgid " Thesaurus completion (^T^N^P)" -msgstr " Thesaurus-tydennys (^T^N^P)" +msgstr " Thesaurus-täydennys (^T^N^P)" -#: ../edit.c:93 msgid " Command-line completion (^V^N^P)" -msgstr " Komentorivitydennys (^V^N^P)" +msgstr " Komentorivitäydennys (^V^N^P)" -#: ../edit.c:94 msgid " User defined completion (^U^N^P)" -msgstr " Kyttjn mrittelem tydennys (^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 " Omnitydennys (^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 tydennys (^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 " (sytt) 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 tgej." +msgstr "Luetaan tägejä." -#: ../edit.c:4519 msgid " Adding" -msgstr " Listn" +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 lhtpisteess" +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 tsmys" +msgstr "Ainoa täsmäys" -#: ../edit.c:4680 #, c-format msgid "match %d of %d" -msgstr "tsmys %d/%d" +msgstr "täsmäys %d/%d" -#: ../edit.c:4684 #, c-format msgid "match %d" -msgstr "tsmys %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: %" -msgstr "E684: Indeksi % luettelon rajojen ulkopuolella" - -#: ../eval.c:139 -#, c-format -msgid "E121: Undefined variable: %s" -msgstr "E121: Mrittelemtn muuttuja: %s" +msgstr "E18: Odottamattomia merkkejä komennossa :let" -#: ../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" +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" - -#: ../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 kytt merkint [:]" - -#: ../eval.c:154 -#, c-format -msgid "E734: Wrong variable type for %s=" -msgstr "E734: Vr muuttujatyyppi muuttujalle %s=" +msgstr "E719: Sanakirjassa ei voi käyttää merkintää [:]" -#: ../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 ky 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 vhemmn 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 enemmn 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 enemmn 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 ksittelyyn" +#. 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 jlkeen 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 kytt '%':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 syvlle nytettvksi" +#, 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: Vri 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 not in a script context: %s" msgstr "E120: 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 sytttilassa" +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 kytt" +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 jlkeen" +msgstr "E727: Alku on lopun jälkeen" -#: ../eval.c:12024 ../eval.c:15297 msgid "" -msgstr "" +msgstr "" -#: ../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: Vliaikaistiedostoon 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 ky 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 ky 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 ky 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 ky 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 ky 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 ky 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 ky 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 tsm: %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 syvlle 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" - -#: ../eval.c:17312 -#, c-format -msgid "E125: Illegal argument: %s" -msgstr "E125: Virheellinen argumentti: %s" +msgstr "E862: g: ei toimi täällä" -#: ../eval.c:17323 #, fuzzy, c-format -msgid "E853: Duplicate argument name: %s" -msgstr "Kaksoiskappale kentn 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 mritell uudestaan, koska se on kytss" +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 sislt 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 sislt 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 enemmn 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 #%" -msgstr "%s palaa kohdassa #%" +#, fuzzy, c-format +#~ msgid "%s returning #%" +#~ 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 sisll" - -#: ../eval.c:19159 -msgid "" -"\n" -"# global variables:\n" -msgstr "" -"\n" -"# globaalit muuttujat:\n" +msgstr "E133: :return ei ole funktion sisällä" -#: ../eval.c:19254 msgid "" "\n" "\tLast set from " @@ -1045,964 +1091,1005 @@ 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 "" -#: ../ex_cmds.c:146 -#, c-format -msgid "> %d, Hex %08x, Octal %o" -msgstr "> %d, hekdana %08x, oktaalina %o" +#, fuzzy, c-format +#~ msgid "E474: Expected string key: %s" +#~ msgstr "E415: odotuksenvastainen =-merkki: %s" -#: ../ex_cmds.c:684 -msgid "E134: Move lines into themselves" -msgstr "E134: Rivien siirto itsejens plle" +#, fuzzy, c-format +#~ msgid "E474: Expected comma before dictionary key: %s" +#~ msgstr "E722: Sanakirjasta puuttuu pilkku: %s" -#: ../ex_cmds.c:747 -msgid "1 line moved" -msgstr "1 rivi siirretty" +#, fuzzy, c-format +#~ msgid "E474: Unfinished escape sequence: %.*s" +#~ msgstr "E540: Sulkematon lausekesarja" -#: ../ex_cmds.c:749 #, c-format -msgid "% lines moved" -msgstr "% rivi siirretty" +#~ msgid "E474: Unfinished unicode escape sequence: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:1175 #, c-format -msgid "% lines filtered" -msgstr "% rivi suodatettu" - -#: ../ex_cmds.c:1194 -msgid "E135: *Filter* Autocommands must not change current buffer" -msgstr "E135: *Filter*-autocommand ei voi vaihtaa puskuria" +#~ msgid "E474: Expected four hex digits after \\u: %.*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: Unknown escape sequence: %.*s" +#~ msgstr "E409: Tuntematon ryhmän nimi: %s" -#: ../ex_cmds.c:1424 #, c-format -msgid "%sviminfo: %s in line: " -msgstr "%sviminfo: %s rivill: " - -#: ../ex_cmds.c:1431 -msgid "E136: viminfo: Too many errors, skipping rest of file" -msgstr "E136: viminfo: liikaa virheit, ohitetaan lopputiedosto" +#~ msgid "E474: ASCII control characters cannot be present inside string: %.*s" +#~ 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: Only UTF-8 strings allowed: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:1460 -msgid " info" -msgstr " info" +#, c-format +#~ msgid "" +#~ "E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: " +#~ "%.*s" +#~ msgstr "" -#: ../ex_cmds.c:1461 -msgid " marks" -msgstr " merkit" +#, fuzzy, c-format +#~ msgid "E474: Expected string end: %.*s" +#~ msgstr "E415: odotuksenvastainen =-merkki: %s" -#: ../ex_cmds.c:1462 -msgid " oldfiles" -msgstr " vanhaatiedostoa" +#, fuzzy, c-format +#~ msgid "E474: Leading zeroes are not allowed: %.*s" +#~ msgstr "E786: Aluetta ei voi käyttää" -#: ../ex_cmds.c:1463 -msgid " FAILED" -msgstr " EPONNISTUI" +#, fuzzy, c-format +#~ msgid "E474: Missing number after minus sign: %.*s" +#~ msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen" -#. 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" +#, fuzzy, c-format +#~ msgid "E474: Missing number after decimal dot: %.*s" +#~ msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen" -#: ../ex_cmds.c:1626 -#, c-format -msgid "E138: Can't write viminfo file %s!" -msgstr "E138: Viminfo-tiedoston kirjoittaminen ei onnistu %s" +#, fuzzy, c-format +#~ msgid "E474: Missing exponent: %.*s" +#~ msgstr "E114: Puuttuva lainausmerkki: %s" -#: ../ex_cmds.c:1635 #, c-format -msgid "Writing viminfo file \"%s\"" -msgstr "Kirjoitetaan viminfo-tiedostoa %s" +#~ msgid "" +#~ "E685: internal error: while converting number \"%.*s\" to float string2float " +#~ "consumed %zu bytes in place of %zu" +#~ msgstr "" -#. 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 "" +#~ "E685: internal error: while converting number \"%.*s\" to integer vim_str2nr " +#~ "consumed %i bytes in place of %zu" +#~ msgstr "" -#: ../ex_cmds.c:1722 -msgid "" -"# You may edit it if you're careful!\n" -"\n" -msgstr "" -"# Muokkaa varovasti!\n" -"\n" +#~ msgid "E474: Attempt to decode a blank string" +#~ msgstr "" -#: ../ex_cmds.c:1723 -msgid "# Value of 'encoding' when this file was written\n" -msgstr "# encoding-muuttujan arvo tiedostoa kirjoitettaessa\n" +#, c-format +#~ msgid "E474: No container to close: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:1800 -msgid "Illegal starting char" -msgstr "Virheellinen aloitusmerkki" +#, c-format +#~ msgid "E474: Closing list with curly bracket: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:2162 -msgid "Write partial file?" -msgstr "Kirjoita osittainen tiedosto" +#, fuzzy, c-format +#~ msgid "E474: Closing dictionary with square bracket: %.*s" +#~ msgstr "E725: dict-funktio ilman sanakirjaa: %s" -#: ../ex_cmds.c:2166 -msgid "E140: Use ! to write partial buffer" -msgstr "E140: Kyt !-komentoa osittaisen puskurin kirjoittamiseen" +#, fuzzy, c-format +#~ msgid "E474: Trailing comma: %.*s" +#~ msgstr "E488: Ylimääräisiä merkkejä perässä" -#: ../ex_cmds.c:2281 #, c-format -msgid "Overwrite existing file \"%s\"?" -msgstr "Ylikirjoitetaanko olemassaoleva tiedosto %s?" +#~ msgid "E474: Expected value after colon: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:2317 -#, c-format -msgid "Swap file \"%s\" exists, overwrite anyway?" -msgstr "Swap-tiedosto %s on olemassa, ylikirjoitetaanko?" +#, fuzzy, c-format +#~ msgid "E474: Expected value: %.*s" +#~ msgstr "E415: odotuksenvastainen =-merkki: %s" -#: ../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)" +#~ msgid "E474: Comma not inside container: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:2381 -#, c-format -msgid "E141: No file name for buffer %" -msgstr "E141: Ei tiedostonime puskurille %" +#, fuzzy, c-format +#~ msgid "E474: Duplicate comma: %.*s" +#~ msgstr "E721: Kaksi samaa avainta sanakirjassa: %s" -#: ../ex_cmds.c:2412 -msgid "E142: File not written: Writing is disabled by 'write' option" -msgstr "" -"E142: Tiedostoa ei kirjoitettu; write-asetus poistaa kirjoituksen kytst" +#, fuzzy, c-format +#~ msgid "E474: Comma after colon: %.*s" +#~ msgstr "E254: Väriä %s ei voi määritellä" -#: ../ex_cmds.c:2434 -#, c-format -msgid "" -"'readonly' option is set for \"%s\".\n" -"Do you wish to write anyway?" -msgstr "" -"readonly asetettu tiedostolle \"%s\".\n" -"Kirjoitetaanko?" +#, fuzzy, c-format +#~ msgid "E474: Using comma in place of colon: %.*s" +#~ msgstr "E722: Sanakirjasta puuttuu pilkku: %s" -#: ../ex_cmds.c:2439 #, c-format -msgid "" -"File permissions of \"%s\" are read-only.\n" -"It may still be possible to write it.\n" -"Do you wish to try?" -msgstr "" -"Tiedosto %s on kirjoitussuojattu.\n" -"Siihen saattaa voida silti kirjoittaa.\n" -"Yritetnk?" +#~ msgid "E474: Leading comma: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:2451 #, c-format -msgid "E505: \"%s\" is read-only (add ! to override)" -msgstr "E505: %s on kirjoitussuojattu (lis komentoon ! ohittaaksesi)" +#~ 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" -#: ../ex_cmds.c:3120 #, c-format -msgid "E143: Autocommands unexpectedly deleted new buffer %s" -msgstr "E143: Autocommand poisti uuden puskurin odotuksen vastaisesti %s" +#~ msgid "E474: Colon after comma: %.*s" +#~ msgstr "" -#: ../ex_cmds.c:3313 -msgid "E144: non-numeric argument to :z" -msgstr "E144: :z:n argumentti ei ole numero" +#, fuzzy, c-format +#~ msgid "E474: Duplicate colon: %.*s" +#~ msgstr "E721: Kaksi samaa avainta sanakirjassa: %s" -#: ../ex_cmds.c:3404 -msgid "E145: Shell commands not allowed in rvim" -msgstr "E145: Kuoren komennot eivt toimi rvimiss" +#, fuzzy, c-format +#~ msgid "E474: Expected null: %.*s" +#~ msgstr "E415: odotuksenvastainen =-merkki: %s" -#: ../ex_cmds.c:3498 -msgid "E146: Regular expressions can't be delimited by letters" -msgstr "E146: Snnllist ilmausta ei voi rajata kirjaimilla" +#, fuzzy, c-format +#~ msgid "E474: Expected true: %.*s" +#~ msgstr "E270: odotuksenvastainen redo" -#: ../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)?" +#, fuzzy, c-format +#~ msgid "E474: Expected false: %.*s" +#~ msgstr "E415: odotuksenvastainen =-merkki: %s" -#: ../ex_cmds.c:4379 -msgid "(Interrupted) " -msgstr "(Keskeytetty)" +#, fuzzy, c-format +#~ msgid "E474: Unidentified byte: %.*s" +#~ msgstr "E121: Määrittelemätön muuttuja: %s" -#: ../ex_cmds.c:4384 -msgid "1 match" -msgstr "1 tsmys" +#, fuzzy, c-format +#~ msgid "E474: Trailing characters: %.*s" +#~ msgstr "E488: Ylimääräisiä merkkejä perässä" -#: ../ex_cmds.c:4384 -msgid "1 substitution" -msgstr "1 korvaus" +#, fuzzy, c-format +#~ msgid "E474: Unexpected end of input: %.*s" +#~ msgstr "E415: odotuksenvastainen =-merkki: %s" -#: ../ex_cmds.c:4387 #, c-format -msgid "% matches" -msgstr "% tsmyst" +#~ msgid "key %s" +#~ msgstr "" -#: ../ex_cmds.c:4388 #, c-format -msgid "% substitutions" -msgstr "% korvausta" - -#: ../ex_cmds.c:4392 -msgid " on 1 line" -msgstr " 1 rivill" +#~ msgid "key %s at index %i from special map" +#~ msgstr "" -#: ../ex_cmds.c:4395 #, c-format -msgid " on % lines" -msgstr " % 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: Snnllinen ilmaus puuttuu globaalista" +#~ msgid "index %i" +#~ msgstr "" -#: ../ex_cmds.c:4508 -#, c-format -msgid "Pattern found in every line: %s" -msgstr "Kuvio lytyi joka rivilt: %s" +#~ msgid "partial" +#~ msgstr "" -#: ../ex_cmds.c:4510 #, fuzzy, c-format -msgid "Pattern not found: %s" -msgstr "Kuviota ei lydy" +#~ msgid "argument %i" +#~ msgstr "-c-argumentti" -#: ../ex_cmds.c:4587 -msgid "" -"\n" -"# Last Substitute String:\n" -"$" -msgstr "" -"\n" -"# Viimeisin korvausmerkkijono:\n" -"$" +#, fuzzy +#~ msgid "partial self dictionary" +#~ msgstr "ei voida muuttaa kiinnitettyä sanakirjaa" -#: ../ex_cmds.c:4679 -msgid "E478: Don't panic!" -msgstr "E478: l panikoi." +#~ msgid "itself" +#~ msgstr "" -#: ../ex_cmds.c:4717 -#, c-format -msgid "E661: Sorry, no '%s' help for %s" -msgstr "E661: Sori, ei lydy %s-ohjetta kohteelle %s" +#. 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 "" -#: ../ex_cmds.c:4719 -#, c-format -msgid "E149: Sorry, no help for %s" -msgstr "E149: Sori, ei lydy ohjetta kohteelle %s" +#~ msgid "E474: Unable to represent NaN value in JSON" +#~ msgstr "" -#: ../ex_cmds.c:4751 -#, c-format -msgid "Sorry, help file \"%s\" not found" -msgstr "Sori, ohjetiedostoa %s ei lydy" +#~ msgid "E474: Unable to represent infinity in JSON" +#~ msgstr "" -#: ../ex_cmds.c:5323 #, c-format -msgid "E150: Not a directory: %s" -msgstr "E150: Ei ole hakemisto: %s" +#~ msgid "" +#~ "E474: String \"%.*s\" contains byte that does not start any UTF-8 character" +#~ msgstr "" -#: ../ex_cmds.c:5446 #, c-format -msgid "E152: Cannot open %s for writing" -msgstr "E152: Ei voi avata tiedostoa %s kirjoittamista varten" +#~ msgid "" +#~ "E474: UTF-8 string contains code point which belongs to a surrogate pair: " +#~ "%.*s" +#~ msgstr "" -#: ../ex_cmds.c:5471 -#, c-format -msgid "E153: Unable to open %s for reading" -msgstr "E153: Ei voi avata tiedostoa %s lukemista varten" +#, fuzzy +#~ msgid "E474: Unable to convert EXT string to JSON" +#~ msgstr "E620: Tulostuskoodaukseen %s muunto ei onnistu" -#: ../ex_cmds.c:5500 #, c-format -msgid "E670: Mix of help file encodings within a language: %s" -msgstr "E670: Monia ohjetiedostokoodauksia kieless: %s" +#~ 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" -#: ../ex_cmds.c:5565 #, c-format -msgid "E154: Duplicate tag \"%s\" in file %s/%s" -msgstr "E154: Kaksoiskappale tgist %s tiedostossa %s/%s" +#~ msgid "E5004: Error while dumping %s, %s: attempt to dump function reference" +#~ msgstr "" -#: ../ex_cmds.c:5687 #, c-format -msgid "E160: Unknown sign command: %s" -msgstr "E160: Tuntematon merkkikomento: %s" +#~ msgid "E5005: Unable to dump %s: container references itself in %s" +#~ msgstr "" -#: ../ex_cmds.c:5704 -msgid "E156: Missing sign name" -msgstr "E156: Merkki puuttuu" +#, fuzzy, c-format +#~ msgid "E684: list index out of range: %" +#~ msgstr "E684: Indeksi %ld luettelon rajojen ulkopuolella" -#: ../ex_cmds.c:5746 -msgid "E612: Too many signs defined" -msgstr "E612: Liikaa merkkej mritelty" +#~ msgid "E6000: Argument is not a function or function name" +#~ msgstr "" -#: ../ex_cmds.c:5813 #, c-format -msgid "E239: Invalid sign text: %s" -msgstr "E239: Virheellinen merkkiteksti: %s" +msgid "E737: Key already exists: %s" +msgstr "E737: Avain on jo olemassa: %s" -#: ../ex_cmds.c:5844 ../ex_cmds.c:6035 -#, c-format -msgid "E155: Unknown sign: %s" -msgstr "E155: Tuntematon merkki: %s" +#, fuzzy +#~ msgid "tv_clear() argument" +#~ msgstr "filter()-argumentti" -#: ../ex_cmds.c:5877 -msgid "E159: Missing sign number" -msgstr "E159: Merkin numero puuttuu" +msgid "E743: variable nested too deep for (un)lock" +msgstr "E743: muuttujassa liian monta tasoa lukituksen käsittelyyn" -#: ../ex_cmds.c:5971 -#, c-format -msgid "E158: Invalid buffer name: %s" -msgstr "E158: Virheellinen puskurin nimi: %s" +#, fuzzy, c-format +#~ msgid "E741: Value is locked: %.*s" +#~ msgstr "E741: Arvo on lukittu: %s" -#: ../ex_cmds.c:6008 -#, c-format -msgid "E157: Invalid sign ID: %" -msgstr "E157: Virheellinen merkin tunnus: %" +#, fuzzy, c-format +#~ msgid "E742: Cannot change value of %.*s" +#~ msgstr "E742: Ei voi muuttaa muuttujan %s arvoa" -#: ../ex_cmds.c:6066 -msgid " (not supported)" -msgstr " (ei tuettu)" +msgid "Unknown" +msgstr "Tuntematon" -#: ../ex_cmds.c:6169 -msgid "[Deleted]" -msgstr "[Poistettu]" +#, fuzzy +#~ msgid "E805: Expected a Number or a String, Float found" +#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle" -#: ../ex_cmds2.c:139 -msgid "Entering Debug mode. Type \"cont\" to continue." -msgstr "Siirrytn vianetsinttilaan, kirjoita cont jatkaaksesi." +#~ msgid "E703: Expected a Number or a String, Funcref found" +#~ msgstr "" -#: ../ex_cmds2.c:143 ../ex_docmd.c:759 -#, c-format -msgid "line %: %s" -msgstr "rivi %: %s" +#, fuzzy +#~ msgid "E745: Expected a Number or a String, List found" +#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle" -#: ../ex_cmds2.c:145 -#, c-format -msgid "cmd: %s" -msgstr "kmnt: %s" +#~ 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 "% 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 "% 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" + +msgid "Write partial file?" +msgstr "Kirjoita osittainen tiedosto" + +msgid "E140: Use ! to write partial buffer" +msgstr "E140: Käytä !-komentoa osittaisen puskurin kirjoittamiseen" + +#, c-format +msgid "Overwrite existing file \"%s\"?" +msgstr "Ylikirjoitetaanko olemassaoleva tiedosto %s?" + +#, c-format +msgid "Swap file \"%s\" exists, overwrite anyway?" +msgstr "Swap-tiedosto %s on olemassa, ylikirjoitetaanko?" + +#, c-format +msgid "E768: Swap file exists: %s (:silent! overrides)" +msgstr "E768: Swap-tiedosto on jo olemassa: %s (komento :silent! ohittaa)" + +#, fuzzy, c-format +#~ msgid "E141: No file name for buffer %" +#~ msgstr "E141: Ei tiedostonimeä puskurille %ld" + +msgid "E142: File not written: Writing is disabled by 'write' option" +msgstr "" +"E142: Tiedostoa ei kirjoitettu; write-asetus poistaa kirjoituksen käytöstä" + +#, c-format +msgid "" +"'readonly' option is set for \"%s\".\n" +"Do you wish to write anyway?" +msgstr "" +"readonly asetettu tiedostolle \"%s\".\n" +"Kirjoitetaanko?" + +#, c-format +msgid "" +"File permissions of \"%s\" are read-only.\n" +"It may still be possible to write it.\n" +"Do you wish to try?" +msgstr "" +"Tiedosto %s on kirjoitussuojattu.\n" +"Siihen saattaa voida silti kirjoittaa.\n" +"Yritetäänkö?" + +#, c-format +msgid "E505: \"%s\" is read-only (add ! to override)" +msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)" + +#, c-format +msgid "E143: Autocommands unexpectedly deleted new buffer %s" +msgstr "E143: Autocommand poisti uuden puskurin odotuksen vastaisesti %s" + +msgid "E144: non-numeric argument to :z" +msgstr "E144: :z:n argumentti ei ole numero" + +#, fuzzy +#~ msgid "E145: Shell commands not allowed in restricted mode" +#~ msgstr "E145: Kuoren komennot eivät toimi rvimissä" + +msgid "E146: Regular expressions can't be delimited by letters" +msgstr "E146: Säännöllistä ilmausta ei voi rajata kirjaimilla" + +#, c-format +msgid "replace with %s (y/n/a/q/l/^E/^Y)?" +msgstr "korvaa kohteella %s (y/n/a/q/l/^E/^Y)?" + +msgid "(Interrupted) " +msgstr "(Keskeytetty)" + +msgid "1 match" +msgstr "1 täsmäys" + +msgid "1 substitution" +msgstr "1 korvaus" + +#, fuzzy, c-format +#~ msgid "% matches" +#~ msgstr "%ld täsmäystä" + +#, fuzzy, c-format +#~ msgid "% substitutions" +#~ msgstr "%ld korvausta" + +msgid " on 1 line" +msgstr " 1 rivillä" + +#, fuzzy, c-format +#~ msgid " on % lines" +#~ msgstr " %ld rivillä" + +msgid "E147: Cannot do :global recursive" +msgstr "E147: :globalia ei voi suorittaa rekursiivisesti" + +msgid "E148: Regular expression missing from global" +msgstr "E148: Säännöllinen ilmaus puuttuu globaalista" + +#, c-format +msgid "Pattern found in every line: %s" +msgstr "Kuvio löytyi joka riviltä: %s" + +#, c-format +msgid "Pattern not found: %s" +msgstr "Kuviota ei löydy: %s" + +msgid "E478: Don't panic!" +msgstr "E478: Älä panikoi." + +#, c-format +msgid "E661: Sorry, no '%s' help for %s" +msgstr "E661: ei löydy %s-ohjetta kohteelle %s" + +#, c-format +msgid "E149: Sorry, no help for %s" +msgstr "E149: ei löydy ohjetta kohteelle %s" + +#, c-format +msgid "Sorry, help file \"%s\" not found" +msgstr "ohjetiedostoa %s ei löydy" + +#, c-format +msgid "E152: Cannot open %s for writing" +msgstr "E152: Ei voi avata tiedostoa %s kirjoittamista varten" + +#, c-format +msgid "E153: Unable to open %s for reading" +msgstr "E153: Ei voi avata tiedostoa %s lukemista varten" + +#, c-format +msgid "E670: Mix of help file encodings within a language: %s" +msgstr "E670: Monia ohjetiedostokoodauksia kielessä: %s" + +#, c-format +msgid "E154: Duplicate tag \"%s\" in file %s/%s" +msgstr "E154: Kaksoiskappale tägistä %s tiedostossa %s/%s" + +#, c-format +msgid "E150: Not a directory: %s" +msgstr "E150: Ei ole hakemisto: %s" + +#, c-format +msgid "E160: Unknown sign command: %s" +msgstr "E160: Tuntematon merkkikomento: %s" + +msgid "E156: Missing sign name" +msgstr "E156: Merkki puuttuu" + +msgid "E612: Too many signs defined" +msgstr "E612: Liikaa merkkejä määritelty" + +#, c-format +msgid "E239: Invalid sign text: %s" +msgstr "E239: Virheellinen merkkiteksti: %s" + +#, c-format +msgid "E155: Unknown sign: %s" +msgstr "E155: Tuntematon merkki: %s" + +msgid "E159: Missing sign number" +msgstr "E159: Merkin numero puuttuu" + +#, c-format +msgid "E158: Invalid buffer name: %s" +msgstr "E158: Virheellinen puskurin nimi: %s" + +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: %" +#~ msgstr "E157: Virheellinen merkin tunnus: %ld" + +#, c-format +msgid "E885: Not possible to change sign %s" +msgstr "E885: Ei voida muuttaa merkkiä %s" + +msgid " (not supported)" +msgstr " (ei tuettu)" + +msgid "[Deleted]" +msgstr "[Poistettu]" + +msgid "Entering Debug mode. Type \"cont\" to continue." +msgstr "Siirrytään vianetsintätilaan, kirjoita cont jatkaaksesi." + +#, fuzzy, c-format +#~ msgid "line %: %s" +#~ msgstr "rivi %ld: %s" + +#, c-format +msgid "cmd: %s" +msgstr "kmnt: %s" + +msgid "frame is zero" +msgstr "kehys on nolla" -#: ../ex_cmds2.c:322 #, c-format -msgid "Breakpoint in \"%s%s\" line %" -msgstr "Katkaisukohta %s%s rivill %" +msgid "frame at highest level: %d" +msgstr "kehys ylimmällä tasolla: %d" + +#, fuzzy, c-format +#~ msgid "Breakpoint in \"%s%s\" line %" +#~ 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 %" -msgstr "%3d %s %s rivi %" +#, fuzzy, c-format +#~ msgid "%3d %s %s line %" +#~ msgstr "%3d %s %s rivi %ld" -#: ../ex_cmds2.c:942 msgid "E750: First use \":profile start {fname}\"" -msgstr "E750: Aloita kskyll :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 "Nimetn" +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 jlkeen" +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: Ensimmisen 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: kntj ei tueta: %s" +msgstr "E666: kääntäjää ei tueta: %s" -#: ../ex_cmds2.c:2257 #, c-format msgid "Searching for \"%s\" in \"%s\"" -msgstr "Etsitn ilmausta %s kohteesta %s" +msgstr "Etsitään ilmausta %s kohteesta %s" -#: ../ex_cmds2.c:2284 #, c-format msgid "Searching for \"%s\"" -msgstr "Etsitn ilmausta %s" +msgstr "Etsitään ilmausta %s" -#: ../ex_cmds2.c:2307 #, c-format -msgid "not found in 'runtimepath': \"%s\"" -msgstr "ei lydy 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 %: could not source \"%s\"" -msgstr "rivi %: ei voitu ladata %s" +#, fuzzy, c-format +#~ msgid "line %: 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 %: sourcing \"%s\"" -msgstr "rivi %: ladataan %s" +#, fuzzy, c-format +#~ msgid "line %: 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 "ympristmuuttuja" +msgstr "ympäristömuuttuja" -#: ../ex_cmds2.c:2773 msgid "error handler" -msgstr "virheksittelin" +msgstr "virhekäsittelin" -#: ../ex_cmds2.c:3020 msgid "W15: Warning: Wrong line separator, ^M may be missing" -msgstr "W15: Varoitus: Vr 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 "Kytss 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 "Siirrytn 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: Kyttjn mrittelemn komennon monimerkityksinen kytt" +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 knt" +msgstr "Takaperoinen arvoalue annettu, OK kääntää" #. append #. typed wrong -#: ../ex_docmd.c:1787 msgid "E494: Use w or w>>" -msgstr "E494: Kyt w:t tai w>>:aa" - -#: ../ex_docmd.c:3454 -msgid "E319: The command is not available in this version" -msgstr "E319: Komento ei ole kytettviss tss 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: % more files to edit" -msgstr "E173: viel % tiedostoa muokattavana" +#, fuzzy, c-format +#~ msgid "E173: % 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, kyt !: 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 Mritelm" +" Nimi Argumentit Osoite Valmis Määritelmä" -#: ../ex_docmd.c:4516 msgid "No user-defined commands found" -msgstr "Ei kyttjn mrittelemi komentoja" +msgstr "Ei käyttäjän määrittelemiä komentoja" -#: ../ex_docmd.c:4538 msgid "E175: No attribute specified" -msgstr "E175: Ei attribuutteja mriteltyn" +msgstr "E175: Ei attribuutteja määriteltynä" -#: ../ex_docmd.c:4583 msgid "E176: Invalid number of arguments" -msgstr "E176: Vr mr attribuutteja" +msgstr "E176: Väärä määrä attribuutteja" -#: ../ex_docmd.c:4594 msgid "E177: Count cannot be specified twice" -msgstr "E177: Lukumr ei voi mritell kahdesti" +msgstr "E177: Lukumäärää ei voi määritellä kahdesti" -#: ../ex_docmd.c:4603 msgid "E178: Invalid default value for count" -msgstr "E178: Lukumrn oletusarvo on vr" +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: Kyttjn mrittelemn 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: Kyttjn mrittelemn komennon monimerkityksinen kytt" +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: Kyttjn 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 tydennysarvo: %s" +msgstr "E180: Virheellinen täydennysarvo: %s" -#: ../ex_docmd.c:5225 msgid "E468: Completion argument only allowed for custom completion" -msgstr "E468: Tydennysargumentti sopii vain itse mriteltyyn tydennykseen" +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 mritelty tydennys 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: Vriteemaa %s ei lydy" +msgstr "E185: Väriteemaa %s ei löydy" -#: ../ex_docmd.c:5263 msgid "Greetings, Vim user!" -msgstr "Tervehdys, Vimin kyttj." +msgstr "Tervehdys, Vimin käyttäjä." -#: ../ex_docmd.c:5431 msgid "E784: Cannot close last tab page" -msgstr "E784: Viimeist vlilehte ei voi sulkea" +msgstr "E784: Viimeistä välilehteä ei voi sulkea" -#: ../ex_docmd.c:5462 msgid "Already only one tab page" -msgstr "Vain yksi vlilehti jljell 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 tll 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 taaksepin 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 \"\"" msgstr "E495: ei autocommand-tiedostoa kohteelle " -#: ../ex_docmd.c:7850 msgid "E496: no autocommand buffer number to substitute for \"\"" msgstr "E496: ei autocommand-puskurinumeroa kohteelle " -#: ../ex_docmd.c:7861 msgid "E497: no autocommand match name to substitute for \"\"" -msgstr "E497: ei autocommand-tsmysnime kohteella " +msgstr "E497: ei autocommand-täsmäysnimeä kohteella " -#: ../ex_docmd.c:7870 msgid "E498: no :source file name to substitute for \"\"" -msgstr "E498: ei :source-tiedostonime kohteelle " +msgstr "E498: ei :source-tiedostonimeä kohteelle " -#: ../ex_docmd.c:7876 -#, fuzzy msgid "E842: no line number to use for \"\"" -msgstr "E498: ei :source-tiedostonime kohteelle " +msgstr "E842: ei rivinumeroa kohteelle " -#: ../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" +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" - -#: ../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 %" -msgstr "%s, rivi %" +#, fuzzy, c-format +#~ msgid "%s, line %" +#~ 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 jlkeen" +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 "tginimi" +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 "Syterivi" - -#: ../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 lydy 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 lydy 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 tekivt 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 eivt saa muuttaa puskuria" - -#: ../fileio.c:672 -msgid "Nvim: Reading from stdin...\n" -msgstr "Vim: Luetaan vakiosytteest...\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 ers 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 "[pitkt 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 %]" -msgstr "[MUUNNOSVIRHE rivill %]" +#, fuzzy, c-format +#~ msgid "[CONVERSION ERROR in line %]" +#~ msgstr "[MUUNNOSVIRHE rivillä %ld]" -#: ../fileio.c:1835 -#, c-format -msgid "[ILLEGAL BYTE in line %]" -msgstr "[VIRHEELLINEN OKTETTI rivill %]" +#, fuzzy, c-format +#~ msgid "[ILLEGAL BYTE in line %]" +#~ 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 lyt vliaikaistiedstoa muuntamiseksi" +msgstr "Ei voi löytää väliaikaistiedstoa muuntamiseksi" -#: ../fileio.c:2110 msgid "Conversion with 'charconvert' failed" -msgstr "Muunnos charconvert eponnistui" +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 mr 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 lyt vliaikaistiedostoa 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 eponnistui (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 % (make 'fenc' empty to " -"override)" -msgstr "" -"E513: kirjoitusvirhe, muunnos eponnistui rivill %(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 (tiedostojrjestelm tysi)" +msgstr "E514: kirjoitusvirhe (tiedostojärjestelmä täysi)" -#: ../fileio.c:3506 msgid " CONVERSION ERROR" msgstr " MUUNNOSVIRHE" -#: ../fileio.c:3509 -#, c-format -msgid " in line %;" -msgstr " rivill %" +#, fuzzy, c-format +#~ msgid " in line %;" +#~ 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 " listty" +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 alkuperistiedostoa" +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 alkuperistiedostoa" +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: Alkuperistiedosto voi hvit 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." - -#: ../fileio.c:3795 -msgid "[dos]" -msgstr "[dos]" +msgstr "älä lopeta editoria kesken tallentamisen." -#: ../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 "% lines, " -msgstr "% rivi, " +#, fuzzy, c-format +#~ msgid "% lines, " +#~ msgstr "%ld riviä, " -#: ../fileio.c:3836 msgid "1 character" msgstr "1 merkki" -#: ../fileio.c:3838 -#, c-format -msgid "% characters" -msgstr "% merkki" +#, fuzzy, c-format +#~ msgid "% 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 srkkii 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 jlkeen!" +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 listietoja." +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 jlkeen" +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 listietoja." +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 " -"jlkeen" +"jälkeen" -#: ../fileio.c:4915 msgid "See \":help W16\" for more info." -msgstr ":help W16 kertoo listietoja." +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 jlkeen" +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 " msgstr "poistetaan autocommand automaattisesti: %s " #. 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 jlkeen: %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: : invalid buffer number " msgstr "E680: : 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 tsmvi 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 tll 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 tll 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 merkinnlle %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 merkinnlle %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 lydy" +msgstr "Lyhennettä ei löydy" -#: ../getchar.c:3010 msgid "No mapping found" -msgstr "Kuvausta ei lydy" +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 jlkeen pit tulla /, ? tai &" +msgstr "E10: \\:n jälkeen pitää tulla /, ? tai &" -#: ../globals.h:1000 msgid "E11: Invalid in command-line window; executes, CTRL-C quits" msgstr "E11: Virheellinen komentorivi-ikkuna, 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 tss hakemistossa tai " -"tgihaussa" +"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 eponnistui" +msgstr "E472: Komento epäonnistui" -#: ../globals.h:1011 msgid "E473: Internal error" -msgstr "E473: Sisinen 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() eponnistui" +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 plt" +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 kytt, koska sit ei knnetty 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 sytetty 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 tsm" +msgstr "E479: Ei täsmää" -#: ../globals.h:1041 #, c-format msgid "E480: No match: %s" -msgstr "E480: Ei tsm: %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 snnlliselle 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 snnllist ilmausta" +msgstr "E35: Ei edellistä säännöllistä ilmausta" -#: ../globals.h:1047 msgid "E481: No range allowed" msgstr "E481: Arvoalue ei sallittu" -#: ../globals.h:1048 msgid "E36: Not enough room" -msgstr "E36: Tila ei riit" - -#: ../globals.h:1049 -#, c-format -msgid "E482: Can't create file %s" -msgstr "E482: Tiedostoa %s ei voi luoda" +msgstr "E36: Tila ei riitä" -#: ../globals.h:1050 msgid "E483: Can't get temp file name" -msgstr "E483: vliaikaistiedoston 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 jlkeen 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 lydy" +msgstr "Kuviota ei löydy" -#: ../globals.h:1061 #, c-format msgid "E486: Pattern not found: %s" -msgstr "E486: Kuviota ei lydy: %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 tsmysmerkkijono" +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 tll" +msgstr "E523: Ei sallittu täällä" -#: ../globals.h:1082 msgid "E359: Screen mode setting not supported" -msgstr "E359: Nytttila-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: tgipino 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: Ylimrisi merkkej perss" +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 not in a script context" msgstr "E81: skriptin ulkopuolella" -#: ../globals.h:1102 #, c-format msgid "E685: Internal error: %s" -msgstr "E685: Sisinen virhe: %s" +msgstr "E685: Sisäinen virhe: %s" -#: ../globals.h:1104 msgid "E363: pattern uses more memory than 'maxmempattern'" -msgstr "E363: kuvio kytt enemmn 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 % 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 psi ALKUUN, jatketaan LOPUSTA" +msgstr "haku pääsi ALKUUN, jatketaan LOPUSTA" -#: ../globals.h:1115 msgid "search hit BOTTOM, continuing at TOP" -msgstr "haku psi 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: pitisi 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 vr" +msgstr "E621: resurssitiedoston %s versio on väärä" -#: ../hardcopy.c:2225 msgid "E673: Incompatible multi-byte encoding and character set." -msgstr "E673: Tukematon monitvauinen merkistkoodaus 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 lydy" +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 lydy" +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 lydy" +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 "Lhetetn tulostimelle..." +msgstr "Lähetetään tulostimelle..." -#: ../hardcopy.c:2881 msgid "E365: Failed to print PostScript file" -msgstr "E365: PostScript-tiedoston tulostus eponnistui" +msgstr "E365: PostScript-tiedoston tulostus epäonnistui" -#: ../hardcopy.c:2883 msgid "Print job sent." -msgstr "Tulostusty lhetetty." +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 "Nyt tm 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 "Nyt yhteydet" +msgstr "Näytä yhteydet" -#: ../if_cscope.c:101 #, c-format msgid "E560: Usage: cs[cope] %s" -msgstr "E560: Kytt: 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 "Tm 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 " -msgstr "E562: Kytt: cstag " +msgstr "E562: Käyttö: cstag " -#: ../if_cscope.c:313 msgid "E257: cstag: tag not found" -msgstr "E257: cstag: tgia ei lydy" +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 "Listty cscope-tietokanta %s" +msgstr "Lisätty cscope-tietokanta %s" -#: ../if_cscope.c:616 -#, c-format -msgid "E262: error reading cscope connection %" -msgstr "E262: Virhe luettaessa cscope-yhteytt %" +#, fuzzy, c-format +#~ msgid "E262: error reading cscope connection %" +#~ 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 eponnistui" +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 eponnistui" +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 eponnistui" +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 eponnistui" +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 eponnistui" +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 tsmyksi 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 (Kytt: %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 tt funktiota kutsuvat funktiot\n" -" d: Etsi tmn funktion kutsumat funktiot\n" -" e: Etsi tm egrep-lauseke\n" -" f: Find tm tiedosto\n" -" g: Etsi tm mritys\n" -" i: Etsi tiedostoja jotka #inkluudaavat tmn\n" -" s: Etsi tm 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 listty" +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-tgi: %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 lisyspolku\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 perss" - -#: ../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 "Vr 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: Syte 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" -"Listietoja: \"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 vakiosytteest" +"Lisätietoja: \"vim -h\"\n" -#: ../main.c:2180 -msgid "-t tag edit file where tag is defined" -msgstr "-t tgi muokkaa tiedostoa tgist" +#. 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 ensimmisest 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" -"kytt:" +#, 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 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 tmn jlkeen" - -#: ../main.c:2199 -msgid "--literal\t\tDon't expand wildcards" -msgstr "--literal\t\tl ksittele 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 (erajo)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\tHelppokytttila (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 kytst" +#, 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 kytst" +#, 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\tBinritila" +#, 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\tVianetsinttila" +#, 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, kyt 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 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\tkynnist arabia-tilassa" +#, fuzzy +#~ msgid " -u Use instead of the default\n" +#~ msgstr "-u \t\tKäytä -tiedostoa .vimrc:iden sijasta" -#: ../main.c:2222 -msgid "-H\t\t\tStart in Hebrew mode" -msgstr "-H\t\t\tkynnist heprea-tilassa" +#~ msgid " -i Use instead of the default\n" +#~ msgstr "" -#: ../main.c:2223 -msgid "-F\t\t\tStart in Farsi mode" -msgstr "-F\t\t\tkynnist 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 \tSet terminal type to " -msgstr "-T \tAseta terminaalin tyypiksi " +#, 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 \t\tUse instead of any .vimrc" -msgstr "-u \t\tKyt -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\tl lataa liitnnisi" +#, 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 vlilehte (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 " + Start at line \n" +#~ msgstr "+\t\t\tAloita riviltä " -#: ../main.c:2229 -msgid "-O[N]\t\tLike -o but split vertically" -msgstr "-O[N]\t\tKuten -o, mutta jaa pystysuunnassa" +#~ msgid " +/ Start at first occurrence of \n" +#~ msgstr "" -#: ../main.c:2230 -msgid "+\t\t\tStart at end of file" -msgstr "+\t\t\tAloita tiedoston lopusta" +#, fuzzy +#~ msgid " --cmd Execute before loading any vimrc\n" +#~ msgstr "--cmd \tSuorita ennen vimrc:iden latausta" -#: ../main.c:2231 -msgid "+\t\tStart at line " -msgstr "+\t\t\tAloita rivilt " +#, fuzzy +msgid "" +" -c Execute after loading the first file\n" +msgstr "-c \t\tSuorita ensimmäisen tiedoston latauduttua" -#: ../main.c:2232 -msgid "--cmd \tExecute before loading any vimrc file" -msgstr "--cmd \tSuorita ennen vimrc:iden latausta" +#, fuzzy +#~ msgid " -S Source after loading the first file\n" +#~ msgstr "-S \t\tLataa ensimmäisen tiedoston latauduttua" -#: ../main.c:2233 -msgid "-c \t\tExecute after loading the first file" -msgstr "-c \t\tSuorita ensimmisen tiedoston latauduttua" +#, fuzzy +#~ msgid " -s Read Normal mode commands from \n" +#~ msgstr "-s \tLue normaalitilan komentoja -tiedostosta" -#: ../main.c:2235 -msgid "-S \t\tSource file after loading the first file" -msgstr "-S \t\tLataa ensimmisen tiedoston latauduttua" +#, fuzzy +#~ msgid " -w Append all typed characters to \n" +#~ msgstr "-w \tLisää kirjoitetut komennot -tiedostoon" -#: ../main.c:2236 -msgid "-s \tRead Normal mode commands from file " -msgstr "-s \tLue normaalitilan komentoja -tiedostosta" +#, fuzzy +#~ msgid " -W Write all typed characters to \n" +#~ msgstr "-W \tKirjoita komennot -tiedostoon" -#: ../main.c:2237 -msgid "-w \tAppend all typed commands to file " -msgstr "-w \tLis kirjoitetut komennot -tiedostoon" +#, fuzzy +#~ msgid " --startuptime Write startup timing messages to \n" +#~ msgstr "--startuptime \tKirjoita käynnistysaikaviestit tiedostoon " -#: ../main.c:2238 -msgid "-W \tWrite all typed commands to file " -msgstr "-W \tKirjoita komennot -tiedostoon" +#~ msgid "" +#~ " --api-info Dump API metadata serialized to msgpack and exit\n" +#~ msgstr "" -#: ../main.c:2240 -msgid "--startuptime \tWrite startup timing messages to " -msgstr "--startuptime \tKirjoita kynnistysaikaviestit tiedostoon " +#~ msgid " --embed Use stdin/stdout as a msgpack-rpc channel\n" +#~ msgstr "" -#: ../main.c:2242 -msgid "-i \t\tUse instead of .viminfo" -msgstr "-i \t\tKyt -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 (tm 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: Mikn merkki ei tsm 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-hykkys?)" +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 hvisi!" +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 pivittnyt 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 tmn 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 "Kyt 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 tll 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 vhimmisarvoa pienempi).\n" +msgstr " on vioittunut (sivun koko on vähimmäisarvoa pienempi).\n" -#: ../memline.c:974 #, c-format msgid "Using swap file \"%s\"" -msgstr "Kytetn swap-tiedostoa %s" +msgstr "Käytetään swap-tiedostoa %s" -#: ../memline.c:980 #, c-format msgid "Original file \"%s\"" -msgstr "Alkuperinen tiedosto %s" +msgstr "Alkuperäinen tiedosto %s" -#: ../memline.c:995 msgid "E308: Warning: Original file may have been changed" -msgstr "E308: Varoitus: Alkuperist 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 "???RIVIMR 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 vr (%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 "??? tst 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 "??? tst kohtaan ???LOPPU rivej saattaa olla listty 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 listietoja" +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 tm 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 alkuperiseen 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 sisllt tsmvt." +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 lytyi:" +msgstr "Swap-tiedostoja löytyi:" -#: ../memline.c:1446 msgid " In current directory:\n" -msgstr " Tss hakemistossa:\n" +msgstr " Tässä hakemistossa:\n" -#: ../memline.c:1448 msgid " Using specified name:\n" -msgstr " Mritellyll nimell:\n" +msgstr " Määritellyllä nimellä:\n" -#: ../memline.c:1450 msgid " In directory " msgstr " Hakemistossa " -#: ../memline.c:1465 msgid " -- none --\n" -msgstr " -- ei mitn --\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 nyt 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" -" kyttjnimi: " +" 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 " (kynniss)" +msgstr " (käynnissä)" -#: ../memline.c:1586 msgid "" "\n" " [not usable on this computer]" msgstr "" "\n" -" [ei toimi tll 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 silytt, swap-tiedostoa ei ole" +msgstr "E313: Ei voi säilyttää, swap-tiedostoa ei ole" -#: ../memline.c:1747 msgid "File preserved" -msgstr "Tiedosto silytetty" +msgstr "Tiedosto säilytetty" -#: ../memline.c:1749 msgid "E314: Preserve failed" -msgstr "E314: Silyttminen eponnistui" +msgstr "E314: Säilyttäminen epäonnistui" -#: ../memline.c:1819 -#, c-format -msgid "E315: ml_get: invalid lnum: %" -msgstr "E315: ml_get: virheellinen lnum: %" +#, fuzzy, c-format +#~ msgid "E315: ml_get: invalid lnum: %" +#~ msgstr "E315: ml_get: virheellinen lnum: %ld" -#: ../memline.c:1851 -#, c-format -msgid "E316: ml_get: cannot find line %" -msgstr "E316: ml_get: rivi % ei lydy" +#, fuzzy, c-format +#~ msgid "E316: ml_get: cannot find line %" +#~ msgstr "E316: ml_get: riviä %ld ei löydy" -#: ../memline.c:2236 msgid "E317: pointer block id wrong 3" -msgstr "E317: osoitinlohkon tunnus vr 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: Pivitetty liikaa lohkoja" +msgstr "E318: Päivitetty liikaa lohkoja" -#: ../memline.c:2511 msgid "E317: pointer block id wrong 4" -msgstr "E317: osoitinlohkon tunnus vr 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 %" -msgstr "E320: Rivi % ei lydy" +#, fuzzy, c-format +#~ msgid "E320: Cannot find line %" +#~ msgstr "E320: Riviä %ld ei löydy" -#: ../memline.c:2916 msgid "E317: pointer block id wrong" -msgstr "E317: osoitinlohkon tunnus vr" +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: % past the end" -msgstr "E322: rivinumero arvoalueen ulkopuoleta: % on loppua suurempi" +#, fuzzy, c-format +#~ msgid "E322: line number out of range: % past the end" +#~ msgstr "E322: rivinumero arvoalueen ulkopuoleta: %ld on loppua suurempi" -#: ../memline.c:2959 -#, c-format -msgid "E323: line count wrong in block %" -msgstr "E323: rivimr vrin lohkossa %" +#, fuzzy, c-format +#~ msgid "E323: line count wrong in block %" +#~ 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 vr 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 lytyi: \"" +"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 kytt samaa tiedostoa.\n" -" Jos nin 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 nin on, kyt 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 (listietoja: \":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 nin, poista swap-tiedosto " +msgstr " Jos teit jo näin, poista swap-tiedosto " -#: ../memline.c:3252 msgid "" "\"\n" " to avoid this message.\n" msgstr "" "\"\n" -" vlttksesi tmn 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 % bytes)" -msgstr "E342: Muisti loppui! (varattaessa % 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 % 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 list 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 lydy: %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 mritelty %s-tilassa" +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" - -#: ../menu.c:1447 -msgid "E337: Menu not found - check menu names" -msgstr "E337: Valikkoa ei lytynyt - 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 %" -msgstr "%s rivi %" +#, fuzzy, c-format +#~ msgid "%s line %" +#~ 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: yls, 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 or click with mouse (empty cancels): " -msgstr "Kirjoita numero ja tai valitse hiirell (tyhj peruu): " +msgstr "Kirjoita numero ja tai valitse hiirellä (tyhjä peruu): " -#: ../misc1.c:2539 msgid "Type number and (empty cancels): " -msgstr "Valitse numero ja (tyhj peruu): " +msgstr "Valitse numero ja (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 vhemmn" +msgstr "1 rivi vähemmän" -#: ../misc1.c:2593 -#, c-format -msgid "% more lines" -msgstr "% rivi lis" +#, fuzzy, c-format +#~ msgid "% more lines" +#~ msgstr "%ld riviä lisää" -#: ../misc1.c:2596 -#, c-format -msgid "% fewer lines" -msgstr "% rivi vhemmn" +#, fuzzy, c-format +#~ msgid "% 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 -msgid "E349: No identifier under cursor" -msgstr "E349: Ei tunnistetta osoittimen alla" +#, c-format +#~ msgid "Invalid channel \"%\"" +#~ msgstr "" -#: ../normal.c:1866 -msgid "E774: 'operatorfunc' is empty" -msgstr "E774: operatorfunc on tyhj" +#~ msgid "Message is not an array" +#~ msgstr "" -#: ../normal.c:2637 -msgid "Warning: terminal cannot highlight" -msgstr "Varoitus: terminaalista puuttuu korostus" +#, fuzzy +#~ msgid "Message is empty" +#~ msgstr "Viesti" -#: ../normal.c:2807 -msgid "E348: No string under cursor" +#~ msgid "Message type must be an integer" +#~ msgstr "" + +#, fuzzy +#~ msgid "Unknown message type" +#~ msgstr "E574: Tuntematon rekisterityyppi %d" + +#~ msgid "Request array size should 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" + +msgid "E774: 'operatorfunc' is empty" +msgstr "E774: operatorfunc on tyhjä" + +msgid "Warning: terminal cannot highlight" +msgstr "Varoitus: terminaalista puuttuu korostus" + +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 tll 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 to exit Nvim" -msgstr "Komento :quit lopettaa Vimin" +#, fuzzy +#~ msgid "Type :quit to exit Nvim" +#~ msgstr "Komento :quit 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 "% lines %sed 1 time" -msgstr "% rivi %s kerran" +#, fuzzy, c-format +#~ msgid "% lines %sed 1 time" +#~ msgstr "%ld riviä %s kerran" -#: ../ops.c:256 -#, c-format -msgid "% lines %sed %d times" -msgstr "% rivi %s %d kertaa" +#, fuzzy, c-format +#~ msgid "% lines %sed %d times" +#~ msgstr "%ld riviä %s %d kertaa" -#: ../ops.c:592 -#, c-format -msgid "% lines to indent... " -msgstr "% rivi sisennettvn..." +#, fuzzy, c-format +#~ msgid "% 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 "% lines indented " -msgstr "% rivi sisennetty " +#, fuzzy, c-format +#~ msgid "% lines indented " +#~ msgstr "%ld riviä sisennetty " -#: ../ops.c:938 msgid "E748: No previously used register" -msgstr "E748: Ei aiemmin kytettyj 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 "% lines changed" -msgstr "% rivi muuttui" +#, fuzzy, c-format +#~ msgid "% 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 % lines yanked" -msgstr "lohko % rivilt kopioitu" +#, fuzzy, c-format +#~ msgid "block of % lines yanked" +#~ msgstr "lohko %ld riviltä kopioitu" -#: ../ops.c:2528 -#, c-format -msgid "% lines yanked" -msgstr "% rivi kopioitu" +#, fuzzy, c-format +#~ msgid "% lines yanked" +#~ msgstr "%ld riviä kopioitu" -#: ../ops.c:2710 #, c-format msgid "E353: Nothing in register %s" -msgstr "E353: Rekisteriss %s ei ole mitn" +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" - -#: ../ops.c:4575 -#, c-format -msgid "E574: Unknown register type %d" -msgstr "E574: Tuntematon rekisterityyppi %d" +"E883: hakulauseke- ja -ilmausrekisteri ei voi sisältää kahta tai useampaa " +"riviä" -#: ../ops.c:5089 -#, c-format -msgid "% Cols; " -msgstr "% saraketta, " +#, fuzzy, c-format +#~ msgid "% Cols; " +#~ msgstr "%ld saraketta, " -#: ../ops.c:5097 -#, c-format +#, fuzzy, c-format msgid "" "Selected %s% of % Lines; % of % Words; " "% of % Bytes" -msgstr "" -"Valittu %s%/% rivi, %/% sanaa, %/" -"% tavua" +msgstr "Valittu %s%ld/%ld riviä, %lld/%lld sanaa, %lld/%lld tavua" -#: ../ops.c:5105 -#, c-format +#, fuzzy, c-format msgid "" "Selected %s% of % Lines; % of % Words; " "% of % Chars; % of % Bytes" msgstr "" -"Valittu %s%/% rivi, %/% sanaa, %/" -"% merkki, %/% 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 % of %; Word % of %; Byte " "% of %" -msgstr "" -"Sarake %s/%s, Rivi %/%, sana %/%, tavu " -"%/%" +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 % of %; Word % of %; Char " "% of %; Byte % of %" msgstr "" -"Sarake %s/%s, rivi %/%, sana %/%, merkki " -"%/%, tavu %/%" +"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 "(+% for BOM)" -msgstr "(+% 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 "(+% 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 jlkeen tarvitaan luku" +msgstr "E521: =:n jälkeen tarvitaan luku" -#: ../option.c:3226 ../option.c:3864 -msgid "E522: Not found in termcap" -msgstr "E522: Puuttuu termcapista" - -#: ../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 tyhjksi 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> jlkeen" +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: Sislt 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> jlkeen" +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 sislt %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: eptasapainoisia 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 tsmv 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: ylimrisi merkkej puolipisteen jlkeen: %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 lydy 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 merkinnn %s[ jljest" +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 tss" +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 tss" +msgstr "E67: \\z1 jne. ei ole sallittu tässä" -#: ../regexp.c:380 #, c-format msgid "E69: Missing ] after %s%%[" -msgstr "E69: ] puuttuu merkinnn %s%%[ jljest" +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@ jlkeen" +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: Siskkistetty %s*" +msgstr "E61: Sisäkkäistetty %s*" -#: ../regexp.c:1690 #, c-format msgid "E62: Nested %s%c" -msgstr "E62: Siskkistetty %s%c" +msgstr "E62: Sisäkkäistetty %s%c" -#: ../regexp.c:1800 msgid "E63: invalid use of \\_" -msgstr "E63: vrinkytetty \\_" +msgstr "E63: väärinkäytetty \\_" -#: ../regexp.c:1850 #, c-format msgid "E64: %s%c follows nothing" -msgstr "E64: %s%c jlkeen ei minkn" +msgstr "E64: %s%c jälkeen ei minkään" -#: ../regexp.c:1902 msgid "E65: Illegal back reference" -msgstr "E65: Virheellinen tsmysviittaus" +msgstr "E65: Virheellinen täsmäysviittaus" -#: ../regexp.c:1943 msgid "E68: Invalid character after \\z" -msgstr "E68: Virheellinen merkki ilmauksen \\z jlkeen" +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 merkinnn %s%%[dxouU] jljess" +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 merkinnn %s%% jljess" +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 alitsmyksi:\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: %" -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 "" - -#: ../regexp_nfa.c:4840 -#, c-format -msgid "(NFA) COULD NOT OPEN %s !" -msgstr "" +msgid "Switching to backtracking RE engine for pattern: " +msgstr "Vaihdetaan käyttämään backtrackkaavaa RE-engineä ilmaukselle: " -#: ../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 " KNTEIS" +msgstr " KÄÄNTEIS" -#: ../screen.c:7441 msgid " INSERT" -msgstr " SYTT" +msgstr " SYÖTTÖ" -#: ../screen.c:7443 msgid " (insert)" -msgstr " (sytt)" +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 psi alkuun lytmtt 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 psi loppuun lytmtt 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 jlkeen pit olla ? tai /" +msgstr "E386: ;:n jälkeen pitää olla ? tai /" -#: ../search.c:4085 msgid " (includes previously listed match)" -msgstr " (sislt viimeksi luetellun tsmyksen)" +msgstr " (sisältää viimeksi luetellun täsmäyksen)" #. cursor at status line -#: ../search.c:4104 msgid "--- Included files " -msgstr "--- Sisllytetyt tiedostot " +msgstr "--- Sisällytetyt tiedostot " -#: ../search.c:4106 msgid "not found " -msgstr "ei lytynyt " +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 LYTYNYT" +msgstr " EI LÖYTYNYT" -#: ../search.c:4211 #, c-format msgid "Scanning included file: %s" -msgstr "Haku sislsi tiedoston: %s" +msgstr "Haku sisälsi tiedoston: %s" -#: ../search.c:4216 #, c-format msgid "Searching included file %s" -msgstr "Haku sislsi tiedoston %s" +msgstr "Haku sisälsi tiedoston %s" -#: ../search.c:4405 msgid "E387: Match is on current line" -msgstr "E387: Tsmys tll rivill" +msgstr "E387: Täsmäys tällä rivillä" -#: ../search.c:4517 msgid "All included files were found" -msgstr "Kaikki sisllytetyt rivit lytyivt" +msgstr "Kaikki sisällytetyt rivit löytyivät" -#: ../search.c:4519 msgid "No included files" -msgstr "Ei sisllytettyj tiedostoja" +msgstr "Ei sisällytettyjä tiedostoja" -#: ../search.c:4527 msgid "E388: Couldn't find definition" -msgstr "E388: Mritelm ei lydy" +msgstr "E388: Määritelmä ei löydy" -#: ../search.c:4529 msgid "E389: Couldn't find pattern" -msgstr "E389: kuvio ei lydy" +msgstr "E389: kuvio ei löydy" -#: ../search.c:4668 -msgid "Substitute " -msgstr "Korvaa " - -#: ../search.c:4681 -#, c-format -msgid "" -"\n" -"# Last %sSearch Pattern:\n" -"~" -msgstr "" -"\n" -"# Edellinen %sHakulauseke:\n" -"~" - -#: ../spell.c:951 -msgid "E759: Format error in spell file" -msgstr "E759: Muotoiluvirhe oikolukutiedostossa" +#~ msgid "too few bytes read" +#~ msgstr "" -#: ../spell.c:952 -msgid "E758: Truncated spell file" -msgstr "E758: Oikolukutiedosto katkaistu" +#, fuzzy, c-format +#~ msgid "System error while skipping in ShaDa file: %s" +#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s" -#: ../spell.c:953 #, c-format -msgid "Trailing text in %s line %d: %s" -msgstr "Teksti rivin perss tiedostossa %s rivill %d: %s" +#~ msgid "" +#~ "Error while reading ShaDa file: last entry specified that it occupies " +#~ "% bytes, but file ended earlier" +#~ msgstr "" -#: ../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" +#, fuzzy, c-format +#~ msgid "System error while closing ShaDa file: %s" +#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s" -#: ../spell.c:955 -msgid "E761: Format error in affix file FOL, LOW or UPP" -msgstr "E761: Affiksitiedoston FOL-, LOW- tai UPP-muotovirhe " +#, fuzzy, c-format +#~ msgid "System error while writing ShaDa file: %s" +#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s" -#: ../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" +#, fuzzy, c-format +#~ msgid "Reading ShaDa file \"%s\"%s%s%s" +#~ msgstr "Luetaan viminfo-tiedostoa \"%s\"%s%s%s" -#: ../spell.c:958 -msgid "Compressing word tree..." -msgstr "Tiivistetn sanapuuta..." +msgid " info" +msgstr " info" -#: ../spell.c:1951 -msgid "E756: Spell checking is not enabled" -msgstr "E756: Oikaisuluku ei ole pll" +msgid " marks" +msgstr " merkit" -#: ../spell.c:2249 -#, c-format -msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\"" -msgstr "Varoitus: Ei lydetty sanalistaa %s.%s.spl tai %s.ascii.spl" +msgid " oldfiles" +msgstr " vanhaatiedostoa" -#: ../spell.c:2473 -#, c-format -msgid "Reading spell file \"%s\"" -msgstr "Luetaan oikaisulukutiedosta %s" +msgid " FAILED" +msgstr " EPÄONNISTUI" -#: ../spell.c:2496 -msgid "E757: This does not look like a spell file" -msgstr "E757: Ei vaikuta oikaisulukutiedostolta" +#, c-format +#~ msgid "System error while opening ShaDa file %s for reading: %s" +#~ msgstr "" -#: ../spell.c:2501 -msgid "E771: Old spell file, needs to be updated" -msgstr "E771: Vanha oikaisulukutiedosto vaatii pivittmist" +#~ msgid "additional elements of ShaDa " +#~ msgstr "" -#: ../spell.c:2504 -msgid "E772: Spell file is for newer version of Vim" -msgstr "E772: Oikaisulukutiedosto on uudemmalle Vimille" +#~ msgid "additional data of ShaDa " +#~ msgstr "" -#: ../spell.c:2602 -msgid "E770: Unsupported section in spell file" -msgstr "E770: Tukematon osio oikaisulukutiedostossa" +#, fuzzy, c-format +#~ msgid "Failed to write variable %s" +#~ msgstr "ei voitu vaihtaa puskuriin %d" -#: ../spell.c:3762 #, c-format -msgid "Warning: region %s not supported" -msgstr "Varoitus: osaa %s ei tueta" +#~ msgid "" +#~ "Failed to parse ShaDa file due to a msgpack parser error at position " +#~ "%" +#~ msgstr "" -#: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Luetaan affiksitiedostoa %s..." +#~ msgid "" +#~ "Failed to parse ShaDa file: incomplete msgpack string at position %" +#~ msgstr "" -#: ../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" +#~ msgid "" +#~ "Failed to parse ShaDa file: extra bytes in msgpack string at position " +#~ "%" +#~ msgstr "" -#: ../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" +#~ msgid "" +#~ "System error while opening ShaDa file %s for reading to merge before writing " +#~ "it: %s" +#~ msgstr "" -#: ../spell.c:4642 +#. Tried names from .tmp.a to .tmp.z, all failed. Something must be +#. wrong then. #, c-format -msgid "Invalid value for FLAG in %s line %d: %s" -msgstr "Tuntematon FLAG kohteessa %s rivill %d: %s" +#~ msgid "E138: All %s.tmp.X files exist, cannot write ShaDa file!" +#~ msgstr "" -#: ../spell.c:4655 -#, c-format -msgid "FLAG after using flags in %s line %d: %s" -msgstr "FLAG kohteessa %s lippujen jlkeen rivill %d: %s" +#, fuzzy, c-format +#~ msgid "System error while opening temporary ShaDa file %s for writing: %s" +#~ msgstr "Väliaikaislokitiedoston avaus kirjoittamista varten ei onnistu" -#: ../spell.c:4723 #, c-format -msgid "" -"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line " -"%d" -msgstr "" -"COMPOUNDFORBIDFLAG PFX:n jlkeen voi antaa vri tuloksia kohteessa %s " -"rivill %d" +#~ msgid "Failed to create directory %s for writing ShaDa file: %s" +#~ msgstr "" -#: ../spell.c:4731 #, c-format -msgid "" -"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line " -"%d" -msgstr "" -"COMPOUNDPERMITFLAG PFX:n jlkeen voi antaa vri tuloksia kohteessa %s " -"rivill %d" +#~ msgid "System error while opening ShaDa file %s for writing: %s" +#~ msgstr "" -#: ../spell.c:4747 -#, c-format -msgid "Wrong COMPOUNDRULES value in %s line %d: %s" -msgstr "Vr COMPOUNDRULES-arvo kohteessa %s rivill %d: %s" +#, fuzzy, c-format +#~ msgid "Writing ShaDa file \"%s\"" +#~ msgstr "Kirjoitetaan viminfo-tiedostoa %s" -#: ../spell.c:4771 -#, c-format -msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s" -msgstr "Vr COMPOUNDWORDMAX-arvo kohteessa %s rivill %d: %s" +#, fuzzy, c-format +#~ msgid "Failed setting uid and gid for file %s: %s" +#~ msgstr "Ladattu kumoustiedoto %s" -#: ../spell.c:4777 -#, c-format -msgid "Wrong COMPOUNDMIN value in %s line %d: %s" -msgstr "Vr COMPOUNDMIN-arvo kohteessa %s rivill %d: %s" +#, fuzzy, c-format +#~ msgid "E137: ShaDa file is not writable: %s" +#~ msgstr "E137: Viminfo-tiedostoon ei voitu kirjoittaa: %s" -#: ../spell.c:4783 -#, c-format -msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s" -msgstr "Vr COMPOUNDSYLMAX-arvo kohteessa %s rivill %d: %s" +#, fuzzy, c-format +#~ msgid "Can't rename ShaDa file from %s to %s!" +#~ msgstr "E886: Viminfo-tiedostoa ei voit uudelleennimetä nimelle %s" -#: ../spell.c:4795 -#, c-format -msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s" -msgstr "Vr CHECKCOMPOUNDPATTERN-arvo kohteessa %s rivill %d: %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]" -#: ../spell.c:4847 #, c-format -msgid "Different combining flag in continued affix block in %s line %d: %s" -msgstr "" -"Eri yhdistelmlippu jatketussa affiksilohkossa kohteessa %s rivill %d: %s" +#~ msgid "Did not rename %s to %s because there were errors during writing it" +#~ msgstr "" -#: ../spell.c:4850 #, c-format -msgid "Duplicate affix in %s line %d: %s" -msgstr "Kaksoiskappale affiksista kohteessa %s rivill %d: %s" +#~ msgid "Do not forget to remove %s or rename it manually to %s." +#~ msgstr "" -#: ../spell.c:4871 -#, c-format -msgid "" -"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s " -"line %d: %s" -msgstr "" -"Affiksia kytetty mys BAD-, RARE-, KEEPCASE-, NEEDAFFIX-, NEEDCOMPOUND- tai " -"NOSUGGEST-arvossa kohteessa %s rivill %d: %s" +#, fuzzy, c-format +#~ msgid "System error while reading ShaDa file: %s" +#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s" + +#, fuzzy, c-format +#~ msgid "System error while reading integer from ShaDa file: %s" +#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s" -#: ../spell.c:4893 #, c-format -msgid "Expected Y or N in %s line %d: %s" -msgstr "Odotettiin Y:t tai N: kohteessa %s rivill %d: %s" +#~ msgid "" +#~ "Error while reading ShaDa file: expected positive integer at position " +#~ "%, but got nothing" +#~ msgstr "" -#: ../spell.c:4968 #, c-format -msgid "Broken condition in %s line %d: %s" -msgstr "Viallinen ehto kohteessa %s rivill %d: %s" +#~ msgid "" +#~ "Error while reading ShaDa file: expected positive integer at position " +#~ "%" +#~ msgstr "" -#: ../spell.c:5091 +#. 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 "Expected REP(SAL) count in %s line %d" -msgstr "Odotettiin REP(SAL)-arvoa kohteessa %s rivill %d" +#~ msgid "" +#~ "Error while reading ShaDa file: there is an item at position % that " +#~ "must not be there: Missing items are for internal uses only" +#~ msgstr "" -#: ../spell.c:5120 #, c-format -msgid "Expected MAP count in %s line %d" -msgstr "Odotettiin MAP-arvoa kohteessa %s rivill %d" +#~ msgid "" +#~ "Error while reading ShaDa file: buffer list at position % contains " +#~ "entry that is not a dictionary" +#~ msgstr "" -#: ../spell.c:5132 #, c-format -msgid "Duplicate character in MAP in %s line %d" -msgstr "Kaksoiskappale merkist MAP:ss kohteessa %s rivill %d" +#~ msgid "" +#~ "Error while reading ShaDa file: buffer list at position % contains " +#~ "entry with invalid line number" +#~ msgstr "" + +#, c-format +#~ msgid "" +#~ "Error while reading ShaDa file: buffer list at position % contains " +#~ "entry with invalid column number" +#~ msgstr "" + +#, c-format +#~ msgid "" +#~ "Error while reading ShaDa file: buffer list at position % 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 % 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" + +msgid "E758: Truncated spell file" +msgstr "E758: Oikolukutiedosto katkaistu" + +#, c-format +msgid "Trailing text in %s line %d: %s" +msgstr "Tekstiä rivin perässä tiedostossa %s rivillä %d: %s" + +#, c-format +msgid "Affix name too long in %s line %d: %s" +msgstr "Affiksin nimi on liian pitkä tiedostossa %s rivillä %d: %s" + +msgid "E761: Format error in affix file FOL, LOW or UPP" +msgstr "E761: Affiksitiedoston FOL-, LOW- tai UPP-muotovirhe " + +msgid "E762: Character in FOL, LOW or UPP is out of range" +msgstr "E762: Merkki FOL:ssä, LOW:ssä tai UPP:ssä ei kuulu arvoalueeseen" + +msgid "Compressing word tree..." +msgstr "Tiivistetään sanapuuta..." + +#, c-format +msgid "Reading spell file \"%s\"" +msgstr "Luetaan oikaisulukutiedosta %s" + +msgid "E757: This does not look like a spell file" +msgstr "E757: Ei vaikuta oikaisulukutiedostolta" + +#, 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ä" + +msgid "E772: Spell file is for newer version of Vim" +msgstr "E772: Oikaisulukutiedosto on uudemmalle Vimille" + +msgid "E770: Unsupported section in spell file" +msgstr "E770: Tukematon osio oikaisulukutiedostossa" + +#, c-format +msgid "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" + +#, c-format +msgid "Reading affix file %s ..." +msgstr "Luetaan affiksitiedostoa %s..." + +#, c-format +msgid "Conversion failure for word in %s line %d: %s" +msgstr "Muunnosvirhe sanalle %s rivillä %d: %s" + +#, c-format +msgid "Conversion in %s not supported: from %s to %s" +msgstr "Muunnosta kohteessa %s ei tueta: kohteesta %s kohteeseen %s" + +#, c-format +msgid "Invalid value for FLAG in %s line %d: %s" +msgstr "Tuntematon FLAG kohteessa %s rivillä %d: %s" + +#, c-format +msgid "FLAG after using flags in %s line %d: %s" +msgstr "FLAG kohteessa %s lippujen jälkeen rivillä %d: %s" + +#, c-format +msgid "" +"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line " +"%d" +msgstr "" +"COMPOUNDFORBIDFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s " +"rivillä %d" + +#, c-format +msgid "" +"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line " +"%d" +msgstr "" +"COMPOUNDPERMITFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s " +"rivillä %d" + +#, c-format +msgid "Wrong COMPOUNDRULES value in %s line %d: %s" +msgstr "Väärä COMPOUNDRULES-arvo kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s" +msgstr "Väärä COMPOUNDWORDMAX-arvo kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Wrong COMPOUNDMIN value in %s line %d: %s" +msgstr "Väärä COMPOUNDMIN-arvo kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s" +msgstr "Väärä COMPOUNDSYLMAX-arvo kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s" +msgstr "Väärä CHECKCOMPOUNDPATTERN-arvo kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Different combining flag in continued affix block in %s line %d: %s" +msgstr "" +"Eri yhdistelmälippu jatketussa affiksilohkossa kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Duplicate affix in %s line %d: %s" +msgstr "Kaksoiskappale affiksista kohteessa %s rivillä %d: %s" + +#, fuzzy, c-format +msgid "" +"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" + +#, c-format +msgid "Expected Y or N in %s line %d: %s" +msgstr "Odotettiin Y:tä tai N:ää kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Broken condition in %s line %d: %s" +msgstr "Viallinen ehto kohteessa %s rivillä %d: %s" + +#, c-format +msgid "Expected REP(SAL) count in %s line %d" +msgstr "Odotettiin REP(SAL)-arvoa kohteessa %s rivillä %d" + +#, c-format +msgid "Expected MAP count in %s line %d" +msgstr "Odotettiin MAP-arvoa kohteessa %s rivillä %d" + +#, c-format +msgid "Duplicate character in MAP in %s line %d" +msgstr "Kaksoiskappale merkistä MAP:ssä kohteessa %s rivillä %d" -#: ../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 jlkikteistettyj 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 jlkikteistettyj 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 "Ensimminen 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 jlkeen 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 %%) jljell" +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 "ntmyksen mukaan yhdistelln..." +msgstr "Ääntämyksen mukaan yhdistellään..." -#: ../spell.c:7368 -#, c-format -msgid "Number of words after soundfolding: %" -msgstr "Sanoja ntmysyhdistelyn jlkeen: %" +#, fuzzy, c-format +#~ msgid "Number of words after soundfolding: %" +#~ 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 kyttmuisti: %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: Enintn 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 kytss" +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 % entries" -msgstr "E765: spellfile ei sisll % kohtaa" - -#: ../spell.c:8074 #, fuzzy, c-format -msgid "Word '%.*s' removed from %s" -msgstr "Sana poistettu kohteesta %s" - -#: ../spell.c:8117 -#, fuzzy, c-format -msgid "Word '%.*s' added to %s" -msgstr "Sana listty kohteeseen %s" - -#: ../spell.c:8381 -msgid "E763: Word characters differ between spell files" -msgstr "E763: Sanan merkit muuttuvat oikaisulukutiedostojen vlill" - -#: ../spell.c:8684 -msgid "Sorry, no suggestions" -msgstr "Sori, ei ehdotuksia" - -#: ../spell.c:8687 -#, c-format -msgid "Sorry, only % suggestions" -msgstr "Sori, vain % 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 lytynyt: %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 pivitt: %s" +#~ msgid "E765: 'spellfile' does not have % entries" +#~ msgstr "E765: spellfile ei sisällä %ld kohtaa" -#: ../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 tsm .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 tlle 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 "vhintn " +msgstr "vähintään " -#: ../syntax.c:3503 msgid "maximal " -msgstr "enitntn " +msgstr "enitntään " -#: ../syntax.c:3513 msgid "; match " -msgstr "; tsm " +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 thn" +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 thn" +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 lydy" +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 mrittelemtt" +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 jljess: %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 mritelty 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 thn" +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 ryhmn 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 lytynyt: %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: ryhmll 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: edustavri tuntematon" +msgstr "E419: edustaväri tuntematon" -#: ../syntax.c:6504 msgid "E420: BG color unknown" -msgstr "E420: taustavri tuntematon" +msgstr "E420: taustaväri tuntematon" -#: ../syntax.c:6564 #, c-format msgid "E421: Color name or number not recognized: %s" -msgstr "E421: Vrin 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 ryhmn nimess" +msgstr "E669: Tulostuskelvoton merkki ryhmän nimessä" -#: ../syntax.c:7434 msgid "W18: Invalid character in group name" -msgstr "W18: Virheellinen merkki ryhmn 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: tgipinon pohja" +msgstr "E555: tägipinon pohja" -#: ../tag.c:105 msgid "E556: at top of tag stack" -msgstr "E556: tgipinon huippu" +msgstr "E556: tägipinon huippu" -#: ../tag.c:380 msgid "E425: Cannot go before first matching tag" -msgstr "E425: Ei voida menn ensimmist tsmv tgi 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: tgi puuttuu: %s" +msgstr "E426: tägi puuttuu: %s" -#: ../tag.c:528 msgid " # pri kind tag" -msgstr " # arvo tyyppi tgi" +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 tgi tsm" +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 tsmvn tgin 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 "tgi %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 " Tgiss 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 FRN LINJE i fil/text" +" # TILL tagg FRÅN LINJE i fil/text" -#: ../tag.c:1303 #, c-format msgid "Searching tags file %s" -msgstr "Etsitn tgitiedostoa %s" +msgstr "Etsitään tägitiedostoa %s" -#: ../tag.c:1545 msgid "Ignoring long line in tags file" -msgstr "Ohitetaan pitk rivi tgitiedostossa" +msgstr "Ohitetaan pitkä rivi tägitiedostossa" -#: ../tag.c:1915 #, c-format msgid "E431: Format error in tags file \"%s\"" -msgstr "E431: Muotovirh tgitiedostossa %s" +msgstr "E431: Muotovirh tägitiedostossa %s" -#: ../tag.c:1917 -#, c-format -msgid "Before byte %" -msgstr "Ennen tavua %" +#, fuzzy, c-format +#~ msgid "Before byte %" +#~ msgstr "Ennen tavua %ld" -#: ../tag.c:1929 #, c-format msgid "E432: Tags file not sorted: %s" -msgstr "E432: Tgitiedosto ei ole jrjestetty: %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 tgitiedostoja" +msgstr "E433: Ei tägitiedostoja" -#: ../tag.c:2536 msgid "E434: Can't find tag pattern" -msgstr "E434: Tgikuviota ei lydy" +msgstr "E434: Tägikuviota ei löydy" -#: ../tag.c:2544 msgid "E435: Couldn't find tag, just guessing!" -msgstr "E435: Tgi ei lydy, arvataan." +msgstr "E435: Tägiä ei löydy, arvataan." -#: ../tag.c:2797 #, c-format msgid "Duplicate field name: %s" -msgstr "Kaksoiskappale kentn 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 lytynyt terminfosta" - -#: ../term.c:1737 -msgid "E559: Terminal entry not found in termcap" -msgstr "E559: Terminaalia ei lytynyt termcapista" - -#: ../term.c:1878 -#, c-format -msgid "E436: No \"%s\" entry in termcap" -msgstr "E436: %s ei lytynyt termcapista" - -#: ../term.c:2249 -msgid "E437: terminal capability \"cm\" required" -msgstr "E437: terminaalilla pit olla cm kyvyissn" - -#. Highlight title -#: ../term.c:4376 -msgid "" -"\n" -"--- Terminal keys ---" -msgstr "" -"\n" -"--- Terminaalinppimet ---" - -#: ../ui.c:481 -msgid "Vim: Error reading input, exiting...\n" -msgstr "Vim: Virhe luettaessa sytett, 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: Rivimr 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 mistn 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 tm 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: Epyhteensopiva kumoustiedosto: %s" +msgstr "E824: Epäyhteensopiva kumoustiedosto: %s" -#: ../undo.c:1328 msgid "File contents changed, cannot use undo info" msgstr "" -"Tiedoston sislt on muuttunut, joen kumoustiedot ovat kyttkelvottomia" +"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 % not found" -msgstr "E830: Kumouslukua % ei lydy" +#, fuzzy, c-format +#~ msgid "E830: Undo number % not found" +#~ msgstr "E830: Kumouslukua %ld ei löydy" -#: ../undo.c:1979 msgid "E438: u_undo: line numbers wrong" -msgstr "E438: u_undo: vrt 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 vhemmn" +msgstr "rivi vähemmän" -#: ../undo.c:2189 msgid "fewer lines" -msgstr "rivi vhemmn" +msgstr "riviä vähemmän" -#: ../undo.c:2193 msgid "change" msgstr "muutos" -#: ../undo.c:2195 msgid "changes" msgstr "muutosta" -# eka %s ylpuolelta, toka %s alapuolelta, kolmas %s aika -#: ../undo.c:2225 -#, c-format -msgid "% %s; %s #% %s" -msgstr "% %s, %s #% %s" +# eka %s yläpuolelta, toka %s alapuolelta, kolmas %s aika +#, fuzzy, c-format +#~ msgid "% %s; %s #% %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 "jlkeen 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 "% seconds ago" -msgstr "% sekuntia sitten" +#, fuzzy, c-format +#~ msgid "% seconds ago" +#~ msgstr "%ld sekuntia sitten" -#: ../undo.c:2372 msgid "E790: undojoin is not allowed after undo" -msgstr "E790: undojoin ei toimi undon jlkeen" +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" -"Ptsit: " - -#: ../version.c:627 msgid "" "\n" "Extra patches: " msgstr "" "\n" -"Muita ptsej: " +"Muita pätsejä: " -#: ../version.c:639 ../version.c:864 -msgid "Modified by " -msgstr "Muokannut " - -#: ../version.c:646 msgid "" "\n" "Compiled " msgstr "" "\n" -"Kntnyt " +"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 " jrjestelmn vimrc: \"" - -#: ../version.c:672 -msgid " user vimrc file: \"" -msgstr " kyttjn vimrc: \"" - -#: ../version.c:677 -msgid " 2nd user vimrc file: \"" -msgstr " 2. kyttjn vimrc: \"" - -#: ../version.c:682 -msgid " 3rd user vimrc file: \"" -msgstr " 3. kyttjn vimrc: \"" - -#: ../version.c:687 -msgid " user exrc file: \"" -msgstr " kyttjn exrc: \"" - -#: ../version.c:692 -msgid " 2nd user exrc file: \"" -msgstr " 2. kyttjn exrc: \"" +msgstr " järjestelmän vimrc: \"" -#: ../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 "Knns: " - -#: ../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 "tekijt 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 lhdekoodia 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 kyhi lapsia" +#~ msgid "https://neovim.io/community" +#~ msgstr "" -#: ../version.c:777 -msgid "type :help iccf for information " -msgstr "kirjoita :help iccf listietoa varten " +#, fuzzy +#~ msgid "type :help nvim if you are new! " +#~ msgstr "kirjoita :help iccf lisätietoa varten " + +#, fuzzy +#~ msgid "type :CheckHealth to optimize Nvim" +#~ msgstr "kirjoita :help iccf lisätietoa varten " -#: ../version.c:779 msgid "type :q to exit " msgstr "kirjoita :q lopettaaksesi " -#: ../version.c:780 -msgid "type :help or for on-line help" -msgstr "kirjoita :help tai ohjetta varten " - -#: ../version.c:781 -msgid "type :help version7 for version info" -msgstr "kirjoita :help version7 versiotietoja varten " - -#: ../version.c:784 -msgid "Running in Vi compatible mode" -msgstr "Suoritetaan Vi-yhteensopivuustilaa" +#, fuzzy +#~ msgid "type :help for help " +#~ msgstr "kirjoita :q lopettaaksesi " -#: ../version.c:785 -msgid "type :set nocp for Vim defaults" -msgstr "kirjoita :set nocp Vimin oletuksiin " +msgid "Help poor children in Uganda!" +msgstr "Auta Ugandan köyhiä lapsia" -#: ../version.c:786 -msgid "type :help cp-default for info on this" -msgstr "kirjoita :help cp-default ohjetta oletuksista varten" +msgid "type :help iccf for information " +msgstr "kirjoita :help iccf 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 "Rekisteridy Vim-kyttjksi." +msgstr "Rekisteröidy Vim-käyttäjäksi." -#: ../version.c:831 msgid "type :help sponsor for information " -msgstr "kirjoita :help sponsor listietoja varten" +msgstr "kirjoita :help sponsor lisätietoja varten" -#: ../version.c:832 msgid "type :help register for information " -msgstr "kirjoita :help register listietoja varten" +msgstr "kirjoita :help register lisätietoja varten" -#: ../version.c:834 msgid "menu Help->Sponsor/Register for information " -msgstr "valikko Ohje->Sponsoroi/Rekisteri listietoja varten" +msgstr "valikko Ohje->Sponsoroi/Rekisteröi lisätietoja varten" -#: ../window.c:119 msgid "Already only one window" -msgstr "En yksi ikkuna jljell" +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 ylnurkkaa ja oikeaa alanurkkaa yhtaikaa" +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 sislt 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() tyhjll 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 tavujrjestys vr" +#~ 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 eponnistui failed" +#~ msgid "internal error: invalid value type" +#~ msgstr "sisäinen virhe: huono arvotyyppi" -#~ msgid "E819: Blowfish test failed" -#~ msgstr "E819: Blowfish-testi eponnistui" +#~ 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 lhettminen 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 lhetys 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 LYTYNYT)" +#~ 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 nkym" +#~ 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 kytss jollei +eval ole pll" +#~ msgid "unable to get option value" +#~ msgstr "ei voitu hakea asetuksen arvoa" -#~ msgid "E196: No digraphs in this version" -#~ msgstr "E196: Digraafeja ei ole tss 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 kytss opendevice-asetuksen takia)" +#~ msgid "function %s does not exist" +#~ msgstr "funktiota %s ei ole" -#~ msgid "Reading from stdin..." -#~ msgstr "Luetaan vakiosytteest" +#~ 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 kytst opendevice-asetuksella" +#~ msgid "internal error: failed to add item to list" +#~ msgstr "sisäinen virhe: ei voitu lisätä kohtaa listaan" -# tietkseni resurssiforkki on applen tiedostojrjestelmn tunnistejuttujuttu -#~ msgid "E460: The resource fork would be lost (add ! to override)" -#~ msgstr "E460: resurssiosa hviisi (lis komentoon ! ohittaaksesi)" +#~ msgid "internal error: not enough list items" +#~ msgstr "sisäinen virhe: ei tarpeeksi listan kohtia" -#~ msgid " " -#~ msgstr " " +#~ msgid "internal error: no vim list item %d" +#~ msgstr "sisäinen virhe: ei vim-listan indeksiä %d" -#~ msgid "E616: vim_SelFile: can't get font %s" -#~ msgstr "E616: vim_SelFile: ei saada fonttia %s" +#~ 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 "E614: vim_SelFile: can't return to current directory" -#~ msgstr "E614: vim_SelFile: nykyiseen hakemistoon ei voi palata" +#~ msgid "slice step cannot be zero" +#~ msgstr "slicen askel ei voi olla nolla" -#~ msgid "Pathname:" -#~ msgstr "Polku:" +#~ msgid "internal error: failed to get vim list item %d" +#~ msgstr "sisäinen virhe: ei pystytty hakea vimin listan indeksiä %d" -#~ msgid "E615: vim_SelFile: can't get current directory" -#~ msgstr "E615: vim_SelFile: nykyist hakemistoa ei saada selville" +#~ msgid "list index out of range" +#~ msgstr "listaindeksi arvoalueen ulkopuolelta" -#~ msgid "OK" -#~ msgstr "OK" +#~ msgid "list constructor does not accept keyword arguments" +#~ msgstr "listakonstruktori ei tue avainsanaparametrejä" -#~ msgid "Cancel" -#~ msgstr "Peru" +#~ msgid "expected sequence element of size 2, but got sequence of size %d" +#~ msgstr "sekvenssin elementin koon pitäisi olla 2, ei %d" -#~ msgid "Vim dialog" -#~ msgstr "Vim-ikkuna" +#~ msgid "hashtab changed during iteration" +#~ msgstr "hashtab muuttui kesken iteraation" -#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." -#~ msgstr "Vierityspalkki: Pixmapin geometria ei selvi" +#~ msgid "cannot set attribute %s" +#~ msgstr "ei voi asettaa attribuuttia %s" -#~ msgid "E232: Cannot create BalloonEval with both message and callback" -#~ msgstr "E232: Ei voi luoda BalloonEvalia viestille ja callbackille" +#~ msgid "cannot delete vim.Dictionary attributes" +#~ msgstr "ei voi poistaa vim.Dictionary-attribuutteja" -#~ msgid "E229: Cannot start the GUI" -#~ msgstr "E229: GUIn kynnistys ei onnistu" +#~ msgid "internal error: imp.find_module returned tuple with NULL" +#~ msgstr "" +#~ "sisäinen virhe: imp.find_module palautti tuplen joka sisältää nullin" -#~ msgid "E230: Cannot read from \"%s\"" -#~ msgstr "E230: Ei voi lukea kohteesta %s" +#~ 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 "E665: Cannot start GUI, no valid font found" -#~ msgstr "E665: Ei voi avata GUIta, sopivaa fonttia ei lydy" +#~ msgid "expected 3-tuple as imp.find_module() result, but got %s" +#~ msgstr "odotettiin 3-tuplea tuloksena imp.find_module()-kutsulle, ei %s" -#~ msgid "E231: 'guifontwide' invalid" -#~ msgstr "E231: guifontwide virheellinen" +#~ msgid "E264: Python: Error initialising I/O objects" +#~ msgstr "E264: Python: Virhe IO-olioiden alustuksessa" -#~ msgid "E599: Value of 'imactivatekey' is invalid" -#~ msgstr "E599: imactivatekeyn arvo on virheellinen" +#~ msgid "invalid attribute: %s" +#~ msgstr "virheellinen attribuutti: %s" -#~ msgid "E254: Cannot allocate color %s" -#~ msgstr "E254: Vri %s ei voi mritell" +#~ msgid "can't delete OutputObject attributes" +#~ msgstr "ei voi poistaa OutputObject-attribuutteja" -#~ msgid "No match at cursor, finding next" -#~ msgstr "Ei tsmyst kursorin alla, etsitn seuraava" +#~ msgid "number must be greater or equal to zero" +#~ msgstr "luvun on oltava yhtä suuri tai suurempi kuin nolla" -#~ msgid "Input _Methods" -#~ msgstr "Syte_menetelmt" +#~ msgid "value is too small to fit into C int type" +#~ msgstr "arvo on liian pieni mahtumaan C:n int-tyyppiin" -#~ msgid "VIM - Search and Replace..." -#~ msgstr "VIM - Etsi ja korvaa..." +#~ 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 "VIM - Search..." -#~ msgstr "VIM - 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 "Find what:" -#~ msgstr "Etsi:" +#~ msgid "expected bytes() or str() instance, but got %s" +#~ msgstr "odotettiin instanssia tyypeistä bytes() tai str(), ei %s" -#~ msgid "Replace with:" -#~ msgstr "Korvaa:" +#~ msgid "expected str() or unicode() instance, but got %s" +#~ msgstr "odottettiin insanssia tyypeistä str() tai unicode(), ei %s" -#~ msgid "Match whole word only" -#~ msgstr "Korvaa kokonaisia sanoja" +#~ msgid "index must be int or slice, not %s" +#~ msgstr "indeksin pitää olla int tai slice, ei %s" -#~ msgid "Match case" -#~ msgstr "Kirjaintaso" +#~ msgid "failed to add key '%s' to dictionary" +#~ msgstr "avaimen %s lisääminen sanakirjaan ei onnistu" -#~ msgid "Direction" -#~ msgstr "Suunta" +#~ msgid "list is locked" +#~ msgstr "luettelo on lukittu" -#~ msgid "Up" -#~ msgstr "Yls" +#~ msgid "Need encryption key for \"%s\"" +#~ msgstr "Tarvitaan salausavain kohteelle %s " -#~ msgid "Down" -#~ msgstr "Alas" +#~ msgid "E744: NetBeans does not allow changes in read-only files" +#~ msgstr "E744: NetBeans ei tue muutoksia kirjoitussuojattuihin tiedostoihin" -#~ msgid "Find Next" -#~ msgstr "Etsi seuraava" +#~ msgid "E463: Region is guarded, cannot modify" +#~ msgstr "E463: Alue on suojattu, muuttaminen ei onnistu" -#~ msgid "Replace" -#~ msgstr "Korvaa" +#~ msgid "E449: Invalid expression received" +#~ msgstr "E449: Virheellinen ilmaus saatu" -#~ msgid "Replace All" -#~ msgstr "Korvaa kaikki" +#~ msgid "E233: cannot open display" +#~ msgstr "E233: näyttöä ei voi avata" -#~ msgid "Vim: Received \"die\" request from session manager\n" -#~ msgstr "Vim: sessiomanageri lhetti die-pyynnn\n" +#~ msgid "E247: no registered server named \"%s\"" +#~ msgstr "E247: palvelinta %s ei ole rekisteröitynä" -#~ msgid "Close" -#~ msgstr "Sulje" +#~ 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 "New tab" -#~ msgstr "Uusi vlilehti" +#~ 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 "Open Tab..." -#~ msgstr "Avaa vlilehti..." +#~ 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 "Vim: Main window unexpectedly destroyed\n" -#~ msgstr "Vim: Pikkuna tuhoutui odottamatta\n" +#~ 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 "&Filter" -#~ msgstr "&Suodata" +#~ msgid "E448: Could not load library function %s" +#~ msgstr "E448: Ei voitu ladta kirjastofunktiota %s" -#~ msgid "&Cancel" -#~ msgstr "&Peru" +#~ msgid "E236: Font \"%s\" is not fixed-width" +#~ msgstr "E236: Fontti %s ei ole tasavälinen" -#~ msgid "Directories" -#~ msgstr "Hakemistot" +#~ msgid "E234: Unknown fontset: %s" +#~ msgstr "E234: Tuntematon fontset: %s" -#~ msgid "Filter" -#~ msgstr "Suodatus" +#~ msgid "gvimext.dll error" +#~ msgstr "gvimext.dll-virhe" -#~ msgid "&Help" -#~ msgstr "O&hje" +#~ msgid "Error creating process: Check if gvim is in your path!" +#~ msgstr "Virhe prosessin käynnistämisessä, varmista että gvim on polulla" -#~ msgid "Files" -#~ msgstr "Tiedostot" +#~ msgid "Edits the selected file(s) with Vim" +#~ msgstr "Muokkaa valittuja tiedostoja Vimillä" -#~ msgid "&OK" -#~ msgstr "&Ok" +#~ msgid "Edit with existing Vim - " +#~ msgstr "Muokkaa olemassaolevalla Vimillä - " -#~ msgid "Selection" -#~ msgstr "Valinta" +#~ msgid "Edit with &Vim" +#~ msgstr "Muokkaa &Vimillä" -#~ msgid "Find &Next" -#~ msgstr "Hae &seuraava" +#~ msgid "Diff with Vim" +#~ msgstr "Diffi Vimillä" -#~ msgid "&Replace" -#~ msgstr "Ko&rvaa" +#~ msgid "Edit with single &Vim" +#~ msgstr "Muokkaa yhdellä &Vimillä" -#~ msgid "Replace &All" -#~ msgstr "Korvaa k&aikki" +#~ msgid "Edit with &multiple Vims" +#~ msgstr "&Muokkaa usealla Vimillä" -#~ msgid "&Undo" -#~ msgstr "&Kumoa" +#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" +#~ msgstr "E299: Perl-suoritus kielletty hiekkalaatikossa ilman Safe-moduulia" -#~ msgid "E671: Cannot find window title \"%s\"" -#~ msgstr "E671: Ikkunan otsikkoa ei lydy %s" +#~ msgid "" +#~ "Sorry, this command is disabled: the Perl library could not be loaded." +#~ msgstr "komento ei toimi, Perl kirjastoa ei voinut ladata." -# OLE on object linking and embedding p windowska -#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." -#~ msgstr "E243: Argumenttia ei tueta: -%s, kyt OLE-versiota" +#~ msgid "E370: Could not load library %s" +#~ msgstr "E370: Kirjaston %s lataaminen ei onnistu" -# MDI eli windowsin moni-ikkunasovellus -#~ msgid "E672: Unable to open window inside MDI application" -#~ msgstr "E672: Ikkunaa ei voitu avata MDI-sovellukseen" +#~ msgid "type :help windows95 for info on this" +#~ msgstr "kirjoita :help windows95 lisätietoja varten" -#~ msgid "Close tab" -#~ msgstr "Sulje vlilehti" +#~ msgid "WARNING: Windows 95/98/ME detected" +#~ msgstr "VAROITUS: Window 95/98/ME havaittu" -#~ msgid "Open tab..." -#~ msgstr "Avaa vlilehti..." +#~ msgid " for Vim defaults " +#~ msgstr " Vim-oletuksia varten" -#~ msgid "Find string (use '\\\\' to find a '\\')" -#~ msgstr "Etsi merkkijonoa (\\\\:ll lyt \\:t)" +#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible" +#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda Vi-yhteensopivuutta" -#~ msgid "Find & Replace (use '\\\\' to find a '\\')" -#~ msgstr "Etsi ja korvaa (\\\\:ll lyt \\:t)" +#~ msgid "menu Edit->Global Settings->Toggle Insert Mode " +#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda syötetilaa" -#~ msgid "Not Used" -#~ msgstr "Ei kytss" +#~ msgid "Running modeless, typed text is inserted" +#~ msgstr "Suoritetaan tilattomana, kirjoitettu teksti syötetään" -#~ msgid "Directory\t*.nothing\n" -#~ msgstr "Hakemisto\t*.nothing\n" +#~ msgid "menu Help->Orphans for information " +#~ msgstr "valikko Ohje->Orvot lisätietoja varten " -#~ msgid "" -#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" -#~ msgstr "" -#~ "Vim E458: Ei voi varata vrikartan alkiota, vrit voivat menn vrin" +#~ msgid "type :help cp-default for info on this" +#~ msgstr "kirjoita :help cp-default ohjetta oletuksista varten" -#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:" -#~ msgstr "E250: Seuraavien merkistjoukkojen fontit puuttuvat fontsetist %s:" +#~ msgid "type :set nocp for Vim defaults" +#~ msgstr "kirjoita :set nocp Vimin oletuksiin " -#~ msgid "E252: Fontset name: %s" -#~ msgstr "E252: Fontsetin nimi: %s" +#~ msgid "Running in Vi compatible mode" +#~ msgstr "Suoritetaan Vi-yhteensopivuustilaa" -#~ msgid "Font '%s' is not fixed-width" -#~ msgstr "Fontti %s ei ole tasavlinen" +#~ msgid "type :help version8 for version info" +#~ msgstr "kirjoita :help version8 versiotietoja varten " -#~ msgid "E253: Fontset name: %s\n" -#~ msgstr "E253: Fontsetin nimi: %s\n" +#~ msgid "type :help or for on-line help" +#~ msgstr "kirjoita :help tai ohjetta varten " -#~ msgid "Font0: %s\n" -#~ msgstr "Fontti0: %s\n" +#~ msgid "version " +#~ msgstr "versio " -#~ msgid "Font1: %s\n" -#~ msgstr "Fontti1: %s\n" +#~ msgid "VIM - Vi IMproved" +#~ msgstr "VIM - Vi IMproved" -#~ msgid "Font% width is not twice that of font0\n" -#~ msgstr "Fontti%:n leveys ei ole kaksi kertaa fontti0:n\n" +#~ msgid " DEBUG BUILD" +#~ msgstr " DEBUG-versio" -#~ msgid "Font0 width: %\n" -#~ msgstr "Fontti0:n leveys: %\n" +#~ msgid "Linking: " +#~ msgstr "Linkitys: " -#~ msgid "" -#~ "Font1 width: %\n" -#~ "\n" -#~ msgstr "" -#~ "Fontti1:n leveys: %\n" -#~ "\n" +#~ msgid "Compiler: " +#~ msgstr "Käännin: " -#~ msgid "Invalid font specification" -#~ msgstr "Virheellinen fonttimritys" +#~ msgid "Compilation: " +#~ msgstr "Käännös: " -#~ msgid "&Dismiss" -#~ msgstr "&Ohita" +#~ msgid " system menu file: \"" +#~ msgstr " järjestelmävalikko: \"" -#~ msgid "no specific match" -#~ msgstr "ei tarkkaa tsmyst" - -#~ 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 "Nyt 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 kytst knnsaikana" +#~ 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 list rivi" +#~ msgid "" +#~ "\n" +#~ "Tiny version " +#~ msgstr "" +#~ "\n" +#~ "Tiny-versio " -#~ msgid "string cannot contain newlines" -#~ msgstr "merkkijono ei saa sislt 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 kytt 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 kytt 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 "" -#~ msgstr "" +#~ 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: ksittelemtn 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 mritelmn vlill" +#~ msgid "" +#~ "\n" +#~ "--- Terminal keys ---" +#~ msgstr "" +#~ "\n" +#~ "--- Terminaalinäppäimet ---" -#~ msgid "Show base class of" -#~ msgstr "Nyt kantaluokka kohteelle" +#~ msgid "E437: terminal capability \"cm\" required" +#~ msgstr "E437: terminaalilla pitää olla cm kyvyissään" -#~ msgid "Show overridden member function" -#~ msgstr "Nyt korvattu jsenfunktio" +#~ msgid "E436: No \"%s\" entry in termcap" +#~ msgstr "E436: %s ei löytynyt termcapista" -#~ msgid "Retrieve from file" -#~ msgstr "Jljit tiedostosta" +#~ msgid "E559: Terminal entry not found in termcap" +#~ msgstr "E559: Terminaalia ei löytynyt termcapista" -#~ msgid "Retrieve from project" -#~ msgstr "Jljit projektista" +#~ msgid "E558: Terminal entry not found in terminfo" +#~ msgstr "E558: Terminaalia ei löytynyt terminfosta" -#~ msgid "Retrieve from all projects" -#~ msgstr "Jljit kaikista projekteista" +#~ msgid "E557: Cannot open termcap file" +#~ msgstr "E557: Ei voi avata termcap-tiedostoa" -#~ msgid "Retrieve" -#~ msgstr "Jljit" +#~ msgid "defaulting to '" +#~ msgstr "oletusarvona " -#~ msgid "Show source of" -#~ msgstr "Nyt lhdekoodi 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 "E422: terminal code too long: %s" +#~ msgstr "E422: terminaalikoodi liian pitkä: %s" -#~ msgid "Browse class" -#~ msgstr "Selaa luokkaa" +#~ msgid "E845: Insufficient memory, word list will be incomplete" +#~ msgstr "E845: Muisti ei riitä, sanalista jää keskeneräiseksi" -#~ msgid "Show class in hierarchy" -#~ msgstr "Nyt luokka hierarkiassa" +#~ msgid "Conversion in %s not supported" +#~ msgstr "Muutosta kohteessa %s ei tueta" -#~ msgid "Show class in restricted hierarchy" -#~ msgstr "Nyt 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 sislt kohteen" +#~ msgid "(NFA) COULD NOT OPEN %s !" +#~ msgstr "(NFA) EI VOI AVATA KOHDETTA %s" -#~ msgid "Xref used by" -#~ msgstr "Xrefi kytt" +#~ 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 "Nyt 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 ympristmuuttujat (sniffemacsin " -#~ "lyty 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 yhdistettess 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 lisys 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 "nppimistkeskeytys" +#~ 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 "" -#~ "cannot register callback command: buffer/window is already being deleted" -#~ msgstr "callbackia ei voi rekisterid: puskuri tai ikkuna on poistettu" +#~ msgid "Could not fix up function pointers to the DLL!" +#~ msgstr "Ei voitu korjata funktio-osoittimia DLL:ssä" -#~ 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 "VIM Error" +#~ msgstr "VIM-virhe" -#~ msgid "cannot register callback command: buffer/window reference not found" -#~ msgstr "" -#~ "callbackia ei voi rekisterid: puskurin tai ikkunan viitett ei lydy" - -#~ msgid "" -#~ "E571: Sorry, this command is disabled: the Tcl library could not be " -#~ "loaded." -#~ msgstr "E571: Sori, komento ei toimi, Tcl-kirjastoa ei voitu ladata." - -#~ msgid "" -#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim." -#~ "org" -#~ msgstr "" -#~ "E281: TCL-virhe: lopetuskoodi ei ole kokonaisluku? Ilmoita asiasta " -#~ "postituslistalle vim-dev@vim.org" - -#~ msgid "E572: exit code %d" -#~ msgstr "E572: palautusarvo %d" - -#~ msgid "cannot get line" -#~ msgstr "ei voida hakea rivi" - -#~ msgid "Unable to register a command server name" -#~ msgstr "Komentopalvelimen nimen rekisterinti ei onnistu" +#~ msgid "Could not load vim32.dll!" +#~ msgstr "Vim32.dll:ää ei voitu ladata" -#~ msgid "E248: Failed to send command to the destination program" -#~ msgstr "E248: Komennon lhetys kohdeohjelmalle ei onnistu" +#~ msgid "At line" +#~ msgstr "Rivillä" -#~ msgid "E573: Invalid server id used: %s" -#~ msgstr "E573: Virheellinen palvelimen tunniste: %s" +#~ msgid "XSMP SmcOpenConnection failed: %s" +#~ msgstr "XSMP SmcOpenConnection epäonnistui: %s" -#~ msgid "E251: VIM instance registry property is badly formed. Deleted!" -#~ msgstr "E251: VIMin instanssin rekisteriarvo on virheellinen, poistettiin." +#~ msgid "XSMP ICE connection watch failed" +#~ msgstr "XSMP:n ICE-yhteyden tarkkailu epäonnistui" -#~ msgid "netbeans is not supported with this GUI\n" -#~ msgstr "netbeans ei toimi tss kyttliittymss\n" +#~ msgid "XSMP opening connection" +#~ msgstr "XSMP avaa yhteyttä" -#~ msgid "This Vim was not compiled with the diff feature." -#~ msgstr "Thn Vimiin ei ole knnetty diff-toimintoja mukaan." +#~ msgid "XSMP handling save-yourself request" +#~ msgstr "XSMP käsittelee save-yourself-pyyntöä" -#~ msgid "'-nb' cannot be used: not enabled at compile time\n" -#~ msgstr "-nb:t ei voi kytt, koska sit ei knnetty mukaan\n" +#~ msgid "Opening the X display failed" +#~ msgstr "X-näytön avaus epäonnistui" -#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n" -#~ msgstr "Vim: Virhe: Gvimin kynnistys NetBeansist ei onnistu\n" +#~ msgid "XSMP lost ICE connection" +#~ msgstr "XSMP kadotti ICE-yhteyden" #~ msgid "" #~ "\n" -#~ "Where case is ignored prepend / to make flag upper case" +#~ "Command terminated\n" #~ msgstr "" #~ "\n" -#~ "Jos aakkoslaji on ohitettu, lis alkuun / tehdksesi asetuksesta " -#~ "suuraakkosia" - -#~ msgid "-register\t\tRegister this gvim for OLE" -#~ msgstr "-register\t\trekisteri gvim OLEa varten" - -#~ msgid "-unregister\t\tUnregister gvim for OLE" -#~ msgstr "-unregister\t\tPoista gvim OLE-rekisterist" - -#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")" -#~ msgstr "-g\t\t\tAvaa GUI (kuten gvimill)" - -#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI" -#~ msgstr "-f tai --nofork\tEdustalle: l haarauta GUIn kynnistyksess" - -#~ msgid "-f\t\t\tDon't use newcli to open window" -#~ msgstr "-f\t\t\tl kyt newcli:t ikkunan avaamiseen" - -#~ msgid "-dev \t\tUse for I/O" -#~ msgstr "-dev \t\tKyt IO:hon" - -#~ msgid "-U \t\tUse instead of any .gvimrc" -#~ msgstr "-U \t\tKyt -tiedostoa .gvimrc:iden sijasta" - -#~ msgid "-x\t\t\tEdit encrypted files" -#~ msgstr "-x\t\t\tMuokkaa salattua tiedostoa" - -#~ msgid "-display \tConnect vim to this particular X-server" -#~ msgstr "-display \tYhdist vim tiettyyn X-palvelimeen" - -#~ msgid "-X\t\t\tDo not connect to X server" -#~ msgstr "-X\t\t\tl yhdist X-palvelimeen" - -#~ msgid "--remote \tEdit in a Vim server if possible" -#~ msgstr "" -#~ "--remote \tMuokkaa Vim-palvelimessa, jos " -#~ "mahdollista" - -#~ msgid "--remote-silent Same, don't complain if there is no server" -#~ msgstr "" -#~ "--remote-silent \tSama, mutta l ilmoita puuttuvasta " -#~ "palvelimesta" - -#~ msgid "" -#~ "--remote-wait As --remote but wait for files to have been edited" -#~ msgstr "" -#~ "--remote-wait kuten --remote, mutta odota tiedostojen " -#~ "muokkaamista" - -#~ msgid "" -#~ "--remote-wait-silent Same, don't complain if there is no server" -#~ msgstr "" -#~ "--remote-wait-silent sama, mutta l ilmoita puuttuvasta " -#~ "palvelimesta" +#~ "Komento loppui\n" #~ msgid "" -#~ "--remote-tab[-wait][-silent] As --remote but use tab page per " -#~ "file" -#~ msgstr "" -#~ "--remote-tab[-wait][-silent] kuten --remote, mutta avaa " -#~ "vlilehti joka tiedostolle" - -#~ msgid "--remote-send \tSend to a Vim server and exit" +#~ "\n" +#~ "Cannot execute shell " #~ msgstr "" -#~ "--remote-send \tLhet painalluksina Vimille ja " -#~ "lopeta" +#~ "\n" +#~ "Kuoren suoritus ei onnistu " #~ msgid "" -#~ "--remote-expr \tEvaluate in a Vim server and print result" +#~ "\n" +#~ "Cannot fork\n" #~ msgstr "" -#~ "--remote-expr \tKsittele Vim-palvelimella ja tulosta " -#~ "tulos" - -#~ msgid "--serverlist\t\tList available Vim server names and exit" -#~ msgstr "--serverlist\t\tLuettele Vim-palvelinten nimet ja lopeta" - -#~ msgid "--servername \tSend to/become the Vim server " -#~ msgstr "--servername \tLhet Vim-palvelimelle tai luo se" +#~ "\n" +#~ "Ei voi haarauttaa\n" #~ msgid "" #~ "\n" -#~ "Arguments recognised by gvim (Motif version):\n" +#~ "Cannot create pipes\n" #~ msgstr "" #~ "\n" -#~ "Gvimin (Motif-version) tuntemat argumentit:\n" +#~ "Putkia ei voi tehdä\n" #~ msgid "" #~ "\n" -#~ "Arguments recognised by gvim (neXtaw version):\n" +#~ "Cannot execute shell sh\n" #~ msgstr "" #~ "\n" -#~ "Gvimin (neXtaw-version) tuntemat argumentit:\n" +#~ "Kuoren sh suoritus ei onnistu\n" + +# 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 "Could not set security context %s for %s" +#~ msgstr "Ei voitu asettaa turvallisuuskontekstia %s kohteelle %s" + +#~ msgid "Opening the X display timed out" +#~ msgstr "X-näytön avaus aikakatkaistiin" + +#~ msgid "Testing the X display failed" +#~ msgstr "X-näytön testaus epäonnistui" #~ msgid "" #~ "\n" -#~ "Arguments recognised by gvim (Athena version):\n" +#~ "Vim: Got X error\n" #~ msgstr "" #~ "\n" -#~ "Gvimin (Athena-version) tuntemat argumentit:\n" - -#~ msgid "-display \tRun vim on " -#~ msgstr "-display \tSuorita vim " +#~ "Vim: X-virhe\n" -#~ msgid "-iconic\t\tStart vim iconified" -#~ msgstr "-iconic\t\tKynnist pienennettyn" +#~ msgid "Opening the X display took %ld msec" +#~ msgstr "X-näytön avaus vei %ld millisekuntia" -#~ msgid "-background \tUse for the background (also: -bg)" -#~ msgstr "-background \tKyt taustavrin (mys: -bg)" +#~ msgid "E245: Illegal char '%c' in font name \"%s\"" +#~ msgstr "E245: Virheellinen merkki %c fontin nimessä %s" -#~ msgid "-foreground \tUse for normal text (also: -fg)" -#~ msgstr "-foreground \tKyt tekstin vrin (mys: -fg)" +#~ msgid "E244: Illegal quality name \"%s\" in font name \"%s\"" +#~ msgstr "E244: Virheellinen laatunimi %s fontin nimessä %s" -#~ msgid "-font \t\tUse for normal text (also: -fn)" -#~ msgstr "-font \t\tKyt tekstiss (mys: -fn)" +#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\"" +#~ msgstr "E244: Virheellinen merkistön nimi %s fontin nimessä %s" -#~ msgid "-boldfont \tUse for bold text" -#~ msgstr "-boldfont \tKyt lihavoidussa tekstiss" +#~ msgid "Printing '%s'" +#~ msgstr "Tulostetaan %s" -#~ msgid "-italicfont \tUse for italic text" -#~ msgstr "-italicfont \tKyt kursivoidussa tekstiss" +#~ msgid "E238: Print error: %s" +#~ msgstr "E238: Tulostinvirhe: %s" -#~ msgid "-geometry \tUse for initial geometry (also: -geom)" -#~ msgstr "" -#~ "-geometry \tKyt mittoja ikkunan asetteluun (mys: -geom)" +#~ msgid "E613: Unknown printer font: %s" +#~ msgstr "E613: Tuntematon tulostimen fontti: %s" -#~ msgid "-borderwidth \tUse a border width of (also: -bw)" -#~ msgstr "-borderwidt \tKyt reunuksissa (mys: -bw) " +#~ msgid "to %s on %s" +#~ msgstr "tulostimelle %s kohteessa %s" -#~ msgid "" -#~ "-scrollbarwidth Use a scrollbar width of (also: -sw)" -#~ msgstr "" -#~ "-scrollbarwidth Kyt vierityspalkissa (mys: -sw)" +#~ msgid "E237: Printer selection failed" +#~ msgstr "E237: Tulostimen valinta epäonnistui" -#~ msgid "-menuheight \tUse a menu bar height of (also: -mh)" -#~ msgstr "-menuheight \tKyt valikossa (mys: -mh)" +#~ msgid "'columns' is not 80, cannot execute external commands" +#~ msgstr "columns ei ole 80, ei voi suorittaa ulkoista komentoa" -#~ msgid "-reverse\t\tUse reverse video (also: -rv)" -#~ msgstr "-reverse\t\tKyt knteisvrej (mys: -rv) " +#~ msgid "I/O ERROR" +#~ msgstr "IO-virhe" -#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)" -#~ msgstr "+reverse\t\tl kyt knteisvrej (mys: +rv)" +#~ msgid "ANCHOR_BUF_SIZE too small." +#~ msgstr "ANCHOR_BUF_SIZE liian pieni." -#~ msgid "-xrm \tSet the specified resource" -#~ msgstr "-xrm \tAseta resurssi" +#~ msgid " returned\n" +#~ msgstr " palautti\n" -#~ msgid "" -#~ "\n" -#~ "Arguments recognised by gvim (RISC OS version):\n" -#~ msgstr "" -#~ "\n" -#~ "Gvimin (RISC OS -version) tuntemat argumentit:\n" +#~ msgid "shell " +#~ msgstr "kuori " -#~ msgid "--columns \tInitial width of window in columns" -#~ msgstr "--columns \tIkkunan alkuleveys sarakkeina" +#~ msgid "Cannot execute " +#~ msgstr "Ei voi suorittaa " -#~ msgid "--rows \tInitial height of window in rows" -#~ msgstr "--rows \tIkkunan alkukorkeus rivein" +#~ msgid "E360: Cannot execute shell with -f option" +#~ msgstr "E360: Kuorta ei voi avata asetuksella -f" -#~ msgid "" -#~ "\n" -#~ "Arguments recognised by gvim (GTK+ version):\n" -#~ msgstr "" -#~ "\n" -#~ "Gvimin (GTK+-version) tuntemat argumentit:\n" +#~ msgid "mch_get_shellsize: not a console??\n" +#~ msgstr "mch_get_shellsize: ei ole konsoli?\n" -#~ msgid "-display \tRun vim on (also: --display)" -#~ msgstr "-display \tSuorita vim nytll (mys: --display)" +#~ msgid "cannot change console mode ?!\n" +#~ msgstr "ei voi vaihtaa konsolitilaa?\n" -# X-ikkunointijrjestelmss saman sovelluksen saman luokan ikkunat -# tunnistetaan rooliresursseista -#~ msgid "--role \tSet a unique role to identify the main window" -#~ msgstr "" -#~ "--role \tAseta pikkunalle ainutlaatuinen rooli tunnisteeksi" +#~ msgid "Vim exiting with %d\n" +#~ msgstr "Vim sulkeutuu koodilla %d\n" -#~ msgid "--socketid \tOpen Vim inside another GTK widget" -#~ msgstr "--socketid \tAvaa Vim annettuun GTK-olioon " +#~ msgid "Cannot create " +#~ msgstr "Ei voi luoda " -#~ msgid "-P \tOpen Vim inside parent application" -#~ msgstr "-P \tAvaa Vim isntohjelman sisn" +#~ msgid "Cannot open NIL:\n" +#~ msgstr "Ei voi avata NILiä:\n" -#~ msgid "--windowid \tOpen Vim inside another win32 widget" -#~ msgstr "--windowid \tAvaa Vim annettuun win32-olioon " +#~ msgid "Need %s version %ld\n" +#~ msgstr "Tarvitaan %s versio %ld\n" -#~ msgid "No display" -#~ msgstr "Ei nytt" +#~ msgid "Need Amigados version 2.04 or later\n" +#~ msgstr "Amigados 2.04 tai uudempi tarvitaan\n" -#~ msgid ": Send failed.\n" -#~ msgstr ": Lhetys eponnistui.\n" +#~ msgid "VIM: Can't open window!\n" +#~ msgstr "VIM: Ei voi avata ikkunaa\n" -#~ msgid ": Send failed. Trying to execute locally\n" -#~ msgstr ": Lhetys eponnistui. Yritetn suorittaa paikallisena\n" +#~ msgid "cannot open " +#~ msgstr "ei voi avata " -#~ msgid "%d of %d edited" -#~ msgstr "%d/%d muokattu" +#~ msgid "E538: No mouse support" +#~ msgstr "E538: Hiirtä ei tueta" -#~ msgid "No display: Send expression failed.\n" -#~ msgstr "Ei nytt: Ilmauksen lhetys eponnistui.\n" +#~ msgid "E533: can't select wide font" +#~ msgstr "E533: Leveän fontin valinta ei onnistu" -#~ msgid ": Send expression failed.\n" -#~ msgstr ": Ilmauksen lhetys eponnistui.\n" +#~ msgid "E598: Invalid fontset" +#~ msgstr "E598: Viallinen fontset" -#~ msgid "E543: Not a valid codepage" -#~ msgstr "E543: Koodisivu ei ole kyp" +#~ msgid "E597: can't select fontset" +#~ msgstr "E597: Fontsetin valinta ei onnistu" -#~ msgid "E285: Failed to create input context" -#~ msgstr "E285: Sytekontekstin luonti ei onnistu" +#~ msgid "E596: Invalid font(s)" +#~ msgstr "E596: Viallisia fontteja" -#~ msgid "E286: Failed to open input method" -#~ msgstr "E286: Sytemetodin avaus ei onnistu" +#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI" +#~ msgstr "E617: Ei voi muuttaa GTK+2-GUIssa" -#~ msgid "E287: Warning: Could not set destroy callback to IM" -#~ msgstr "" -#~ "E287: Varoitus: Ei voitu asettaa destroy-kutsua sytemetodipalvelimelle" +#~ msgid "E531: Use \":gui\" to start the GUI" +#~ msgstr "E531: Käytä komentoa :gui GUIn käynnistämiseen" -#~ msgid "E288: input method doesn't support any style" -#~ msgstr "E288: sytemetodi ei tue tyylej" +#~ msgid "E530: Cannot change term in GUI" +#~ msgstr "E530: Ei voi vaihtaa termiä GUIssa" -#~ msgid "E289: input method doesn't support my preedit type" -#~ msgstr "E289: sytemetodi ei tue tt preedit-tyyppi" +#~ msgid "E522: Not found in termcap" +#~ msgstr "E522: Puuttuu termcapista" -#~ msgid "" -#~ "E833: %s is encrypted and this version of Vim does not support encryption" -#~ msgstr "E833: %s on salattu eik tm Vim tue salausta" +#~ msgid "Thanks for flying Vim" +#~ msgstr "Kiitos että ajoit Vimiä" -#~ msgid "Swap file is encrypted: \"%s\"" -#~ msgstr "Swap-tiedosto on salattu: %s" +#~ msgid "%<%f%h%m%=Page %N" +#~ msgstr "%<%f%h%m%=Sivu %N" #~ msgid "" #~ "\n" -#~ "If you entered a new crypt key but did not write the text file," +#~ "# Registers:\n" #~ msgstr "" #~ "\n" -#~ "Jos kytit uutta salausavainta muttet kirjoittanut tekstitiedostoa," +#~ "# Rekisterit:\n" -#~ msgid "" -#~ "\n" -#~ "enter the new crypt key." -#~ msgstr "" -#~ "\n" -#~ "anna uusi salausavain." +#~ msgid "Illegal register name" +#~ msgstr "Virheellinen rekisterin nimi" + +#~ msgid "freeing %ld lines" +#~ msgstr "vapautetaan %ld riviä" + +#~ msgid "cannot yank; delete anyway" +#~ msgstr "Ei voi kopioida; poista joka tapauksessa" + +#~ msgid "E775: Eval feature not available" +#~ msgstr "E775: Eval ei ole käytettävissä" + +#~ msgid "E505: %s is read-only (add ! to override)" +#~ msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)" + +#~ msgid "E511: netbeans already connected" +#~ msgstr "E511: netbeans on yhdistetty jo" + +#~ msgid "E838: netbeans is not supported with this GUI" +#~ msgstr "E838: netbeans ei toimi tässä käyttöliittymässä" + +#~ msgid "E658: NetBeans connection lost for buffer %ld" +#~ msgstr "E658: NetBeans-yhteys katkesi puskurille %ld" + +#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\"" +#~ msgstr "E668: Väärä avaustila NetBeans-yhteyden infotiedostolle: %s" + +#~ msgid "E547: Illegal mouseshape" +#~ msgstr "E547: Virheellinen hiiren muoto" + +#~ msgid "E341: Internal error: lalloc(%ld, )" +#~ msgstr "E341: Sisäinen virhe: lalloc(%ld, )" + +#~ msgid "E340: Line is becoming too long" +#~ msgstr "E340: Rivistä tulee liian pitkä" #~ msgid "" +#~ "[calls] total re/malloc()'s %lu, total free()'s %lu\n" #~ "\n" -#~ "If you wrote the text file after changing the crypt key press enter" #~ msgstr "" +#~ "[kutsut] yht. re/malloc() %lu, yht. free() %lu\n" #~ "\n" -#~ "Jos kirjoitit tekstitiedoston salausavaimen vaihdon jlkeen paina enteri" #~ msgid "" #~ "\n" -#~ "to use the same key for text file and swap file" +#~ "[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n" #~ msgstr "" #~ "\n" -#~ "kyttksesi samaa avainta teksti- ja swppitiedostoille" +#~ "[tavua] yht. alloc-free %lu-%lu, käytössä %lu, käyttöhuippu %lu\n" -#~ msgid "Using crypt key from swap file for the text file.\n" -#~ msgstr "Kytetn swpin salausavainta tekstitiedostolle\n" +#~ msgid "ERROR: " +#~ msgstr "VIRHE: " -#~ msgid "" -#~ "\n" -#~ " [not usable with this version of Vim]" -#~ msgstr "" -#~ "\n" -#~ " [ei toimi tmn Vim-version kanssa]" - -#~ msgid "Tear off this menu" -#~ msgstr "Repise valikko irti" +#~ msgid "E338: Sorry, no file browser in console mode" +#~ msgstr "E338: tiedostonselain puuttuu konsolitilasta" -#~ msgid "Select Directory dialog" -#~ msgstr "Hakemiston valintaikkuna" +#~ msgid "Open File dialog" +#~ msgstr "Avausikkuna" #~ msgid "Save File dialog" #~ msgstr "Tallennusikkuna" -#~ msgid "Open File dialog" -#~ msgstr "Avausikkuna" +#~ msgid "Select Directory dialog" +#~ msgstr "Hakemiston valintaikkuna" -#~ msgid "E338: Sorry, no file browser in console mode" -#~ msgstr "E338: Sori, tiedostonselain puuttuu konsolitilasta" +#~ msgid "Messages maintainer: Bram Moolenaar " +#~ msgstr "Käännöksen ylläpitäjä: Flammie Pirinen " -#~ msgid "Vim: preserving files...\n" -#~ msgstr "Vim: sstetn tiedostoja...\n" +#~ msgid "E337: Menu not found - check menu names" +#~ msgstr "E337: Valikkoa ei löytynyt - tarkista valikkojen nimet" -#~ msgid "Vim: Finished.\n" -#~ msgstr "Vim: Valmis.\n" +#~ msgid "E336: Menu path must lead to a sub-menu" +#~ msgstr "E336: Valikkopolun pitää johtaa alivalikkoon" -#~ msgid "ERROR: " -#~ msgstr "VIRHE: " +#~ msgid "Tear off this menu" +#~ msgstr "Repäise valikko irti" + +#~ msgid "Swap file already exists!" +#~ msgstr "Swap-tiedosto on jo olemassa" #~ msgid "" #~ "\n" -#~ "[bytes] total alloc-freed %-%, in use %, peak use " -#~ "%\n" +#~ " [not usable with this version of Vim]" #~ msgstr "" #~ "\n" -#~ "[tavua] yht. alloc-free %-%, kytss %, " -#~ "kytthuippu %\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 "" -#~ "[calls] total re/malloc()'s %, total free()'s %\n" #~ "\n" +#~ "to use the same key for text file and swap file" #~ msgstr "" -#~ "[kutsut] yht. re/malloc() %, yht. free() %\n" #~ "\n" +#~ "käyttääksesi samaa avainta teksti- ja swäppitiedostoille" -#~ msgid "E340: Line is becoming too long" -#~ msgstr "E340: Rivist tulee liian pitk" - -#~ msgid "E341: Internal error: lalloc(%, )" -#~ msgstr "E341: Sisinen virhe: lalloc(%, )" - -#~ msgid "E547: Illegal mouseshape" -#~ msgstr "E547: Virheellinen hiiren muoto" - -#~ msgid "Enter encryption key: " -#~ msgstr "Anna salausavain: " - -#~ msgid "Enter same key again: " -#~ msgstr "Anna sama avain uudestaan: " - -#~ msgid "Keys don't match!" -#~ msgstr "Avaimet eivt tsm!" - -#~ msgid "Cannot connect to Netbeans #2" -#~ msgstr "Ei voi yhdist Netbeans #2:een" - -#~ msgid "Cannot connect to Netbeans" -#~ msgstr "Ei voi yhdist Netbeansiin" - -#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\"" -#~ msgstr "E668: Vr avaustila NetBeans-yhteyden infotiedostolle: %s" +#~ msgid "" +#~ "\n" +#~ "If you wrote the text file after changing the crypt key press enter" +#~ msgstr "" +#~ "\n" +#~ "Jos kirjoitit tekstitiedoston salausavaimen vaihdon jälkeen paina enteriä" -#~ msgid "read from Netbeans socket" -#~ msgstr "luettu Netbeans-soketista" +#~ msgid "" +#~ "\n" +#~ "enter the new crypt key." +#~ msgstr "" +#~ "\n" +#~ "anna uusi salausavain." -#~ msgid "E658: NetBeans connection lost for buffer %" -#~ msgstr "E658: NetBeans-yhteys katkesi puskurille %" +#~ 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 "E511: netbeans already connected" -#~ msgstr "E511: netbeans on yhdistetty jo" +#~ msgid "Swap file is encrypted: \"%s\"" +#~ msgstr "Swap-tiedosto on salattu: %s" -#~ msgid "E505: " -#~ msgstr "E505: " +#~ 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 "E775: Eval feature not available" -#~ msgstr "E775: Eval ei ole kytettviss" +#~ msgid "E843: Error while updating swap file crypt" +#~ msgstr "E843: Virhe päivitettäessä swapin kryptausta" -#~ msgid "freeing % lines" -#~ msgstr "vapautetaan % rivi" +#~ msgid "E289: input method doesn't support my preedit type" +#~ msgstr "E289: syötemetodi ei tue tätä preedit-tyyppiä" -#~ msgid "E530: Cannot change term in GUI" -#~ msgstr "E530: Ei voi vaihtaa termi GUIssa" +#~ msgid "E288: input method doesn't support any style" +#~ msgstr "E288: syötemetodi ei tue tyylejä" -#~ msgid "E531: Use \":gui\" to start the GUI" -#~ msgstr "E531: Kyt komentoa :gui GUIn kynnistmiseen" +#~ msgid "E287: Warning: Could not set destroy callback to IM" +#~ msgstr "" +#~ "E287: Varoitus: Ei voitu asettaa destroy-kutsua syötemetodipalvelimelle" -#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI" -#~ msgstr "E617: Ei voi muuttaa GTK+2-GUIssa" +#~ msgid "E286: Failed to open input method" +#~ msgstr "E286: Syötemetodin avaus ei onnistu" -#~ msgid "E596: Invalid font(s)" -#~ msgstr "E596: Viallisia fontteja" +#~ msgid "E285: Failed to create input context" +#~ msgstr "E285: Syötekontekstin luonti ei onnistu" -#~ msgid "E597: can't select fontset" -#~ msgstr "E597: Fontsetin valinta ei onnistu" +#~ msgid "E284: Cannot set IC values" +#~ msgstr "E284: Ei voi asettaa IC-arvoja" -#~ msgid "E598: Invalid fontset" -#~ msgstr "E598: Viallinen fontset" +#~ msgid "E543: Not a valid codepage" +#~ msgstr "E543: Koodisivu ei ole käypä" -#~ msgid "E533: can't select wide font" -#~ msgstr "E533: Leven fontin valinta ei onnistu" +#~ msgid "Missing '>'" +#~ msgstr "> puuttuu" -#~ msgid "E534: Invalid wide font" -#~ msgstr "E534: Viallinen leve fontti" +#~ msgid "" +#~ "\n" +#~ "# History of marks within files (newest to oldest):\n" +#~ msgstr "" +#~ "\n" +#~ "# Tiedostojen merkkien historia (uusimmasta vanhimpaan):\n" -#~ msgid "E538: No mouse support" -#~ msgstr "E538: Hiirt ei tueta" +#~ msgid "" +#~ "\n" +#~ "# Jumplist (newest first):\n" +#~ msgstr "" +#~ "\n" +#~ "# Hyppylista (uusin ensiksi):\n" -#~ msgid "cannot open " -#~ msgstr "ei voi avata " +#~ msgid "" +#~ "\n" +#~ "# File marks:\n" +#~ msgstr "" +#~ "\n" +#~ "# Tiedoston merkit:\n" -#~ msgid "VIM: Can't open window!\n" -#~ msgstr "VIM: Ei voi avata ikkunaa\n" +#~ msgid ": Send expression failed.\n" +#~ msgstr ": Ilmauksen lähetys epäonnistui.\n" -#~ msgid "Need Amigados version 2.04 or later\n" -#~ msgstr "Amigados 2.04 tai uudempi tarvitaan\n" +#~ msgid "No display: Send expression failed.\n" +#~ msgstr "Ei näyttöä: Ilmauksen lähetys epäonnistui.\n" -#~ msgid "Need %s version %\n" -#~ msgstr "Tarvitaan %s versio %\n" +#~ msgid "%d of %d edited" +#~ msgstr "%d/%d muokattu" -#~ msgid "Cannot open NIL:\n" -#~ msgstr "Ei voi avata NILi:\n" +#~ msgid ": Send failed. Trying to execute locally\n" +#~ msgstr ": Lähetys epäonnistui. Yritetään suorittaa paikallisena\n" -#~ msgid "Cannot create " -#~ msgstr "Ei voi luoda " +#~ msgid ": Send failed.\n" +#~ msgstr ": Lähetys epäonnistui.\n" -#~ msgid "Vim exiting with %d\n" -#~ msgstr "Vim sulkeutuu koodilla %d\n" +#~ msgid "No display" +#~ msgstr "Ei näyttöä" -#~ msgid "cannot change console mode ?!\n" -#~ msgstr "ei voi vaihtaa konsolitilaa?\n" +#~ msgid "--windowid \tOpen Vim inside another win32 widget" +#~ msgstr "--windowid \tAvaa Vim annettuun win32-olioon " -#~ msgid "mch_get_shellsize: not a console??\n" -#~ msgstr "mch_get_shellsize: ei ole konsoli?\n" +#~ msgid "-P \tOpen Vim inside parent application" +#~ msgstr "-P \tAvaa Vim isäntäohjelman sisään" -#~ msgid "E360: Cannot execute shell with -f option" -#~ msgstr "E360: Kuorta ei voi avata asetuksella -f" +#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout" +#~ msgstr "--echo-wid\t\tTulosta gvimin Window ID vakiotulosteeseen" -#~ msgid "Cannot execute " -#~ msgstr "Ei voi suorittaa " +#~ msgid "--socketid \tOpen Vim inside another GTK widget" +#~ msgstr "--socketid \tAvaa Vim annettuun GTK-olioon " -#~ msgid "shell " -#~ msgstr "kuori " +# X-ikkunointijärjestelmässä saman sovelluksen saman luokan ikkunat +# tunnistetaan rooliresursseista +#~ msgid "--role \tSet a unique role to identify the main window" +#~ msgstr "" +#~ "--role \tAseta pääikkunalle ainutlaatuinen rooli tunnisteeksi" -#~ msgid " returned\n" -#~ msgstr " palautti\n" +#~ msgid "-display \tRun vim on (also: --display)" +#~ msgstr "-display \tSuorita vim näytöllä (myös: --display)" -#~ msgid "ANCHOR_BUF_SIZE too small." -#~ msgstr "ANCHOR_BUF_SIZE liian pieni." +#~ msgid "" +#~ "\n" +#~ "Arguments recognised by gvim (GTK+ version):\n" +#~ msgstr "" +#~ "\n" +#~ "Gvimin (GTK+-version) tuntemat argumentit:\n" -#~ msgid "I/O ERROR" -#~ msgstr "IO-virhe" +#~ msgid "-xrm \tSet the specified resource" +#~ msgstr "-xrm \tAseta resurssi" -#~ msgid "Message" -#~ msgstr "Viesti" +#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)" +#~ msgstr "+reverse\t\tÄlä käytä käänteisvärejä (myös: +rv)" -#~ msgid "'columns' is not 80, cannot execute external commands" -#~ msgstr "columns ei ole 80, ei voi suorittaa ulkoista komentoa" +#~ msgid "-reverse\t\tUse reverse video (also: -rv)" +#~ msgstr "-reverse\t\tKäytä käänteisvärejä (myös: -rv) " -#~ msgid "E237: Printer selection failed" -#~ msgstr "E237: Tulostimen valinta eponnistui" +#~ msgid "-menuheight \tUse a menu bar height of (also: -mh)" +#~ msgstr "-menuheight \tKäytä valikossa (myös: -mh)" -#~ msgid "to %s on %s" -#~ msgstr "tulostimelle %s kohteessa %s" +#~ msgid "" +#~ "-scrollbarwidth Use a scrollbar width of (also: -sw)" +#~ msgstr "" +#~ "-scrollbarwidth Käytä vierityspalkissa (myös: -sw)" -#~ msgid "E613: Unknown printer font: %s" -#~ msgstr "E613: Tuntematon tulostimen fontti: %s" +#~ msgid "-borderwidth \tUse a border width of (also: -bw)" +#~ msgstr "-borderwidt \tKäytä reunuksissa (myös: -bw) " -#~ msgid "E238: Print error: %s" -#~ msgstr "E238: Tulostinvirhe: %s" +#~ msgid "-geometry \tUse for initial geometry (also: -geom)" +#~ msgstr "" +#~ "-geometry \tKäytä mittoja ikkunan asetteluun (myös: -geom)" -#~ msgid "Printing '%s'" -#~ msgstr "Tulostetaan %s" +#~ msgid "-italicfont \tUse for italic text" +#~ msgstr "-italicfont \tKäytä kursivoidussa tekstissä" -#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\"" -#~ msgstr "E244: Virheellinen merkistn nimi %s fontin nimess %s" +#~ msgid "-boldfont \tUse for bold text" +#~ msgstr "-boldfont \tKäytä lihavoidussa tekstissä" -#~ msgid "E245: Illegal char '%c' in font name \"%s\"" -#~ msgstr "E245: Virheellinen merkki %c fontin nimess %s" +#~ msgid "-font \t\tUse for normal text (also: -fn)" +#~ msgstr "-font \t\tKäytä tekstissä (myös: -fn)" -#~ msgid "Vim: Double signal, exiting\n" -#~ msgstr "Vim: Kaksoissignaali, lopetetaan\n" +#~ msgid "-foreground \tUse for normal text (also: -fg)" +#~ msgstr "-foreground \tKäytä tekstin värinä (myös: -fg)" -#~ msgid "Vim: Caught deadly signal %s\n" -#~ msgstr "Vim: Tappava signaali %s\n" +#~ msgid "-background \tUse for the background (also: -bg)" +#~ msgstr "-background \tKäytä taustavärinä (myös: -bg)" -#~ msgid "Vim: Caught deadly signal\n" -#~ msgstr "Vim: Tappava signaali\n" +#~ msgid "-iconic\t\tStart vim iconified" +#~ msgstr "-iconic\t\tKäynnistä pienennettynä" -#~ msgid "Opening the X display took % msec" -#~ msgstr "X-nytn avaus vei % millisekuntia" +#~ msgid "-display \tRun vim on " +#~ msgstr "-display \tSuorita vim " #~ msgid "" #~ "\n" -#~ "Vim: Got X error\n" +#~ "Arguments recognised by gvim (Athena version):\n" #~ msgstr "" #~ "\n" -#~ "Vim: X-virhe\n" - -#~ msgid "Testing the X display failed" -#~ msgstr "X-nytn testaus eponnistui" - -#~ msgid "Opening the X display timed out" -#~ msgstr "X-nytn avaus aikakatkaistiin" +#~ "Gvimin (Athena-version) tuntemat argumentit:\n" #~ msgid "" #~ "\n" -#~ "Cannot execute shell sh\n" +#~ "Arguments recognised by gvim (neXtaw version):\n" #~ msgstr "" #~ "\n" -#~ "Kuoren sh suoritus ei onnistu\n" +#~ "Gvimin (neXtaw-version) tuntemat argumentit:\n" #~ msgid "" #~ "\n" -#~ "Cannot create pipes\n" +#~ "Arguments recognised by gvim (Motif version):\n" #~ msgstr "" #~ "\n" -#~ "Putkia ei voi tehd\n" +#~ "Gvimin (Motif-version) tuntemat argumentit:\n" + +#~ msgid "-i \t\tUse instead of .viminfo" +#~ msgstr "-i \t\tKäytä -tiedostoa .viminfon sijaan" + +#~ msgid "--servername \tSend to/become the Vim server " +#~ msgstr "--servername \tLähetä Vim-palvelimelle tai luo se" + +#~ msgid "--serverlist\t\tList available Vim server names and exit" +#~ msgstr "--serverlist\t\tLuettele Vim-palvelinten nimet ja lopeta" #~ msgid "" -#~ "\n" -#~ "Cannot fork\n" +#~ "--remote-expr \tEvaluate in a Vim server and print result" #~ msgstr "" -#~ "\n" -#~ "Ei voi haarauttaa\n" +#~ "--remote-expr \tKäsittele Vim-palvelimella ja tulosta " +#~ "tulos" + +#~ msgid "--remote-send \tSend to a Vim server and exit" +#~ msgstr "" +#~ "--remote-send \tLähetä painalluksina Vimille ja " +#~ "lopeta" #~ msgid "" -#~ "\n" -#~ "Command terminated\n" +#~ "--remote-tab[-wait][-silent] As --remote but use tab page per " +#~ "file" #~ msgstr "" -#~ "\n" -#~ "Komento loppui\n" +#~ "--remote-tab[-wait][-silent] kuten --remote, mutta avaa " +#~ "välilehti joka tiedostolle" -#~ msgid "XSMP lost ICE connection" -#~ msgstr "XSMP kadotti ICE-yhteyden" +#~ msgid "" +#~ "--remote-wait-silent Same, don't complain if there is no server" +#~ msgstr "" +#~ "--remote-wait-silent sama, mutta älä ilmoita puuttuvasta " +#~ "palvelimesta" -#~ msgid "Opening the X display failed" -#~ msgstr "X-nytn avaus eponnistui" +#~ msgid "" +#~ "--remote-wait As --remote but wait for files to have been edited" +#~ msgstr "" +#~ "--remote-wait kuten --remote, mutta odota tiedostojen " +#~ "muokkaamista" -#~ msgid "XSMP handling save-yourself request" -#~ msgstr "XSMP ksittelee save-yourself-pyynt" +#~ msgid "--remote-silent Same, don't complain if there is no server" +#~ msgstr "" +#~ "--remote-silent \tSama, mutta älä ilmoita puuttuvasta " +#~ "palvelimesta" -#~ msgid "XSMP opening connection" -#~ msgstr "XSMP avaa yhteytt" +#~ msgid "--remote \tEdit in a Vim server if possible" +#~ msgstr "" +#~ "--remote \tMuokkaa Vim-palvelimessa, jos " +#~ "mahdollista" -#~ msgid "XSMP ICE connection watch failed" -#~ msgstr "XSMP:n ICE-yhteyden tarkkailu eponnistui" +#~ msgid "-X\t\t\tDo not connect to X server" +#~ msgstr "-X\t\t\tÄlä yhdistä X-palvelimeen" -#~ msgid "XSMP SmcOpenConnection failed: %s" -#~ msgstr "XSMP SmcOpenConnection eponnistui: %s" +#~ msgid "-display \tConnect vim to this particular X-server" +#~ msgstr "-display \tYhdistä vim tiettyyn X-palvelimeen" -#~ msgid "At line" -#~ msgstr "Rivill" +#~ msgid "-x\t\t\tEdit encrypted files" +#~ msgstr "-x\t\t\tMuokkaa salattua tiedostoa" -#~ msgid "Could not load vim32.dll!" -#~ msgstr "Vim32.dll: ei voitu ladata" +#~ msgid "+\t\t\tStart at end of file" +#~ msgstr "+\t\t\tAloita tiedoston lopusta" -#~ msgid "VIM Error" -#~ msgstr "VIM-virhe" +#~ msgid "-U \t\tUse instead of any .gvimrc" +#~ msgstr "-U \t\tKäytä -tiedostoa .gvimrc:iden sijasta" -#~ msgid "Could not fix up function pointers to the DLL!" -#~ msgstr "Ei voitu korjata funktio-osoittimia DLL:ss" +#~ 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 "shell returned %d" -#~ msgstr "kuori palautti arvon %d" +#~ msgid "-T \tSet terminal type to " +#~ msgstr "-T \tAseta terminaalin tyypiksi " -#~ msgid "Vim: Caught %s event\n" -#~ msgstr "Vim: Napattiin %s\n" +#~ msgid "-F\t\t\tStart in Farsi mode" +#~ msgstr "-F\t\t\tkäynnistä farsi-tilassa" -#~ msgid "close" -#~ msgstr "sulkeminen" +#~ msgid "-H\t\t\tStart in Hebrew mode" +#~ msgstr "-H\t\t\tkäynnistä heprea-tilassa" -#~ msgid "logoff" -#~ msgstr "uloskirjautuminen" +#~ msgid "-A\t\t\tstart in Arabic mode" +#~ msgstr "-A\t\t\tkäynnistä arabia-tilassa" -#~ msgid "shutdown" -#~ msgstr "sammutus" +#~ msgid "-dev \t\tUse for I/O" +#~ msgstr "-dev \t\tKäytä IO:hon" -#~ msgid "E371: Command not found" -#~ msgstr "E371: Komentoa ei lydy" +#~ msgid "-f\t\t\tDon't use newcli to open window" +#~ msgstr "-f\t\t\tÄlä käytä newcli:tä ikkunan avaamiseen" -#~ 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 lydy muuttujasta $PATH.\n" -#~ "Ulkoiset komennot eivt pyshdy suorituksen lopussa.\n" -#~ "Listietoja komennolla :help win32-vimrun" +#~ msgid "-L\t\t\tSame as -r" +#~ msgstr "-L\t\t\tkuten -r" -#~ msgid "Vim Warning" -#~ msgstr "Vim-varoitus" +#~ msgid "-D\t\t\tDebugging mode" +#~ msgstr "-D\t\t\tVianetsintätila" -#~ msgid "Error file" -#~ msgstr "Virhetiedosto" +#~ msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'" +#~ msgstr "-N\t\t\tEi Vi-yhteensopivuutta: nocompatible" -#~ msgid "Conversion in %s not supported" -#~ msgstr "Muutosta kohteessa %s ei tueta" +#~ msgid "-C\t\t\tCompatible with Vi: 'compatible'" +#~ msgstr "-C\t\t\tVi-yhteensopivuustila: compatible" -#~ msgid "E430: Tag file path truncated for %s\n" -#~ msgstr "E430: Tgitiedoston polku katkaistu kohdassa %s\n" +#~ msgid "-l\t\t\tLisp mode" +#~ msgstr "-l\t\t\tLisp-tila" -#~ msgid "new shell started\n" -#~ msgstr "uusi kuori avattu\n" +#~ msgid "-b\t\t\tBinary mode" +#~ msgstr "-b\t\t\tBinääritila" -#~ msgid "Used CUT_BUFFER0 instead of empty selection" -#~ msgstr "Kytettiin CUT_BUFFER0:aa tyhjn valinnan sijaan" +#~ msgid "-Z\t\t\tRestricted mode (like \"rvim\")" +#~ msgstr "-Z\t\t\tRajoitettu tila (kuten rvimillä)" -#~ msgid "No undo possible; continue anyway" -#~ msgstr "Ei voi kumota, jatketaan silti" +#~ msgid "-R\t\t\tReadonly mode (like \"view\")" +#~ msgstr "-R\t\t\tKirjoitussuojattu tila (kuten view'lla)" -#~ msgid "E832: Non-encrypted file has encrypted undo file: %s" -#~ msgstr "E832: Salaamattomalla tiedostolla on salattu kumoustiedosto: %s" +#~ msgid "-y\t\t\tEasy mode (like \"evim\", modeless)" +#~ msgstr "-y\t\t\tHelppokäyttötila (kuten evimissä, ilman tiloja)" -#~ msgid "E826: Undo file decryption failed: %s" -#~ msgstr "E826: Kumoustiedoston purku eponnistui: %s" +#~ msgid "-d\t\t\tDiff mode (like \"vimdiff\")" +#~ msgstr "-d\t\t\tDiff-tila (kuten vimdiffillä)" -#~ msgid "E827: Undo file is encrypted: %s" -#~ msgstr "E827: Kumoustiedosto on salattu: %s" +#~ msgid "-E\t\t\tImproved Ex mode" +#~ msgstr "-E\t\t\tParanneltu Ex-tila" + +#~ msgid "-e\t\t\tEx mode (like \"ex\")" +#~ msgstr "-e\t\t\tEx-tila (kute exillä)" + +#~ msgid "-v\t\t\tVi mode (like \"vi\")" +#~ msgstr "-v\t\t\tVi-tila (kuten villä)" + +#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI" +#~ msgstr "-f tai --nofork\tEdustalle: Älä haarauta GUIn käynnistyksessä" + +#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")" +#~ msgstr "-g\t\t\tAvaa GUI (kuten gvimillä)" + +#~ msgid "-unregister\t\tUnregister gvim for OLE" +#~ msgstr "-unregister\t\tPoista gvim OLE-rekisteristä" + +#~ msgid "-register\t\tRegister this gvim for OLE" +#~ msgstr "-register\t\trekisteröi gvim OLEa varten" #~ msgid "" #~ "\n" -#~ "MS-Windows 16/32-bit GUI version" +#~ "Where case is ignored prepend / to make flag upper case" #~ msgstr "" #~ "\n" -#~ "MS-Windows 16- t. 32-bittinen GUI-versio" +#~ "Jos aakkoslaji on ohitettu, lisää alkuun / tehdäksesi asetuksesta " +#~ "suuraakkosia" #~ msgid "" #~ "\n" -#~ "MS-Windows 64-bit GUI version" +#~ " or:" #~ msgstr "" #~ "\n" -#~ "MS-Windows 64-bittinen GUI-versio" +#~ " tai:" + +#~ msgid " vim [arguments] " +#~ msgstr " vim [argumentit] " + +#~ 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 "Vim: Error: Failure to start gvim from NetBeans\n" +#~ msgstr "Vim: Virhe: Gvimin käynnistys NetBeansistä ei onnistu\n" + +#~ msgid "This Vim was not compiled with the diff feature." +#~ msgstr "Tähän Vimiin ei ole käännetty diff-toimintoja mukaan." + +#~ msgid "'-nb' cannot be used: not enabled at compile time\n" +#~ msgstr "-nb:tä ei voi käyttää, koska sitä ei käännetty mukaan\n" + +#~ msgid "netbeans is not supported with this GUI\n" +#~ msgstr "netbeans ei toimi tässä käyttöliittymässä\n" + +#~ msgid "%d files to edit\n" +#~ msgstr "%d tiedostoa muokattavana\n" + +#~ msgid "E251: VIM instance registry property is badly formed. Deleted!" +#~ msgstr "E251: VIMin instanssin rekisteriarvo on virheellinen, poistettiin." + +#~ msgid "E573: Invalid server id used: %s" +#~ msgstr "E573: Virheellinen palvelimen tunniste: %s" + +#~ msgid "E248: Failed to send command to the destination program" +#~ msgstr "E248: Komennon lähetys kohdeohjelmalle ei onnistu" + +#~ msgid "Unable to register a command server name" +#~ msgstr "Komentopalvelimen nimen rekisteröinti ei onnistu" + +#~ msgid "cannot get line" +#~ msgstr "ei voida hakea riviä" + +#~ msgid "E572: exit code %d" +#~ msgstr "E572: palautusarvo %d" #~ msgid "" -#~ "\n" -#~ "MS-Windows 32-bit GUI version" +#~ "E571: Sorry, this command is disabled: the Tcl library could not be " +#~ "loaded." +#~ msgstr "E571: komento ei toimi, Tcl-kirjastoa ei voitu ladata." + +#~ msgid "cannot register callback command: buffer/window reference not found" #~ msgstr "" -#~ "\n" -#~ "MS-Windows 32-bittinen GUI-version" +#~ "callbackia ei voi rekisteröidä: puskurin tai ikkunan viitettä ei löydy" -#~ msgid " in Win32s mode" -#~ msgstr " Win32s-tilassa" +#~ 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 " with OLE support" -#~ msgstr " OLE-tuella" +#~ msgid "" +#~ "cannot register callback command: buffer/window is already being deleted" +#~ msgstr "callbackia ei voi rekisteröidä: puskuri tai ikkuna on poistettu" + +#~ msgid "cannot create buffer/window command: object is being deleted" +#~ msgstr "ei voi luoda puskuri- tai ikkunakomentoa, olio on poistumassa" + +#~ msgid "vim error" +#~ msgstr "vim-virhe" + +#~ msgid "unknown vimOption" +#~ msgstr "tuntematon vimOption" + +#~ msgid "unknown flag: " +#~ msgstr "tuntematon asetus: " + +#~ msgid "cannot insert/append line" +#~ msgstr "rivin lisäys ei onnistu" + +#~ 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 "not implemented yet" +#~ msgstr "ei toteutettu" + +#~ msgid "E273: unknown longjmp status %d" +#~ msgstr "E273: tuntematon longjmp-tila %d" + +#~ msgid "E272: unhandled exception" +#~ msgstr "E272: käsittelemätön poikkeus" + +#~ msgid "E271: retry outside of rescue clause" +#~ msgstr "E271: retry rescuen ulkopuolella" + +#~ msgid "E269: unexpected break" +#~ msgstr "E269: Odotuksenvastainen break" + +#~ msgid "E268: unexpected next" +#~ msgstr "E268: Odotuksenvastainen next" + +#~ msgid "E267: unexpected return" +#~ msgstr "E267: odotuksenvastainen return" #~ msgid "" -#~ "\n" -#~ "MS-Windows 64-bit console version" +#~ "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" -#~ "MS-Windows 32-bittinen konsoliversio" +#~ "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 "" +#~ "E887: Sorry, this command is disabled, the Python's site module could not " +#~ "be loaded." +#~ msgstr "" +#~ "E887: Komento ei toimi, Pythonin site-moduulien lataaminen ei onnistunut." + +#~ msgid "" +#~ "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 "" +#~ "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 "" +#~ "E895: Sorry, this command is disabled, the MzScheme's racket/base module " +#~ "could not be loaded." +#~ msgstr "" +#~ "E895: Komento ei toimi, MzScheme-moduulia racket/base ei voitu ladata." + +#~ 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 "Lua library cannot be loaded." +#~ msgstr "Luan kirjastoa ei voitu ladata." + +#~ msgid "E626: cannot get cscope database information" +#~ msgstr "E626: ei voi hakea cscope-tietokannan tietoja" + +#~ msgid "E625: cannot open cscope database: %s" +#~ msgstr "E625: ei voi avata cscope-tietokantaa: %s" + +#~ msgid "E563: stat error" +#~ msgstr "E563: stat-virhe" + +#~ msgid "E256: Hangul automata ERROR" +#~ msgstr "E256: Hangu-automaattivirhe" + +#~ msgid "Size:" +#~ msgstr "Koko:" + +#~ msgid "Style:" +#~ msgstr "Tyyli:" + +#~ msgid "Font:" +#~ msgstr "Fontti:" + +#~ msgid "Encoding:" +#~ msgstr "Koodaus:" + +#~ msgid "Show size in Points" +#~ msgstr "Näytä koko pisteinä" + +#~ msgid "Name:" +#~ msgstr "Nimi:" + +#~ msgid "Vim - Font Selector" +#~ msgstr "Vim - fonttivalitsin" + +#~ msgid "no specific match" +#~ msgstr "ei tarkkaa täsmäystä" + +#~ msgid "&Dismiss" +#~ msgstr "&Ohita" + +#~ 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 "" +#~ "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" + +# MDI eli windowsin moni-ikkunasovellus +#~ msgid "E672: Unable to open window inside MDI application" +#~ msgstr "E672: Ikkunaa ei voitu avata MDI-sovellukseen" + +# 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 "Directory\t*.nothing\n" +#~ msgstr "Hakemisto\t*.nothing\n" + +#~ msgid "Not Used" +#~ msgstr "Ei käytössä" + +#~ msgid "Find & Replace (use '\\\\' to find a '\\')" +#~ msgstr "Etsi ja korvaa (\\\\:llä löytää \\:t)" + +#~ msgid "Find string (use '\\\\' to find a '\\')" +#~ msgstr "Etsi merkkijonoa (\\\\:llä löytää \\:t)" + +#~ msgid "Open tab..." +#~ msgstr "Avaa välilehti..." + +#~ msgid "&Undo" +#~ msgstr "&Kumoa" + +#~ msgid "Replace &All" +#~ msgstr "Korvaa k&aikki" + +#~ msgid "&Replace" +#~ msgstr "Ko&rvaa" + +#~ msgid "Find &Next" +#~ msgstr "Hae &seuraava" + +#~ msgid "Selection" +#~ msgstr "Valinta" + +#~ msgid "&OK" +#~ msgstr "&Ok" + +#~ msgid "Files" +#~ msgstr "Tiedostot" + +#~ msgid "&Help" +#~ msgstr "O&hje" + +#~ msgid "Filter" +#~ msgstr "Suodatus" + +#~ msgid "Directories" +#~ msgstr "Hakemistot" + +#~ msgid "&Cancel" +#~ msgstr "&Peru" + +#~ msgid "&Filter" +#~ msgstr "&Suodata" + +#~ msgid "Vim: Main window unexpectedly destroyed\n" +#~ msgstr "Vim: Pääikkuna tuhoutui odottamatta\n" + +#~ msgid "Open Tab..." +#~ msgstr "Avaa välilehti..." + +#~ msgid "New tab" +#~ msgstr "Uusi välilehti" + +#~ msgid "Close tab" +#~ msgstr "Sulje välilehti" + +#~ msgid "Vim: Received \"die\" request from session manager\n" +#~ msgstr "Vim: sessiomanageri lähetti die-pyynnön\n" + +#~ msgid "_Close" +#~ msgstr "_Sulje" + +#~ msgid "Replace All" +#~ msgstr "Korvaa kaikki" + +#~ msgid "Replace" +#~ msgstr "Korvaa" + +#~ msgid "Find Next" +#~ msgstr "Etsi seuraava" + +#~ msgid "Down" +#~ msgstr "Alas" + +#~ msgid "Up" +#~ msgstr "Ylös" + +#~ msgid "Direction" +#~ msgstr "Suunta" + +#~ msgid "Match case" +#~ msgstr "Kirjaintaso" + +#~ msgid "Match whole word only" +#~ msgstr "Korvaa kokonaisia sanoja" + +#~ msgid "Replace with:" +#~ msgstr "Korvaa:" + +#~ msgid "Find what:" +#~ msgstr "Etsi:" + +#~ msgid "VIM - Search..." +#~ msgstr "VIM - Etsi..." + +#~ msgid "VIM - Search and Replace..." +#~ msgstr "VIM - Etsi ja korvaa..." + +#~ msgid "Input _Methods" +#~ msgstr "Syöte_menetelmät" + +#~ msgid "No" +#~ msgstr "Ei" + +#~ msgid "Yes" +#~ msgstr "Kyllä" + +#~ msgid "_OK" +#~ msgstr "_OK" + +#~ msgid "_Open" +#~ msgstr "_Avaa" + +#~ msgid "_Save" +#~ msgstr "_Tallenna" + +#~ msgid "_Cancel" +#~ msgstr "_Peru" + +#~ msgid "E232: Cannot create BalloonEval with both message and callback" +#~ msgstr "E232: Ei voi luoda BalloonEvalia viestille ja callbackille" + +#~ msgid "Vim dialog" +#~ msgstr "Vim-ikkuna" + +#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." +#~ msgstr "Vierityspalkki: Pixmapin geometria ei selviä" -#~ msgid "" -#~ "\n" -#~ "MS-Windows 32-bit console version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 32-bittinen konsoliversio" +#~ msgid "Cancel" +#~ msgstr "Peru" -#~ msgid "" -#~ "\n" -#~ "MS-Windows 16-bit version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 16-bittinen versio" +#~ msgid "OK" +#~ msgstr "OK" -#~ msgid "" -#~ "\n" -#~ "32-bit MS-DOS version" -#~ msgstr "" -#~ "\n" -#~ "32-bittinen MS-DOS-versio" +#~ msgid "E615: vim_SelFile: can't get current directory" +#~ msgstr "E615: vim_SelFile: nykyistä hakemistoa ei saada selville" -#~ msgid "" -#~ "\n" -#~ "16-bit MS-DOS version" -#~ msgstr "" -#~ "\n" -#~ "16-bittinen MS-DOS-versio" +#~ msgid "Pathname:" +#~ msgstr "Polku:" -#~ msgid "" -#~ "\n" -#~ "MacOS X (unix) version" -#~ msgstr "" -#~ "\n" -#~ "MacOS X-version (unix)" +#~ msgid "E614: vim_SelFile: can't return to current directory" +#~ msgstr "E614: vim_SelFile: nykyiseen hakemistoon ei voi palata" -#~ msgid "" -#~ "\n" -#~ "MacOS X version" -#~ msgstr "" -#~ "\n" -#~ "MacOS X-version" +#~ msgid "E616: vim_SelFile: can't get font %s" +#~ msgstr "E616: vim_SelFile: ei saada fonttia %s" -#~ msgid "" -#~ "\n" -#~ "MacOS version" -#~ msgstr "" -#~ "\n" -#~ "MacOS-version" +#~ msgid " " +#~ msgstr " " -#~ msgid "" -#~ "\n" -#~ "RISC OS version" -#~ msgstr "" -#~ "\n" -#~ "RISC OS-version" +#~ msgid "No match at cursor, finding next" +#~ msgstr "Ei täsmäystä kursorin alla, etsitään seuraava" -#~ msgid "" -#~ "\n" -#~ "OpenVMS version" -#~ msgstr "" -#~ "\n" -#~ "OpenVMS-version" +#~ msgid "E599: Value of 'imactivatekey' is invalid" +#~ msgstr "E599: imactivatekeyn arvo on virheellinen" -#~ msgid "" -#~ "\n" -#~ "Big version " -#~ msgstr "" -#~ "\n" -#~ "Big-version " +#~ msgid "E231: 'guifontwide' invalid" +#~ msgstr "E231: guifontwide virheellinen" -#~ msgid "" -#~ "\n" -#~ "Normal version " -#~ msgstr "" -#~ "\n" -#~ "Normal-versio " +#~ msgid "E665: Cannot start GUI, no valid font found" +#~ msgstr "E665: Ei voi avata GUIta, sopivaa fonttia ei löydy" -#~ msgid "" -#~ "\n" -#~ "Small version " -#~ msgstr "" -#~ "\n" -#~ "Small-versio " +#~ msgid "E230: Cannot read from \"%s\"" +#~ msgstr "E230: Ei voi lukea kohteesta %s" -#~ msgid "" -#~ "\n" -#~ "Tiny version " -#~ msgstr "" -#~ "\n" -#~ "Tiny-versio " +#~ msgid "E229: Cannot start the GUI" +#~ msgstr "E229: GUIn käynnistys ei onnistu" -#~ msgid "with GTK2-GNOME GUI." -#~ msgstr "GTK2-Gnome-GUIlla." +#~ msgid "E851: Failed to create a new process for the GUI" +#~ msgstr "E851: Ei voitu luoda uutta prosessia käyttöliittymälle" -#~ msgid "with GTK2 GUI." -#~ msgstr "GTK2-GUIlla." +# 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 "with X11-Motif GUI." -#~ msgstr "X11-Motif-GUIlla." +#~ msgid "writing to device disabled with 'opendevice' option" +#~ msgstr "laitteeseen kirjoittaminen pois käytöstä opendevice-asetuksella" -#~ msgid "with X11-neXtaw GUI." -#~ msgstr "X11-neXtaw-GUIlla." +#~ msgid "Partial writes disallowed for NetBeans buffers" +#~ msgstr "Osittaiset kirjoitukset kielletty NetBeans-puskureissa" -#~ msgid "with X11-Athena GUI." -#~ msgstr "X11-Athena-GUIlla." +#~ msgid "NetBeans disallows writes of unmodified buffers" +#~ msgstr "NetBeans ei salli kirjoittaa muokkaamattomiin puskureihin" -#~ msgid "with Photon GUI." -#~ msgstr "Photon-GUIlla." +#~ msgid "Reading from stdin..." +#~ msgstr "Luetaan vakiosyötteestä" -#~ msgid "with GUI." -#~ msgstr "GUIlla." +#~ msgid "Vim: Reading from stdin...\n" +#~ msgstr "Vim: Luetaan vakiosyötteestä...\n" -#~ msgid "with Carbon GUI." -#~ msgstr "Carbon-GUIlla." +#~ msgid "is a device (disabled with 'opendevice' option)" +#~ msgstr "on laite (ei käytössä opendevice-asetuksen takia)" -#~ msgid "with Cocoa GUI." -#~ msgstr "Cocoa-GUIlla." +#~ msgid "Debug Line" +#~ msgstr "Vianetsintärivi" -#~ msgid "with (classic) GUI." -#~ msgstr "perinteisell GUIlla." +#~ msgid "Input Line" +#~ msgstr "Syöterivi" -#~ msgid " system gvimrc file: \"" -#~ msgstr " jrjestelmn gvimrc: \"" +#~ msgid "Expression" +#~ msgstr "Ilmaus" -#~ msgid " user gvimrc file: \"" -#~ msgstr " kyttjn gvimrc: \"" +#~ msgid "Search String" +#~ msgstr "Hakujono" -#~ msgid "2nd user gvimrc file: \"" -#~ msgstr "2. kyttjn gvimrc: \"" +#~ msgid "Command Line" +#~ msgstr "Komentorivi" -#~ msgid "3rd user gvimrc file: \"" -#~ msgstr "3. kyttjn gvimrc: \"" +#~ msgid "" +#~ "\n" +#~ "# %s History (newest to oldest):\n" +#~ msgstr "" +#~ "\n" +#~ "# %s Historia (uusimmasta alkaen):\n" -#~ msgid " system menu file: \"" -#~ msgstr " jrjestelmvalikko: \"" +#~ msgid "E196: No digraphs in this version" +#~ msgstr "E196: Digraafeja ei ole tässä versiossa" -#~ msgid "Compiler: " -#~ msgstr "Knnin: " +#~ msgid "E195: Cannot open viminfo file for reading" +#~ msgstr "E195: Viminfoa ei voi avata lukemista varten" -#~ msgid "menu Help->Orphans for information " -#~ msgstr "valikko Ohje->Orvot listietoja varten " +#~ msgid "E809: #< is not available without the +eval feature" +#~ msgstr "E809: #< ei ole käytössä jollei +eval ole päällä" -#~ msgid "Running modeless, typed text is inserted" -#~ msgstr "Suoritetaan tilattomana, kirjoitettu teksti sytetn" +#~ msgid "Save Setup" +#~ msgstr "Tallenna asetukset" -#~ msgid "menu Edit->Global Settings->Toggle Insert Mode " -#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda sytetilaa" +#~ msgid "Save Session" +#~ msgstr "Tallenna sessio" -#~ msgid " for two modes " -#~ msgstr " kahta tilaa varten " +#~ msgid "Save View" +#~ msgstr "Tallenna näkymä" -#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible" -#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda Vi-yhteensopivuutta" +#~ msgid "Save Redirection" +#~ msgstr "Tallenna uudelleenosoitus" -#~ msgid " for Vim defaults " -#~ msgstr " Vim-oletuksia varten" +#~ msgid "E930: Cannot use :redir inside execute()" +#~ msgstr "E930: Komentoa :redir ei voi käyttää funktion execute() sisällä" -#~ msgid "WARNING: Windows 95/98/ME detected" -#~ msgstr "VAROITUS: Window 95/98/ME havaittu" +#~ msgid "E466: :winpos requires two number arguments" +#~ msgstr "E466: :winpos vaatii kaksi lukuargumenttia" -#~ msgid "type :help windows95 for info on this" -#~ msgstr "kirjoita :help windows95 listietoja varten" +#~ msgid "E188: Obtaining window position not implemented for this platform" +#~ msgstr "E188: Ikkunan sijainnin selvitys ei toimi tällä alustalla" -#~ msgid "E370: Could not load library %s" -#~ msgstr "E370: Kirjaston %s lataaminen ei onnistu" +#~ msgid "Window position: X %d, Y %d" +#~ msgstr "Ikkunan sijainti: X %d, Y %d" #~ msgid "" -#~ "Sorry, this command is disabled: the Perl library could not be loaded." -#~ msgstr "Sori, komento ei toimi, Perl kirjastoa ei voinut ladata." +#~ "E747: Cannot change directory, buffer is modified (add ! to override)" +#~ msgstr "" +#~ "E747: Hakemistoa ei voida muuttaa, puskuria on muokattu (lisää " +#~ "komentoon ! ohittaaksesi" -#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" -#~ msgstr "E299: Perl-suoritus kielletty hiekkalaatikossa ilman Safe-moduulia" +#~ msgid "Append File" +#~ msgstr "Lisää tiedostoon" -#~ msgid "Edit with &multiple Vims" -#~ msgstr "&Muokkaa usealla Vimill" +#~ msgid "Edit File in new window" +#~ msgstr "Muokkaa uudessa ikkunassa" -#~ msgid "Edit with single &Vim" -#~ msgstr "Muokkaa yhdell &Vimill" +#~ msgid "unknown" +#~ msgstr "tuntematon" -#~ msgid "Diff with Vim" -#~ msgstr "Diffi Vimill" +#~ msgid "E172: Only one file name allowed" +#~ msgstr "E172: Vain yksi tiedostonimi sallitaan" -#~ msgid "Edit with &Vim" -#~ msgstr "Muokkaa &Vimill" +#~ msgid "Source Vim script" +#~ msgstr "Lataa vim-skripti" -#~ msgid "Edit with existing Vim - " -#~ msgstr "Muokkaa olemassaolevalla Vimill - " +#~ msgid " (NOT FOUND)" +#~ msgstr " (EI LÖYTYNYT)" -#~ msgid "Edits the selected file(s) with Vim" -#~ msgstr "Muokkaa valittuja tiedostoja Vimill" +#~ msgid "" +#~ "\n" +#~ "# Last Substitute String:\n" +#~ "$" +#~ msgstr "" +#~ "\n" +#~ "# Viimeisin korvausmerkkijono:\n" +#~ "$" -#~ msgid "Error creating process: Check if gvim is in your path!" -#~ msgstr "Virhe prosessin kynnistmisess, varmista ett gvim on polulla" +#~ msgid "Edit File" +#~ msgstr "Muokkaa tiedostoa" -#~ msgid "gvimext.dll error" -#~ msgstr "gvimext.dll-virhe" +#~ msgid "Save As" +#~ msgstr "Tallenna nimellä" -#~ msgid "Path length too long!" -#~ msgstr "Liian pitk polku" +#~ msgid "" +#~ "\n" +#~ "# Bar lines, copied verbatim:\n" +#~ msgstr "" +#~ "\n" +#~ "# Bar-rivit, kopiotu sellaisenaan:\n" -#~ msgid "E234: Unknown fontset: %s" -#~ msgstr "E234: Tuntematon fontset: %s" +#~ msgid "Illegal starting char" +#~ msgstr "Virheellinen aloitusmerkki" -#~ msgid "E235: Unknown font: %s" -#~ msgstr "E235: Tuntematon fontti: %s" +#~ msgid "# Value of 'encoding' when this file was written\n" +#~ msgstr "# encoding-muuttujan arvo tiedostoa kirjoitettaessa\n" -#~ msgid "E236: Font \"%s\" is not fixed-width" -#~ msgstr "E236: Fontti %s ei ole tasavlinen" +#~ msgid "" +#~ "# You may edit it if you're careful!\n" +#~ "\n" +#~ msgstr "" +#~ "# Muokkaa varovasti!\n" +#~ "\n" -#~ msgid "E448: Could not load library function %s" -#~ msgstr "E448: Ei voitu ladta kirjastofunktiota %s" +#~ msgid "# This viminfo file was generated by Vim %s.\n" +#~ msgstr "# Vimin %s generoima viminfo-tiedosto.\n" -#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" -#~ msgstr "E26: Hepreaa ei voi kytt, koska sit ei knnetty mukaan\n" +#~ msgid "E138: Can't write viminfo file %s!" +#~ msgstr "E138: Viminfo-tiedoston kirjoittaminen ei onnistu %s" -#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n" -#~ msgstr "E27: Farsia ei voi kytt, koska sit ei knnetty mukaan\n" +#~ msgid "E929: Too many viminfo temp files, like %s!" +#~ msgstr "E929: liikaa viminfo-väliaikaistiedostoja, kuten %s." -#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n" -#~ msgstr "E800: Arabiaa ei voi kytt, koska sit ei knnetty mukaan\n" +#~ msgid "E136: viminfo: Too many errors, skipping rest of file" +#~ msgstr "E136: viminfo: liikaa virheitä, ohitetaan lopputiedosto" -#~ msgid "E247: no registered server named \"%s\"" -#~ msgstr "E247: palvelinta %s ei ole rekisterityn" +#~ msgid "%sviminfo: %s in line: " +#~ msgstr "%sviminfo: %s rivillä: " -#~ msgid "E233: cannot open display" -#~ msgstr "E233: nytt ei voi avata" +#~ msgid "E258: Unable to send to client" +#~ msgstr "E258: Asiakkaalle lähetys ei onnistunut" -#~ msgid "E449: Invalid expression received" -#~ msgstr "E449: Virheellinen ilmaus saatu" +#~ msgid "E277: Unable to read a server reply" +#~ msgstr "E277: Palvelimen vastauksen lukeminen ei onnistunut" -#~ msgid "E463: Region is guarded, cannot modify" -#~ msgstr "E463: Alue on suojattu, muuttaminen ei onnistu" +#~ msgid "E240: No connection to Vim server" +#~ msgstr "E240: Ei yhteyttä vim-palvelimeen" -#~ msgid "E744: NetBeans does not allow changes in read-only files" -#~ msgstr "E744: NetBeans ei tue muutoksia kirjoitussuojattuihin tiedostoihin" +#~ msgid "" +#~ "&OK\n" +#~ "&Cancel" +#~ msgstr "" +#~ "&OK\n" +#~ "&Peru" -#~ msgid "Need encryption key for \"%s\"" -#~ msgstr "Tarvitaan salausavain kohteelle %s " +#~ msgid "" +#~ "\n" +#~ "# global variables:\n" +#~ msgstr "" +#~ "\n" +#~ "# globaalit muuttujat:\n" -#~ msgid "writelines() requires list of strings" -#~ msgstr "writelines()-komennolle pit antaa merkkijonolista" +#~ msgid "E729: using Funcref as a String" +#~ msgstr "E729: Funcref ei käy merkkijonosta" -#~ msgid "E264: Python: Error initialising I/O objects" -#~ msgstr "E264: Python: Virhe IO-olioiden alustuksessa" +#~ msgid "E914: Using a Channel as a Float" +#~ msgstr "E914: Käytettiin Channelia Floattina" -#~ msgid "no such buffer" -#~ msgstr "puskuria ei ole" +#~ msgid "E911: Using a Job as a Float" +#~ msgstr "E911: Job ei käy Floatista" -#~ msgid "attempt to refer to deleted window" -#~ msgstr "yritettiin viitata poistettuun ikkunaan" +#~ msgid "E913: Using a Channel as a Number" +#~ msgstr "E913: Channel ei käy Numberista" -#~ msgid "readonly attribute" -#~ msgstr "kirjoitussuojattu attribuutti" +#~ msgid "E910: Using a Job as a Number" +#~ msgstr "E910: Job ei käy Numberista" -#~ msgid "cursor position outside buffer" -#~ msgstr "kursorin sijainti puskurin ulkopuolella" +#~ msgid "E703: Using a Funcref as a Number" +#~ msgstr "E703: Funcref ei käy Numberista" -#~ msgid "" -#~ msgstr "" +#~ msgid "E724: variable nested too deep for displaying" +#~ msgstr "E724: muuttuja on upotettu liian syvälle näytettäväksi" -#~ msgid "" -#~ msgstr "" +#~ msgid "Patch file" +#~ msgstr "Patch-tiedosto" -#~ msgid "" -#~ msgstr "" +#~ msgid "[crypted]" +#~ msgstr "[salattu]" -#~ msgid "no such window" -#~ msgstr "ikkunaa ei ole" +#~ msgid "Keys don't match!" +#~ msgstr "Avaimet eivät täsmää!" -#~ msgid "attempt to refer to deleted buffer" -#~ msgstr "yritettiin viitata poistettuun puskuriin" +#~ msgid "Enter same key again: " +#~ msgstr "Anna sama avain uudestaan: " + +#~ msgid "Enter encryption key: " +#~ msgstr "Anna salausavain: " + +#~ msgid "Warning: Using a weak encryption method; see :help 'cm'" +#~ msgstr "Varoitus: Käytetään heikkoa salausmenetelmää, ks. :help 'cm'" -# New Line eli uusi rivinvaihtomerkki (ei CR, LF tai CR LF) -#~ msgid "[NL found]" -#~ msgstr "[NL puuttuu]" +#~ msgid "E821: File is encrypted with unknown method" +#~ msgstr "E821: Tiedoston salaus on tuntematon" -#~ msgid "Vim dialog..." -#~ msgstr "Vim-ikkuna..." +#~ msgid "E918: buffer must be loaded: %s" +#~ msgstr "E918: puskuria ei voi ladata: %s" -#~ msgid "Font Selection" -#~ msgstr "Fontin valinta" +#~ 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 "E569: maximum number of cscope connections reached" -#~ msgstr "E569: enimmismr cscope-yhteyksi otettu" +#~ msgid "E920: _io file requires _name to be set" +#~ msgstr "E920: _io-tiedostolla pitää olla _name asetettu" -#~ msgid "-name \t\tUse resource as if vim was " -#~ msgstr "-name \t\tKyt resurssia vim " +#~ msgid "E906: not an open channel" +#~ msgstr "E906: ei ole avoin kanava" -#~ msgid "\t\t\t (Unimplemented)\n" -#~ msgstr "\t\t\t (toteuttamatta)\n" +#~ 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 kytst" +#~ msgid "" +#~ "\n" +#~ "# Buffer list:\n" +#~ msgstr "" +#~ "\n" +#~ "# Puskuriluettelo:\n" -#~ msgid "E292: Input Method Server is not running" -#~ msgstr "E292: Sytemetodipalvelin ei ole kynniss" +#~ 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 thn" +#~ 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" -- cgit From c5d7eaf66468d5f71049a602e820c19d8ad8c772 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 15 Apr 2017 13:21:38 -0400 Subject: vim-patch:7.4.2152 Problem: No proper translation of messages with a count. Solution: Use ngettext(). (Sergey Alyoshin) https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5 --- src/nvim/eval.c | 7 +++---- src/nvim/fold.c | 18 ++++++++++-------- src/nvim/screen.c | 2 +- src/nvim/version.c | 2 +- src/nvim/vim.h | 2 ++ 5 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index dcbd7ab152..60c4e725b7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8663,7 +8663,6 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u *r; int len; char *txt; - long count; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -8691,8 +8690,8 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) s = skipwhite(s + 1); } } - count = (long)(foldend - foldstart + 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(dashes) // for %s + 20 // for %3ld @@ -8712,7 +8711,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char_u *text; - char_u buf[51]; + char_u buf[FOLD_TEXT_LEN]; foldinfo_T foldinfo; int fold_count; diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 34db4d2171..ff3f46cb78 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -1689,12 +1689,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) @@ -1781,8 +1779,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; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index a8993be4e5..f34dbf5d64 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1684,7 +1684,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; diff --git a/src/nvim/version.c b/src/nvim/version.c index 9a5d7ce169..cd904da573 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -289,7 +289,7 @@ static const int included_patches[] = { // 2155 NA // 2154 NA // 2153 NA - // 2152, + 2152, 2151, // 2150 NA 2149, diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 172e62b039..f29ccdd296 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -204,6 +204,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. -- cgit From cb02137dfac7357650a2e9cc32acb66326e59058 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 15 Apr 2017 13:54:40 -0400 Subject: vim-patch:7.4.2209 Problem: Cannot map . (Stephen Riehm) Solution: Solve the memory access problem in another way. (Dominique Pelle) Allow for using in a string. https://github.com/vim/vim/commit/35a4cfa200917dd171b1fff3cd5b6cee9add673d --- src/nvim/eval.c | 2 +- src/nvim/keymap.c | 40 +++++++++++++++++++++++---------------- src/nvim/option.c | 2 +- src/nvim/os/input.c | 3 ++- src/nvim/testdir/test_mapping.vim | 8 ++++++++ src/nvim/version.c | 2 +- 6 files changed, 37 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 60c4e725b7..9f56d8db0c 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -4764,7 +4764,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) // Special key, e.g.: "\" 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; diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 72b0d0aa40..9838b63a6b 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -490,17 +490,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 +538,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; @@ -573,10 +577,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] != '"' && bp[l + 1] == '>') { - // Anything accepted, like , except , because the " - // ends the string. + // Anything accepted, like . + // or are not special in strings as " is + // the string delimiter. With a backslash it works: + 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; } } } @@ -612,18 +620,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); } @@ -828,7 +835,8 @@ 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; diff --git a/src/nvim/option.c b/src/nvim/option.c index 0070a0056d..8748406ba4 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4818,7 +4818,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; } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 5f0f2ec677..1fa1f52806 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -182,7 +182,8 @@ size_t input_enqueue(String keys) while (rbuffer_space(input_buffer) >= 6 && ptr < end) { uint8_t buf[6] = { 0 }; unsigned int new_size - = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true); + = 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); diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index 6b313ff54f..7f93ddd56e 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -150,3 +150,11 @@ func Test_break_undo() call assert_equal('new line here', getline(line('$') - 1)) set nomodified endfunc + +func Test_map_meta_quotes() + imap foo + call feedkeys("Go-\-\", "xt") + call assert_equal("-foo-", getline('$')) + set nomodified + iunmap +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index cd904da573..f7a78a15f9 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -232,7 +232,7 @@ static const int included_patches[] = { 2212, // 2211 NA // 2210 NA - // 2209, + 2209, 2208, // 2207 NA // 2206 NA -- cgit From a6f50c1120f4427d1b4f531ac564d83b770fd62f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 19 Apr 2017 23:22:27 -0400 Subject: version.c: Mark 7.4.{2165,2173,2179} applied --- src/nvim/version.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index f7a78a15f9..4edfe88e18 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -262,13 +262,13 @@ static const int included_patches[] = { // 2182 NA // 2181 NA 2180, - // 2179, + 2179, 2178, 2177, // 2176 NA 2175, 2174, - // 2173, + 2173, 2172, // 2171 NA 2170, @@ -276,7 +276,7 @@ static const int included_patches[] = { // 2168 NA // 2167 NA // 2166 NA - // 2165, + 2165, 2164, 2163, 2162, -- cgit From 17052946c744abd53d8f3349f453964ffa818bea Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 20 Apr 2017 12:32:14 +0200 Subject: 'scrollback': Allow :setlocal -1 on normal buffers Avoids a spurious :loadview error. --- src/nvim/option.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 8748406ba4..ae038389b4 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4223,7 +4223,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, } else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) { // 'scrollback' if (*pp < -1 || *pp > SB_MAX - || (opt_flags == OPT_LOCAL && !curbuf->terminal)) { + || (*pp != -1 && opt_flags == OPT_LOCAL && !curbuf->terminal)) { errmsg = e_invarg; *pp = old_value; } else if (curbuf->terminal) { -- cgit From 9cdbbd49825561d642705990a2704b2241cf0584 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Mon, 17 Apr 2017 11:32:14 +0200 Subject: ui: support more cursor shape modes throttle unneccessary cursor shape events --- src/nvim/api/ui.c | 23 +++++++++---------- src/nvim/cursor_shape.c | 35 ++++++++++++++++++++++++++++- src/nvim/cursor_shape.h | 3 ++- src/nvim/ex_getln.c | 16 +++++++++++++ src/nvim/mouse.c | 1 + src/nvim/tui/tui.c | 60 +++++++++++++------------------------------------ src/nvim/ui.c | 31 +++++++++---------------- src/nvim/ui.h | 2 +- src/nvim/ui_bridge.c | 4 ++-- 9 files changed, 93 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index de60339e5f..0053050717 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -266,19 +266,14 @@ static void remote_ui_mouse_off(UI *ui) push_call(ui, "mouse_off", args); } -static void remote_ui_mode_change(UI *ui, int mode) +static void remote_ui_mode_change(UI *ui, int mode_idx) { 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"))); - } + + char *full_name = shape_table[mode_idx].full_name; + ADD(args, STRING_OBJ(cstr_to_string(full_name))); + + ADD(args, INTEGER_OBJ(mode_idx)); push_call(ui, "mode_change", args); } @@ -393,8 +388,10 @@ static void remote_ui_update_sp(UI *ui, int sp) 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; + if (data->buffer.size > 0) { + channel_send_event(data->channel_id, "redraw", data->buffer); + data->buffer = (Array)ARRAY_DICT_INIT; + } } static void remote_ui_suspend(UI *ui) diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index 34ee53bf75..57dc241c54 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -11,7 +11,7 @@ #include "nvim/ui.h" /// Handling of cursor and mouse pointer shapes in various modes. -static cursorentry_T shape_table[SHAPE_IDX_COUNT] = +cursorentry_T shape_table[SHAPE_IDX_COUNT] = { // Values are set by 'guicursor' and 'mouseshape'. // Adjust the SHAPE_IDX_ defines when changing this! @@ -63,6 +63,7 @@ Dictionary cursor_shape_dict(void) PUT(dic, "id_lm", INTEGER_OBJ(cur->id_lm)); } PUT(dic, "short_name", STRING_OBJ(cstr_to_string(cur->name))); + PUT(dic, "mode_idx", INTEGER_OBJ(i)); PUT(all, cur->full_name, DICTIONARY_OBJ(dic)); } @@ -260,3 +261,35 @@ int cursor_mode_str2int(const char *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 7cf65cba3c..2c466603f0 100644 --- a/src/nvim/cursor_shape.h +++ b/src/nvim/cursor_shape.h @@ -25,7 +25,7 @@ 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 -} MouseMode; +} ModeShape; typedef enum { SHAPE_BLOCK = 0, ///< block cursor @@ -53,6 +53,7 @@ typedef struct cursor_entry { 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/ex_getln.c b/src/nvim/ex_getln.c index 0b6036ace9..5d228e7492 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -351,6 +351,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; } @@ -2092,6 +2093,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. @@ -2262,6 +2275,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 +2295,7 @@ void unputcmdline(void) draw_cmdline(ccline.cmdpos, 1); msg_no_more = FALSE; cursorcmd(); + ui_cursor_shape(); } /* @@ -2598,6 +2613,7 @@ void redrawcmdline(void) compute_cmdrow(); redrawcmd(); cursorcmd(); + ui_cursor_shape(); } static void redrawcmdprompt(void) diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 2ebe199f47..0029f364da 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -456,6 +456,7 @@ void setmouse(void) { int checkfor; + ui_cursor_shape(); /* be quick when mouse is off */ if (*p_mouse == NUL) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index f34f5f1bc4..3498e8f4e7 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -73,7 +73,7 @@ typedef struct { bool busy; cursorentry_T cursor_shapes[SHAPE_IDX_COUNT]; HlAttrs print_attrs; - int showing_mode; + ModeShape showing_mode; struct { int enable_mouse, disable_mouse; int enable_bracketed_paste, disable_bracketed_paste; @@ -131,7 +131,7 @@ static void terminfo_start(UI *ui) data->can_use_terminal_scroll = true; data->bufpos = 0; data->bufsize = sizeof(data->buf) - CNORM_COMMAND_MAX_SIZE; - data->showing_mode = 0; + 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; @@ -173,7 +173,7 @@ static void terminfo_stop(UI *ui) { TUIData *data = ui->data; // Destroy output stuff - tui_mode_change(ui, NORMAL); + tui_mode_change(ui, SHAPE_IDX_N); tui_mouse_off(ui); unibi_out(ui, unibi_exit_attribute_mode); // cursor should be set to normal before exiting alternate screen @@ -451,7 +451,7 @@ CursorShape tui_cursor_decode_shape(const char *shape_str) return shape; } -static cursorentry_T decode_cursor_entry(Dictionary args) +static cursorentry_T decode_cursor_entry(Dictionary args, int *mode_idx) { cursorentry_T r; @@ -467,6 +467,8 @@ static cursorentry_T decode_cursor_entry(Dictionary args) r.blinkoff = (int)value.data.integer; } else if (strequal(key, "hl_id")) { r.id = (int)value.data.integer; + } else if (strequal(key, "mode_idx")) { + *mode_idx = (int)value.data.integer; } } return r; @@ -484,15 +486,15 @@ static void tui_cursor_style_set(UI *ui, bool enabled, Dictionary args) // Keys: as defined by `shape_table`. for (size_t i = 0; i < args.size; i++) { char *mode_name = args.items[i].key.data; - const int mode_id = cursor_mode_str2int(mode_name); - assert(mode_id >= 0); - cursorentry_T r = decode_cursor_entry(args.items[i].value.data.dictionary); + int mode_idx; + cursorentry_T r = decode_cursor_entry(args.items[i].value.data.dictionary, + &mode_idx); + assert(mode_idx >= 0); r.full_name = mode_name; - data->cursor_shapes[mode_id] = r; + data->cursor_shapes[mode_idx] = r; } - MouseMode cursor_mode = tui_mode2cursor(data->showing_mode); - tui_set_cursor(ui, cursor_mode); + tui_set_mode(ui, data->showing_mode); } static void tui_update_menu(UI *ui) @@ -529,7 +531,7 @@ static void tui_mouse_off(UI *ui) } /// @param mode one of SHAPE_XXX -static void tui_set_cursor(UI *ui, MouseMode mode) +static void tui_set_mode(UI *ui, ModeShape mode) { if (!cursor_style_enabled) { return; @@ -584,42 +586,12 @@ static void tui_set_cursor(UI *ui, MouseMode mode) } } -/// Returns cursor mode from edit mode -static MouseMode tui_mode2cursor(int mode) -{ - switch (mode) { - case INSERT: return SHAPE_IDX_I; - case CMDLINE: return SHAPE_IDX_C; - case REPLACE: return SHAPE_IDX_R; - case NORMAL: - default: return SHAPE_IDX_N; - } -} - /// @param mode editor mode -static void tui_mode_change(UI *ui, int mode) +static void tui_mode_change(UI *ui, int mode_idx) { TUIData *data = ui->data; - - if (mode == INSERT) { - if (data->showing_mode != INSERT) { - tui_set_cursor(ui, SHAPE_IDX_I); - } - } else if (mode == CMDLINE) { - if (data->showing_mode != CMDLINE) { - tui_set_cursor(ui, SHAPE_IDX_C); - } - } else if (mode == REPLACE) { - if (data->showing_mode != REPLACE) { - tui_set_cursor(ui, SHAPE_IDX_R); - } - } else { - assert(mode == NORMAL); - if (data->showing_mode != NORMAL) { - tui_set_cursor(ui, SHAPE_IDX_N); - } - } - data->showing_mode = mode; + 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, diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 28f71b7ef2..8c5e579301 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -53,6 +53,7 @@ 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; // UI_CALL invokes a function on all registered UI instances. The functions can // have 0-5 arguments (configurable by SELECT_NTH). @@ -150,12 +151,6 @@ 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()) { @@ -181,6 +176,8 @@ void ui_refresh(void) screen_resize(width, height); pum_set_external(pum_external); ui_cursor_style_set(); + old_mode_idx = -1; + ui_cursor_shape(); } static void ui_refresh_event(void **argv) @@ -541,25 +538,19 @@ static void flush_cursor_update(void) } } -// 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; + UI_CALL(mode_change, mode_idx); } - UI_CALL(mode_change, mode); conceal_check_cursur_line(); } diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 8ffc5a45a6..d63ceb106c 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -28,7 +28,7 @@ struct ui_t { void (*busy_stop)(UI *ui); void (*mouse_on)(UI *ui); void (*mouse_off)(UI *ui); - void (*mode_change)(UI *ui, int mode); + void (*mode_change)(UI *ui, int mode_idx); 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); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 9f780663ac..59942fb2cb 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -249,9 +249,9 @@ static void ui_bridge_mouse_off_event(void **argv) ui->mouse_off(ui); } -static void ui_bridge_mode_change(UI *b, int mode) +static void ui_bridge_mode_change(UI *b, int mode_idx) { - UI_CALL(b, mode_change, 2, b, INT2PTR(mode)); + UI_CALL(b, mode_change, 2, b, INT2PTR(mode_idx)); } static void ui_bridge_mode_change_event(void **argv) { -- cgit From 7ea5c78687168c07bfc4582c84145e86a5252f94 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Tue, 18 Apr 2017 13:42:04 +0200 Subject: ui: use an array for mode styles --- src/nvim/api/ui.c | 10 +++++----- src/nvim/cursor_shape.c | 14 +++++++------- src/nvim/tui/tui.c | 25 ++++++++++--------------- src/nvim/ui.c | 10 +++++----- src/nvim/ui.ch | 0 src/nvim/ui.h | 2 +- src/nvim/ui_bridge.c | 20 ++++++++++---------- 7 files changed, 38 insertions(+), 43 deletions(-) create mode 100644 src/nvim/ui.ch (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 0053050717..3e7e2718bb 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -70,7 +70,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->clear = remote_ui_clear; ui->eol_clear = remote_ui_eol_clear; ui->cursor_goto = remote_ui_cursor_goto; - ui->cursor_style_set = remote_ui_cursor_style_set; + 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; @@ -295,12 +295,12 @@ static void remote_ui_scroll(UI *ui, int count) push_call(ui, "scroll", args); } -static void remote_ui_cursor_style_set(UI *ui, bool enabled, Dictionary data) +static void remote_ui_mode_info_set(UI *ui, bool guicursor_enabled, Array data) { Array args = ARRAY_DICT_INIT; - ADD(args, BOOLEAN_OBJ(enabled)); - ADD(args, copy_object(DICTIONARY_OBJ(data))); - push_call(ui, "cursor_style_set", args); + ADD(args, BOOLEAN_OBJ(guicursor_enabled)); + ADD(args, copy_object(ARRAY_OBJ(data))); + push_call(ui, "mode_info_set", args); } static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index 57dc241c54..3099a5189b 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -34,11 +34,11 @@ cursorentry_T shape_table[SHAPE_IDX_COUNT] = { "showmatch", 0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR }, }; -/// Converts cursor_shapes into a Dictionary of dictionaries -/// @return dictionary of the form {"normal" : { "cursor_shape": ... }, ...} -Dictionary cursor_shape_dict(void) +/// Converts cursor_shapes into an Array of Dictionaries +/// @return Array of the form {[ "cursor_shape": ... ], ...} +Array mode_style_array(void) { - Dictionary all = ARRAY_DICT_INIT; + Array all = ARRAY_DICT_INIT; for (int i = 0; i < SHAPE_IDX_COUNT; i++) { Dictionary dic = ARRAY_DICT_INIT; @@ -62,10 +62,10 @@ Dictionary cursor_shape_dict(void) 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))); - PUT(dic, "mode_idx", INTEGER_OBJ(i)); - PUT(all, cur->full_name, DICTIONARY_OBJ(dic)); + ADD(all, DICTIONARY_OBJ(dic)); } return all; @@ -241,7 +241,7 @@ char_u *parse_shape_opt(int what) shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm; } } - ui_cursor_style_set(); + ui_mode_info_set(); return NULL; } diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 3498e8f4e7..172160fddb 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -101,7 +101,7 @@ UI *tui_start(void) ui->clear = tui_clear; ui->eol_clear = tui_eol_clear; ui->cursor_goto = tui_cursor_goto; - ui->cursor_style_set = tui_cursor_style_set; + 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; @@ -451,7 +451,7 @@ CursorShape tui_cursor_decode_shape(const char *shape_str) return shape; } -static cursorentry_T decode_cursor_entry(Dictionary args, int *mode_idx) +static cursorentry_T decode_cursor_entry(Dictionary args) { cursorentry_T r; @@ -467,31 +467,26 @@ static cursorentry_T decode_cursor_entry(Dictionary args, int *mode_idx) r.blinkoff = (int)value.data.integer; } else if (strequal(key, "hl_id")) { r.id = (int)value.data.integer; - } else if (strequal(key, "mode_idx")) { - *mode_idx = (int)value.data.integer; } } return r; } -static void tui_cursor_style_set(UI *ui, bool enabled, Dictionary args) +static void tui_mode_info_set(UI *ui, bool guicursor_enabled, Array args) { - cursor_style_enabled = enabled; - if (!enabled) { + cursor_style_enabled = guicursor_enabled; + if (!guicursor_enabled) { return; // Do not send cursor style control codes. } TUIData *data = ui->data; assert(args.size); - // Keys: as defined by `shape_table`. + + // cursor style entries as defined by `shape_table`. for (size_t i = 0; i < args.size; i++) { - char *mode_name = args.items[i].key.data; - int mode_idx; - cursorentry_T r = decode_cursor_entry(args.items[i].value.data.dictionary, - &mode_idx); - assert(mode_idx >= 0); - r.full_name = mode_name; - data->cursor_shapes[mode_idx] = r; + 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); diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 8c5e579301..5fb57dd257 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -175,7 +175,7 @@ void ui_refresh(void) row = col = 0; screen_resize(width, height); pum_set_external(pum_external); - ui_cursor_style_set(); + ui_mode_info_set(); old_mode_idx = -1; ui_cursor_shape(); } @@ -375,12 +375,12 @@ void ui_cursor_goto(int new_row, int new_col) pending_cursor_update = true; } -void ui_cursor_style_set(void) +void ui_mode_info_set(void) { - Dictionary style = cursor_shape_dict(); + Array style = mode_style_array(); bool enabled = (*p_guicursor != NUL); - UI_CALL(cursor_style_set, enabled, style); - api_free_dictionary(style); + UI_CALL(mode_info_set, enabled, style); + api_free_array(style); } void ui_update_menu(void) diff --git a/src/nvim/ui.ch b/src/nvim/ui.ch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/nvim/ui.h b/src/nvim/ui.h index d63ceb106c..f5cbf748ee 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -22,7 +22,7 @@ struct ui_t { void (*clear)(UI *ui); void (*eol_clear)(UI *ui); void (*cursor_goto)(UI *ui, int row, int col); - void (*cursor_style_set)(UI *ui, bool enabled, Dictionary cursor_styles); + void (*mode_info_set)(UI *ui, bool enabled, Array cursor_styles); void (*update_menu)(UI *ui); void (*busy_start)(UI *ui); void (*busy_stop)(UI *ui); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 59942fb2cb..e899cbf397 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -60,7 +60,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->bridge.clear = ui_bridge_clear; rv->bridge.eol_clear = ui_bridge_eol_clear; rv->bridge.cursor_goto = ui_bridge_cursor_goto; - rv->bridge.cursor_style_set = ui_bridge_cursor_style_set; + 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; @@ -180,23 +180,23 @@ static void ui_bridge_cursor_goto_event(void **argv) ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2])); } -static void ui_bridge_cursor_style_set(UI *b, bool enabled, Dictionary styles) +static void ui_bridge_mode_info_set(UI *b, bool enabled, Array modes) { bool *enabledp = xmalloc(sizeof(*enabledp)); - Object *stylesp = xmalloc(sizeof(*stylesp)); + Object *modesp = xmalloc(sizeof(*modesp)); *enabledp = enabled; - *stylesp = copy_object(DICTIONARY_OBJ(styles)); - UI_CALL(b, cursor_style_set, 3, b, enabledp, stylesp); + *modesp = copy_object(ARRAY_OBJ(modes)); + UI_CALL(b, mode_info_set, 3, b, enabledp, modesp); } -static void ui_bridge_cursor_style_set_event(void **argv) +static void ui_bridge_mode_info_set_event(void **argv) { UI *ui = UI(argv[0]); bool *enabled = argv[1]; - Object *styles = argv[2]; - ui->cursor_style_set(ui, *enabled, styles->data.dictionary); + Object *modes = argv[2]; + ui->mode_info_set(ui, *enabled, modes->data.array); xfree(enabled); - api_free_object(*styles); - xfree(styles); + api_free_object(*modes); + xfree(modes); } static void ui_bridge_update_menu(UI *b) -- cgit From a396874da0efaeb7def5e26afab9ae1c980510a0 Mon Sep 17 00:00:00 2001 From: Othon Briganó Date: Fri, 21 Apr 2017 10:21:02 -0300 Subject: refactor/single-include: getchar.h (#6560) --- src/nvim/CMakeLists.txt | 1 - src/nvim/getchar.h | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index a91657f1bd..e4b3b4de13 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -429,7 +429,6 @@ function(get_test_target prefix sfile relative_path_var target_var) endfunction() set(NO_SINGLE_CHECK_HEADERS - getchar.h if_cscope_defs.h misc2.h msgpack_rpc/server.h diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h index bdf65909b6..28584e0534 100644 --- a/src/nvim/getchar.h +++ b/src/nvim/getchar.h @@ -1,6 +1,10 @@ #ifndef NVIM_GETCHAR_H #define NVIM_GETCHAR_H +#include "nvim/types.h" +#include "nvim/buffer_defs.h" +#include "nvim/ex_cmds_defs.h" + /* Values for "noremap" argument of ins_typebuf(). Also used for * map->m_noremap and menu->noremap[]. */ #define REMAP_YES 0 /* allow remapping */ @@ -12,6 +16,7 @@ #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 -- cgit From f50e03f2e35cf4bee8cedb2c95bf9619f3b57bc2 Mon Sep 17 00:00:00 2001 From: sander2 Date: Fri, 21 Apr 2017 15:45:51 +0200 Subject: ex_cmds.c: Fix bug in ex_z (#6557) vim-patch:8.0.0571 --- src/nvim/ex_cmds.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 117ef6a507..7726e0fc6d 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -2877,8 +2877,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) { @@ -2898,8 +2901,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; } /* -- cgit From 654c50b227b7616300763da75ad4a79151883694 Mon Sep 17 00:00:00 2001 From: relnod Date: Sat, 22 Apr 2017 15:43:35 +0200 Subject: refactor/single-include: window.h, version.h (#6570) --- src/nvim/CMakeLists.txt | 2 -- src/nvim/version.h | 2 ++ src/nvim/window.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index e4b3b4de13..04fe56952f 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -456,8 +456,6 @@ set(NO_SINGLE_CHECK_HEADERS ui_bridge.h undo.h undo_defs.h - version.h - window.h ) foreach(hfile ${NVIM_HEADERS}) get_test_target(test-includes "${hfile}" relative_path texe) diff --git a/src/nvim/version.h b/src/nvim/version.h index 1de809e539..a0babfb156 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; 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 +#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 */ -- cgit From e41c044b530d2cc3f548fcef07862640eb249c58 Mon Sep 17 00:00:00 2001 From: Othon Briganó Date: Sat, 22 Apr 2017 10:44:58 -0300 Subject: refactor/single-include (#6563) --- src/nvim/CMakeLists.txt | 3 --- src/nvim/screen.h | 4 ++++ src/nvim/search.h | 6 ++++++ src/nvim/syntax.h | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 04fe56952f..597864845e 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -440,13 +440,10 @@ set(NO_SINGLE_CHECK_HEADERS quickfix.h regexp.h regexp_defs.h - screen.h - search.h sha256.h sign_defs.h spell.h spellfile.h - syntax.h syntax_defs.h tag.h terminal.h 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 +#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.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 #include +#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/syntax.h b/src/nvim/syntax.h index 574e3372e2..bb733ead30 100644 --- a/src/nvim/syntax.h +++ b/src/nvim/syntax.h @@ -4,7 +4,7 @@ #include #include "nvim/buffer_defs.h" - +#include "nvim/ex_cmds_defs.h" /// Terminal highlighting attribute bits. /// Attributes above HL_ALL are used for syntax highlighting. -- cgit From 1e83add288b4f9183d39387356fc7e8f294d5d4b Mon Sep 17 00:00:00 2001 From: relnod Date: Sat, 22 Apr 2017 16:55:28 +0200 Subject: refactor/single-include: ui.h, ui_bridge.h, ugrid.h (#6571) --- src/nvim/CMakeLists.txt | 3 --- src/nvim/ui.h | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 597864845e..db5e62fd67 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -448,9 +448,6 @@ set(NO_SINGLE_CHECK_HEADERS tag.h terminal.h tui/tui.h - ugrid.h - ui.h - ui_bridge.h undo.h undo_defs.h ) diff --git a/src/nvim/ui.h b/src/nvim/ui.h index f5cbf748ee..fcf52ac9e1 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -6,6 +6,7 @@ #include #include "api/private/defs.h" +#include "nvim/buffer_defs.h" typedef struct { bool bold, underline, undercurl, italic, reverse; -- cgit From c703d0529b3c4f6485d6ce6f37033d4658356b05 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 22 Apr 2017 18:19:37 +0200 Subject: 'guicursor': iTerm: Set cursor color. iTerm uses proprietary escape codes to set cursor color. https://www.iterm2.com/documentation-escape-codes.html --- src/nvim/tui/tui.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 6ea6376202..ae7551098d 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -43,6 +43,15 @@ #define OUTBUF_SIZE 0xffff #define TOO_MANY_EVENTS 1000000 +#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1)) + +typedef enum TermType { + kTermUnknown, + kTermGnome, + kTermiTerm, + kTermKonsole, + kTermRxvt, +} TermType; typedef struct { int top, bot, left, right; @@ -77,6 +86,7 @@ typedef struct { cursorentry_T cursor_shapes[SHAPE_IDX_COUNT]; HlAttrs print_attrs; ModeShape showing_mode; + TermType term; struct { int enable_mouse, disable_mouse; int enable_bracketed_paste, disable_bracketed_paste; @@ -528,7 +538,6 @@ static void tui_mouse_off(UI *ui) } } -/// @param mode one of SHAPE_XXX static void tui_set_mode(UI *ui, ModeShape mode) { if (!cursor_style_enabled) { @@ -537,14 +546,14 @@ static void tui_set_mode(UI *ui, ModeShape mode) TUIData *data = ui->data; cursorentry_T c = data->cursor_shapes[mode]; int shape = c.shape; - bool inside_tmux = os_getenv("TMUX") != NULL; + bool is_tmux = os_getenv("TMUX") != NULL; unibi_var_t vars[26 + 26] = { { 0 } }; -# define TMUX_WRAP(seq) (inside_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq) +# define TMUX_WRAP(seq) (is_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq) // Support changing cursor shape on some popular terminals. const char *vte_version = os_getenv("VTE_VERSION"); - if (os_getenv("KONSOLE_PROFILE_NAME") || os_getenv("KONSOLE_DBUS_SESSION")) { + if (data->term == kTermKonsole) { // Konsole uses a proprietary escape code to set the cursor shape // and does not support DECSCUSR. switch (shape) { @@ -921,6 +930,24 @@ static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str, } } +static TermType detect_term(const char *term, const char *colorterm) +{ + if (STARTS_WITH(term, "rxvt")) { + return kTermRxvt; + } + if (os_getenv("KONSOLE_PROFILE_NAME") || os_getenv("KONSOLE_DBUS_SESSION")) { + return kTermKonsole; + } + const char *termprg = os_getenv("TERM_PROGRAM"); + if (termprg && strstr(termprg, "iTerm.app")) { + return kTermiTerm; + } + if (colorterm && strstr(colorterm, "gnome-terminal")) { + return kTermGnome; + } + return kTermUnknown; +} + static void fix_terminfo(TUIData *data) { unibi_term *ut = data->ut; @@ -930,10 +957,9 @@ static void fix_terminfo(TUIData *data) if (!term) { goto end; } + data->term = detect_term(term, colorterm); -#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1)) - - if (STARTS_WITH(term, "rxvt")) { + if (data->term == kTermRxvt) { 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"); unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m"); @@ -945,7 +971,7 @@ static void fix_terminfo(TUIData *data) unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\"); } - if (STARTS_WITH(term, "xterm") || STARTS_WITH(term, "rxvt")) { + if (STARTS_WITH(term, "xterm") || data->term == kTermRxvt) { const char *normal = unibi_get_str(ut, unibi_cursor_normal); if (!normal) { unibi_set_str(ut, unibi_cursor_normal, "\x1b[?25h"); @@ -982,7 +1008,7 @@ static void fix_terminfo(TUIData *data) if ((colorterm && strstr(colorterm, "256")) || strstr(term, "256") || strstr(term, "xterm")) { - // Assume TERM~=xterm or COLORTERM~=256 supports 256 colors. + // 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); @@ -990,8 +1016,13 @@ static void fix_terminfo(TUIData *data) end: // Fill some empty slots with common terminal strings - data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( - ut, NULL, "\033]12;#%p1%06x\007"); + if (data->term == kTermiTerm) { + data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( + ut, NULL, "\033]Pl%p1%06x\033\\"); + } else { + data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( + ut, NULL, "\033]12;#%p1%06x\007"); + } 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, -- cgit From 719095d7d33a05679f47f5adc1309b5432529385 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 22 Apr 2017 18:53:01 +0200 Subject: os_term_is_nice: Return true for rxvt and iTerm. --- src/nvim/os/env.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 72bd0bf788..8f7a6e72b5 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -915,9 +915,20 @@ bool os_term_is_nice(void) return true; #else const char *vte_version = os_getenv("VTE_VERSION"); - return (vte_version && atoi(vte_version) >= 3900) - || NULL != os_getenv("KONSOLE_PROFILE_NAME") - || NULL != os_getenv("KONSOLE_DBUS_SESSION"); + 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 } -- cgit From 1fe8945748620713402cab77a46501ec5311778b Mon Sep 17 00:00:00 2001 From: Patrick Jackson Date: Sat, 22 Apr 2017 17:32:56 -0700 Subject: refactor: Remove unused MAP_IMPL. (#6573) --- src/nvim/map.c | 1 - src/nvim/map.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src') diff --git a/src/nvim/map.c b/src/nvim/map.c index 54a9e559af..366b286d14 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -142,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) diff --git a/src/nvim/map.h b/src/nvim/map.h index ba3e84cb31..a4fccf47f9 100644 --- a/src/nvim/map.h +++ b/src/nvim/map.h @@ -25,7 +25,6 @@ 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) -- cgit From 5c9860a0a2bf27d409c986673f0a74542561c4c3 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Wed, 1 Mar 2017 10:43:47 +0100 Subject: api: Do not truncate errors <1 MB. #6237 Closes #5984 --- src/nvim/api/buffer.c | 44 ++++++++-------- src/nvim/api/private/defs.h | 4 +- src/nvim/api/private/helpers.c | 113 +++++++++++++++++++++++++---------------- src/nvim/api/private/helpers.h | 10 ---- src/nvim/api/tabpage.c | 4 +- src/nvim/api/ui.c | 18 +++---- src/nvim/api/vim.c | 44 ++++++++-------- src/nvim/api/window.c | 16 +++--- src/nvim/eval.c | 5 +- src/nvim/msgpack_rpc/channel.c | 73 +++++++++++++------------- src/nvim/msgpack_rpc/helpers.c | 22 ++++---- src/nvim/terminal.c | 10 ++-- src/nvim/tui/input.c | 2 +- 13 files changed, 197 insertions(+), 168 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 1b3592679b..2f306ebfc8 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -171,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; } @@ -187,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; } @@ -283,14 +283,14 @@ 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, + _api_set_error(err, + kErrorTypeValidation, _("Argument \"start\" is higher than \"end\"")); return; } @@ -304,8 +304,8 @@ void nvim_buf_set_lines(uint64_t channel_id, for (size_t i = 0; i < new_len; i++) { if (replacement.items[i].type != kObjectTypeString) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("All items in the replacement array must be strings")); goto end; } @@ -317,7 +317,7 @@ void nvim_buf_set_lines(uint64_t channel_id, 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")); + _api_set_error(err, kErrorTypeException, _("string cannot contain newlines")); new_len = i + 1; goto end; } @@ -330,7 +330,7 @@ void nvim_buf_set_lines(uint64_t channel_id, 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; } @@ -340,7 +340,7 @@ 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; } } @@ -357,12 +357,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 @@ -375,12 +375,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; } @@ -627,7 +627,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")); } } @@ -639,7 +639,9 @@ 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; + xfree(stub.msg); + return ret; } /// Inserts a sequence of lines to a buffer at a certain index @@ -678,7 +680,7 @@ 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; } @@ -696,7 +698,7 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) } if (posp == NULL) { - api_set_error(err, Validation, _("Invalid mark name")); + _api_set_error(err, kErrorTypeValidation, _("Invalid mark name")); return rv; } @@ -751,11 +753,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) { @@ -792,7 +794,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..a07422bd12 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -8,7 +8,7 @@ #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 { .set = false, .msg = NULL } #define REMOTE_TYPE(type) typedef handle_T type #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -38,7 +38,7 @@ typedef enum { typedef struct { ErrorType type; - char msg[1024]; + char *msg; bool set; } Error; diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 5877b848fc..e6632525e1 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -61,7 +61,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; @@ -69,15 +69,14 @@ bool try_end(Error *err) ET_ERROR, NULL, &should_free); - xstrlcpy(err->msg, msg, sizeof(err->msg)); - err->set = true; + _api_set_error(err, err->type, "%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(); } @@ -94,7 +93,7 @@ Object dict_get_value(dict_T *dict, String key, Error *err) dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); if (di == NULL) { - api_set_error(err, Validation, _("Key not found")); + _api_set_error(err, kErrorTypeValidation, _("Key not found")); return (Object) OBJECT_INIT; } @@ -118,17 +117,17 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, 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 variable names 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; } @@ -136,13 +135,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, if (di != NULL) { if (di->di_flags & DI_FLAGS_RO) { - api_set_error(err, Exception, _("Key is read-only: %s"), key.data); + _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, Exception, _("Key is fixed: %s"), key.data); + _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, Exception, _("Key is locked: %s"), key.data); + _api_set_error(err, kErrorTypeException, _("Key is locked: %s"), key.data); return rv; } } @@ -151,7 +150,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool 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 \"%s\" doesn't exist"), key.data); } else { // Return the old value if (retval) { @@ -203,7 +202,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; } @@ -214,8 +213,8 @@ Object get_option_from(void *from, int type, String name, Error *err) type, from); if (!flags) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("Invalid option name \"%s\""), name.data); return rv; @@ -233,14 +232,14 @@ Object get_option_from(void *from, int type, String name, Error *err) rv.data.string.data = stringval; rv.data.string.size = strlen(stringval); } else { - api_set_error(err, - Exception, + _api_set_error(err, + kErrorTypeException, _("Unable to get value for option \"%s\""), name.data); } } else { - api_set_error(err, - Exception, + _api_set_error(err, + kErrorTypeException, _("Unknown type for option \"%s\""), name.data); } @@ -258,15 +257,15 @@ 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; } int flags = get_option_value_strict(name.data, NULL, NULL, type, to); if (flags == 0) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("Invalid option name \"%s\""), name.data); return; @@ -274,14 +273,14 @@ 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, + _api_set_error(err, + kErrorTypeException, _("Unable to unset option \"%s\""), name.data); return; } else if (!(flags & SOPT_GLOBAL)) { - api_set_error(err, - Exception, + _api_set_error(err, + kErrorTypeException, _("Cannot unset option \"%s\" " "because it doesn't have a global value"), name.data); @@ -296,8 +295,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (flags & SOPT_BOOL) { if (value.type != kObjectTypeBoolean) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("Option \"%s\" requires a boolean value"), name.data); return; @@ -307,16 +306,16 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) set_option_value_for(name.data, val, NULL, opt_flags, type, to, err); } else if (flags & SOPT_NUM) { if (value.type != kObjectTypeInteger) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("Option \"%s\" requires an integer value"), name.data); return; } if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("Value for option \"%s\" is outside range"), name.data); return; @@ -326,8 +325,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) set_option_value_for(name.data, val, NULL, opt_flags, type, to, err); } else { if (value.type != kObjectTypeString) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("Option \"%s\" requires a string value"), name.data); return; @@ -561,13 +560,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; @@ -576,13 +575,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; @@ -591,7 +590,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; @@ -659,7 +658,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; } @@ -713,7 +712,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) String key = item.key; if (key.size == 0) { - api_set_error(err, Validation, + _api_set_error(err, kErrorTypeValidation, _("Empty dictionary keys aren't allowed")); // cleanup tv_dict_free(dict); @@ -801,6 +800,12 @@ void api_free_dictionary(Dictionary value) xfree(value.items); } +void api_free_error(Error *value) +{ + xfree(value->msg); + value->msg = NULL; +} + Dictionary api_metadata(void) { static Dictionary metadata = ARRAY_DICT_INIT; @@ -926,8 +931,8 @@ static void set_option_value_for(char *key, if (try_end(err)) { return; } - api_set_error(err, - Exception, + _api_set_error(err, + kErrorTypeException, _("Problem while switching windows")); return; } @@ -965,6 +970,26 @@ static void set_option_value_err(char *key, 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 +{ + 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->set = true; + err->type = errType; +} diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 20b4015fb5..681945ac9c 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -8,16 +8,6 @@ #include "nvim/memory.h" #include "nvim/lib/kvec.h" -// -V:api_set_error:618 -#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) { \ diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index 29592408fc..e6d5f7edad 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -193,6 +193,8 @@ 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; + xfree(stub.msg); + return ret; } diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 2a33d2ad72..534274db0f 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -55,12 +55,12 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, FUNC_API_SINCE(1) FUNC_API_NOEVAL { 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, + _api_set_error(err, kErrorTypeValidation, _("Expected width > 0 and height > 0")); return; } @@ -126,7 +126,7 @@ void nvim_ui_detach(uint64_t channel_id, Error *err) FUNC_API_SINCE(1) FUNC_API_NOEVAL { 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); @@ -138,12 +138,12 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width, FUNC_API_SINCE(1) FUNC_API_NOEVAL { 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, + _api_set_error(err, kErrorTypeValidation, _("Expected width > 0 and height > 0")); return; } @@ -159,7 +159,7 @@ void nvim_ui_set_option(uint64_t channel_id, String name, FUNC_API_SINCE(1) FUNC_API_NOEVAL { 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); @@ -173,19 +173,19 @@ void nvim_ui_set_option(uint64_t channel_id, String name, static void ui_set_option(UI *ui, String name, Object value, Error *error) { if (strcmp(name.data, "rgb") == 0) { 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) { if (value.type != kObjectTypeBoolean) { - api_set_error(error, Validation, + _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")); + _api_set_error(error, kErrorTypeValidation, _("No such ui option")); } } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index e5ef4a35c1..bd4a196367 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -188,7 +188,7 @@ Object nvim_eval(String expr, Error *err) typval_T rettv; if (eval0((char_u *)expr.data, &rettv, NULL, true) == FAIL) { - api_set_error(err, Exception, "Failed to evaluate expression"); + _api_set_error(err, kErrorTypeException, "Failed to evaluate expression"); } if (!try_end(err)) { @@ -214,7 +214,7 @@ Object nvim_call_function(String fname, Array args, Error *err) { Object rv = OBJECT_INIT; if (args.size > MAX_FUNC_ARGS) { - api_set_error(err, Validation, + _api_set_error(err, kErrorTypeValidation, _("Function called with too many arguments.")); return rv; } @@ -237,7 +237,7 @@ Object nvim_call_function(String fname, Array args, Error *err) curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy, 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); @@ -262,7 +262,7 @@ 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; } @@ -318,7 +318,7 @@ 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; } @@ -330,7 +330,7 @@ void nvim_set_current_dir(String dir, Error *err) 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; } @@ -538,8 +538,8 @@ void nvim_set_current_buf(Buffer buffer, Error *err) try_start(); int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0); if (!try_end(err) && result == FAIL) { - api_set_error(err, - Exception, + _api_set_error(err, + kErrorTypeException, _("Failed to switch to buffer %d"), buffer); } @@ -591,8 +591,8 @@ void nvim_set_current_win(Window window, Error *err) try_start(); goto_tabpage_win(win_find_tabpage(win), win); if (!try_end(err) && win != curwin) { - api_set_error(err, - Exception, + _api_set_error(err, + kErrorTypeException, _("Failed to switch to window %d"), window); } @@ -645,8 +645,8 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) try_start(); goto_tabpage_tp(tp, true, true); if (!try_end(err) && tp != curtab) { - api_set_error(err, - Exception, + _api_set_error(err, + kErrorTypeException, _("Failed to switch to tabpage %d"), tabpage); } @@ -744,30 +744,30 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) size_t i; // also used for freeing the variables for (i = 0; i < calls.size; i++) { if (calls.items[i].type != kObjectTypeArray) { - api_set_error(err, - Validation, + _api_set_error(err, + 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, + _api_set_error(err, + 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, + _api_set_error(err, + kErrorTypeValidation, _("name must be String")); goto validation_error; } String name = call.items[0].data.string; if (call.items[1].type != kObjectTypeArray) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("args must be Array")); goto validation_error; } @@ -794,10 +794,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_free_error(&nested_error); return rv; } diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index e1bb70ee0d..254ab1c09f 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -64,8 +64,8 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err) if (pos.size != 2 || pos.items[0].type != kObjectTypeInteger || pos.items[1].type != kObjectTypeInteger) { - api_set_error(err, - Validation, + _api_set_error(err, + kErrorTypeValidation, _("Argument \"pos\" must be a [row, col] array")); return; } @@ -78,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; } @@ -132,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; } @@ -177,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; } @@ -387,6 +387,8 @@ 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; + xfree(stub.msg); + return ret; } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7cef0d81ed..56dc35c31d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6524,6 +6524,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_array(args); api_free_object(result); + xfree(err.msg); } /* @@ -13794,6 +13795,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_object(result); + xfree(err.msg); } // "rpcstart()" function (DEPRECATED) @@ -16523,7 +16525,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) curbuf->b_p_swf = false; (void)setfname(curbuf, (char_u *)buf, NULL, true); // Save the job id and pid in b:terminal_job_{id,pid} - Error 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); dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_pid"), @@ -16532,6 +16534,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) Terminal *term = terminal_open(topts); data->term = term; data->refcount++; + xfree(err.msg); return; } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index b2c6ef852c..06cdf7d1f1 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -192,7 +192,7 @@ Object channel_send_call(uint64_t id, 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; } @@ -212,7 +212,7 @@ 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; @@ -220,14 +220,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); @@ -412,38 +411,38 @@ static void handle_request(Channel *channel, msgpack_object *request) channel->id); call_set_error(channel, buf); } - return; - } - - // Retrieve the request handler - MsgpackRpcRequestHandler handler; - msgpack_object *method = msgpack_rpc_method(request); - - if (method) { - handler = msgpack_rpc_get_handler_for(method->via.bin.ptr, - method->via.bin.size); } else { - handler.fn = msgpack_rpc_handle_missing_method; - handler.async = true; - } + // Retrieve the request handler + MsgpackRpcRequestHandler handler; + msgpack_object *method = msgpack_rpc_method(request); - Array args = ARRAY_DICT_INIT; - if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) { - handler.fn = msgpack_rpc_handle_invalid_arguments; - handler.async = true; - } + if (method) { + handler = msgpack_rpc_get_handler_for(method->via.bin.ptr, + method->via.bin.size); + } else { + handler.fn = msgpack_rpc_handle_missing_method; + handler.async = true; + } - RequestEvent *event_data = xmalloc(sizeof(RequestEvent)); - event_data->channel = channel; - event_data->handler = handler; - event_data->args = args; - event_data->request_id = request_id; - incref(channel); - if (handler.async) { - on_request_event((void **)&event_data); - } else { - multiqueue_put(channel->events, on_request_event, 1, event_data); + Array args = ARRAY_DICT_INIT; + if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) { + handler.fn = msgpack_rpc_handle_invalid_arguments; + handler.async = true; + } + + RequestEvent *event_data = xmalloc(sizeof(RequestEvent)); + event_data->channel = channel; + event_data->handler = handler; + event_data->args = args; + event_data->request_id = request_id; + incref(channel); + if (handler.async) { + on_request_event((void **)&event_data); + } else { + multiqueue_put(channel->events, on_request_event, 1, event_data); + } } + xfree(error.msg); } static void on_request_event(void **argv) @@ -470,6 +469,7 @@ static void on_request_event(void **argv) api_free_array(args); decref(channel); xfree(e); + xfree(error.msg); } static bool channel_write(Channel *channel, WBuffer *buffer) @@ -512,12 +512,13 @@ static bool channel_write(Channel *channel, 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)); + xfree(e.msg); } static void send_request(Channel *channel, diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 967ce31c1b..c273343b41 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -475,8 +475,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, error->type, "Invalid method name"); return NIL; } @@ -485,8 +484,7 @@ 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, error->type, "Invalid method arguments"); return NIL; } @@ -572,29 +570,29 @@ 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) " + _api_set_error(err, kErrorTypeValidation, _("Request array size should be 4 (request) " "or 3 (notification)")); return; } @@ -602,19 +600,19 @@ void msgpack_rpc_validate(uint64_t *response_id, 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/terminal.c b/src/nvim/terminal.c index 19b9bdc19f..43e4ea87e3 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -633,13 +633,14 @@ 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 { - Error 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); + xfree(err.msg); } static int term_settermprop(VTermProp prop, VTermValue *val, void *data) @@ -1220,12 +1221,15 @@ 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); \ + xfree(err.msg); \ if (o.type == kObjectTypeNil) { \ - o = dict_get_value(&globvardict, cstr_as_string(k), &err); \ + Error err2 = ERROR_INIT; \ + o = dict_get_value(&globvardict, cstr_as_string(k), &err2); \ + xfree(err2.msg); \ } \ } while (0) diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 3f2ccd4746..921f67fb7d 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -228,7 +228,7 @@ static int get_key_code_timeout(void) if (nvim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) { ms = nvim_get_option(cstr_as_string("ttimeoutlen"), &err).data.integer; } - + xfree(err.msg); return (int)ms; } -- cgit From 2a49163103827465f25810f5f4e3d4305159f209 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 15:59:59 +0200 Subject: api_clear_error() --- src/nvim/api/buffer.c | 2 +- src/nvim/api/private/helpers.c | 3 ++- src/nvim/api/tabpage.c | 2 +- src/nvim/api/vim.c | 2 +- src/nvim/api/window.c | 2 +- src/nvim/eval.c | 7 ++--- src/nvim/msgpack_rpc/channel.c | 60 +++++++++++++++++++++--------------------- src/nvim/terminal.c | 9 +++---- src/nvim/tui/input.c | 2 +- 9 files changed, 45 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 2f306ebfc8..81d25d7c95 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -640,7 +640,7 @@ Boolean nvim_buf_is_valid(Buffer buffer) { Error stub = ERROR_INIT; Boolean ret = find_buffer_by_handle(buffer, &stub) != NULL; - xfree(stub.msg); + api_clear_error(&stub); return ret; } diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index e6632525e1..547ac29bed 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -800,7 +800,8 @@ void api_free_dictionary(Dictionary value) xfree(value.items); } -void api_free_error(Error *value) +void api_clear_error(Error *value) + FUNC_ATTR_NONNULL_ALL { xfree(value->msg); value->msg = NULL; diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index e6d5f7edad..6f2f9e1d2a 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -194,7 +194,7 @@ Boolean nvim_tabpage_is_valid(Tabpage tabpage) { Error stub = ERROR_INIT; Boolean ret = find_tab_by_handle(tabpage, &stub) != NULL; - xfree(stub.msg); + api_clear_error(&stub); return ret; } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index bd4a196367..2c78ffdec1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -799,7 +799,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) validation_error: api_free_array(results); theend: - api_free_error(&nested_error); + api_clear_error(&nested_error); return rv; } diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 254ab1c09f..b8326c1198 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -388,7 +388,7 @@ Boolean nvim_win_is_valid(Window window) { Error stub = ERROR_INIT; Boolean ret = find_window_by_handle(window, &stub) != NULL; - xfree(stub.msg); + api_clear_error(&stub); return ret; } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 56dc35c31d..1e174712a3 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6524,7 +6524,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_array(args); api_free_object(result); - xfree(err.msg); + api_clear_error(&err); } /* @@ -13795,7 +13795,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_object(result); - xfree(err.msg); + api_clear_error(&err); } // "rpcstart()" function (DEPRECATED) @@ -16528,13 +16528,14 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) 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; data->refcount++; - xfree(err.msg); return; } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 06cdf7d1f1..bd7f84fed9 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -411,38 +411,38 @@ static void handle_request(Channel *channel, msgpack_object *request) channel->id); call_set_error(channel, buf); } - } else { - // Retrieve the request handler - MsgpackRpcRequestHandler handler; - msgpack_object *method = msgpack_rpc_method(request); + api_clear_error(&error); + return; + } + // Retrieve the request handler + MsgpackRpcRequestHandler handler; + msgpack_object *method = msgpack_rpc_method(request); - if (method) { - handler = msgpack_rpc_get_handler_for(method->via.bin.ptr, - method->via.bin.size); - } else { - handler.fn = msgpack_rpc_handle_missing_method; - handler.async = true; - } + if (method) { + handler = msgpack_rpc_get_handler_for(method->via.bin.ptr, + method->via.bin.size); + } else { + handler.fn = msgpack_rpc_handle_missing_method; + handler.async = true; + } - Array args = ARRAY_DICT_INIT; - if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) { - handler.fn = msgpack_rpc_handle_invalid_arguments; - handler.async = true; - } + Array args = ARRAY_DICT_INIT; + if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) { + handler.fn = msgpack_rpc_handle_invalid_arguments; + handler.async = true; + } - RequestEvent *event_data = xmalloc(sizeof(RequestEvent)); - event_data->channel = channel; - event_data->handler = handler; - event_data->args = args; - event_data->request_id = request_id; - incref(channel); - if (handler.async) { - on_request_event((void **)&event_data); - } else { - multiqueue_put(channel->events, on_request_event, 1, event_data); - } + RequestEvent *event_data = xmalloc(sizeof(RequestEvent)); + event_data->channel = channel; + event_data->handler = handler; + event_data->args = args; + event_data->request_id = request_id; + incref(channel); + if (handler.async) { + on_request_event((void **)&event_data); + } else { + multiqueue_put(channel->events, on_request_event, 1, event_data); } - xfree(error.msg); } static void on_request_event(void **argv) @@ -469,7 +469,7 @@ static void on_request_event(void **argv) api_free_array(args); decref(channel); xfree(e); - xfree(error.msg); + api_clear_error(&error); } static bool channel_write(Channel *channel, WBuffer *buffer) @@ -518,7 +518,7 @@ static void send_error(Channel *channel, uint64_t id, char *err) &e, NIL, &out_buffer)); - xfree(e.msg); + api_clear_error(&e); } static void send_request(Channel *channel, diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 43e4ea87e3..c44fe15be5 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -640,7 +640,7 @@ static void buf_set_term_title(buf_T *buf, char *title) false, false, &err); - xfree(err.msg); + api_clear_error(&err); } static int term_settermprop(VTermProp prop, VTermValue *val, void *data) @@ -1225,11 +1225,10 @@ static bool is_focused(Terminal *term) /* Only called from terminal_open where curbuf->terminal is the */ \ /* context */ \ o = dict_get_value(curbuf->b_vars, cstr_as_string(k), &err); \ - xfree(err.msg); \ + api_clear_error(&err); \ if (o.type == kObjectTypeNil) { \ - Error err2 = ERROR_INIT; \ - o = dict_get_value(&globvardict, cstr_as_string(k), &err2); \ - xfree(err2.msg); \ + o = dict_get_value(&globvardict, cstr_as_string(k), &err); \ + api_clear_error(&err); \ } \ } while (0) diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 921f67fb7d..be016668fc 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -228,7 +228,7 @@ static int get_key_code_timeout(void) if (nvim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) { ms = nvim_get_option(cstr_as_string("ttimeoutlen"), &err).data.integer; } - xfree(err.msg); + api_clear_error(&err); return (int)ms; } -- cgit From 62c3f436a96e2102ec5c1e3af974c8e57fe4e76c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 16:43:07 +0200 Subject: api_clear_error: Skip if error was not set. --- src/nvim/api/private/helpers.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 547ac29bed..3bf584ff2f 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -803,6 +803,9 @@ void api_free_dictionary(Dictionary value) void api_clear_error(Error *value) FUNC_ATTR_NONNULL_ALL { + if (!value->set) { + return; + } xfree(value->msg); value->msg = NULL; } -- cgit From 2ed91f222f1dddda10fbdc9cb80df2be7d4c2da3 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 19:58:13 +0200 Subject: api/internal: Remove `set` field from Error type. --- src/nvim/api/buffer.c | 4 ++-- src/nvim/api/private/defs.h | 6 ++++-- src/nvim/api/private/helpers.c | 11 ++++++----- src/nvim/api/ui.c | 4 ++-- src/nvim/api/vim.c | 6 +++--- src/nvim/eval.c | 4 ++-- src/nvim/msgpack_rpc/channel.c | 2 +- src/nvim/msgpack_rpc/helpers.c | 6 +++--- 8 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 81d25d7c95..cffc7a2e38 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -65,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; } @@ -203,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); } diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index a07422bd12..60bf38265f 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -8,9 +8,11 @@ #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, .msg = NULL } +#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 +22,7 @@ typedef int handle_T; // Basic types typedef enum { + kErrorTypeNone = -1, kErrorTypeException, kErrorTypeValidation } ErrorType; @@ -39,7 +42,6 @@ typedef enum { typedef struct { ErrorType type; char *msg; - bool set; } Error; typedef bool Boolean; diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 3bf584ff2f..58534d78a0 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -69,7 +69,7 @@ bool try_end(Error *err) ET_ERROR, NULL, &should_free); - _api_set_error(err, err->type, "%s", msg); + _api_set_error(err, kErrorTypeException, "%s", msg); free_global_msglist(); if (should_free) { @@ -80,7 +80,7 @@ bool try_end(Error *err) discard_current_exception(); } - return err->set; + return ERROR_SET(err); } /// Recursively expands a vimscript value in a dict @@ -803,11 +803,12 @@ void api_free_dictionary(Dictionary value) void api_clear_error(Error *value) FUNC_ATTR_NONNULL_ALL { - if (!value->set) { + if (!ERROR_SET(value)) { return; } xfree(value->msg); value->msg = NULL; + value->type = kErrorTypeNone; } Dictionary api_metadata(void) @@ -953,7 +954,7 @@ static void set_option_value_for(char *key, break; } - if (err->set) { + if (ERROR_SET(err)) { return; } @@ -981,6 +982,7 @@ static void set_option_value_err(char *key, 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); @@ -994,6 +996,5 @@ void _api_set_error(Error *err, ErrorType errType, const char *format, ...) vsnprintf(err->msg, bufsize, format, args2); va_end(args2); - err->set = true; err->type = errType; } diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 534274db0f..4c39bc57eb 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -97,7 +97,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, 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; } @@ -165,7 +165,7 @@ void nvim_ui_set_option(uint64_t channel_id, String name, 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(); } } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2c78ffdec1..924ea419a1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -165,7 +165,7 @@ String nvim_command_output(String str, Error *err) nvim_command(str, err); do_cmdline_cmd("redir END"); - if (err->set) { + if (ERROR_SET(err)) { return (String) STRING_INIT; } @@ -776,7 +776,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; } @@ -785,7 +785,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)); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1e174712a3..d7feed8bfd 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6512,7 +6512,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) Error err = ERROR_INIT; Object result = fn(INTERNAL_CALL, args, &err); - if (err.set) { + if (ERROR_SET(&err)) { nvim_err_writeln(cstr_as_string(err.msg)); goto end; } @@ -13784,7 +13784,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; } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index bd7f84fed9..36a3210c70 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -397,7 +397,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, diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index c273343b41..800f5edb85 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -475,7 +475,7 @@ Object msgpack_rpc_handle_missing_method(uint64_t channel_id, Array args, Error *error) { - _api_set_error(error, error->type, "Invalid method name"); + _api_set_error(error, kErrorTypeException, "Invalid method name"); return NIL; } @@ -484,7 +484,7 @@ Object msgpack_rpc_handle_invalid_arguments(uint64_t channel_id, Array args, Error *error) { - _api_set_error(error, error->type, "Invalid method arguments"); + _api_set_error(error, kErrorTypeException, "Invalid method arguments"); return NIL; } @@ -517,7 +517,7 @@ void msgpack_rpc_serialize_response(uint64_t response_id, msgpack_pack_int(pac, 1); msgpack_pack_uint64(pac, response_id); - if (err->set) { + if (ERROR_SET(err)) { // error represented by a [type, message] array msgpack_pack_array(pac, 2); msgpack_rpc_from_integer(err->type, pac); -- cgit From 3fbc660d57f4726044662bde1bf52c527e45fb98 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 21:54:44 +0200 Subject: api_set_error(): rename --- src/nvim/api/buffer.c | 36 ++++++++++++------------ src/nvim/api/private/helpers.c | 62 +++++++++++++++++++++--------------------- src/nvim/api/ui.c | 18 ++++++------ src/nvim/api/vim.c | 26 +++++++++--------- src/nvim/api/window.c | 10 +++---- src/nvim/msgpack_rpc/channel.c | 12 ++++---- src/nvim/msgpack_rpc/helpers.c | 20 +++++++------- 7 files changed, 92 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index cffc7a2e38..4d6081bb5e 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -171,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, kErrorTypeValidation, _("Index out of bounds")); + api_set_error(err, kErrorTypeValidation, _("Index out of bounds")); return rv; } @@ -187,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, kErrorTypeValidation, _("Line index is too high")); + api_set_error(err, kErrorTypeValidation, _("Line index is too high")); goto end; } @@ -283,13 +283,13 @@ void nvim_buf_set_lines(uint64_t channel_id, end = normalize_index(buf, end, &oob); if (strict_indexing && oob) { - _api_set_error(err, kErrorTypeValidation, _("Index out of bounds")); + api_set_error(err, kErrorTypeValidation, _("Index out of bounds")); return; } if (start > end) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Argument \"start\" is higher than \"end\"")); return; @@ -304,7 +304,7 @@ void nvim_buf_set_lines(uint64_t channel_id, for (size_t i = 0; i < new_len; i++) { if (replacement.items[i].type != kObjectTypeString) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("All items in the replacement array must be strings")); goto end; @@ -317,7 +317,7 @@ void nvim_buf_set_lines(uint64_t channel_id, 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, kErrorTypeException, _("string cannot contain newlines")); + api_set_error(err, kErrorTypeException, _("string cannot contain newlines")); new_len = i + 1; goto end; } @@ -330,7 +330,7 @@ void nvim_buf_set_lines(uint64_t channel_id, 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, kErrorTypeException, _("Failed to save undo information")); + api_set_error(err, kErrorTypeException, _("Failed to save undo information")); goto end; } @@ -340,7 +340,7 @@ 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, kErrorTypeException, _("Failed to delete line")); + api_set_error(err, kErrorTypeException, _("Failed to delete line")); goto end; } } @@ -357,12 +357,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, kErrorTypeValidation, _("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, kErrorTypeException, _("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 @@ -375,12 +375,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, kErrorTypeValidation, _("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, kErrorTypeException, _("Failed to insert line")); + api_set_error(err, kErrorTypeException, _("Failed to insert line")); goto end; } @@ -627,7 +627,7 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err) } if (ren_ret == FAIL) { - _api_set_error(err, kErrorTypeException, _("Failed to rename buffer")); + api_set_error(err, kErrorTypeException, _("Failed to rename buffer")); } } @@ -680,7 +680,7 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) } if (name.size != 1) { - _api_set_error(err, kErrorTypeValidation, _("Mark name must be a single character")); + api_set_error(err, kErrorTypeValidation, _("Mark name must be a single character")); return rv; } @@ -698,7 +698,7 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) } if (posp == NULL) { - _api_set_error(err, kErrorTypeValidation, _("Invalid mark name")); + api_set_error(err, kErrorTypeValidation, _("Invalid mark name")); return rv; } @@ -753,11 +753,11 @@ Integer nvim_buf_add_highlight(Buffer buffer, } if (line < 0 || line >= MAXLNUM) { - _api_set_error(err, kErrorTypeValidation, _("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, kErrorTypeValidation, _("Column value outside range")); + api_set_error(err, kErrorTypeValidation, _("Column value outside range")); return 0; } if (col_end < 0 || col_end > MAXCOL) { @@ -794,7 +794,7 @@ void nvim_buf_clear_highlight(Buffer buffer, } if (line_start < 0 || line_start >= MAXLNUM) { - _api_set_error(err, kErrorTypeValidation, _("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/helpers.c b/src/nvim/api/private/helpers.c index 58534d78a0..d7274920b6 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -61,7 +61,7 @@ bool try_end(Error *err) discard_current_exception(); } - _api_set_error(err, kErrorTypeException, _("Keyboard interrupt")); + api_set_error(err, kErrorTypeException, _("Keyboard interrupt")); got_int = false; } else if (msg_list != NULL && *msg_list != NULL) { int should_free; @@ -69,14 +69,14 @@ bool try_end(Error *err) ET_ERROR, NULL, &should_free); - _api_set_error(err, kErrorTypeException, "%s", msg); + api_set_error(err, kErrorTypeException, "%s", msg); free_global_msglist(); if (should_free) { xfree(msg); } } else if (did_throw) { - _api_set_error(err, kErrorTypeException, "%s", current_exception->value); + api_set_error(err, kErrorTypeException, "%s", current_exception->value); discard_current_exception(); } @@ -93,7 +93,7 @@ Object dict_get_value(dict_T *dict, String key, Error *err) dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); if (di == NULL) { - _api_set_error(err, kErrorTypeValidation, _("Key not found")); + api_set_error(err, kErrorTypeValidation, _("Key not found")); return (Object) OBJECT_INIT; } @@ -117,17 +117,17 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, Object rv = OBJECT_INIT; if (dict->dv_lock) { - _api_set_error(err, kErrorTypeException, _("Dictionary is locked")); + api_set_error(err, kErrorTypeException, _("Dictionary is locked")); return rv; } if (key.size == 0) { - _api_set_error(err, kErrorTypeValidation, _("Empty variable names 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, kErrorTypeValidation, _("Key length is too high")); + api_set_error(err, kErrorTypeValidation, _("Key length is too high")); return rv; } @@ -135,13 +135,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, if (di != NULL) { if (di->di_flags & DI_FLAGS_RO) { - _api_set_error(err, kErrorTypeException, _("Key is read-only: %s"), key.data); + 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); + 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); + api_set_error(err, kErrorTypeException, _("Key is locked: %s"), key.data); return rv; } } @@ -150,7 +150,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, // Delete the key if (di == NULL) { // Doesn't exist, fail - _api_set_error(err, kErrorTypeValidation, _("Key \"%s\" doesn't exist"), key.data); + api_set_error(err, kErrorTypeValidation, _("Key \"%s\" doesn't exist"), key.data); } else { // Return the old value if (retval) { @@ -202,7 +202,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, kErrorTypeValidation, _("Empty option name")); + api_set_error(err, kErrorTypeValidation, _("Empty option name")); return rv; } @@ -213,7 +213,7 @@ Object get_option_from(void *from, int type, String name, Error *err) type, from); if (!flags) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Invalid option name \"%s\""), name.data); @@ -232,13 +232,13 @@ Object get_option_from(void *from, int type, String name, Error *err) rv.data.string.data = stringval; rv.data.string.size = strlen(stringval); } else { - _api_set_error(err, + api_set_error(err, kErrorTypeException, _("Unable to get value for option \"%s\""), name.data); } } else { - _api_set_error(err, + api_set_error(err, kErrorTypeException, _("Unknown type for option \"%s\""), name.data); @@ -257,14 +257,14 @@ 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, kErrorTypeValidation, _("Empty option name")); + api_set_error(err, kErrorTypeValidation, _("Empty option name")); return; } int flags = get_option_value_strict(name.data, NULL, NULL, type, to); if (flags == 0) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Invalid option name \"%s\""), name.data); @@ -273,13 +273,13 @@ 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, + api_set_error(err, kErrorTypeException, _("Unable to unset option \"%s\""), name.data); return; } else if (!(flags & SOPT_GLOBAL)) { - _api_set_error(err, + api_set_error(err, kErrorTypeException, _("Cannot unset option \"%s\" " "because it doesn't have a global value"), @@ -295,7 +295,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (flags & SOPT_BOOL) { if (value.type != kObjectTypeBoolean) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Option \"%s\" requires a boolean value"), name.data); @@ -306,7 +306,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) set_option_value_for(name.data, val, NULL, opt_flags, type, to, err); } else if (flags & SOPT_NUM) { if (value.type != kObjectTypeInteger) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Option \"%s\" requires an integer value"), name.data); @@ -314,7 +314,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) } if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Value for option \"%s\" is outside range"), name.data); @@ -325,7 +325,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) set_option_value_for(name.data, val, NULL, opt_flags, type, to, err); } else { if (value.type != kObjectTypeString) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Option \"%s\" requires a string value"), name.data); @@ -560,7 +560,7 @@ buf_T *find_buffer_by_handle(Buffer buffer, Error *err) buf_T *rv = handle_get_buffer(buffer); if (!rv) { - _api_set_error(err, kErrorTypeValidation, _("Invalid buffer id")); + api_set_error(err, kErrorTypeValidation, _("Invalid buffer id")); } return rv; @@ -575,7 +575,7 @@ win_T *find_window_by_handle(Window window, Error *err) win_T *rv = handle_get_window(window); if (!rv) { - _api_set_error(err, kErrorTypeValidation, _("Invalid window id")); + api_set_error(err, kErrorTypeValidation, _("Invalid window id")); } return rv; @@ -590,7 +590,7 @@ tabpage_T *find_tab_by_handle(Tabpage tabpage, Error *err) tabpage_T *rv = handle_get_tabpage(tabpage); if (!rv) { - _api_set_error(err, kErrorTypeValidation, _("Invalid tabpage id")); + api_set_error(err, kErrorTypeValidation, _("Invalid tabpage id")); } return rv; @@ -658,7 +658,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, kErrorTypeValidation, _("Integer value outside range")); + api_set_error(err, kErrorTypeValidation, _("Integer value outside range")); return false; } @@ -712,7 +712,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) String key = item.key; if (key.size == 0) { - _api_set_error(err, kErrorTypeValidation, + api_set_error(err, kErrorTypeValidation, _("Empty dictionary keys aren't allowed")); // cleanup tv_dict_free(dict); @@ -936,7 +936,7 @@ static void set_option_value_for(char *key, if (try_end(err)) { return; } - _api_set_error(err, + api_set_error(err, kErrorTypeException, _("Problem while switching windows")); return; @@ -975,11 +975,11 @@ static void set_option_value_err(char *key, return; } - _api_set_error(err, kErrorTypeException, "%s", errmsg); + api_set_error(err, kErrorTypeException, "%s", errmsg); } } -void _api_set_error(Error *err, ErrorType errType, const char *format, ...) +void api_set_error(Error *err, ErrorType errType, const char *format, ...) FUNC_ATTR_NONNULL_ALL { assert(kErrorTypeNone != errType); diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 4c39bc57eb..26c0a8119b 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -55,12 +55,12 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (pmap_has(uint64_t)(connected_uis, channel_id)) { - _api_set_error(err, kErrorTypeException, _("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, kErrorTypeValidation, + api_set_error(err, kErrorTypeValidation, _("Expected width > 0 and height > 0")); return; } @@ -126,7 +126,7 @@ void nvim_ui_detach(uint64_t channel_id, Error *err) FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - _api_set_error(err, kErrorTypeException, _("UI is not attached for channel")); + api_set_error(err, kErrorTypeException, _("UI is not attached for channel")); return; } remote_ui_disconnect(channel_id); @@ -138,12 +138,12 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - _api_set_error(err, kErrorTypeException, _("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, kErrorTypeValidation, + api_set_error(err, kErrorTypeValidation, _("Expected width > 0 and height > 0")); return; } @@ -159,7 +159,7 @@ void nvim_ui_set_option(uint64_t channel_id, String name, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - _api_set_error(error, kErrorTypeException, _("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); @@ -173,19 +173,19 @@ void nvim_ui_set_option(uint64_t channel_id, String name, static void ui_set_option(UI *ui, String name, Object value, Error *error) { if (strcmp(name.data, "rgb") == 0) { if (value.type != kObjectTypeBoolean) { - _api_set_error(error, kErrorTypeValidation, _("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) { if (value.type != kObjectTypeBoolean) { - _api_set_error(error, kErrorTypeValidation, + api_set_error(error, kErrorTypeValidation, _("popupmenu_external must be a Boolean")); return; } ui->pum_external = value.data.boolean; } else { - _api_set_error(error, kErrorTypeValidation, _("No such ui option")); + api_set_error(error, kErrorTypeValidation, _("No such ui option")); } } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 924ea419a1..16c630b0e6 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -188,7 +188,7 @@ Object nvim_eval(String expr, Error *err) typval_T rettv; if (eval0((char_u *)expr.data, &rettv, NULL, true) == FAIL) { - _api_set_error(err, kErrorTypeException, "Failed to evaluate expression"); + api_set_error(err, kErrorTypeException, "Failed to evaluate expression"); } if (!try_end(err)) { @@ -214,7 +214,7 @@ Object nvim_call_function(String fname, Array args, Error *err) { Object rv = OBJECT_INIT; if (args.size > MAX_FUNC_ARGS) { - _api_set_error(err, kErrorTypeValidation, + api_set_error(err, kErrorTypeValidation, _("Function called with too many arguments.")); return rv; } @@ -237,7 +237,7 @@ Object nvim_call_function(String fname, Array args, Error *err) curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy, true, NULL, NULL); if (r == FAIL) { - _api_set_error(err, kErrorTypeException, _("Error calling function.")); + api_set_error(err, kErrorTypeException, _("Error calling function.")); } if (!try_end(err)) { rv = vim_to_object(&rettv); @@ -262,7 +262,7 @@ Integer nvim_strwidth(String str, Error *err) FUNC_API_SINCE(1) { if (str.size > INT_MAX) { - _api_set_error(err, kErrorTypeValidation, _("String length is too high")); + api_set_error(err, kErrorTypeValidation, _("String length is too high")); return 0; } @@ -318,7 +318,7 @@ void nvim_set_current_dir(String dir, Error *err) FUNC_API_SINCE(1) { if (dir.size >= MAXPATHL) { - _api_set_error(err, kErrorTypeValidation, _("Directory string is too long")); + api_set_error(err, kErrorTypeValidation, _("Directory string is too long")); return; } @@ -330,7 +330,7 @@ void nvim_set_current_dir(String dir, Error *err) if (vim_chdir((char_u *)string, kCdScopeGlobal)) { if (!try_end(err)) { - _api_set_error(err, kErrorTypeException, _("Failed to change directory")); + api_set_error(err, kErrorTypeException, _("Failed to change directory")); } return; } @@ -538,7 +538,7 @@ void nvim_set_current_buf(Buffer buffer, Error *err) try_start(); int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0); if (!try_end(err) && result == FAIL) { - _api_set_error(err, + api_set_error(err, kErrorTypeException, _("Failed to switch to buffer %d"), buffer); @@ -591,7 +591,7 @@ void nvim_set_current_win(Window window, Error *err) try_start(); goto_tabpage_win(win_find_tabpage(win), win); if (!try_end(err) && win != curwin) { - _api_set_error(err, + api_set_error(err, kErrorTypeException, _("Failed to switch to window %d"), window); @@ -645,7 +645,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) try_start(); goto_tabpage_tp(tp, true, true); if (!try_end(err) && tp != curtab) { - _api_set_error(err, + api_set_error(err, kErrorTypeException, _("Failed to switch to tabpage %d"), tabpage); @@ -744,21 +744,21 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) size_t i; // also used for freeing the variables for (i = 0; i < calls.size; i++) { if (calls.items[i].type != kObjectTypeArray) { - _api_set_error(err, + api_set_error(err, 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, + api_set_error(err, 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, + api_set_error(err, kErrorTypeValidation, _("name must be String")); goto validation_error; @@ -766,7 +766,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) String name = call.items[0].data.string; if (call.items[1].type != kObjectTypeArray) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("args must be Array")); goto validation_error; diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index b8326c1198..dd52b2d690 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -64,7 +64,7 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err) if (pos.size != 2 || pos.items[0].type != kObjectTypeInteger || pos.items[1].type != kObjectTypeInteger) { - _api_set_error(err, + api_set_error(err, kErrorTypeValidation, _("Argument \"pos\" must be a [row, col] array")); return; @@ -78,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, kErrorTypeValidation, _("Cursor position outside buffer")); + api_set_error(err, kErrorTypeValidation, _("Cursor position outside buffer")); return; } if (col > MAXCOL || col < 0) { - _api_set_error(err, kErrorTypeValidation, _("Column value outside range")); + api_set_error(err, kErrorTypeValidation, _("Column value outside range")); return; } @@ -132,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, kErrorTypeValidation, _("Height value outside range")); + api_set_error(err, kErrorTypeValidation, _("Height value outside range")); return; } @@ -177,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, kErrorTypeValidation, _("Width value outside range")); + api_set_error(err, kErrorTypeValidation, _("Width value outside range")); return; } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 36a3210c70..3cf85316d9 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -192,7 +192,7 @@ Object channel_send_call(uint64_t id, Channel *channel = NULL; if (!(channel = pmap_get(uint64_t)(channels, id)) || channel->closed) { - _api_set_error(err, kErrorTypeException, _("Invalid channel \"%" PRIu64 "\""), id); + api_set_error(err, kErrorTypeException, _("Invalid channel \"%" PRIu64 "\""), id); api_free_array(args); return NIL; } @@ -212,7 +212,7 @@ Object channel_send_call(uint64_t id, if (frame.errored) { if (frame.result.type == kObjectTypeString) { - _api_set_error(err, kErrorTypeException, "%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; @@ -220,13 +220,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) { - _api_set_error(err, (ErrorType)array.items[0].data.integer, "%s", + api_set_error(err, (ErrorType)array.items[0].data.integer, "%s", array.items[1].data.string.data); } else { - _api_set_error(err, kErrorTypeException, "%s", "unknown error"); + api_set_error(err, kErrorTypeException, "%s", "unknown error"); } } else { - _api_set_error(err, kErrorTypeException, "%s", "unknown error"); + api_set_error(err, kErrorTypeException, "%s", "unknown error"); } api_free_object(frame.result); @@ -512,7 +512,7 @@ static bool channel_write(Channel *channel, WBuffer *buffer) static void send_error(Channel *channel, uint64_t id, char *err) { Error e = ERROR_INIT; - _api_set_error(&e, kErrorTypeException, "%s", err); + api_set_error(&e, kErrorTypeException, "%s", err); channel_write(channel, serialize_response(channel->id, id, &e, diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 800f5edb85..0ad1d9ae4b 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -475,7 +475,7 @@ Object msgpack_rpc_handle_missing_method(uint64_t channel_id, Array args, Error *error) { - _api_set_error(error, kErrorTypeException, "Invalid method name"); + api_set_error(error, kErrorTypeException, "Invalid method name"); return NIL; } @@ -484,7 +484,7 @@ Object msgpack_rpc_handle_invalid_arguments(uint64_t channel_id, Array args, Error *error) { - _api_set_error(error, kErrorTypeException, "Invalid method arguments"); + api_set_error(error, kErrorTypeException, "Invalid method arguments"); return NIL; } @@ -570,29 +570,29 @@ 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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("Request array size should be 4 (request) " + api_set_error(err, kErrorTypeValidation, _("Request array size should be 4 (request) " "or 3 (notification)")); return; } @@ -600,19 +600,19 @@ void msgpack_rpc_validate(uint64_t *response_id, if (type == kMessageTypeRequest) { msgpack_object *id_obj = msgpack_rpc_msg_id(req); if (!id_obj) { - _api_set_error(err, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("Parameters must be an array")); + api_set_error(err, kErrorTypeValidation, _("Parameters must be an array")); return; } } -- cgit From e2936ed39768c07e810cd3c3e6255cf48fba494f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 22:06:02 +0200 Subject: tui/input.c: Use default 'ttimeoutlen' if option get fails. Should never happen, but better to be explicit. Helped-by: oni-link --- src/nvim/tui/input.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index be016668fc..b86ab8cf2f 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -223,10 +223,12 @@ 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; -- cgit From 086c354a0aad2769042dc91bf5bad021109f56e4 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 22:30:08 +0200 Subject: api: Do not translate error messages. Also re-word some error messages: - "Key does not exist: %s" - "Invalid channel: %" - "Request array size must be 4 (request) or 3 (notification)" - "String cannot contain newlines" References #6150 --- src/nvim/api/buffer.c | 38 +++++++++++++------------- src/nvim/api/private/helpers.c | 60 ++++++++++++++++++++++-------------------- src/nvim/api/ui.c | 18 ++++++------- src/nvim/api/vim.c | 26 +++++++++--------- src/nvim/api/window.c | 10 +++---- src/nvim/msgpack_rpc/channel.c | 7 ++--- src/nvim/msgpack_rpc/helpers.c | 18 ++++++------- src/nvim/po/fi.po | 6 ++--- src/nvim/po/uk.po | 6 ++--- 9 files changed, 97 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 4d6081bb5e..ae5728ee21 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -171,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, kErrorTypeValidation, _("Index out of bounds")); + api_set_error(err, kErrorTypeValidation, "Index out of bounds"); return rv; } @@ -187,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, kErrorTypeValidation, _("Line index is too high")); + api_set_error(err, kErrorTypeValidation, "Line index is too high"); goto end; } @@ -283,7 +283,7 @@ void nvim_buf_set_lines(uint64_t channel_id, end = normalize_index(buf, end, &oob); if (strict_indexing && oob) { - api_set_error(err, kErrorTypeValidation, _("Index out of bounds")); + api_set_error(err, kErrorTypeValidation, "Index out of bounds"); return; } @@ -291,7 +291,7 @@ void nvim_buf_set_lines(uint64_t channel_id, if (start > end) { api_set_error(err, kErrorTypeValidation, - _("Argument \"start\" is higher than \"end\"")); + "Argument \"start\" is higher than \"end\""); return; } @@ -306,7 +306,7 @@ void nvim_buf_set_lines(uint64_t channel_id, if (replacement.items[i].type != kObjectTypeString) { api_set_error(err, kErrorTypeValidation, - _("All items in the replacement array must be strings")); + "All items in the replacement array must be strings"); goto end; } @@ -317,7 +317,8 @@ void nvim_buf_set_lines(uint64_t channel_id, 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, kErrorTypeException, _("string cannot contain newlines")); + api_set_error(err, kErrorTypeException, + "String cannot contain newlines"); new_len = i + 1; goto end; } @@ -330,7 +331,7 @@ void nvim_buf_set_lines(uint64_t channel_id, 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, kErrorTypeException, _("Failed to save undo information")); + api_set_error(err, kErrorTypeException, "Failed to save undo information"); goto end; } @@ -340,7 +341,7 @@ 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, kErrorTypeException, _("Failed to delete line")); + api_set_error(err, kErrorTypeException, "Failed to delete line"); goto end; } } @@ -357,12 +358,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, kErrorTypeValidation, _("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, kErrorTypeException, _("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 @@ -375,12 +376,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, kErrorTypeValidation, _("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, kErrorTypeException, _("Failed to insert line")); + api_set_error(err, kErrorTypeException, "Failed to insert line"); goto end; } @@ -627,7 +628,7 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err) } if (ren_ret == FAIL) { - api_set_error(err, kErrorTypeException, _("Failed to rename buffer")); + api_set_error(err, kErrorTypeException, "Failed to rename buffer"); } } @@ -680,7 +681,8 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) } if (name.size != 1) { - api_set_error(err, kErrorTypeValidation, _("Mark name must be a single character")); + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); return rv; } @@ -698,7 +700,7 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) } if (posp == NULL) { - api_set_error(err, kErrorTypeValidation, _("Invalid mark name")); + api_set_error(err, kErrorTypeValidation, "Invalid mark name"); return rv; } @@ -753,11 +755,11 @@ Integer nvim_buf_add_highlight(Buffer buffer, } if (line < 0 || line >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, _("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, kErrorTypeValidation, _("Column value outside range")); + api_set_error(err, kErrorTypeValidation, "Column value outside range"); return 0; } if (col_end < 0 || col_end > MAXCOL) { @@ -794,7 +796,7 @@ void nvim_buf_clear_highlight(Buffer buffer, } if (line_start < 0 || line_start >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, _("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/helpers.c b/src/nvim/api/private/helpers.c index d7274920b6..69cb19c14f 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -61,7 +61,7 @@ bool try_end(Error *err) discard_current_exception(); } - api_set_error(err, kErrorTypeException, _("Keyboard interrupt")); + api_set_error(err, kErrorTypeException, "Keyboard interrupt"); got_int = false; } else if (msg_list != NULL && *msg_list != NULL) { int should_free; @@ -93,8 +93,8 @@ Object dict_get_value(dict_T *dict, String key, Error *err) dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); if (di == NULL) { - api_set_error(err, kErrorTypeValidation, _("Key not found")); - return (Object) OBJECT_INIT; + api_set_error(err, kErrorTypeValidation, "Key not found"); + return (Object)OBJECT_INIT; } return vim_to_object(&di->di_tv); @@ -117,17 +117,18 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, Object rv = OBJECT_INIT; if (dict->dv_lock) { - api_set_error(err, kErrorTypeException, _("Dictionary is locked")); + api_set_error(err, kErrorTypeException, "Dictionary is locked"); return rv; } if (key.size == 0) { - api_set_error(err, kErrorTypeValidation, _("Empty variable names 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, kErrorTypeValidation, _("Key length is too high")); + api_set_error(err, kErrorTypeValidation, "Key length is too high"); return rv; } @@ -135,13 +136,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, if (di != NULL) { if (di->di_flags & DI_FLAGS_RO) { - api_set_error(err, kErrorTypeException, _("Key is read-only: %s"), key.data); + 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); + 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); + api_set_error(err, kErrorTypeException, "Key is locked: %s", key.data); return rv; } } @@ -150,7 +151,8 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, // Delete the key if (di == NULL) { // Doesn't exist, fail - api_set_error(err, kErrorTypeValidation, _("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) { @@ -202,7 +204,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, kErrorTypeValidation, _("Empty option name")); + api_set_error(err, kErrorTypeValidation, "Empty option name"); return rv; } @@ -215,7 +217,7 @@ Object get_option_from(void *from, int type, String name, Error *err) if (!flags) { api_set_error(err, kErrorTypeValidation, - _("Invalid option name \"%s\""), + "Invalid option name \"%s\"", name.data); return rv; } @@ -234,13 +236,13 @@ Object get_option_from(void *from, int type, String name, Error *err) } else { api_set_error(err, kErrorTypeException, - _("Unable to get value for option \"%s\""), + "Unable to get value for option \"%s\"", name.data); } } else { api_set_error(err, kErrorTypeException, - _("Unknown type for option \"%s\""), + "Unknown type for option \"%s\"", name.data); } @@ -257,7 +259,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, kErrorTypeValidation, _("Empty option name")); + api_set_error(err, kErrorTypeValidation, "Empty option name"); return; } @@ -266,7 +268,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (flags == 0) { api_set_error(err, kErrorTypeValidation, - _("Invalid option name \"%s\""), + "Invalid option name \"%s\"", name.data); return; } @@ -275,14 +277,14 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (type == SREQ_GLOBAL) { api_set_error(err, kErrorTypeException, - _("Unable to unset option \"%s\""), + "Unable to unset option \"%s\"", name.data); return; } else if (!(flags & SOPT_GLOBAL)) { api_set_error(err, kErrorTypeException, - _("Cannot unset option \"%s\" " - "because it doesn't have a global value"), + "Cannot unset option \"%s\" " + "because it doesn't have a global value", name.data); return; } else { @@ -297,7 +299,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (value.type != kObjectTypeBoolean) { api_set_error(err, kErrorTypeValidation, - _("Option \"%s\" requires a boolean value"), + "Option \"%s\" requires a boolean value", name.data); return; } @@ -308,7 +310,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (value.type != kObjectTypeInteger) { api_set_error(err, kErrorTypeValidation, - _("Option \"%s\" requires an integer value"), + "Option \"%s\" requires an integer value", name.data); return; } @@ -316,7 +318,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) { api_set_error(err, kErrorTypeValidation, - _("Value for option \"%s\" is outside range"), + "Value for option \"%s\" is outside range", name.data); return; } @@ -327,7 +329,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) if (value.type != kObjectTypeString) { api_set_error(err, kErrorTypeValidation, - _("Option \"%s\" requires a string value"), + "Option \"%s\" requires a string value", name.data); return; } @@ -560,7 +562,7 @@ buf_T *find_buffer_by_handle(Buffer buffer, Error *err) buf_T *rv = handle_get_buffer(buffer); if (!rv) { - api_set_error(err, kErrorTypeValidation, _("Invalid buffer id")); + api_set_error(err, kErrorTypeValidation, "Invalid buffer id"); } return rv; @@ -575,7 +577,7 @@ win_T *find_window_by_handle(Window window, Error *err) win_T *rv = handle_get_window(window); if (!rv) { - api_set_error(err, kErrorTypeValidation, _("Invalid window id")); + api_set_error(err, kErrorTypeValidation, "Invalid window id"); } return rv; @@ -590,7 +592,7 @@ tabpage_T *find_tab_by_handle(Tabpage tabpage, Error *err) tabpage_T *rv = handle_get_tabpage(tabpage); if (!rv) { - api_set_error(err, kErrorTypeValidation, _("Invalid tabpage id")); + api_set_error(err, kErrorTypeValidation, "Invalid tabpage id"); } return rv; @@ -658,7 +660,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, kErrorTypeValidation, _("Integer value outside range")); + api_set_error(err, kErrorTypeValidation, "Integer value outside range"); return false; } @@ -713,7 +715,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) if (key.size == 0) { api_set_error(err, kErrorTypeValidation, - _("Empty dictionary keys aren't allowed")); + "Empty dictionary keys aren't allowed"); // cleanup tv_dict_free(dict); return false; @@ -938,7 +940,7 @@ static void set_option_value_for(char *key, } api_set_error(err, kErrorTypeException, - _("Problem while switching windows")); + "Problem while switching windows"); return; } set_option_value_err(key, numval, stringval, opt_flags, err); diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 26c0a8119b..f0da0d1812 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -55,13 +55,13 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(err, kErrorTypeException, _("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, kErrorTypeValidation, - _("Expected width > 0 and height > 0")); + "Expected width > 0 and height > 0"); return; } UI *ui = xcalloc(1, sizeof(UI)); @@ -126,7 +126,7 @@ void nvim_ui_detach(uint64_t channel_id, Error *err) FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(err, kErrorTypeException, _("UI is not attached for channel")); + api_set_error(err, kErrorTypeException, "UI is not attached for channel"); return; } remote_ui_disconnect(channel_id); @@ -138,13 +138,13 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(err, kErrorTypeException, _("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, kErrorTypeValidation, - _("Expected width > 0 and height > 0")); + "Expected width > 0 and height > 0"); return; } @@ -159,7 +159,7 @@ void nvim_ui_set_option(uint64_t channel_id, String name, FUNC_API_SINCE(1) FUNC_API_NOEVAL { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { - api_set_error(error, kErrorTypeException, _("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); @@ -173,19 +173,19 @@ void nvim_ui_set_option(uint64_t channel_id, String name, static void ui_set_option(UI *ui, String name, Object value, Error *error) { if (strcmp(name.data, "rgb") == 0) { if (value.type != kObjectTypeBoolean) { - api_set_error(error, kErrorTypeValidation, _("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) { if (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, - _("popupmenu_external must be a Boolean")); + "popupmenu_external must be a Boolean"); return; } ui->pum_external = value.data.boolean; } else { - api_set_error(error, kErrorTypeValidation, _("No such ui option")); + api_set_error(error, kErrorTypeValidation, "No such ui option"); } } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 16c630b0e6..da00fbc6e3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -166,7 +166,7 @@ String nvim_command_output(String str, Error *err) do_cmdline_cmd("redir END"); if (ERROR_SET(err)) { - return (String) STRING_INIT; + return (String)STRING_INIT; } return cstr_to_string((char *)get_vim_var_str(VV_COMMAND_OUTPUT)); @@ -215,7 +215,7 @@ Object nvim_call_function(String fname, Array args, Error *err) Object rv = OBJECT_INIT; if (args.size > MAX_FUNC_ARGS) { api_set_error(err, kErrorTypeValidation, - _("Function called with too many arguments.")); + "Function called with too many arguments."); return rv; } @@ -237,7 +237,7 @@ Object nvim_call_function(String fname, Array args, Error *err) curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy, true, NULL, NULL); if (r == FAIL) { - api_set_error(err, kErrorTypeException, _("Error calling function.")); + api_set_error(err, kErrorTypeException, "Error calling function."); } if (!try_end(err)) { rv = vim_to_object(&rettv); @@ -262,7 +262,7 @@ Integer nvim_strwidth(String str, Error *err) FUNC_API_SINCE(1) { if (str.size > INT_MAX) { - api_set_error(err, kErrorTypeValidation, _("String length is too high")); + api_set_error(err, kErrorTypeValidation, "String length is too high"); return 0; } @@ -318,7 +318,7 @@ void nvim_set_current_dir(String dir, Error *err) FUNC_API_SINCE(1) { if (dir.size >= MAXPATHL) { - api_set_error(err, kErrorTypeValidation, _("Directory string is too long")); + api_set_error(err, kErrorTypeValidation, "Directory string is too long"); return; } @@ -330,7 +330,7 @@ void nvim_set_current_dir(String dir, Error *err) if (vim_chdir((char_u *)string, kCdScopeGlobal)) { if (!try_end(err)) { - api_set_error(err, kErrorTypeException, _("Failed to change directory")); + api_set_error(err, kErrorTypeException, "Failed to change directory"); } return; } @@ -540,7 +540,7 @@ void nvim_set_current_buf(Buffer buffer, Error *err) if (!try_end(err) && result == FAIL) { api_set_error(err, kErrorTypeException, - _("Failed to switch to buffer %d"), + "Failed to switch to buffer %d", buffer); } } @@ -593,7 +593,7 @@ void nvim_set_current_win(Window window, Error *err) if (!try_end(err) && win != curwin) { api_set_error(err, kErrorTypeException, - _("Failed to switch to window %d"), + "Failed to switch to window %d", window); } } @@ -647,7 +647,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) if (!try_end(err) && tp != curtab) { api_set_error(err, kErrorTypeException, - _("Failed to switch to tabpage %d"), + "Failed to switch to tabpage %d", tabpage); } } @@ -746,21 +746,21 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) if (calls.items[i].type != kObjectTypeArray) { api_set_error(err, kErrorTypeValidation, - _("All items in calls array must be arrays")); + "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, kErrorTypeValidation, - _("All items in calls array must be arrays of size 2")); + "All items in calls array must be arrays of size 2"); goto validation_error; } if (call.items[0].type != kObjectTypeString) { api_set_error(err, kErrorTypeValidation, - _("name must be String")); + "Name must be String"); goto validation_error; } String name = call.items[0].data.string; @@ -768,7 +768,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) if (call.items[1].type != kObjectTypeArray) { api_set_error(err, kErrorTypeValidation, - _("args must be Array")); + "Args must be Array"); goto validation_error; } Array args = call.items[1].data.array; diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index dd52b2d690..859bf88398 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -66,7 +66,7 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err) || pos.items[1].type != kObjectTypeInteger) { api_set_error(err, kErrorTypeValidation, - _("Argument \"pos\" must be a [row, col] array")); + "Argument \"pos\" must be a [row, col] array"); return; } @@ -78,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, kErrorTypeValidation, _("Cursor position outside buffer")); + api_set_error(err, kErrorTypeValidation, "Cursor position outside buffer"); return; } if (col > MAXCOL || col < 0) { - api_set_error(err, kErrorTypeValidation, _("Column value outside range")); + api_set_error(err, kErrorTypeValidation, "Column value outside range"); return; } @@ -132,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, kErrorTypeValidation, _("Height value outside range")); + api_set_error(err, kErrorTypeValidation, "Height value outside range"); return; } @@ -177,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, kErrorTypeValidation, _("Width value outside range")); + api_set_error(err, kErrorTypeValidation, "Width value outside range"); return; } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 3cf85316d9..59594357de 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -192,7 +192,7 @@ Object channel_send_call(uint64_t id, Channel *channel = NULL; if (!(channel = pmap_get(uint64_t)(channels, id)) || channel->closed) { - api_set_error(err, kErrorTypeException, _("Invalid channel \"%" PRIu64 "\""), id); + api_set_error(err, kErrorTypeException, "Invalid channel: %" PRIu64, id); api_free_array(args); return NIL; } @@ -212,7 +212,8 @@ Object channel_send_call(uint64_t id, if (frame.errored) { if (frame.result.type == kObjectTypeString) { - api_set_error(err, kErrorTypeException, "%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; @@ -221,7 +222,7 @@ Object channel_send_call(uint64_t id, || array.items[0].data.integer == kErrorTypeValidation) && array.items[1].type == kObjectTypeString) { api_set_error(err, (ErrorType)array.items[0].data.integer, "%s", - array.items[1].data.string.data); + array.items[1].data.string.data); } else { api_set_error(err, kErrorTypeException, "%s", "unknown error"); } diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 0ad1d9ae4b..0228582d37 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -570,49 +570,49 @@ void msgpack_rpc_validate(uint64_t *response_id, *response_id = NO_RESPONSE; // Validate the basic structure of the msgpack-rpc payload if (req->type != MSGPACK_OBJECT_ARRAY) { - api_set_error(err, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("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, kErrorTypeValidation, _("Parameters must be an array")); + api_set_error(err, kErrorTypeValidation, "Parameters must be an array"); return; } } diff --git a/src/nvim/po/fi.po b/src/nvim/po/fi.po index d817144151..3551c07ff2 100644 --- a/src/nvim/po/fi.po +++ b/src/nvim/po/fi.po @@ -116,7 +116,7 @@ msgstr "merkkijono ei saa sisältää rivinvaihtoja" #. Doesn't exist, fail #, fuzzy, c-format -#~ msgid "Key \"%s\" doesn't exist" +#~ msgid "Key does not exist: %s" #~ msgstr "Tiedostoa %s ei ole" #, fuzzy @@ -3986,7 +3986,7 @@ msgid "Calling shell to execute: \"%s\"" msgstr "Kutsutaan kuorta suorittamaan: %s" #, c-format -#~ msgid "Invalid channel \"%\"" +#~ msgid "Invalid channel: %" #~ msgstr "" #~ msgid "Message is not an array" @@ -4003,7 +4003,7 @@ msgstr "Kutsutaan kuorta suorittamaan: %s" #~ msgid "Unknown message type" #~ msgstr "E574: Tuntematon rekisterityyppi %d" -#~ msgid "Request array size should be 4 (request) or 3 (notification)" +#~ msgid "Request array size must be 4 (request) or 3 (notification)" #~ msgstr "" #~ msgid "ID must be a positive integer" 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 \"%\"" +msgid "Invalid channel: %" msgstr "Некоректний канал «%»" 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" -- cgit From 8dc3eca49ba4203fb28ae4d70f3bfac35442199a Mon Sep 17 00:00:00 2001 From: Patrick Jackson Date: Mon, 24 Apr 2017 03:39:48 -0700 Subject: api/dispatch: Mark generated functions table readonly (#6576) --- src/nvim/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d7feed8bfd..c02d172458 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6009,7 +6009,7 @@ char_u *get_expr_name(expand_T *xp, int idx) /// @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); @@ -6378,7 +6378,7 @@ call_func( } } else { // Find the function name in the table, call its implementation. - VimLFuncDef *const fdef = find_internal_func((const char *)fname); + const VimLFuncDef *const fdef = find_internal_func((const char *)fname); if (fdef != NULL) { if (argcount < fdef->min_argc) { error = ERROR_TOOFEW; -- cgit From 8f346a322bc18949ae256203ffa801d7ba1dd1c0 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 24 Apr 2017 22:45:03 +0200 Subject: test/fs: sanity check for literal "~" directory (#6579) If the CWD contains a directory with the literal name "~" then the tests will have bogus failures. --- src/nvim/os/fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index c39ff5d358..aaa750db50 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -61,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 { -- cgit From 22932d8ac22f6dba3b3df068c6932bf3ad478d92 Mon Sep 17 00:00:00 2001 From: relnod Date: Tue, 25 Apr 2017 20:45:59 +0200 Subject: refactor/single-include (#6586) --- src/nvim/CMakeLists.txt | 4 ---- src/nvim/popupmnu.h | 2 ++ src/nvim/quickfix.h | 3 +++ src/nvim/regexp.h | 4 ++++ 4 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index db5e62fd67..9e9e9b6026 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -432,13 +432,9 @@ set(NO_SINGLE_CHECK_HEADERS if_cscope_defs.h misc2.h msgpack_rpc/server.h - option.h os/shell.h os_unix.h os/win_defs.h - popupmnu.h - quickfix.h - regexp.h regexp_defs.h sha256.h sign_defs.h 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/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/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 */ -- cgit From 7e571bca5d5e00e9e33e266b983a48bb4014183f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 25 Apr 2017 15:05:33 -0400 Subject: tui: Only set cursor color if the highlight group is valid (#6585) Closes #6584 --- src/nvim/tui/tui.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index ae7551098d..e1b97f5306 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -587,9 +587,11 @@ static void tui_set_mode(UI *ui, ModeShape mode) if (c.id != 0 && ui->rgb) { int attr = syn_id2attr(c.id); - attrentry_T *aep = syn_cterm_attr2entry(attr); - data->params[0].i = aep->rgb_bg_color; - unibi_out(ui, data->unibi_ext.set_cursor_color); + if (attr > 0) { + attrentry_T *aep = syn_cterm_attr2entry(attr); + data->params[0].i = aep->rgb_bg_color; + unibi_out(ui, data->unibi_ext.set_cursor_color); + } } } -- cgit From 88023d51238698dd625c26300142d3dbe5770b73 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 24 Feb 2017 09:35:27 +0000 Subject: api/ui: externalize tabline --- src/nvim/api/ui.c | 12 ++++++++++-- src/nvim/screen.c | 36 +++++++++++++++++++++++++++++++++++- src/nvim/tui/tui.c | 1 + src/nvim/ui.c | 34 ++++++++++++++++++++++++++++++++++ src/nvim/ui.h | 9 ++++++++- src/nvim/ui_bridge.c | 1 + src/nvim/window.c | 4 ++++ 7 files changed, 93 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index f0da0d1812..28fc641dec 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -69,6 +69,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->height = (int)height; ui->rgb = true; ui->pum_external = false; + ui->tabline_external = false; ui->resize = remote_ui_resize; ui->clear = remote_ui_clear; ui->eol_clear = remote_ui_eol_clear; @@ -171,19 +172,26 @@ void nvim_ui_set_option(uint64_t channel_id, String name, } static void ui_set_option(UI *ui, String name, Object value, Error *error) { - if (strcmp(name.data, "rgb") == 0) { + if (strequal(name.data, "rgb")) { if (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean"); return; } ui->rgb = value.data.boolean; - } else if (strcmp(name.data, "popupmenu_external") == 0) { + } else if (strequal(name.data, "popupmenu_external")) { if (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, "popupmenu_external must be a Boolean"); return; } ui->pum_external = value.data.boolean; + } else if (strequal(name.data, "tabline_external")) { + if (value.type != kObjectTypeBoolean) { + api_set_error(error, kErrorTypeValidation, + "tabline_external must be a Boolean"); + return; + } + ui->tabline_external = value.data.boolean; } else { api_set_error(error, kErrorTypeValidation, "No such ui option"); } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 10dc86d5fa..ed85b6e8b8 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -132,6 +132,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. */ @@ -6885,8 +6886,13 @@ static void draw_tabline(void) if (ScreenLines == NULL) { return; } - redraw_tabline = false; + if (ui_is_widget_external(kUITabline)) { + draw_tabline_ext(); + return; + } + + redraw_tabline = false; if (tabline_height() < 1) return; @@ -7027,6 +7033,34 @@ static void draw_tabline(void) redraw_tabline = FALSE; } +// send tabline update to external ui +void draw_tabline_ext(void) +{ + win_T *cwp; + + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(curtab->handle)); + Array tabs = ARRAY_DICT_INIT; + FOR_ALL_TABS(tp) { + if (tp == curtab) { + cwp = curwin; + } else { + cwp = tp->tp_curwin; + } + get_trans_bufname(cwp->w_buffer); + Array tab = ARRAY_DICT_INIT; + ADD(tab, INTEGER_OBJ(tp->handle)); + + Dictionary tab_info = ARRAY_DICT_INIT; + PUT(tab_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff))); + ADD(tab, DICTIONARY_OBJ(tab_info)); + ADD(tabs, ARRAY_OBJ(tab)); + } + ADD(args, ARRAY_OBJ(tabs)); + + ui_event("tabline_update", args); +} + /* * Get buffer name for "buf" into NameBuff[]. * Takes care of special buffer names and translates special characters. diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index e1b97f5306..cd94fe9d49 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -110,6 +110,7 @@ UI *tui_start(void) ui->stop = tui_stop; ui->rgb = p_tgc; ui->pum_external = false; + ui->tabline_external = false; ui->resize = tui_resize; ui->clear = tui_clear; ui->eol_clear = tui_eol_clear; diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 69916fa4cd..6dcc3de1b0 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -58,6 +58,10 @@ static int busy = 0; static int height, width; static int old_mode_idx = -1; +static bool tabline_external = false; +static bool cmdline_external = false; +static bool wildmenu_external = false; + // UI_CALL invokes a function on all registered UI instances. The functions can // have 0-5 arguments (configurable by SELECT_NTH). // @@ -167,17 +171,20 @@ void ui_refresh(void) int width = INT_MAX, height = INT_MAX; bool pum_external = true; + bool tabline_external = 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; + tabline_external &= ui->tabline_external; } row = col = 0; screen_resize(width, height); pum_set_external(pum_external); + ui_set_widget_external(kUITabline, tabline_external); ui_mode_info_set(); old_mode_idx = -1; ui_cursor_shape(); @@ -557,3 +564,30 @@ void ui_cursor_shape(void) conceal_check_cursur_line(); } +bool ui_is_widget_external(UIWidget widget) +{ + switch (widget) { + case kUITabline: + return tabline_external; + case kUICmdline: + return cmdline_external; + case kUIWildmenu: + return wildmenu_external; + } + return false; +} + +void ui_set_widget_external(UIWidget widget, bool external) +{ + switch (widget) { + case kUITabline: + tabline_external = external; + break; + case kUICmdline: + cmdline_external = external; + break; + case kUIWildmenu: + wildmenu_external = external; + break; + } +} diff --git a/src/nvim/ui.h b/src/nvim/ui.h index fcf52ac9e1..a1ff449eaf 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -8,6 +8,13 @@ #include "api/private/defs.h" #include "nvim/buffer_defs.h" +// values for externalized widgets +typedef enum { + kUITabline, + kUICmdline, + kUIWildmenu +} UIWidget; + typedef struct { bool bold, underline, undercurl, italic, reverse; int foreground, background, special; @@ -16,7 +23,7 @@ typedef struct { typedef struct ui_t UI; struct ui_t { - bool rgb, pum_external; + bool rgb, pum_external, tabline_external; int width, height; void *data; void (*resize)(UI *ui, int rows, int columns); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 5697c765ba..9a3fcab13c 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -58,6 +58,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->ui = ui; rv->bridge.rgb = ui->rgb; rv->bridge.pum_external = ui->pum_external; + rv->bridge.tabline_external = ui->tabline_external; rv->bridge.stop = ui_bridge_stop; rv->bridge.resize = ui_bridge_resize; rv->bridge.clear = ui_bridge_clear; diff --git a/src/nvim/window.c b/src/nvim/window.c index 60bba19b07..effce8b413 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -48,6 +48,7 @@ #include "nvim/syntax.h" #include "nvim/terminal.h" #include "nvim/undo.h" +#include "nvim/ui.h" #include "nvim/os/os.h" @@ -5223,6 +5224,9 @@ static void last_status_rec(frame_T *fr, int statusline) */ int tabline_height(void) { + if (ui_is_widget_external(kUITabline)) { + return 0; + } assert(first_tabpage); switch (p_stal) { case 0: return 0; -- cgit From 00843902d3472ac4e74106fc06fa60e599914496 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 25 Apr 2017 02:17:15 +0200 Subject: api/ui: externalize tabline - Work with a bool[] array parallel to the UIWidget enum. - Rename some functions. - Documentation. --- src/nvim/api/ui.c | 40 ++++++++++++++++++++++++++++++++-------- src/nvim/popupmnu.c | 9 +-------- src/nvim/screen.c | 18 +++++------------- src/nvim/tui/tui.c | 5 +++-- src/nvim/ui.c | 51 +++++++++++++++++++-------------------------------- src/nvim/ui.h | 10 ++++++---- src/nvim/ui_bridge.c | 6 ++++-- src/nvim/window.c | 4 ++-- 8 files changed, 72 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 28fc641dec..08d285eedc 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -68,8 +68,6 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->width = (int)width; ui->height = (int)height; ui->rgb = true; - ui->pum_external = false; - ui->tabline_external = false; ui->resize = remote_ui_resize; ui->clear = remote_ui_clear; ui->eol_clear = remote_ui_eol_clear; @@ -96,6 +94,8 @@ 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 (ERROR_SET(err)) { @@ -171,7 +171,8 @@ void nvim_ui_set_option(uint64_t channel_id, String name, } } -static void ui_set_option(UI *ui, String name, Object value, Error *error) { +static void ui_set_option(UI *ui, String name, Object value, Error *error) +{ if (strequal(name.data, "rgb")) { if (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean"); @@ -179,19 +180,42 @@ static void ui_set_option(UI *ui, String name, Object value, Error *error) { } ui->rgb = value.data.boolean; } else if (strequal(name.data, "popupmenu_external")) { + // LEGACY: Deprecated option, use `ui_ext` instead. if (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, "popupmenu_external must be a Boolean"); return; } - ui->pum_external = value.data.boolean; - } else if (strequal(name.data, "tabline_external")) { - if (value.type != kObjectTypeBoolean) { + ui->ui_ext[kUIPopupmenu] = value.data.boolean; + } else if (strequal(name.data, "ui_ext")) { + if (value.type != kObjectTypeArray) { api_set_error(error, kErrorTypeValidation, - "tabline_external must be a Boolean"); + "ui_ext must be an Array"); return; } - ui->tabline_external = value.data.boolean; + + for (size_t i = 0; i < value.data.array.size; i++) { + Object item = value.data.array.items[i]; + if (item.type != kObjectTypeString) { + api_set_error(error, kErrorTypeValidation, + "ui_ext: item must be a String"); + return; + } + char *name = item.data.string.data; + if (strequal(name, "cmdline")) { + ui->ui_ext[kUICmdline] = true; + } else if (strequal(name, "popupmenu")) { + ui->ui_ext[kUIPopupmenu] = true; + } else if (strequal(name, "tabline")) { + ui->ui_ext[kUITabline] = true; + } else if (strequal(name, "wildmenu")) { + ui->ui_ext[kUIWildmenu] = true; + } else { + api_set_error(error, kErrorTypeValidation, + "ui_ext: unknown widget: %s", name); + return; + } + } } else { api_set_error(error, kErrorTypeValidation, "No such ui option"); } diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 6e81c5a171..b8650d8c62 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -41,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" @@ -80,7 +78,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) 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: @@ -751,8 +749,3 @@ int pum_get_height(void) { return pum_height; } - -void pum_set_external(bool external) -{ - pum_wants_external = external; -} diff --git a/src/nvim/screen.c b/src/nvim/screen.c index ed85b6e8b8..a6563534aa 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -6886,14 +6886,13 @@ static void draw_tabline(void) if (ScreenLines == NULL) { return; } + redraw_tabline = false; - if (ui_is_widget_external(kUITabline)) { - draw_tabline_ext(); + if (ui_is_external(kUITabline)) { + ui_ext_tabline_update(); return; } - redraw_tabline = false; - if (tabline_height() < 1) return; @@ -7033,20 +7032,13 @@ static void draw_tabline(void) redraw_tabline = FALSE; } -// send tabline update to external ui -void draw_tabline_ext(void) +void ui_ext_tabline_update(void) { - win_T *cwp; - Array args = ARRAY_DICT_INIT; ADD(args, INTEGER_OBJ(curtab->handle)); Array tabs = ARRAY_DICT_INIT; FOR_ALL_TABS(tp) { - if (tp == curtab) { - cwp = curwin; - } else { - cwp = tp->tp_curwin; - } + win_T *cwp = (tp == curtab) ? curwin : tp->tp_curwin; get_trans_bufname(cwp->w_buffer); Array tab = ARRAY_DICT_INIT; ADD(tab, INTEGER_OBJ(tp->handle)); diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index cd94fe9d49..21abc19c47 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -109,8 +109,6 @@ UI *tui_start(void) UI *ui = xcalloc(1, sizeof(UI)); ui->stop = tui_stop; ui->rgb = p_tgc; - ui->pum_external = false; - ui->tabline_external = false; ui->resize = tui_resize; ui->clear = tui_clear; ui->eol_clear = tui_eol_clear; @@ -136,6 +134,9 @@ 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); } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 6dcc3de1b0..713dffb46c 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -47,6 +47,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 { @@ -58,10 +59,6 @@ static int busy = 0; static int height, width; static int old_mode_idx = -1; -static bool tabline_external = false; -static bool cmdline_external = false; -static bool wildmenu_external = false; - // UI_CALL invokes a function on all registered UI instances. The functions can // have 0-5 arguments (configurable by SELECT_NTH). // @@ -170,21 +167,25 @@ void ui_refresh(void) } int width = INT_MAX, height = INT_MAX; - bool pum_external = true; - bool tabline_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; - tabline_external &= ui->tabline_external; + for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) { + ext_widgets[i] &= ui->ui_ext[i]; + } } row = col = 0; screen_resize(width, height); - pum_set_external(pum_external); - ui_set_widget_external(kUITabline, tabline_external); + 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(); @@ -564,30 +565,16 @@ void ui_cursor_shape(void) conceal_check_cursur_line(); } -bool ui_is_widget_external(UIWidget widget) +/// Returns true if `widget` is externalized. +bool ui_is_external(UIWidget widget) { - switch (widget) { - case kUITabline: - return tabline_external; - case kUICmdline: - return cmdline_external; - case kUIWildmenu: - return wildmenu_external; - } - return false; + return ui_ext[widget]; } -void ui_set_widget_external(UIWidget widget, bool external) +/// 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) { - switch (widget) { - case kUITabline: - tabline_external = external; - break; - case kUICmdline: - cmdline_external = external; - break; - case kUIWildmenu: - wildmenu_external = external; - break; - } + ui_ext[widget] = external; } diff --git a/src/nvim/ui.h b/src/nvim/ui.h index a1ff449eaf..9338ab3ea3 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -8,12 +8,13 @@ #include "api/private/defs.h" #include "nvim/buffer_defs.h" -// values for externalized widgets typedef enum { + kUICmdline = 0, + kUIPopupmenu, kUITabline, - kUICmdline, - kUIWildmenu + kUIWildmenu, } UIWidget; +#define UI_WIDGETS (kUIWildmenu + 1) typedef struct { bool bold, underline, undercurl, italic, reverse; @@ -23,7 +24,8 @@ typedef struct { typedef struct ui_t UI; struct ui_t { - bool rgb, pum_external, tabline_external; + bool rgb; + bool ui_ext[UI_WIDGETS]; ///< Externalized widgets int width, height; void *data; void (*resize)(UI *ui, int rows, int columns); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 9a3fcab13c..b7b12ae39e 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -57,8 +57,6 @@ 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.tabline_external = ui->tabline_external; rv->bridge.stop = ui_bridge_stop; rv->bridge.resize = ui_bridge_resize; rv->bridge.clear = ui_bridge_clear; @@ -86,6 +84,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); diff --git a/src/nvim/window.c b/src/nvim/window.c index effce8b413..69c0a838ea 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5224,8 +5224,8 @@ static void last_status_rec(frame_T *fr, int statusline) */ int tabline_height(void) { - if (ui_is_widget_external(kUITabline)) { - return 0; + if (ui_is_external(kUITabline)) { + return 0; } assert(first_tabpage); switch (p_stal) { -- cgit From c8e1af93de90b2e23579f726fd4aa6a65f9387b6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 25 Apr 2017 10:14:29 +0200 Subject: api: nvim_ui_attach(): Flatten ext_* options. --- src/nvim/api/ui.c | 57 ++++++++++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 08d285eedc..3c0e8bc049 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -173,13 +173,33 @@ void nvim_ui_set_option(uint64_t channel_id, String name, 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, kErrorTypeValidation, "rgb must be a Boolean"); return; } ui->rgb = value.data.boolean; - } else if (strequal(name.data, "popupmenu_external")) { + 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, kErrorTypeValidation, @@ -187,38 +207,11 @@ static void ui_set_option(UI *ui, String name, Object value, Error *error) return; } ui->ui_ext[kUIPopupmenu] = value.data.boolean; - } else if (strequal(name.data, "ui_ext")) { - if (value.type != kObjectTypeArray) { - api_set_error(error, kErrorTypeValidation, - "ui_ext must be an Array"); - return; - } - - for (size_t i = 0; i < value.data.array.size; i++) { - Object item = value.data.array.items[i]; - if (item.type != kObjectTypeString) { - api_set_error(error, kErrorTypeValidation, - "ui_ext: item must be a String"); - return; - } - char *name = item.data.string.data; - if (strequal(name, "cmdline")) { - ui->ui_ext[kUICmdline] = true; - } else if (strequal(name, "popupmenu")) { - ui->ui_ext[kUIPopupmenu] = true; - } else if (strequal(name, "tabline")) { - ui->ui_ext[kUITabline] = true; - } else if (strequal(name, "wildmenu")) { - ui->ui_ext[kUIWildmenu] = true; - } else { - api_set_error(error, kErrorTypeValidation, - "ui_ext: unknown widget: %s", name); - return; - } - } - } else { - api_set_error(error, kErrorTypeValidation, "No such ui option"); + return; } + + api_set_error(error, kErrorTypeValidation, "No such ui option"); +#undef UI_EXT_OPTION } static void push_call(UI *ui, char *name, Array args) -- cgit From 6944abad2f3f443027af1966a2a310034d2179b2 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 25 Apr 2017 11:13:29 +0200 Subject: api/ext_tabline: List of Dicts. --- src/nvim/screen.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index a6563534aa..de24156579 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -7038,15 +7038,14 @@ void ui_ext_tabline_update(void) ADD(args, INTEGER_OBJ(curtab->handle)); 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); - Array tab = ARRAY_DICT_INIT; - ADD(tab, INTEGER_OBJ(tp->handle)); - - Dictionary tab_info = ARRAY_DICT_INIT; PUT(tab_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff))); - ADD(tab, DICTIONARY_OBJ(tab_info)); - ADD(tabs, ARRAY_OBJ(tab)); + + ADD(tabs, DICTIONARY_OBJ(tab_info)); } ADD(args, ARRAY_OBJ(tabs)); -- cgit From 56911050e0e8b1917ef6d750cf8dac6fdcb9ef06 Mon Sep 17 00:00:00 2001 From: relnod Date: Thu, 27 Apr 2017 21:43:27 +0200 Subject: refactor/single-include (#6604) --- src/nvim/CMakeLists.txt | 5 ----- src/nvim/sha256.h | 1 + src/nvim/sign_defs.h | 2 ++ src/nvim/spell.h | 2 ++ src/nvim/spellfile.h | 1 + src/nvim/tag.h | 3 +++ 6 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 9e9e9b6026..691f230b6e 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -436,12 +436,7 @@ set(NO_SINGLE_CHECK_HEADERS os_unix.h os/win_defs.h regexp_defs.h - sha256.h - sign_defs.h - spell.h - spellfile.h syntax_defs.h - tag.h terminal.h tui/tui.h undo.h 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 // for uint32_t +#include #include "nvim/types.h" // for char_u 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.h b/src/nvim/spell.h index e950644a6d..ad66df4c5d 100644 --- a/src/nvim/spell.h +++ b/src/nvim/spell.h @@ -4,6 +4,8 @@ #include #include "nvim/spell_defs.h" +#include "nvim/ex_cmds_defs.h" +#include "nvim/globals.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "spell.h.generated.h" diff --git a/src/nvim/spellfile.h b/src/nvim/spellfile.h index 89acddda0d..633ee014a7 100644 --- a/src/nvim/spellfile.h +++ b/src/nvim/spellfile.h @@ -5,6 +5,7 @@ #include "nvim/spell_defs.h" #include "nvim/types.h" +#include "nvim/ex_cmds_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "spellfile.h.generated.h" 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(). */ -- cgit From 2b6a3819e5d0135102e0a771be9272e73ea88389 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 28 Apr 2017 02:20:40 +0200 Subject: build_stl_str_hl: Array name should be plural. --- src/nvim/buffer.c | 149 +++++++++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 46f2cdac79..e0812b4aed 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3060,7 +3060,7 @@ int build_stl_str_hl( 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; @@ -3080,7 +3080,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; @@ -3182,16 +3182,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; } @@ -3207,7 +3207,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); @@ -3217,11 +3217,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; } @@ -3235,18 +3235,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; } // } @@ -3257,24 +3257,24 @@ int build_stl_str_hl( 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) + 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++) { + 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; @@ -3293,8 +3293,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 @@ -3332,9 +3332,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; @@ -3369,17 +3369,17 @@ int build_stl_str_hl( /* %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; + if (items[n].type == TabPage && items[n].minwid >= 0) { + minwid = items[n].minwid; break; } } 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; @@ -3394,10 +3394,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; @@ -3420,11 +3420,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; @@ -3451,7 +3451,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) { @@ -3703,9 +3703,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++; } @@ -3716,8 +3716,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) { @@ -3874,7 +3874,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. @@ -3899,8 +3899,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) { @@ -3915,13 +3914,13 @@ 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; + if (items[i].type == Trunc) { + // Truncate at %< items. + trunc_p = items[i].start; item_idx = i; break; } @@ -3954,7 +3953,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; } @@ -4009,12 +4008,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; } } // } @@ -4030,7 +4029,7 @@ int build_stl_str_hl( // 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++; } } @@ -4042,7 +4041,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++; } @@ -4055,16 +4054,16 @@ int build_stl_str_hl( 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++) { + char_u *sep_loc = items[separator_locations[i]].start + dislocation; + STRMOVE(sep_loc, items[separator_locations[i]].start); + for (char_u *s = items[separator_locations[i]].start; s < sep_loc; 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; } } @@ -4076,9 +4075,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++; } } @@ -4090,14 +4089,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; @@ -4107,11 +4106,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++; } } -- cgit From 0ddebbc354273ada61734e5d35517ac49362c2d9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 28 Apr 2017 05:27:47 +0200 Subject: lint --- src/nvim/buffer.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index e0812b4aed..7477118d6f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3256,12 +3256,13 @@ 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 < items[groupitems[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 */ + // 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 items[idx].start -= n; @@ -3366,16 +3367,17 @@ 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) + // %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; + } } items[curitem].type = TabPage; items[curitem].start = out_p; @@ -3396,7 +3398,7 @@ int build_stl_str_hl( } items[curitem].type = ClickFunc; items[curitem].start = out_p; - items[curitem].cmd = xmemdupz(t, (size_t) (((char *) fmt_p - t))); + items[curitem].cmd = xmemdupz(t, (size_t)(((char *)fmt_p - t))); items[curitem].minwid = minwid; fmt_p++; curitem++; @@ -3917,13 +3919,14 @@ int build_stl_str_hl( trunc_p = items[0].start; item_idx = 0; - for (int i = 0; i < itemcnt; i++) + 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 @@ -4052,11 +4055,11 @@ 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 = items[separator_locations[i]].start + dislocation; - STRMOVE(sep_loc, items[separator_locations[i]].start); - for (char_u *s = items[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; } @@ -4090,7 +4093,7 @@ int build_stl_str_hl( StlClickRecord *cur_tab_rec = tabtab; for (long l = 0; l < itemcnt; l++) { if (items[l].type == TabPage) { - cur_tab_rec->start = (char *) items[l].start; + 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; @@ -4107,7 +4110,7 @@ int build_stl_str_hl( cur_tab_rec->def.func = NULL; cur_tab_rec++; } else if (items[l].type == ClickFunc) { - cur_tab_rec->start = (char *) items[l].start; + cur_tab_rec->start = (char *)items[l].start; cur_tab_rec->def.type = kStlClickFuncRun; cur_tab_rec->def.tabnr = items[l].minwid; cur_tab_rec->def.func = items[l].cmd; -- cgit From 7044aa6e8256844bc1bd23eb61d4a41ca6d418d0 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 28 Apr 2017 07:01:46 +0200 Subject: api/ext_tabline: `curtab` should be a Tabpage handle. --- src/nvim/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index de24156579..f2709c48fd 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -7035,7 +7035,7 @@ static void draw_tabline(void) void ui_ext_tabline_update(void) { Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(curtab->handle)); + ADD(args, TABPAGE_OBJ(curtab->handle)); Array tabs = ARRAY_DICT_INIT; FOR_ALL_TABS(tp) { Dictionary tab_info = ARRAY_DICT_INIT; -- cgit From 3ea10077534cb1dcb1597ffcf85e601fa0c0e27b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 13 Mar 2017 15:02:37 +0100 Subject: api: nvim_get_mode() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Asynchronous API functions are served immediately, which means pending input could change the state of Nvim shortly after an async API function result is returned. nvim_get_mode() is different: - If RPCs are known to be blocked, it responds immediately (without flushing the input/event queue) - else it is handled just-in-time before waiting for input, after pending input was processed. This makes the result more reliable (but not perfect). Internally this is handled as a special case, but _semantically_ nothing has changed: API users never know when input flushes, so this internal special-case doesn't violate that. As far as API users are concerned, nvim_get_mode() is just another asynchronous API function. In all cases nvim_get_mode() never blocks for more than the time it takes to flush the input/event queue (~µs). Note: This doesn't address #6166; nvim_get_mode() will provoke #6166 if e.g. `d` is operator-pending. Closes #6159 --- src/nvim/api/vim.c | 21 ++++++++++++++++ src/nvim/eval.c | 55 ++++++------------------------------------ src/nvim/event/loop.c | 3 +-- src/nvim/event/multiqueue.c | 35 +++++++++++++++++++++++++++ src/nvim/memory.c | 4 --- src/nvim/msgpack_rpc/channel.c | 10 ++++++++ src/nvim/msgpack_rpc/helpers.c | 2 +- src/nvim/normal.c | 5 ++-- src/nvim/os/input.c | 16 ++++++++++++ src/nvim/state.c | 49 +++++++++++++++++++++++++++++++++++++ src/nvim/tui/tui.c | 3 --- 11 files changed, 143 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index da00fbc6e3..7c57a5b456 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -11,6 +11,7 @@ #include "nvim/api/vim.h" #include "nvim/ascii.h" +#include "nvim/log.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" #include "nvim/api/buffer.h" @@ -27,6 +28,7 @@ #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" @@ -701,6 +703,25 @@ 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(); + ILOG("blocked=%d", blocked); + + PUT(rv, "mode", STRING_OBJ(cstr_as_string(modestr))); + PUT(rv, "blocking", BOOLEAN_OBJ(blocked)); + + return rv; +} + Array nvim_get_api_info(uint64_t channel_id) FUNC_API_SINCE(1) FUNC_API_ASYNC FUNC_API_NOEVAL { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c02d172458..b0f47d8e45 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12575,59 +12575,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]; + char *mode = get_mode(); - buf[1] = NUL; - buf[2] = NUL; - - if (VIsual_active) { - if (VIsual_select) - buf[0] = VIsual_mode + 's' - 'v'; - else - buf[0] = VIsual_mode; - } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE - || State == CONFIRM) { - buf[0] = 'r'; - if (State == ASKMORE) - buf[1] = 'm'; - else if (State == CONFIRM) - buf[1] = '?'; - } else if (State == EXTERNCMD) - buf[0] = '!'; - else if (State & INSERT) { - if (State & VREPLACE_FLAG) { - buf[0] = 'R'; - buf[1] = 'v'; - } else if (State & REPLACE_FLAG) - buf[0] = 'R'; - else - buf[0] = 'i'; - } else if (State & CMDLINE) { - buf[0] = 'c'; - if (exmode_active) - buf[1] = 'v'; - } else if (exmode_active) { - buf[0] = 'c'; - buf[1] = 'e'; - } else 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; } diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 6963978581..c709ce9a1c 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -44,8 +44,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; } diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index a17bae31e3..b144347fdb 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -55,6 +55,7 @@ #include "nvim/event/multiqueue.h" #include "nvim/memory.h" +#include "nvim/log.h" #include "nvim/os/time.h" typedef struct multiqueue_item MultiQueueItem; @@ -151,6 +152,40 @@ void multiqueue_process_events(MultiQueue *this) } } +void multiqueue_process_debug(MultiQueue *this) +{ + assert(this); + QUEUE *start = QUEUE_HEAD(&this->headtail); + QUEUE *cur = start; + // MultiQueue *start = this; + // MultiQueue *cur = start; + do { + MultiQueueItem *item = multiqueue_node_data(cur); + Event ev; + if (item->link) { + assert(!this->parent); + // get the next node in the linked queue + MultiQueue *linked = item->data.queue; + assert(!multiqueue_empty(linked)); + MultiQueueItem *child = + multiqueue_node_data(QUEUE_HEAD(&linked->headtail)); + ev = child->data.item.event; + } else { + ev = item->data.item.event; + } + + // Event event = multiqueue_get(this); + // if (event.handler) { + // event.handler(event.argv); + // } + + ILOG("ev: priority=%d, handler=%p arg1=%s", ev.priority, ev.handler, + ev.argv ? ev.argv[0] : "(null)"); + + cur = cur->next; + } while (cur && cur != start); +} + /// Removes all events without processing them. void multiqueue_purge_events(MultiQueue *this) { diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 0ee4776581..74c58fb203 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -345,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 diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 59594357de..799e6eadef 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -28,7 +28,9 @@ #include "nvim/map.h" #include "nvim/log.h" #include "nvim/misc1.h" +#include "nvim/state.h" #include "nvim/lib/kvec.h" +#include "nvim/os/input.h" #define CHANNEL_BUFFER_SIZE 0xffff @@ -433,6 +435,14 @@ static void handle_request(Channel *channel, msgpack_object *request) handler.async = true; } + if (handler.async) { + char buf[256] = { 0 }; + memcpy(buf, method->via.bin.ptr, MIN(255, method->via.bin.size)); + if (strcmp("nvim_get_mode", buf) == 0) { + handler.async = input_blocking(); + } + } + RequestEvent *event_data = xmalloc(sizeof(RequestEvent)); event_data->channel = channel; event_data->handler = handler; diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 0228582d37..91ef5524ea 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -76,7 +76,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. diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 51da9429b6..09ad7beb4b 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -14,6 +14,7 @@ #include #include "nvim/vim.h" +#include "nvim/log.h" #include "nvim/ascii.h" #include "nvim/normal.h" #include "nvim/buffer.h" @@ -541,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; @@ -1083,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); } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 7b5e14dd19..26f2be6c02 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -23,6 +23,7 @@ #include "nvim/main.h" #include "nvim/misc1.h" #include "nvim/state.h" +#include "nvim/log.h" #define READ_BUFFER_SIZE 0xfff #define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4) @@ -38,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" @@ -327,13 +329,27 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, return bufsize; } +/// @return true if the main loop is blocked and waiting for input. +bool input_blocking(void) +{ + return blocking; +} + static bool input_poll(int ms) { if (do_profiling == PROF_YES && ms) { prof_inchar_enter(); } + if ((ms == - 1 || ms > 0) + && !(events_enabled || input_ready() || input_eof) + ) { + blocking = true; + multiqueue_process_debug(main_loop.events); + multiqueue_process_events(main_loop.events); + } LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof); + blocking = false; if (do_profiling == PROF_YES && ms) { prof_inchar_exit(); diff --git a/src/nvim/state.c b/src/nvim/state.c index 210708c3f4..be6aa21664 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -98,3 +98,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/tui/tui.c b/src/nvim/tui/tui.c index 21abc19c47..356221f7ce 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -74,9 +74,6 @@ 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; -- cgit From acfd2a2a29ae852ecc965ca888eb5049400bf39d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Mar 2017 00:44:03 +0100 Subject: input.c: Process only safe events before blocking. Introduce multiqueue_process_priority() to process only events at or above a certain priority. --- src/nvim/api/vim.c | 1 - src/nvim/event/defs.h | 5 +++ src/nvim/event/multiqueue.c | 93 +++++++++++++++++++++++------------------- src/nvim/event/multiqueue.h | 2 +- src/nvim/msgpack_rpc/channel.c | 32 ++++++++------- src/nvim/os/input.c | 10 ++--- 6 files changed, 78 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 7c57a5b456..a00afc24fa 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -714,7 +714,6 @@ Dictionary nvim_get_mode(void) Dictionary rv = ARRAY_DICT_INIT; char *modestr = get_mode(); bool blocked = input_blocking(); - ILOG("blocked=%d", blocked); PUT(rv, "mode", STRING_OBJ(cstr_as_string(modestr))); PUT(rv, "blocking", BOOLEAN_OBJ(blocked)); diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index e5335d9f25..509a3f8e7f 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -6,6 +6,11 @@ #define EVENT_HANDLER_MAX_ARGC 6 +typedef enum { + kEvPriorityNormal = 1, + kEvPriorityAsync = 2, // safe to run in any state +} EventPriority; + typedef void (*argv_callback)(void **argv); typedef struct message { int priority; diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index b144347fdb..a479a032f4 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -127,6 +127,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); @@ -145,45 +146,38 @@ 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); } } } -void multiqueue_process_debug(MultiQueue *this) +void multiqueue_process_priority(MultiQueue *this, int priority) { assert(this); QUEUE *start = QUEUE_HEAD(&this->headtail); - QUEUE *cur = start; - // MultiQueue *start = this; - // MultiQueue *cur = start; - do { + QUEUE *cur = start; + while (!multiqueue_empty(this)) { MultiQueueItem *item = multiqueue_node_data(cur); - Event ev; - if (item->link) { - assert(!this->parent); - // get the next node in the linked queue - MultiQueue *linked = item->data.queue; - assert(!multiqueue_empty(linked)); - MultiQueueItem *child = - multiqueue_node_data(QUEUE_HEAD(&linked->headtail)); - ev = child->data.item.event; + assert(!item->link || !this->parent); // Only a parent queue has link-nodes + Event ev = multiqueueitem_get_event(item, false); + + if (ev.priority >= priority) { + if (ev.handler) { + ev.handler(ev.argv); + } + // Processed. Remove this item and get the new head. + (void)multiqueue_remove(this); + cur = QUEUE_HEAD(&this->headtail); } else { - ev = item->data.item.event; + // Not processed. Skip this item and get the next one. + cur = cur->next->next; + if (!cur || cur == start) { + break; + } } - - // Event event = multiqueue_get(this); - // if (event.handler) { - // event.handler(event.argv); - // } - - ILOG("ev: priority=%d, handler=%p arg1=%s", ev.priority, ev.handler, - ev.argv ? ev.argv[0] : "(null)"); - - cur = cur->next; - } while (cur && cur != start); + } } /// Removes all events without processing them. @@ -213,36 +207,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) @@ -250,6 +256,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..72145482aa 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(kEvPriorityNormal, h, __VA_ARGS__)); #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 799e6eadef..9e43924db1 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -435,24 +435,26 @@ static void handle_request(Channel *channel, msgpack_object *request) handler.async = true; } - if (handler.async) { - char buf[256] = { 0 }; - memcpy(buf, method->via.bin.ptr, MIN(255, method->via.bin.size)); - if (strcmp("nvim_get_mode", buf) == 0) { - handler.async = input_blocking(); - } - } - - 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 = sizeof("nvim_get_mode") - 1 == method->via.bin.size + && !strncmp("nvim_get_mode", method->via.bin.ptr, method->via.bin.size); + + if (is_get_mode && !input_blocking()) { + // Schedule on the main loop with special priority. #6247 + Event ev = event_create(kEvPriorityAsync, on_request_event, 1, evdata); + multiqueue_put_event(channel->events, ev); + } 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); } } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 26f2be6c02..de6d4a9010 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -341,12 +341,12 @@ static bool input_poll(int ms) prof_inchar_enter(); } - if ((ms == - 1 || ms > 0) - && !(events_enabled || input_ready() || input_eof) - ) { + if ((ms == - 1 || ms > 0) && !events_enabled && !input_eof) { + // We have discovered that the pending input will provoke a blocking wait. + // Process any events marked with priority `kEvPriorityAsync`: these events + // must be handled after flushing input. See channel.c:handle_request #6247 blocking = true; - multiqueue_process_debug(main_loop.events); - multiqueue_process_events(main_loop.events); + multiqueue_process_priority(main_loop.events, kEvPriorityAsync); } LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof); blocking = false; -- cgit From f17a8185191b778960953508a5bf9b5f95b0560c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 27 Apr 2017 13:54:54 +0200 Subject: api/nvim_get_mode: Use child-queue instead of "priority". --- src/nvim/api/vim.c | 1 - src/nvim/event/multiqueue.c | 1 - src/nvim/msgpack_rpc/channel.c | 7 +++---- src/nvim/msgpack_rpc/channel.h | 5 +++++ src/nvim/normal.c | 1 - src/nvim/os/input.c | 8 +++----- 6 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a00afc24fa..11f15b5ad1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -11,7 +11,6 @@ #include "nvim/api/vim.h" #include "nvim/ascii.h" -#include "nvim/log.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" #include "nvim/api/buffer.h" diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index a479a032f4..66a261b554 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -55,7 +55,6 @@ #include "nvim/event/multiqueue.h" #include "nvim/memory.h" -#include "nvim/log.h" #include "nvim/os/time.h" typedef struct multiqueue_item MultiQueueItem; diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 9e43924db1..911f2a6fa4 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -28,7 +28,6 @@ #include "nvim/map.h" #include "nvim/log.h" #include "nvim/misc1.h" -#include "nvim/state.h" #include "nvim/lib/kvec.h" #include "nvim/os/input.h" @@ -91,6 +90,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); @@ -446,9 +446,8 @@ static void handle_request(Channel *channel, msgpack_object *request) && !strncmp("nvim_get_mode", method->via.bin.ptr, method->via.bin.size); if (is_get_mode && !input_blocking()) { - // Schedule on the main loop with special priority. #6247 - Event ev = event_create(kEvPriorityAsync, on_request_event, 1, evdata); - multiqueue_put_event(channel->events, ev); + // 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); 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/normal.c b/src/nvim/normal.c index 09ad7beb4b..f73e3079b9 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -14,7 +14,6 @@ #include #include "nvim/vim.h" -#include "nvim/log.h" #include "nvim/ascii.h" #include "nvim/normal.h" #include "nvim/buffer.h" diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index de6d4a9010..31e06ce404 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -23,7 +23,7 @@ #include "nvim/main.h" #include "nvim/misc1.h" #include "nvim/state.h" -#include "nvim/log.h" +#include "nvim/msgpack_rpc/channel.h" #define READ_BUFFER_SIZE 0xfff #define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4) @@ -342,11 +342,9 @@ static bool input_poll(int ms) } if ((ms == - 1 || ms > 0) && !events_enabled && !input_eof) { - // We have discovered that the pending input will provoke a blocking wait. - // Process any events marked with priority `kEvPriorityAsync`: these events - // must be handled after flushing input. See channel.c:handle_request #6247 + // The pending input provoked a blocking wait. Do special events now. #6247 blocking = true; - multiqueue_process_priority(main_loop.events, kEvPriorityAsync); + multiqueue_process_events(ch_before_blocking_events); } LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof); blocking = false; -- cgit From 8f59d1483934f91011b755406251136c406e77f6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 27 Apr 2017 14:38:41 +0200 Subject: event: Remove "priority" concept. It was replaced by the "child queue" concept (MultiQueue). --- src/nvim/event/defs.h | 13 +++---------- src/nvim/event/multiqueue.c | 27 --------------------------- src/nvim/event/multiqueue.h | 2 +- src/nvim/message.c | 2 +- src/nvim/tui/input.c | 4 ++-- src/nvim/tui/tui.c | 2 +- src/nvim/ui.c | 2 +- src/nvim/ui_bridge.c | 4 ++-- 8 files changed, 11 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index 509a3f8e7f..cc875d74b9 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -6,23 +6,16 @@ #define EVENT_HANDLER_MAX_ARGC 6 -typedef enum { - kEvPriorityNormal = 1, - kEvPriorityAsync = 2, // safe to run in any state -} EventPriority; - 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; \ @@ -34,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/multiqueue.c b/src/nvim/event/multiqueue.c index 66a261b554..ef9f3f1870 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -152,33 +152,6 @@ void multiqueue_process_events(MultiQueue *this) } } -void multiqueue_process_priority(MultiQueue *this, int priority) -{ - assert(this); - QUEUE *start = QUEUE_HEAD(&this->headtail); - QUEUE *cur = start; - while (!multiqueue_empty(this)) { - MultiQueueItem *item = multiqueue_node_data(cur); - assert(!item->link || !this->parent); // Only a parent queue has link-nodes - Event ev = multiqueueitem_get_event(item, false); - - if (ev.priority >= priority) { - if (ev.handler) { - ev.handler(ev.argv); - } - // Processed. Remove this item and get the new head. - (void)multiqueue_remove(this); - cur = QUEUE_HEAD(&this->headtail); - } else { - // Not processed. Skip this item and get the next one. - cur = cur->next->next; - if (!cur || cur == start) { - break; - } - } - } -} - /// Removes all events without processing them. void multiqueue_purge_events(MultiQueue *this) { diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h index 72145482aa..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(kEvPriorityNormal, h, __VA_ARGS__)); + multiqueue_put_event(q, event_create(h, __VA_ARGS__)); #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/message.c b/src/nvim/message.c index 146937c25a..696855e3aa 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -604,7 +604,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)); } /* diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index b86ab8cf2f..3d37fabeee 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -102,7 +102,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); @@ -352,7 +352,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/tui.c b/src/nvim/tui/tui.c index 356221f7ce..5653924154 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -773,7 +773,7 @@ static void tui_suspend(UI *ui) // 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)); } static void tui_set_title(UI *ui, char *title) diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 713dffb46c..924a4192bc 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -198,7 +198,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) diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index b7b12ae39e..d790770892 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -40,13 +40,13 @@ static argv_callback uilog_event = NULL; uilog_event = ui_bridge_##name##_event; \ } \ ((UIBridgeData *)ui)->scheduler( \ - event_create(1, ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)); \ + event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)); \ } while (0) #else // Schedule a function call on the UI bridge thread. #define UI_CALL(ui, name, argc, ...) \ ((UIBridgeData *)ui)->scheduler( \ - event_create(1, ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) + event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)) #endif #define INT2PTR(i) ((void *)(uintptr_t)i) -- cgit From 409e56b1392c431a36c0a48cac58d6df3cf424d7 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 28 Apr 2017 20:42:06 +0200 Subject: vim-patch:818078ddfbb8 Updated runtime files and translations. https://github.com/vim/vim/commit/818078ddfbb8cc2546f697c5675a251d095722ec --- src/nvim/po/eo.po | 289 +++++++++++++++++++++++++++++++++++++++------------ src/nvim/po/fr.po | 303 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 459 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/nvim/po/eo.po b/src/nvim/po/eo.po index b7bc6397ef..10cab0342e 100644 --- a/src/nvim/po/eo.po +++ b/src/nvim/po/eo.po @@ -23,8 +23,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Esperanto)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-07-02 16:21+0200\n" -"PO-Revision-Date: 2016-07-02 17:05+0200\n" +"POT-Creation-Date: 2016-08-26 20:54+0200\n" +"PO-Revision-Date: 2016-08-26 20:30+0200\n" "Last-Translator: Dominique PELLÉ \n" "Language-Team: \n" "Language: eo\n" @@ -56,6 +56,9 @@ msgstr "E82: Ne eblas disponigi iun ajn bufron, nun eliras..." msgid "E83: Cannot allocate buffer, using other one..." msgstr "E83: Ne eblas disponigi bufron, nun uzas alian..." +msgid "E931: Buffer cannot be registered" +msgstr "E931: Bufro ne povas esti registrita" + msgid "E515: No buffers were unloaded" msgstr "E515: Neniu bufro estis malŝargita" @@ -206,6 +209,33 @@ msgstr "" msgid "Signs for %s:" msgstr "Emfazaj simbolaĵoj de %s:" +msgid "E901: gethostbyname() in channel_open()" +msgstr "E901: gethostbyname() en channel_open()" + +msgid "E898: socket() in channel_open()" +msgstr "E898: gethostbyname() en channel_open()" + +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 " line=% id=%d name=%s" msgstr " linio=% id=%d nomo=%s" @@ -432,10 +462,6 @@ msgstr "E719: Uzo de [:] ne eblas kun Vortaro" msgid "E734: Wrong variable type for %s=" msgstr "E734: Nevalida datumtipo de variablo de %s=" -#, c-format -msgid "E130: Unknown function: %s" -msgstr "E130: Nekonata funkcio: %s" - #, c-format msgid "E461: Illegal variable name: %s" msgstr "E461: Nevalida nomo de variablo: %s" @@ -474,10 +500,6 @@ msgstr "E711: Lista valoro ne havas sufiĉe da eroj" msgid "E690: Missing \"in\" after :for" msgstr "E690: \"in\" mankas post \":for\"" -#, c-format -msgid "E107: Missing parentheses: %s" -msgstr "E107: Mankas krampoj: %s" - #, c-format msgid "E108: No such variable: \"%s\"" msgstr "E108: Ne estas tia variablo: \"%s\"" @@ -534,59 +556,115 @@ msgstr "E114: Mankas citilo: %s" msgid "E115: Missing quote: %s" msgstr "E115: Mankas citilo: %s" -#, c-format -msgid "E696: Missing comma in List: %s" -msgstr "E696: Mankas komo en Listo: %s" - -#, c-format -msgid "E697: Missing end of List ']': %s" -msgstr "E697: Mankas fino de Listo ']': %s" - msgid "Not enough memory to set references, garbage collection aborted!" msgstr "Ne sufiĉa memoro por valorigi referencojn, senrubigado ĉesigita!" -#, c-format -msgid "E720: Missing colon in Dictionary: %s" -msgstr "E720: Mankas dupunkto en la vortaro: %s" +msgid "E724: variable nested too deep for displaying" +msgstr "E724: variablo ingita tro profunde por vidigi" -#, c-format -msgid "E721: Duplicate key in Dictionary: \"%s\"" -msgstr "E721: Ripetita ŝlosilo en la vortaro: \"%s\"" +msgid "E805: Using a Float as a Number" +msgstr "E805: Uzo de Glitpunktnombro kiel Nombro" -#, c-format -msgid "E722: Missing comma in Dictionary: %s" -msgstr "E722: Mankas komo en la vortaro: %s" +msgid "E703: Using a Funcref as a Number" +msgstr "E703: Uzo de Funcref kiel Nombro" -#, c-format -msgid "E723: Missing end of Dictionary '}': %s" -msgstr "E723: Mankas fino de vortaro '}': %s" +msgid "E745: Using a List as a Number" +msgstr "E745: Uzo de Listo kiel Nombro" -msgid "E724: variable nested too deep for displaying" -msgstr "E724: variablo ingita tro profunde por vidigi" +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" + +msgid "E892: Using a String as a Float" +msgstr "E892: Uzo de Ĉeno kiel Glitpunktnombro" + +msgid "E893: Using a List as a Float" +msgstr "E893: Uzo de Listo kiel Glitpunktnombro" + +msgid "E894: Using a Dictionary as a Float" +msgstr "E894: Uzo de Vortaro kiel Glitpunktnombro" + +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" + +msgid "E730: using List as a String" +msgstr "E730: uzo de Listo kiel Ĉeno" + +msgid "E731: using Dictionary as a String" +msgstr "E731: uzo de Vortaro kiel Ĉeno" + +msgid "E908: using an invalid value as a String" +msgstr "E908: uzo de nevalida valoro kiel Ĉeno" #, c-format -msgid "E740: Too many arguments for function %s" -msgstr "E740: Tro da argumentoj por funkcio: %s" +msgid "E795: Cannot delete variable %s" +msgstr "E795: Ne eblas forviŝi variablon %s" #, c-format -msgid "E116: Invalid arguments for function %s" -msgstr "E116: Nevalidaj argumentoj por funkcio: %s" +msgid "E704: Funcref variable name must start with a capital: %s" +msgstr "E704: Nomo de variablo Funcref devas finiĝi per majusklo: %s" #, c-format -msgid "E117: Unknown function: %s" -msgstr "E117: Nekonata funkcio: %s" +msgid "E705: Variable name conflicts with existing function: %s" +msgstr "E705: Nomo de variablo konfliktas kun ekzistanta funkcio: %s" #, c-format -msgid "E119: Not enough arguments for function: %s" -msgstr "E119: Ne sufiĉe da argumentoj por funkcio: %s" +msgid "E741: Value is locked: %s" +msgstr "E741: Valoro estas ŝlosita: %s" + +msgid "Unknown" +msgstr "Nekonata" #, c-format -msgid "E120: Using not in a script context: %s" -msgstr "E120: estas uzata ekster kunteksto de skripto: %s" +msgid "E742: Cannot change value of %s" +msgstr "E742: Ne eblas ŝanĝi valoron de %s" + +msgid "E698: variable nested too deep for making a copy" +msgstr "E698: variablo ingita tro profunde por fari kopion" + +msgid "" +"\n" +"# global variables:\n" +msgstr "" +"\n" +"# mallokaj variabloj:\n" + +msgid "" +"\n" +"\tLast set from " +msgstr "" +"\n" +"\tLaste ŝaltita de " + +msgid "map() argument" +msgstr "argumento de map()" + +msgid "filter() argument" +msgstr "argumento de filter()" #, c-format -msgid "E725: Calling dict function without Dictionary: %s" -msgstr "E725: Alvoko de funkcio dict sen Vortaro: %s" +msgid "E686: Argument of %s must be a List" +msgstr "E686: Argumento de %s devas esti Listo" + +msgid "E928: String required" +msgstr "E928: Ĉeno bezonata" msgid "E808: Number or Float required" msgstr "E808: Nombro aŭ Glitpunktnombro bezonata" @@ -594,9 +672,6 @@ msgstr "E808: Nombro aŭ Glitpunktnombro bezonata" msgid "add() argument" msgstr "argumento de add()" -msgid "E699: Too many arguments" -msgstr "E699: Tro da argumentoj" - msgid "E785: complete() can only be used in Insert mode" msgstr "E785: complete() uzeblas nur en Enmeta reĝimo" @@ -636,6 +711,10 @@ msgstr "E786: Amplekso nepermesebla" msgid "E701: Invalid type for len()" msgstr "E701: Nevalida datumtipo de len()" +#, c-format +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" @@ -1054,6 +1133,10 @@ msgstr "Bedaŭrinde, la helpdosiero \"%s\" ne troveblas" msgid "E150: Not a directory: %s" msgstr "E150: Ne estas dosierujo: %s" +#, c-format +msgid "E151: No match: %s" +msgstr "E151: Neniu kongruo: %s" + #, c-format msgid "E152: Cannot open %s for writing" msgstr "E152: Ne eblas malfermi %s en skribreĝimo" @@ -1095,6 +1178,9 @@ msgstr "E159: Mankas numero de simbolo" msgid "E158: Invalid buffer name: %s" msgstr "E158: Nevalida nomo de bufro: %s" +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: %" msgstr "E157: Nevalida identigilo de simbolo: %" @@ -1105,6 +1191,9 @@ msgstr " (nesubtenata)" msgid "[Deleted]" msgstr "[Forviŝita]" +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." @@ -1204,6 +1293,10 @@ msgstr "linio %: rulas \"%s\"" msgid "finished sourcing %s" msgstr "finis ruli %s" +#, c-format +msgid "continuing in %s" +msgstr "daŭrigas en %s" + msgid "modeline" msgstr "reĝimlinio" @@ -1932,9 +2025,6 @@ msgstr "E462: Ne eblis prepari por reŝargi \"%s\"" msgid "E321: Could not reload \"%s\"" msgstr "E321: Ne eblis reŝargi \"%s\"" -msgid "--Deleted--" -msgstr "--Forviŝita--" - #, c-format msgid "auto-removing autocommand: %s " msgstr "aŭto-forviŝas aŭtokomandon: %s " @@ -1944,6 +2034,12 @@ msgstr "aŭto-forviŝas aŭtokomandon: %s " msgid "E367: No such group: \"%s\"" msgstr "E367: Ne ekzistas tia grupo: \"%s\"" +msgid "W19: Deleting augroup that is still in use" +msgstr "W19: Forviŝo de augroup kiu estas ankoraŭ uzata" + +msgid "--Deleted--" +msgstr "--Forviŝita--" + #, c-format msgid "E215: Illegal character after *: %s" msgstr "E215: Nevalida signo post *: %s" @@ -2005,8 +2101,10 @@ msgid "E351: Cannot delete fold with current 'foldmethod'" msgstr "E351: Ne eblas forviŝi faldon per la aktuala 'foldmethod'" #, c-format -msgid "+--%3ld lines folded " -msgstr "+--%3ld linioj falditaj " +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld linio faldita " +msgstr[1] "+--%3ld linioj falditaj " #. buffer has already been read msgid "E222: Add to read buffer" @@ -2550,6 +2648,7 @@ msgstr "%-5s: %s%*s (Uzo: %s)" msgid "" "\n" +" a: Find assignments to this symbol\n" " c: Find functions calling this function\n" " d: Find functions called by this function\n" " e: Find this egrep pattern\n" @@ -2558,9 +2657,9 @@ msgid "" " i: Find files #including this file\n" " s: Find this C symbol\n" " t: Find this text string\n" -" a: Find assignments to this symbol\n" 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" @@ -2569,7 +2668,6 @@ msgstr "" " i: Trovi dosierojn, kiuj inkluzivas (#include) tiun dosieron\n" " s: Trovi tiun C-simbolon\n" " t: Trovi tiun ĉenon\n" -" a: Trovi valirizojn al tiu simbolo\n" msgid "E568: duplicate cscope database not added" msgstr "E568: ripetita datumbazo de cscope ne aldonita" @@ -2613,6 +2711,14 @@ msgstr "neniu konekto de cscope\n" msgid " # pid database name prepend path\n" msgstr " # pid nomo de datumbazo prefiksa vojo\n" +#, 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" @@ -3861,15 +3967,18 @@ msgstr "(%d de %d)%s%s: " msgid " (line deleted)" msgstr " (forviŝita linio)" +#, 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" msgid "E381: At top of quickfix stack" msgstr "E381: Ĉe la supro de stako de rapidriparo" -#, c-format -msgid "error list %d of %d; %d errors" -msgstr "listo de eraroj %d de %d; %d eraroj" +msgid "No entries" +msgstr "Neniu ano" msgid "E382: Cannot write, 'buftype' option is set" msgstr "E382: Ne eblas skribi, opcio 'buftype' estas ŝaltita" @@ -4082,9 +4191,6 @@ msgstr " hebrea" msgid " Arabic" msgstr " araba" -msgid " (lang)" -msgstr " (lingvo)" - msgid " (paste)" msgstr " (algluo)" @@ -4179,8 +4285,47 @@ msgstr "" "# Lasta serĉa ŝablono %s:\n" "~" -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" msgid "E758: Truncated spell file" msgstr "E758: Trunkita literuma dosiero" @@ -4226,8 +4371,24 @@ msgid "E770: Unsupported section in spell file" msgstr "E770: Nesubtenata sekcio en literuma dosiero" #, c-format -msgid "Warning: region %s not supported" -msgstr "Averto: regiono %s ne subtenata" +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" #, c-format msgid "Reading affix file %s ..." diff --git a/src/nvim/po/fr.po b/src/nvim/po/fr.po index 2d99d67099..4b1b0476ca 100644 --- a/src/nvim/po/fr.po +++ b/src/nvim/po/fr.po @@ -15,8 +15,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Franais)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-07-02 16:21+0200\n" -"PO-Revision-Date: 2016-07-02 17:06+0200\n" +"POT-Creation-Date: 2016-08-26 20:54+0200\n" +"PO-Revision-Date: 2016-08-26 20:34+0200\n" "Last-Translator: Dominique Pell \n" "Language-Team: \n" "Language: fr\n" @@ -53,6 +53,9 @@ msgid "E83: Cannot allocate buffer, using other one..." msgstr "" "E83: L'allocation du tampon a chou : arrtez Vim, librez de la mmoire" +msgid "E931: Buffer cannot be registered" +msgstr "E931: Le tampon ne peut pas tre enregistr" + msgid "E515: No buffers were unloaded" msgstr "E515: Aucun tampon n'a t dcharg" @@ -220,6 +223,33 @@ msgstr "" msgid "Signs for %s:" msgstr "Symboles dans %s :" +msgid "E901: gethostbyname() in channel_open()" +msgstr "E901: gethostbyname() dans channel_open()" + +msgid "E898: socket() in channel_open()" +msgstr "E898: socket() dans channel_open()" + +msgid "E903: received command with non-string argument" +msgstr "E903: commande reue avec une argument qui n'est pas une chane" + +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 troisime argument de \"call\" doit tre une liste" + +#, c-format +msgid "E905: received unknown command: %s" +msgstr "E905: commande inconnue reue : %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 " line=% id=%d name=%s" msgstr " ligne=% id=%d nom=%s" @@ -489,10 +519,6 @@ msgstr "E719: Utilisation de [:] impossible avec un Dictionnaire" msgid "E734: Wrong variable type for %s=" msgstr "E734: Type de variable erron avec %s=" -#, c-format -msgid "E130: Unknown function: %s" -msgstr "E130: Fonction inconnue : %s" - #, c-format msgid "E461: Illegal variable name: %s" msgstr "E461: Nom de variable invalide : %s" @@ -533,10 +559,6 @@ msgstr "E711: La Liste n'a pas assez d' msgid "E690: Missing \"in\" after :for" msgstr "E690: \"in\" manquant aprs :for" -#, c-format -msgid "E107: Missing parentheses: %s" -msgstr "E107: Parenthses manquantes : %s" - #, c-format msgid "E108: No such variable: \"%s\"" msgstr "E108: Variable inexistante : %s" @@ -598,60 +620,119 @@ msgstr "E114: Il manque \" msgid "E115: Missing quote: %s" msgstr "E115: Il manque ' la fin de %s" -#, c-format -msgid "E696: Missing comma in List: %s" -msgstr "E696: Il manque une virgule dans la Liste %s" - -#, c-format -msgid "E697: Missing end of List ']': %s" -msgstr "E697: Il manque ']' la fin de la Liste %s" - msgid "Not enough memory to set references, garbage collection aborted!" msgstr "" "Pas assez de mmoire pour les rfrences, arrt du ramassage de mites !" -#, 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 imbrique pour tre affiche" -#, c-format -msgid "E721: Duplicate key in Dictionary: \"%s\"" -msgstr "E721: Cl \"%s\" duplique dans le Dictionnaire" +msgid "E805: Using a Float as a Number" +msgstr "E805: Utilisation d'un Flottant comme un Nombre" -#, 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" -#, 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" -msgid "E724: variable nested too deep for displaying" -msgstr "E724: variable trop imbrique pour tre affiche" +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 Tche 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 Chane 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 spciale comme un Flottant" + +msgid "E911: Using a Job as a Float" +msgstr "E911: Utilisation d'une Tche 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 Chane" + +msgid "E730: using List as a String" +msgstr "E730: Utilisation d'une Liste comme une Chane" + +msgid "E731: using Dictionary as a String" +msgstr "E731: Utilisation d'un Dictionnaire comme une Chane" + +msgid "E908: using an invalid value as a String" +msgstr "E908: Utilisation d'une valeur invalide comme une Chane" #, 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" #, 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" #, 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" #, c-format -msgid "E119: Not enough arguments for function: %s" -msgstr "E119: La fonction %s n'a pas reu assez d'arguments" +msgid "E741: Value is locked: %s" +msgstr "E741: La valeur de %s est verrouille" + +msgid "Unknown" +msgstr "Inconnu" #, c-format -msgid "E120: Using not in a script context: %s" -msgstr "E120: 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 imbrique pour en faire une copie" + +# AB - La version franaise est capitalise pour tre en accord avec les autres +# commentaires enregistrs dans le fichier viminfo. +msgid "" +"\n" +"# global variables:\n" +msgstr "" +"\n" +"# Variables globales:\n" + +# DB - Plus prcis ("la dernire fois") ? +msgid "" +"\n" +"\tLast set from " +msgstr "" +"\n" +"\tModifi la dernire fois dans " + +msgid "map() argument" +msgstr "argument de map()" + +msgid "filter() argument" +msgstr "argument de filter()" #, 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: Chane requis" msgid "E808: Number or Float required" msgstr "E808: Nombre ou Flottant requis" @@ -659,9 +740,6 @@ msgstr "E808: Nombre ou Flottant requis" msgid "add() argument" msgstr "argument de add()" -msgid "E699: Too many arguments" -msgstr "E699: Trop d'arguments" - msgid "E785: complete() can only be used in Insert mode" msgstr "E785: complete() n'est utilisable que dans le mode Insertion" @@ -704,6 +782,10 @@ msgstr "E786: Les plages ne sont pas autoris msgid "E701: Invalid type for len()" msgstr "E701: Type invalide avec len()" +#, c-format +msgid "E798: ID is reserved for \":match\": %ld" +msgstr "E798: ID est rserv pour \":match\": %ld" + msgid "E726: Stride is zero" msgstr "E726: Le pas est nul" @@ -1192,15 +1274,17 @@ msgstr "D msgid "E150: Not a directory: %s" msgstr "E150: %s n'est pas un rpertoire" -# AB - La version anglaise est plus prcise, mais trop technique. +#, c-format +msgid "E151: No match: %s" +msgstr "E151: Aucune correspondance : %s" + #, 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 prcise, mais trop technique. #, c-format msgid "E153: Unable to open %s for reading" -msgstr "E153: Impossible de lire %s" +msgstr "E153: Impossible d'ouvrir %s en lecture" #, c-format msgid "E670: Mix of help file encodings within a language: %s" @@ -1247,6 +1331,9 @@ msgstr "E159: Il manque l'ID du symbole" 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 franaise est meilleure que la # version anglaise. #, c-format @@ -1259,6 +1346,9 @@ msgstr " (non support msgid "[Deleted]" msgstr "[Effac]" +msgid "No old files" +msgstr "Aucun vieux fichier" + # AB - La version franaise de la premire phrase ne me satisfait pas. # DB - Suggestion. msgid "Entering Debug mode. Type \"cont\" to continue." @@ -1309,7 +1399,8 @@ msgid "E162: No write since last change for buffer \"%s\"" msgstr "E162: Le tampon %s n'a pas t enregistr" msgid "Warning: Entered other buffer unexpectedly (check autocommands)" -msgstr "Alerte : Entre inattendue dans un autre tampon (vrifier autocommandes)" +msgstr "" +"Alerte : Entre inattendue dans un autre tampon (vrifier autocommandes)" msgid "E163: There is only one file to edit" msgstr "E163: Il n'y a qu'un seul fichier diter" @@ -1360,6 +1451,11 @@ msgstr "ligne % : sourcement de \"%s\"" msgid "finished sourcing %s" msgstr "fin du sourcement de %s" +# AB - Ce texte fait partie d'un message de dbogage. +#, c-format +msgid "continuing in %s" +msgstr "de retour dans %s" + msgid "modeline" msgstr "ligne de mode" @@ -2108,9 +2204,6 @@ msgstr "E462: Impossible de pr msgid "E321: Could not reload \"%s\"" msgstr "E321: Impossible de recharger \"%s\"" -msgid "--Deleted--" -msgstr "--Effac--" - #, c-format msgid "auto-removing autocommand: %s " msgstr "Autocommandes marques pour auto-suppression : %s " @@ -2120,6 +2213,12 @@ msgstr "Autocommandes marqu msgid "E367: No such group: \"%s\"" msgstr "E367: Aucun groupe \"%s\"" +msgid "W19: Deleting augroup that is still in use" +msgstr "W19: Effacement d'augroup toujours en usage" + +msgid "--Deleted--" +msgstr "--Effac--" + #, c-format msgid "E215: Illegal character after *: %s" msgstr "E215: Caractre non valide aprs * : %s" @@ -2182,8 +2281,10 @@ msgid "E351: Cannot delete fold with current 'foldmethod'" msgstr "E351: Impossible de supprimer un repli avec la 'foldmethod'e actuelle" #, c-format -msgid "+--%3ld lines folded " -msgstr "+--%3ld lignes replies " +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld ligne replie " +msgstr[1] "+--%3ld lignes replies " #. buffer has already been read msgid "E222: Add to read buffer" @@ -2735,6 +2836,7 @@ msgstr "%-5s: %s%*s (Utilisation : %s)" msgid "" "\n" +" a: Find assignments to this symbol\n" " c: Find functions calling this function\n" " d: Find functions called by this function\n" " e: Find this egrep pattern\n" @@ -2743,9 +2845,9 @@ msgid "" " i: Find files #including this file\n" " s: Find this C symbol\n" " t: Find this text string\n" -" a: Find assignments to this symbol\n" msgstr "" "\n" +" a: Trouver les affectations ce symbole\n" " c: Trouver les fonctions appelant cette fonction\n" " d: Trouver les fonctions appeles par cette fonction\n" " e: Trouver ce motif egrep\n" @@ -2754,7 +2856,6 @@ msgstr "" " i: Trouver les fichiers qui #incluent ce fichier\n" " s: Trouver ce symbole C\n" " t: Trouver cette chane\n" -" a: Trouver les assignements ce symbole\n" msgid "E568: duplicate cscope database not added" msgstr "E568: base de donnes cscope redondante non ajoute" @@ -2799,6 +2900,14 @@ msgstr "aucune connexion cscope\n" msgid " # pid database name prepend path\n" msgstr " # pid nom de la base de donnes chemin\n" +#, 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" @@ -4038,15 +4147,18 @@ msgstr "(%d sur %d)%s%s : " msgid " (line deleted)" msgstr " (ligne efface)" +#, 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" msgid "E381: At top of quickfix stack" msgstr "E381: Au sommet de la pile quickfix" -#, c-format -msgid "error list %d of %d; %d errors" -msgstr "liste d'erreurs %d sur %d ; %d erreurs" +msgid "No entries" +msgstr "Aucune entre" msgid "E382: Cannot write, 'buftype' option is set" msgstr "E382: criture impossible, l'option 'buftype' est active" @@ -4257,9 +4369,6 @@ msgstr " h msgid " Arabic" msgstr " arabe" -msgid " (lang)" -msgstr " (langue)" - msgid " (paste)" msgstr " (collage)" @@ -4354,8 +4463,48 @@ msgstr "" "# Dernier motif de recherche %s :\n" "~" -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 vrification orthographique n'est pas active" + +#, 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 : rgion %s non supporte" + +msgid "Sorry, no suggestions" +msgstr "Dsol, aucune suggestion" + +#, c-format +msgid "Sorry, only %ld suggestions" +msgstr "Dsol, seulement %ld suggestions" + +#. for when 'cmdheight' > 1 +#. avoid more prompt +#, c-format +msgid "Change \"%.*s\" to:" +msgstr "Remplacer \"%.*s\" par :" + +# DB - todo : l'intrt de traduire ce message m'chappe. +#, c-format +msgid " < \"%.*s\"" +msgstr " < \"%.*s\"" + +msgid "E752: No previous spell replacement" +msgstr "E752: Pas de suggestion orthographique prcdente" + +#, c-format +msgid "E753: Not found: %s" +msgstr "E753: Introuvable : %s" msgid "E758: Truncated spell file" msgstr "E758: Fichier orthographique tronqu" @@ -4401,8 +4550,24 @@ msgid "E770: Unsupported section in spell file" msgstr "E770: Section non supporte dans le fichier orthographique" #, c-format -msgid "Warning: region %s not supported" -msgstr "Alerte : rgion %s non supporte" +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 obsolte, mise jour ncessaire : %s" + +#, c-format +msgid "E780: .sug file is for newer version of Vim: %s" +msgstr "E780: Fichier .sug prvu pour une version de Vim plus rcente : %s" + +#, c-format +msgid "E781: .sug file doesn't match .spl file: %s" +msgstr "E781: Le fichier .sug ne correspond pas au fichier .spl : %s" + +#, c-format +msgid "E782: error while reading .sug file: %s" +msgstr "E782: Erreur lors de la lecture de fichier de suggestions : %s" #, c-format msgid "Reading affix file %s ..." -- cgit From 86b596dc7a49f1b148ef82a356b972b93ed0f6d4 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 28 Apr 2017 21:14:34 +0200 Subject: vim-patch:f37506f60f87 Updated runtime files. Remove HiLink commands. https://github.com/vim/vim/commit/f37506f60f87d52a9e8850e30067645e2b13783c --- src/nvim/po/eo.po | 4812 ++++++++++++++++++----------------- src/nvim/po/fr.po | 4895 ++++++++++++++++++------------------ src/nvim/po/ja.euc-jp.po | 6223 +++++++++++++++++++--------------------------- src/nvim/po/ja.po | 6220 +++++++++++++++++++-------------------------- 4 files changed, 9899 insertions(+), 12251 deletions(-) (limited to 'src') diff --git a/src/nvim/po/eo.po b/src/nvim/po/eo.po index 10cab0342e..3fb300c63f 100644 --- a/src/nvim/po/eo.po +++ b/src/nvim/po/eo.po @@ -5,7 +5,7 @@ # # UNUA TRADUKISTO Dominique PELLE # PROVLEGANTO(J) Felipe CASTRO -# Antono MECHELYNCK +# Antono MECHELYNCK # 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-08-26 20:54+0200\n" -"PO-Revision-Date: 2016-08-26 20:30+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É \n" "Language-Team: \n" "Language: eo\n" @@ -32,13 +32,20 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#, 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" -#, 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" msgid "[Location List]" msgstr "[Listo de lokoj]" @@ -59,6 +66,9 @@ msgstr "E83: Ne eblas disponigi bufron, nun uzas alian..." 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" @@ -106,19 +116,17 @@ msgid "E88: Cannot go before first buffer" msgstr "E88: Ne eblas iri antaŭ la unuan bufron" #, c-format -msgid "" -"E89: No write since last change for buffer % (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 % (aldonu ! por " +"E89: Neniu skribo de post la lasta ŝanĝo de la bufro %ld (aldonu ! por " "transpasi)" -#. wrap around (may cause duplicates) msgid "W14: Warning: List of file names overflow" msgstr "W14: Averto: Listo de dosiernomoj troas" #, c-format -msgid "E92: Buffer % not found" -msgstr "E92: Bufro % ne trovita" +msgid "E92: Buffer %ld not found" +msgstr "E92: Bufro %ld ne trovita" #, c-format msgid "E93: More than one match for %s" @@ -129,8 +137,8 @@ msgid "E94: No matching buffer for %s" msgstr "E94: Neniu bufro kongruas kun %s" #, c-format -msgid "line %" -msgstr "linio %" +msgid "line %ld" +msgstr "linio %ld" msgid "E95: Buffer with this name already exists" msgstr "E95: Bufro kun tiu nomo jam ekzistas" @@ -158,12 +166,12 @@ msgid "1 line --%d%%--" msgstr "1 linio --%d%%--" #, c-format -msgid "% lines --%d%%--" -msgstr "% linioj --%d%%--" +msgid "%ld lines --%d%%--" +msgstr "%ld linioj --%d%%--" #, c-format -msgid "line % of % --%d%%-- col " -msgstr "linio % de % --%d%%-- kol " +msgid "line %ld of %ld --%d%%-- col " +msgstr "linio %ld de %ld --%d%%-- kol " msgid "[No Name]" msgstr "[Neniu nomo]" @@ -209,6 +217,13 @@ msgstr "" msgid "Signs for %s:" msgstr "Emfazaj simbolaĵoj de %s:" +#, c-format +msgid " line=%ld id=%d name=%s" +msgstr " linio=%ld id=%d nomo=%s" + +msgid "E902: Cannot connect to port" +msgstr "E902: Ne eblas konekti al pordo" + msgid "E901: gethostbyname() in channel_open()" msgstr "E901: gethostbyname() en channel_open()" @@ -237,24 +252,69 @@ msgid "E631: %s(): write failed" msgstr "E631: %s(): Konservo malsukcesis" #, c-format -msgid " line=% id=%d name=%s" -msgstr " linio=% id=%d nomo=%s" +msgid "E917: Cannot use a callback with %s()" +msgstr "E917: Ne eblas uzi reagfunkcion kun %s()" -msgid "E545: Missing colon" -msgstr "E545: Mankas dupunkto" +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 "E546: Illegal mode" -msgstr "E546: Reĝimo nepermesata" +msgid "E906: not an open channel" +msgstr "E906: ne estas malfermita kanalo" -msgid "E548: digit expected" -msgstr "E548: cifero atendata" +msgid "E920: _io file requires _name to be set" +msgstr "E920: dosiero _io bezonas _name" -msgid "E549: Illegal percentage" -msgstr "E549: Nevalida procento" +msgid "E915: in_io buffer requires in_buf or in_name to be set" +msgstr "E915: bufro in_io bezonas in_buf aŭ in_name" + +#, c-format +msgid "E918: buffer must be loaded: %s" +msgstr "E918: bufro devas esti ŝargita: %s" + +msgid "E821: File is encrypted with unknown method" +msgstr "E821: Dosiero estas ĉifrita per nekonata metodo" + +msgid "Warning: Using a weak encryption method; see :help 'cm'" +msgstr "Averto: uzo de malfortika ĉifrada metodo; vidu :help 'cm'" + +msgid "Enter encryption key: " +msgstr "Tajpu la ŝlosilon de ĉifrado: " + +msgid "Enter same key again: " +msgstr "Tajpu la ŝlosilon denove: " + +msgid "Keys don't match!" +msgstr "Ŝlosiloj ne kongruas!" + +msgid "[crypted]" +msgstr "[ĉifrita]" + +#, c-format +msgid "E720: Missing colon in Dictionary: %s" +msgstr "E720: Mankas dupunkto en la vortaro: %s" + +#, c-format +msgid "E721: Duplicate key in Dictionary: \"%s\"" +msgstr "E721: Ripetita ŝlosilo en la vortaro: \"%s\"" + +#, c-format +msgid "E722: Missing comma in Dictionary: %s" +msgstr "E722: Mankas komo en la vortaro: %s" + +#, c-format +msgid "E723: Missing end of Dictionary '}': %s" +msgstr "E723: Mankas fino de vortaro '}': %s" + +msgid "extend() argument" +msgstr "argumento de extend()" + +#, c-format +msgid "E737: Key already exists: %s" +msgstr "E737: Ŝlosilo jam ekzistas: %s" #, c-format -msgid "E96: Can not diff more than % buffers" -msgstr "E96: Ne eblas dosierdiferenci pli ol % bufrojn" +msgid "E96: Cannot diff more than %ld buffers" +msgstr "E96: Ne eblas dosierdiferenci pli ol %ld bufrojn" msgid "E810: Cannot read or write temp files" msgstr "E810: Ne eblas legi aŭ skribi provizorajn dosierojn" @@ -262,6 +322,9 @@ msgstr "E810: Ne eblas legi aŭ skribi provizorajn dosierojn" msgid "E97: Cannot create diffs" msgstr "E97: Ne eblas krei dosierdiferencojn" +msgid "Patch file" +msgstr "Flika dosiero" + msgid "E816: Cannot read patch output" msgstr "E816: Ne eblas legi eliron de flikilo \"patch\"" @@ -406,13 +469,10 @@ msgstr "kongruo %d de %d" msgid "match %d" msgstr "kongruo %d" +#. maximum nesting of lists and dicts msgid "E18: Unexpected characters in :let" msgstr "E18: Neatenditaj signoj en \":let\"" -#, c-format -msgid "E684: list index out of range: %" -msgstr "E684: indekso de listo ekster limoj: %" - #, c-format msgid "E121: Undefined variable: %s" msgstr "E121: Nedifinita variablo: %s" @@ -420,41 +480,6 @@ msgstr "E121: Nedifinita variablo: %s" msgid "E111: Missing ']'" msgstr "E111: Mankas ']'" -#, c-format -msgid "E686: Argument of %s must be a List" -msgstr "E686: Argumento de %s devas esti Listo" - -#, c-format -msgid "E712: Argument of %s must be a List or Dictionary" -msgstr "E712: Argumento de %s devas esti Listo aŭ Vortaro" - -msgid "E714: List required" -msgstr "E714: Listo bezonata" - -msgid "E715: Dictionary required" -msgstr "E715: Vortaro bezonata" - -msgid "E928: String required" -msgstr "E928: Ĉeno bezonata" - -#, c-format -msgid "E118: Too many arguments for function: %s" -msgstr "E118: Tro da argumentoj por funkcio: %s" - -#, c-format -msgid "E716: Key not present in Dictionary: %s" -msgstr "E716: Ŝlosilo malekzistas en Vortaro: %s" - -#, c-format -msgid "E122: Function %s already exists, add ! to replace it" -msgstr "E122: La funkcio %s jam ekzistas (aldonu ! por anstataŭigi ĝin)" - -msgid "E717: Dictionary entry already exists" -msgstr "E717: Rikordo de vortaro jam ekzistas" - -msgid "E718: Funcref required" -msgstr "E718: Funcref bezonata" - msgid "E719: Cannot use [:] with a Dictionary" msgstr "E719: Uzo de [:] ne eblas kun Vortaro" @@ -513,7 +538,7 @@ msgstr "E109: Mankas ':' post '?'" msgid "E691: Can only compare List with List" msgstr "E691: Eblas nur kompari Liston kun Listo" -msgid "E692: Invalid operation for Lists" +msgid "E692: Invalid operation for List" msgstr "E692: Nevalida operacio de Listoj" msgid "E735: Can only compare Dictionary with Dictionary" @@ -522,9 +547,6 @@ msgstr "E735: Eblas nur kompari Vortaron kun Vortaro" msgid "E736: Invalid operation for Dictionary" msgstr "E736: Nevalida operacio de Vortaro" -msgid "E693: Can only compare Funcref with Funcref" -msgstr "E693: Eblas nur kompari Funcref kun Funcref" - msgid "E694: Invalid operation for Funcrefs" msgstr "E694: Nevalida operacio de Funcref-oj" @@ -675,30 +697,37 @@ 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" #, c-format -msgid "E737: Key already exists: %s" -msgstr "E737: Ŝlosilo jam ekzistas: %s" - -msgid "extend() argument" -msgstr "argumento de extend()" - -msgid "map() argument" -msgstr "argumento de map()" - -msgid "filter() argument" -msgstr "argumento de filter()" - -#, c-format -msgid "+-%s%3ld lines: " -msgstr "+-%s%3ld linioj: " +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld linio: " +msgstr[1] "+-%s%3ld linioj: " #, c-format msgid "E700: Unknown function: %s" msgstr "E700: Nekonata funkcio: %s" +msgid "E922: expected a dict" +msgstr "E922: vortaro atendita" + +msgid "E923: Second argument of function() must be a list or a dict" +msgstr "E923: Dua argumento de function() devas esti listo aŭ Vortaro" + +msgid "" +"&OK\n" +"&Cancel" +msgstr "" +"&Bone\n" +"&Rezigni" + msgid "called inputrestore() more often than inputsave()" msgstr "alvokis inputrestore() pli ofte ol inputsave()" @@ -708,6 +737,9 @@ msgstr "argumento de insert()" msgid "E786: Range not allowed" msgstr "E786: Amplekso nepermesebla" +msgid "E916: not a valid job" +msgstr "E916: nevalida tasko" + msgid "E701: Invalid type for len()" msgstr "E701: Nevalida datumtipo de len()" @@ -724,6 +756,16 @@ msgstr "E727: Komenco preter fino" msgid "" msgstr "" +msgid "E240: No connection to Vim server" +msgstr "E240: Neniu konekto al Vim-servilo" + +#, c-format +msgid "E241: Unable to send to %s" +msgstr "E241: Ne eblas sendi al %s" + +msgid "E277: Unable to read a server reply" +msgstr "E277: Ne eblas legi respondon de servilo" + msgid "remove() argument" msgstr "argumento de remove()" @@ -733,6 +775,9 @@ 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" + #, c-format msgid "E927: Invalid action: '%s'" msgstr "E927: Nevalida ago: '%s'" @@ -740,266 +785,131 @@ msgstr "E927: Nevalida ago: '%s'" msgid "sort() argument" msgstr "argumento de sort()" -#, fuzzy -#~ msgid "uniq() argument" -#~ msgstr "argumento de add()" +msgid "uniq() argument" +msgstr "argumento de uniq()" msgid "E702: Sort compare function failed" -msgstr "E702: Ordiga funkcio fiaskis" +msgstr "E702: Ordiga funkcio malsukcesis" -#, fuzzy -#~ msgid "E882: Uniq compare function failed" -#~ msgstr "E702: Ordiga funkcio fiaskis" +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 "E805: Using a Float as a Number" -msgstr "E805: Uzo de Glitpunktnombro kiel Nombro" - -msgid "E703: Using a Funcref as a Number" -msgstr "E703: Uzo de Funcref kiel Nombro" - -msgid "E745: Using a List as a Number" -msgstr "E745: Uzo de Listo kiel Nombro" - -msgid "E728: Using a Dictionary as a Number" -msgstr "E728: Uzo de Vortaro kiel Nombro" - -msgid "E891: Using a Funcref as a Float" -msgstr "E891: Uzo de Funcref kiel Glitpunktnombro" - -msgid "E892: Using a String as a Float" -msgstr "E892: Uzo de Ĉeno kiel Glitpunktnombro" - -msgid "E893: Using a List as a Float" -msgstr "E893: Uzo de Listo kiel Glitpunktnombro" - -msgid "E894: Using a Dictionary as a Float" -msgstr "E894: Uzo de Vortaro kiel Glitpunktnombro" - -msgid "E729: using Funcref as a String" -msgstr "E729: uzo de Funcref kiel Ĉeno" - -msgid "E730: using List as a String" -msgstr "E730: uzo de Listo kiel Ĉeno" - -msgid "E731: using Dictionary as a String" -msgstr "E731: uzo de Vortaro kiel Ĉeno" - -msgid "E908: using an invalid value as a String" -msgstr "E908: uzo de nevalida valoro kiel Ĉeno" - -#, c-format -msgid "E706: Variable type mismatch for: %s" -msgstr "E706: Nekongrua datumtipo de variablo: %s" - -#, c-format -msgid "E795: Cannot delete variable %s" -msgstr "E795: Ne eblas forviŝi variablon %s" +msgid "E921: Invalid callback argument" +msgstr "E921: Nevalida argumento de reagfunctio" #, 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" +msgid "<%s>%s%s %d, Hex %02x, Octal %03o" +msgstr "<%s>%s%s %d, Deksesuma %02x, Okuma %03o" #, c-format -msgid "E705: Variable name conflicts with existing function: %s" -msgstr "E705: Nomo de variablo konfliktas kun ekzistanta funkcio: %s" +msgid "> %d, Hex %04x, Octal %o" +msgstr "> %d, Deksesuma %04x, Okuma %o" #, c-format -msgid "E741: Value is locked: %s" -msgstr "E741: Valoro estas ŝlosita: %s" - -msgid "Unknown" -msgstr "Nekonata" +msgid "> %d, Hex %08x, Octal %o" +msgstr "> %d, Deksesuma %08x, Okuma %o" -#, c-format -msgid "E742: Cannot change value of %s" -msgstr "E742: Ne eblas ŝanĝi valoron de %s" +msgid "E134: Move lines into themselves" +msgstr "E134: Movas liniojn en ilin mem" -msgid "E698: variable nested too deep for making a copy" -msgstr "E698: variablo ingita tro profunde por fari kopion" +msgid "1 line moved" +msgstr "1 linio movita" #, c-format -msgid "E123: Undefined function: %s" -msgstr "E123: Nedifinita funkcio: %s" +msgid "%ld lines moved" +msgstr "%ld linioj movitaj" #, c-format -msgid "E124: Missing '(': %s" -msgstr "E124: Mankas '(': %s" +msgid "%ld lines filtered" +msgstr "%ld linioj filtritaj" -msgid "E862: Cannot use g: here" -msgstr "E862: Ne eblas uzi g: ĉi tie" +msgid "E135: *Filter* Autocommands must not change current buffer" +msgstr "E135: *Filtraj* Aŭtokomandoj ne rajtas ŝanĝi aktualan bufron" -#, c-format -msgid "E125: Illegal argument: %s" -msgstr "E125: Nevalida argumento: %s" +msgid "[No write since last change]\n" +msgstr "[Neniu skribo de post lasta ŝanĝo]\n" #, c-format -msgid "E853: Duplicate argument name: %s" -msgstr "E853: Ripetita nomo de argumento: %s" - -msgid "E126: Missing :endfunction" -msgstr "E126: Mankas \":endfunction\"" +msgid "%sviminfo: %s in line: " +msgstr "%sviminfo: %s en linio: " -#, c-format -msgid "E707: Function name conflicts with variable: %s" -msgstr "E707: Nomo de funkcio konfliktas kun variablo: %s" +msgid "E136: viminfo: Too many errors, skipping rest of file" +msgstr "E136: viminfo: Tro da eraroj, nun ignoras la reston de la dosiero" #, c-format -msgid "E127: Cannot redefine function %s: It is in use" -msgstr "E127: Ne eblas redifini funkcion %s: Estas nuntempe uzata" +msgid "Reading viminfo file \"%s\"%s%s%s" +msgstr "Legado de dosiero viminfo \"%s\"%s%s%s" -#, 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 " info" +msgstr " informo" -msgid "E129: Function name required" -msgstr "E129: Nomo de funkcio bezonata" +msgid " marks" +msgstr " markoj" -#, 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 " oldfiles" +msgstr " malnovaj dosieroj" -#, 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 " FAILED" +msgstr " MALSUKCESIS" +#. avoid a wait_return for this message, it's annoying #, c-format -msgid "E131: Cannot delete function %s: It is in use" -msgstr "E131: Ne eblas forviŝi funkcion %s: Estas nuntempe uzata" - -msgid "E132: Function call depth is higher than 'maxfuncdepth'" -msgstr "E132: Profundo de funkcia alvoko superas 'maxfuncdepth'" +msgid "E137: Viminfo file is not writable: %s" +msgstr "E137: Dosiero viminfo ne skribeblas: %s" #, c-format -msgid "calling %s" -msgstr "alvokas %s" +msgid "E929: Too many viminfo temp files, like %s!" +msgstr "E929: Tro da provizoraj dosieroj viminfo, kiel %s!" #, c-format -msgid "%s aborted" -msgstr "%s ĉesigita" +msgid "E138: Can't write viminfo file %s!" +msgstr "E138: Ne eblas skribi dosieron viminfo %s!" #, c-format -msgid "%s returning #%" -msgstr "%s liveras #%" +msgid "Writing viminfo file \"%s\"" +msgstr "Skribas dosieron viminfo \"%s\"" #, c-format -msgid "%s returning %s" -msgstr "%s liveras %s" +msgid "E886: Can't rename viminfo file to %s!" +msgstr "E886: Ne eblas renomi dosieron viminfo al %s!" +#. Write the info: #, c-format -msgid "continuing in %s" -msgstr "daŭrigas en %s" - -msgid "E133: :return not inside a function" -msgstr "E133: \":return\" ekster funkcio" +msgid "# This viminfo file was generated by Vim %s.\n" +msgstr "# Tiu dosiero viminfo estis kreita de Vim %s.\n" msgid "" +"# You may edit it if you're careful!\n" "\n" -"# global variables:\n" msgstr "" +"# Vi povas redakti ĝin se vi estas singarda.\n" "\n" -"# mallokaj variabloj:\n" + +msgid "# Value of 'encoding' when this file was written\n" +msgstr "# Valoro de 'encoding' kiam tiu dosiero estis kreita\n" + +msgid "Illegal starting char" +msgstr "Nevalida eka signo" msgid "" "\n" -"\tLast set from " +"# Bar lines, copied verbatim:\n" msgstr "" "\n" -"\tLaste ŝaltita de " +"# Linioj komencantaj per |, kopiitaj sen ŝanĝo:\n" -msgid "No old files" -msgstr "Neniu malnova dosiero" - -#, c-format -msgid "<%s>%s%s %d, Hex %02x, Octal %03o" -msgstr "<%s>%s%s %d, Deksesuma %02x, Okuma %03o" - -#, c-format -msgid "> %d, Hex %04x, Octal %o" -msgstr "> %d, Deksesuma %04x, Okuma %o" - -#, c-format -msgid "> %d, Hex %08x, Octal %o" -msgstr "> %d, Deksesuma %08x, Okuma %o" - -msgid "E134: Move lines into themselves" -msgstr "E134: Movas liniojn en ilin mem" - -msgid "1 line moved" -msgstr "1 linio movita" - -#, c-format -msgid "% lines moved" -msgstr "% linioj movitaj" - -#, c-format -msgid "% lines filtered" -msgstr "% linioj filtritaj" - -msgid "E135: *Filter* Autocommands must not change current buffer" -msgstr "E135: *Filtraj* Aŭtokomandoj ne rajtas ŝanĝi aktualan bufron" - -msgid "[No write since last change]\n" -msgstr "[Neniu skribo de post lasta ŝanĝo]\n" - -#, c-format -msgid "%sviminfo: %s in line: " -msgstr "%sviminfo: %s en linio: " - -msgid "E136: viminfo: Too many errors, skipping rest of file" -msgstr "E136: viminfo: Tro da eraroj, nun ignoras la reston de la dosiero" - -#, c-format -msgid "Reading viminfo file \"%s\"%s%s%s" -msgstr "Legado de dosiero viminfo \"%s\"%s%s%s" - -msgid " info" -msgstr " informo" - -msgid " marks" -msgstr " markoj" - -msgid " oldfiles" -msgstr " malnovaj dosieroj" - -msgid " FAILED" -msgstr " FIASKIS" - -#. avoid a wait_return for this message, it's annoying -#, c-format -msgid "E137: Viminfo file is not writable: %s" -msgstr "E137: Dosiero viminfo ne skribeblas: %s" - -#, c-format -msgid "E138: Can't write viminfo file %s!" -msgstr "E138: Ne eblas skribi dosieron viminfo %s!" - -#, c-format -msgid "Writing viminfo file \"%s\"" -msgstr "Skribas dosieron viminfo \"%s\"" - -#. Write the info: -#, c-format -msgid "# This viminfo file was generated by Vim %s.\n" -msgstr "# Tiu dosiero viminfo estis kreita de Vim %s.\n" - -msgid "" -"# You may edit it if you're careful!\n" -"\n" -msgstr "" -"# Vi povas redakti ĝin se vi estas singarda.\n" -"\n" - -msgid "# Value of 'encoding' when this file was written\n" -msgstr "# Valoro de 'encoding' kiam tiu dosiero estis kreita\n" - -msgid "Illegal starting char" -msgstr "Nevalida eka signo" +msgid "Save As" +msgstr "Konservi kiel" msgid "Write partial file?" msgstr "Ĉu skribi partan dosieron?" @@ -1020,8 +930,8 @@ msgid "E768: Swap file exists: %s (:silent! overrides)" msgstr "E768: Permutodosiero .swp ekzistas: %s (:silent! por transpasi)" #, c-format -msgid "E141: No file name for buffer %" -msgstr "E141: Neniu dosiernomo de bufro %" +msgid "E141: No file name for buffer %ld" +msgstr "E141: Neniu dosiernomo de bufro %ld" msgid "E142: File not written: Writing is disabled by 'write' option" msgstr "E142: Dosiero ne skribita: Skribo malŝaltita per la opcio 'write'" @@ -1048,6 +958,9 @@ msgstr "" msgid "E505: \"%s\" is read-only (add ! to override)" msgstr "E505: \"%s\" estas nurlegebla (aldonu ! por transpasi)" +msgid "Edit File" +msgstr "Redakti dosieron" + #, c-format msgid "E143: Autocommands unexpectedly deleted new buffer %s" msgstr "E143: Aŭtokomandoj neatendite forviŝis novan bufron %s" @@ -1075,19 +988,19 @@ msgid "1 substitution" msgstr "1 anstataŭigo" #, c-format -msgid "% matches" -msgstr "% kongruoj" +msgid "%ld matches" +msgstr "%ld kongruoj" #, c-format -msgid "% substitutions" -msgstr "% anstataŭigoj" +msgid "%ld substitutions" +msgstr "%ld anstataŭigoj" msgid " on 1 line" msgstr " en 1 linio" #, c-format -msgid " on % lines" -msgstr " en % linioj" +msgid " on %ld lines" +msgstr " en %ld linioj" msgid "E147: Cannot do :global recursive" msgstr "E147: Ne eblas fari \":global\" rekursie" @@ -1129,10 +1042,6 @@ msgstr "E149: Bedaŭrinde estas neniu helpo por %s" msgid "Sorry, help file \"%s\" not found" msgstr "Bedaŭrinde, la helpdosiero \"%s\" ne troveblas" -#, c-format -msgid "E150: Not a directory: %s" -msgstr "E150: Ne estas dosierujo: %s" - #, c-format msgid "E151: No match: %s" msgstr "E151: Neniu kongruo: %s" @@ -1153,6 +1062,10 @@ msgstr "E670: Miksaĵo de kodoprezento de helpa dosiero en lingvo: %s" 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" @@ -1182,8 +1095,15 @@ 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: %" -msgstr "E157: Nevalida identigilo de simbolo: %" +msgid "E157: Invalid sign ID: %ld" +msgstr "E157: Nevalida identigilo de simbolo: %ld" + +#, c-format +msgid "E885: Not possible to change sign %s" +msgstr "E885: Ne eblas ŝanĝi simbolon %s" + +msgid " (NOT FOUND)" +msgstr " (NETROVITA)" msgid " (not supported)" msgstr " (nesubtenata)" @@ -1198,8 +1118,8 @@ msgid "Entering Debug mode. Type \"cont\" to continue." msgstr "Eniras sencimigan reĝimon. Tajpu \"cont\" por daŭrigi." #, c-format -msgid "line %: %s" -msgstr "linio %: %s" +msgid "line %ld: %s" +msgstr "linio %ld: %s" #, c-format msgid "cmd: %s" @@ -1213,8 +1133,8 @@ msgid "frame at highest level: %d" msgstr "kadro je la plej alta nivelo: %d" #, c-format -msgid "Breakpoint in \"%s%s\" line %" -msgstr "Kontrolpunkto en \"%s%s\" linio %" +msgid "Breakpoint in \"%s%s\" line %ld" +msgstr "Kontrolpunkto en \"%s%s\" linio %ld" #, c-format msgid "E161: Breakpoint not found: %s" @@ -1224,8 +1144,8 @@ msgid "No breakpoints defined" msgstr "Neniu kontrolpunkto estas difinita" #, c-format -msgid "%3d %s %s line %" -msgstr "%3d %s %s linio %" +msgid "%3d %s %s line %ld" +msgstr "%3d %s %s linio %ld" msgid "E750: First use \":profile start {fname}\"" msgstr "E750: Uzu unue \":profile start {dosiernomo}\"" @@ -1269,6 +1189,9 @@ msgstr "Serĉado de \"%s\"" msgid "not found in '%s': \"%s\"" msgstr "ne trovita en '%s: \"%s\"" +msgid "Source Vim script" +msgstr "Ruli Vim-skripton" + #, c-format msgid "Cannot source a directory: \"%s\"" msgstr "Ne eblas ruli dosierujon: \"%s\"" @@ -1278,16 +1201,16 @@ msgid "could not source \"%s\"" msgstr "ne eblis ruli \"%s\"" #, c-format -msgid "line %: could not source \"%s\"" -msgstr "linio %: ne eblis ruli \"%s\"" +msgid "line %ld: could not source \"%s\"" +msgstr "linio %ld: ne eblis ruli \"%s\"" #, c-format msgid "sourcing \"%s\"" msgstr "rulas \"%s\"" #, c-format -msgid "line %: sourcing \"%s\"" -msgstr "linio %: rulas \"%s\"" +msgid "line %ld: sourcing \"%s\"" +msgstr "linio %ld: rulas \"%s\"" #, c-format msgid "finished sourcing %s" @@ -1329,8 +1252,6 @@ msgstr "Aktuala %slingvo: \"%s\"" 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 msgid "Entering Ex mode. Type \"visual\" to go to Normal mode." msgstr "Eniras reĝimon Ex. Tajpu \"visual\" por iri al reĝimo Normala." @@ -1362,12 +1283,10 @@ msgstr "E493: Inversa amplekso donita" msgid "Backwards range given, OK to swap" msgstr "Inversa amplekso donita, permuteblas" -#. append -#. typed wrong msgid "E494: Use w or w>>" msgstr "E494: Uzu w aŭ w>>" -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" msgid "E172: Only one file name allowed" @@ -1384,8 +1303,8 @@ msgid "E173: 1 more file to edit" msgstr "E173: 1 plia redaktenda dosiero" #, c-format -msgid "E173: % more files to edit" -msgstr "E173: % pliaj redaktendaj dosieroj" +msgid "E173: %ld more files to edit" +msgstr "E173: %ld pliaj redaktendaj dosieroj" msgid "E174: Command already exists: add ! to replace it" msgstr "E174: La komando jam ekzistas: aldonu ! por anstataŭigi ĝin" @@ -1451,6 +1370,9 @@ msgstr "" msgid "E467: Custom completion requires a function argument" msgstr "E467: Uzula kompletigo bezonas funkcian argumenton" +msgid "unknown" +msgstr "nekonata" + #, c-format msgid "E185: Cannot find color scheme '%s'" msgstr "E185: Ne eblas trovi agordaron de koloroj '%s'" @@ -1464,6 +1386,9 @@ msgstr "E784: Ne eblas fermi lastan langeton" msgid "Already only one tab page" msgstr "Jam nur unu langeto" +msgid "Edit File in new window" +msgstr "Redakti Dosieron en nova fenestro" + #, c-format msgid "Tab page %d" msgstr "Langeto %d" @@ -1471,6 +1396,9 @@ msgstr "Langeto %d" msgid "No swap file" msgstr "Neniu permutodosiero .swp" +msgid "Append File" +msgstr "Postaldoni dosieron" + msgid "E747: Cannot change directory, buffer is modified (add ! to override)" msgstr "" "E747: Ne eblas ŝanĝi dosierujon, bufro estas ŝanĝita (aldonu ! por transpasi)" @@ -1484,6 +1412,10 @@ msgstr "E187: Nekonata" msgid "E465: :winsize requires two number arguments" msgstr "E465: \":winsize\" bezonas du numerajn argumentojn" +#, c-format +msgid "Window position: X %d, Y %d" +msgstr "Pozicio de fenestro: X %d, Y %d" + msgid "E188: Obtaining window position not implemented for this platform" msgstr "" "E188: Akiro de pozicio de fenestro ne estas realigita por tiu platformo" @@ -1491,6 +1423,22 @@ msgstr "" msgid "E466: :winpos requires two number arguments" msgstr "E466: \":winpos\" bezonas du numerajn argumentojn" +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" @@ -1510,6 +1458,9 @@ msgstr "E191: Argumento devas esti litero, citilo aŭ retrocitilo" msgid "E192: Recursive use of :normal too deep" msgstr "E192: Tro profunda rekursia alvoko de \":normal\"" +msgid "E809: #< is not available without the +eval feature" +msgstr "E809: #< ne haveblas sen la eblo +eval" + msgid "E194: No alternate file name to substitute for '#'" msgstr "E194: Neniu alterna dosiernomo por anstataŭigi al '#'" @@ -1532,9 +1483,9 @@ msgstr "E498: neniu dosiernomo \":source\" por anstataŭigi al \"\"" msgid "E842: no line number to use for \"\"" msgstr "E842: neniu uzebla numero de linio por \"\"" -#, fuzzy, 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\"" +#, no-c-format +msgid "E499: Empty file name for '%' or '#', only works with \":p:h\"" +msgstr "E499: Malplena dosiernomo por '%' aŭ '#', nur funkcias kun \":p:h\"" msgid "E500: Evaluates to an empty string" msgstr "E500: Liveras malplenan ĉenon" @@ -1542,6 +1493,9 @@ msgstr "E500: Liveras malplenan ĉenon" msgid "E195: Cannot open viminfo file for reading" msgstr "E195: Ne eblas malfermi dosieron viminfo en lega reĝimo" +msgid "E196: No digraphs in this version" +msgstr "E196: Neniu duliteraĵo en tiu versio" + msgid "E608: Cannot :throw exceptions with 'Vim' prefix" msgstr "E608: Ne eblas lanĉi (:throw) escepton kun prefikso 'Vim'" @@ -1559,8 +1513,8 @@ msgid "Exception discarded: %s" msgstr "Escepto ne konservita: %s" #, c-format -msgid "%s, line %" -msgstr "%s, linio %" +msgid "%s, line %ld" +msgstr "%s, linio %ld" #. always scroll up, don't overwrite #, c-format @@ -1693,33 +1647,6 @@ msgstr "E198: cmd_pchar preter la longo de komando" msgid "E199: Active window or buffer deleted" msgstr "E199: Aktiva fenestro aŭ bufro forviŝita" -msgid "E854: path too long for completion" -msgstr "E854: tro longa vojo por kompletigo" - -#, c-format -msgid "" -"E343: Invalid path: '**[number]' must be at the end of the path or be " -"followed by '%s'." -msgstr "" -"E343: Nevalida vojo: '**[nombro]' devas esti ĉe la fino de la vojo aŭ " -"sekvita de '%s'." - -#, c-format -msgid "E344: Can't find directory \"%s\" in cdpath" -msgstr "E344: Ne eblas trovi dosierujon \"%s\" en cdpath" - -#, c-format -msgid "E345: Can't find file \"%s\" in path" -msgstr "E345: Ne eblas trovi dosieron \"%s\" en serĉvojo" - -#, c-format -msgid "E346: No more directory \"%s\" found in cdpath" -msgstr "E346: Ne plu trovis dosierujon \"%s\" en cdpath" - -#, c-format -msgid "E347: No more file \"%s\" found in path" -msgstr "E347: Ne plu trovis dosieron \"%s\" en serĉvojo" - msgid "E812: Autocommands changed buffer or buffer name" msgstr "E812: Aŭtokomandoj ŝanĝis bufron aŭ nomon de bufro" @@ -1732,6 +1659,9 @@ msgstr "estas dosierujo" msgid "is not a file" msgstr "ne estas dosiero" +msgid "is a device (disabled with 'opendevice' option)" +msgstr "estas aparatdosiero (malŝaltita per la opcio 'opendevice')" + msgid "[New File]" msgstr "[Nova dosiero]" @@ -1750,26 +1680,25 @@ msgstr "E200: La aŭtokomandoj *ReadPre igis la dosieron nelegebla" msgid "E201: *ReadPre autocommands must not change current buffer" msgstr "E201: La aŭtokomandoj *ReadPre ne rajtas ŝanĝi la aktualan bufron" -msgid "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! msgid "E202: Conversion made file unreadable!" msgstr "E202: Konverto igis la dosieron nelegebla!" -#. fifo or socket msgid "[fifo/socket]" msgstr "[rektvica memoro/kontaktoskatolo]" -#. fifo msgid "[fifo]" msgstr "[rektvica memoro]" -#. or socket msgid "[socket]" msgstr "[kontaktoskatolo]" -#. or character special msgid "[character special]" msgstr "[speciala signo]" @@ -1786,12 +1715,12 @@ msgid "[converted]" msgstr "[konvertita]" #, c-format -msgid "[CONVERSION ERROR in line %]" -msgstr "[ERARO DE KONVERTO en linio %]" +msgid "[CONVERSION ERROR in line %ld]" +msgstr "[ERARO DE KONVERTO en linio %ld]" #, c-format -msgid "[ILLEGAL BYTE in line %]" -msgstr "[NEVALIDA BAJTO en linio %]" +msgid "[ILLEGAL BYTE in line %ld]" +msgstr "[NEVALIDA BAJTO en linio %ld]" msgid "[READ ERRORS]" msgstr "[ERAROJ DE LEGADO]" @@ -1800,7 +1729,7 @@ msgid "Can't find temp file for conversion" msgstr "Ne eblas trovi provizoran dosieron por konverti" msgid "Conversion with 'charconvert' failed" -msgstr "Konverto kun 'charconvert' fiaskis" +msgstr "Konverto kun 'charconvert' malsukcesis" msgid "can't read output of 'charconvert'" msgstr "ne eblas legi la eligon de 'charconvert'" @@ -1814,9 +1743,18 @@ msgstr "E203: Aŭtokomandoj forviŝis aŭ malŝargis la skribendan bufron" msgid "E204: Autocommand changed number of lines in unexpected way" msgstr "E204: Aŭtokomando ŝanĝis la nombron de linioj neatendite" +msgid "NetBeans disallows writes of unmodified buffers" +msgstr "NetBeans malpermesas skribojn de neŝanĝitaj bufroj" + +msgid "Partial writes disallowed for NetBeans buffers" +msgstr "Partaj skriboj malpermesitaj ĉe bufroj NetBeans" + msgid "is not a file or writable device" msgstr "ne estas dosiero aŭ skribebla aparatdosiero" +msgid "writing to device disabled with 'opendevice' option" +msgstr "skribo al aparatdosiero malŝaltita per la opcio 'opendevice'" + msgid "is read-only (add ! to override)" msgstr "estas nurlegebla (aldonu ! por transpasi)" @@ -1835,7 +1773,9 @@ msgstr "E509: Ne eblas krei restaŭrkopion (aldonu ! por transpasi)" msgid "E510: Can't make backup file (add ! to override)" msgstr "E510: Ne eblas krei restaŭrkopion (aldonu ! por transpasi)" -#. Can't write without a tempfile! +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" @@ -1850,20 +1790,21 @@ msgstr "E212: Ne eblas malfermi la dosieron por skribi" # AM: fsync: ne traduku (nomo de C-komando) msgid "E667: Fsync failed" -msgstr "E667: Fsync fiaskis" +msgstr "E667: Fsync malsukcesis" msgid "E512: Close failed" -msgstr "E512: Fermo fiaskis" +msgstr "E512: Fermo malsukcesis" 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)" #, c-format msgid "" -"E513: write error, conversion failed in line % (make 'fenc' empty to " +"E513: write error, conversion failed in line %ld (make 'fenc' empty to " "override)" msgstr "" -"E513: skriberaro, konverto fiaskis en linio % (igu 'fenc' malplena " +"E513: skriberaro, konverto malsukcesis en linio %ld (igu 'fenc' malplena " "por transpasi)" msgid "E514: write error (file system full?)" @@ -1873,8 +1814,8 @@ msgid " CONVERSION ERROR" msgstr " ERARO DE KONVERTO" #, c-format -msgid " in line %;" -msgstr " en linio %;" +msgid " in line %ld;" +msgstr " en linio %ld;" msgid "[Device]" msgstr "[Aparatdosiero]" @@ -1935,15 +1876,15 @@ msgid "1 line, " msgstr "1 linio, " #, c-format -msgid "% lines, " -msgstr "% linioj, " +msgid "%ld lines, " +msgstr "%ld linioj, " msgid "1 character" msgstr "1 signo" #, c-format -msgid "% characters" -msgstr "% signoj" +msgid "%lld characters" +msgstr "%lld signoj" msgid "[noeol]" msgstr "[sen EOL]" @@ -2025,6 +1966,9 @@ msgstr "E462: Ne eblis prepari por reŝargi \"%s\"" msgid "E321: Could not reload \"%s\"" msgstr "E321: Ne eblis reŝargi \"%s\"" +msgid "--Deleted--" +msgstr "--Forviŝita--" + #, c-format msgid "auto-removing autocommand: %s " msgstr "aŭto-forviŝas aŭtokomandon: %s " @@ -2034,12 +1978,12 @@ msgstr "aŭto-forviŝas aŭtokomandon: %s " msgid "E367: No such group: \"%s\"" msgstr "E367: Ne ekzistas tia grupo: \"%s\"" +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" -msgid "--Deleted--" -msgstr "--Forviŝita--" - #, c-format msgid "E215: Illegal character after *: %s" msgstr "E215: Nevalida signo post *: %s" @@ -2106,7 +2050,6 @@ msgid_plural "+--%3ld lines folded " msgstr[0] "+--%3ld linio faldita " msgstr[1] "+--%3ld linioj falditaj " -#. buffer has already been read msgid "E222: Add to read buffer" msgstr "E222: Aldoni al lega bufro" @@ -2138,329 +2081,294 @@ msgstr "Neniu mapo trovita" 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 -msgid "--No lines in buffer--" -msgstr "--Neniu linio en bufro--" +msgid "E851: Failed to create a new process for the GUI" +msgstr "E851: Malsukcesis krei novan procezon por la grafika interfaco" -#. -#. * 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 "E852: The child process failed to start the GUI" +msgstr "E852: La ida procezo malsukcesis startigi la grafikan interfacon" -msgid "E471: Argument required" -msgstr "E471: Argumento bezonata" +msgid "E229: Cannot start the GUI" +msgstr "E229: Ne eblas lanĉi la grafikan interfacon" -msgid "E10: \\ should be followed by /, ? or &" -msgstr "E10: \\ devus esti sekvita de /, ? aŭ &" +#, c-format +msgid "E230: Cannot read from \"%s\"" +msgstr "E230: Ne eblas legi el \"%s\"" -msgid "E11: Invalid in command-line window; executes, CTRL-C quits" +msgid "E665: Cannot start GUI, no valid font found" msgstr "" -"E11: Nevalida en fenestro de komanda linio; plenumas, CTRL-C eliras" +"E665: Ne eblas startigi grafikan interfacon, neniu valida tiparo trovita" -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 "E231: 'guifontwide' invalid" +msgstr "E231: 'guifontwide' nevalida" -msgid "E171: Missing :endif" -msgstr "E171: Mankas \":endif\"" +msgid "E599: Value of 'imactivatekey' is invalid" +msgstr "E599: Valoro de 'imactivatekey' estas nevalida" -msgid "E600: Missing :endtry" -msgstr "E600: Mankas \":endtry\"" +#, c-format +msgid "E254: Cannot allocate color %s" +msgstr "E254: Ne eblas disponigi koloron %s" -msgid "E170: Missing :endwhile" -msgstr "E170: Mankas \":endwhile\"" +msgid "No match at cursor, finding next" +msgstr "Neniu kongruo ĉe kursorpozicio, trovas sekvan" -msgid "E170: Missing :endfor" -msgstr "E170: Mankas \":endfor\"" +msgid " " +msgstr " " -msgid "E588: :endwhile without :while" -msgstr "E588: \":endwhile\" sen \":while\"" +#, c-format +msgid "E616: vim_SelFile: can't get font %s" +msgstr "E616: vim_SelFile: ne eblas akiri tiparon %s" -msgid "E588: :endfor without :for" -msgstr "E588: \":endfor\" sen \":for\"" +msgid "E614: vim_SelFile: can't return to current directory" +msgstr "E614: vim_SelFile: ne eblas reveni al la aktuala dosierujo" -msgid "E13: File exists (add ! to override)" -msgstr "E13: Dosiero ekzistas (aldonu ! por transpasi)" +msgid "Pathname:" +msgstr "Serĉvojo:" -msgid "E472: Command failed" -msgstr "E472: La komando fiaskis" +msgid "E615: vim_SelFile: can't get current directory" +msgstr "E615: vim_SelFile: ne eblas akiri aktualan dosierujon" -msgid "E473: Internal error" -msgstr "E473: Interna eraro" +msgid "OK" +msgstr "Bone" -msgid "Interrupted" -msgstr "Interrompita" +msgid "Cancel" +msgstr "Rezigni" -msgid "E14: Invalid address" -msgstr "E14: Nevalida adreso" +msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." +msgstr "" +"Fenestraĵo de rulumskalo: Ne eblis akiri geometrion de reduktita rastrumbildo" -msgid "E474: Invalid argument" -msgstr "E474: Nevalida argumento" +msgid "Vim dialog" +msgstr "Vim dialogo" -#, c-format -msgid "E475: Invalid argument: %s" -msgstr "E475: Nevalida argumento: %s" +msgid "E232: Cannot create BalloonEval with both message and callback" +msgstr "E232: Ne eblas krei BalloonEval kun ambaŭ mesaĝo kaj reagfunkcio" -#, c-format -msgid "E15: Invalid expression: %s" -msgstr "E15: Nevalida esprimo: %s" +msgid "_Cancel" +msgstr "_Rezigni" -msgid "E16: Invalid range" -msgstr "E16: Nevalida amplekso" +msgid "_Save" +msgstr "_Konservi" -msgid "E476: Invalid command" -msgstr "E476: Nevalida komando" +msgid "_Open" +msgstr "_Malfermi" -#, c-format -msgid "E17: \"%s\" is a directory" -msgstr "E17: \"%s\" estas dosierujo" +msgid "_OK" +msgstr "_Bone" -#, fuzzy -#~ msgid "E900: Invalid job id" -#~ msgstr "E49: Nevalida grando de rulumo" +msgid "" +"&Yes\n" +"&No\n" +"&Cancel" +msgstr "" +"&Jes\n" +"&Ne\n" +"&Rezigni" -#~ msgid "E901: Job table is full" -#~ msgstr "" +msgid "Yes" +msgstr "Jes" -#, c-format -msgid "E364: Library call failed for \"%s()\"" -msgstr "E364: Alvoko al biblioteko fiaskis por \"%s()\"" +msgid "No" +msgstr "Ne" -msgid "E19: Mark has invalid line number" -msgstr "E19: Marko havas nevalidan numeron de linio" +# todo '_' is for hotkey, i guess? +msgid "Input _Methods" +msgstr "Enigaj _metodoj" -msgid "E20: Mark not set" -msgstr "E20: Marko ne estas agordita" +msgid "VIM - Search and Replace..." +msgstr "VIM - Serĉi kaj anstataŭigi..." -msgid "E21: Cannot make changes, 'modifiable' is off" -msgstr "E21: Ne eblas fari ŝanĝojn, 'modifiable' estas malŝaltita" +msgid "VIM - Search..." +msgstr "VIM- Serĉi..." -msgid "E22: Scripts nested too deep" -msgstr "E22: Tro profunde ingitaj skriptoj" +msgid "Find what:" +msgstr "Serĉi kion:" -msgid "E23: No alternate file" -msgstr "E23: Neniu alterna dosiero" +msgid "Replace with:" +msgstr "Anstataŭigi per:" -msgid "E24: No such abbreviation" -msgstr "E24: Ne estas tia mallongigo" +#. whole word only button +msgid "Match whole word only" +msgstr "Kongrui kun nur plena vorto" -msgid "E477: No ! allowed" -msgstr "E477: Neniu ! permesebla" +#. match case button +msgid "Match case" +msgstr "Uskleca kongruo" -msgid "E25: Nvim does not have a built-in GUI" -msgstr "E25: Grafika interfaco ne uzeblas: Malŝaltita dum kompilado" +msgid "Direction" +msgstr "Direkto" -#, c-format -msgid "E28: No such highlight group name: %s" -msgstr "E28: Neniu grupo de emfazo kiel: %s" +#. 'Up' and 'Down' buttons +msgid "Up" +msgstr "Supren" -msgid "E29: No inserted text yet" -msgstr "E29: Ankoraŭ neniu enmetita teksto" +msgid "Down" +msgstr "Suben" -msgid "E30: No previous command line" -msgstr "E30: Neniu antaŭa komanda linio" +msgid "Find Next" +msgstr "Trovi sekvantan" -msgid "E31: No such mapping" -msgstr "E31: Neniu tiel mapo" +msgid "Replace" +msgstr "Anstataŭigi" -msgid "E479: No match" -msgstr "E479: Neniu kongruo" +msgid "Replace All" +msgstr "Anstataŭigi ĉiujn" -#, c-format -msgid "E480: No match: %s" -msgstr "E480: Neniu kongruo: %s" +msgid "_Close" +msgstr "_Fermi" -msgid "E32: No file name" -msgstr "E32: Neniu dosiernomo" +msgid "Vim: Received \"die\" request from session manager\n" +msgstr "Vim: Ricevis peton \"die\" (morti) el la seanca administrilo\n" -msgid "E33: No previous substitute regular expression" -msgstr "E33: Neniu antaŭa regulesprimo de anstataŭigo" +msgid "Close tab" +msgstr "Fermi langeton" -msgid "E34: No previous command" -msgstr "E34: Neniu antaŭa komando" +msgid "New tab" +msgstr "Nova langeto" -msgid "E35: No previous regular expression" -msgstr "E35: Neniu antaŭa regulesprimo" - -msgid "E481: No range allowed" -msgstr "E481: Amplekso nepermesebla" - -msgid "E36: Not enough room" -msgstr "E36: Ne sufiĉe da spaco" - -#, c-format -msgid "E482: Can't create file %s" -msgstr "E482: Ne eblas krei dosieron %s" +msgid "Open Tab..." +msgstr "Malfermi langeton..." -msgid "E483: Can't get temp file name" -msgstr "E483: Ne eblas akiri provizoran dosiernomon" +msgid "Vim: Main window unexpectedly destroyed\n" +msgstr "Vim: Ĉefa fenestro neatendite detruiĝis\n" -#, c-format -msgid "E484: Can't open file %s" -msgstr "E484: Ne eblas malfermi dosieron %s" +msgid "&Filter" +msgstr "&Filtri" -#, c-format -msgid "E485: Can't read file %s" -msgstr "E485: Ne eblas legi dosieron %s" +msgid "&Cancel" +msgstr "&Rezigni" -msgid "E37: No write since last change (add ! to override)" -msgstr "E37: Neniu skribo de post lasta ŝanĝo (aldonu ! por transpasi)" +msgid "Directories" +msgstr "Dosierujoj" -#, fuzzy -#~ msgid "E37: No write since last change" -#~ msgstr "[Neniu skribo de post lasta ŝanĝo]\n" +msgid "Filter" +msgstr "Filtri" -msgid "E38: Null argument" -msgstr "E38: Nula argumento" +msgid "&Help" +msgstr "&Helpo" -msgid "E39: Number expected" -msgstr "E39: Nombro atendita" +msgid "Files" +msgstr "Dosieroj" -#, c-format -msgid "E40: Can't open errorfile %s" -msgstr "E40: Ne eblas malfermi eraran dosieron %s" +msgid "&OK" +msgstr "&Bone" -msgid "E41: Out of memory!" -msgstr "E41: Ne plu restas memoro!" +msgid "Selection" +msgstr "Apartigo" -msgid "Pattern not found" -msgstr "Ŝablono ne trovita" +msgid "Find &Next" +msgstr "Trovi &Sekvanta" -#, c-format -msgid "E486: Pattern not found: %s" -msgstr "E486: Ŝablono ne trovita: %s" +msgid "&Replace" +msgstr "&Anstataŭigi" -msgid "E487: Argument must be positive" -msgstr "E487: La argumento devas esti pozitiva" +msgid "Replace &All" +msgstr "Anstataŭigi ĉi&on" -msgid "E459: Cannot go back to previous directory" -msgstr "E459: Ne eblas reiri al antaŭa dosierujo" +msgid "&Undo" +msgstr "&Malfari" -msgid "E42: No Errors" -msgstr "E42: Neniu eraro" +msgid "Open tab..." +msgstr "Malfermi langeton..." -msgid "E776: No location list" -msgstr "E776: Neniu listo de loko" +msgid "Find string (use '\\\\' to find a '\\')" +msgstr "Trovi ĉenon (uzu '\\\\' por trovi '\\')" -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 '\\')" -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" -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" #, 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\"" #, c-format -msgid "E794: Cannot set variable in the sandbox: \"%s\"" -msgstr "E794: Ne eblas agordi variablon en la sabloludejo: \"%s\"" - -msgid "E713: Cannot use empty key for Dictionary" -msgstr "E713: Ne eblas uzi malplenan ŝlosilon de Vortaro" - -msgid "E47: Error while reading errorfile" -msgstr "E47: Eraro dum legado de erardosiero" - -msgid "E48: Not allowed in sandbox" -msgstr "E48: Nepermesebla en sabloludejo" - -msgid "E523: Not allowed here" -msgstr "E523: Nepermesebla tie" - -msgid "E359: Screen mode setting not supported" -msgstr "E359: Reĝimo de ekrano ne subtenata" - -msgid "E49: Invalid scroll size" -msgstr "E49: Nevalida grando de rulumo" - -msgid "E91: 'shell' option is empty" -msgstr "E91: La opcio 'shell' estas malplena" - -msgid "E255: Couldn't read in sign data!" -msgstr "E255: Ne eblis legi datumojn de simboloj!" - -msgid "E72: Close error on swap file" -msgstr "E72: Eraro dum malfermo de permutodosiero .swp" +msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." +msgstr "E243: Ne subtenata argumento: \"-%s\"; Uzu la version OLE." -msgid "E73: tag stack empty" -msgstr "E73: malplena stako de etikedo" - -msgid "E74: Command too complex" -msgstr "E74: Komando tro kompleksa" +msgid "E672: Unable to open window inside MDI application" +msgstr "E672: Ne eblas malfermi fenestron interne de aplikaĵo MDI" -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" -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:" -msgid "E77: Too many file names" -msgstr "E77: Tro da dosiernomoj" +#, c-format +msgid "E252: Fontset name: %s" +msgstr "E252: Nomo de tiparo: %s" -msgid "E488: Trailing characters" -msgstr "E488: Vostaj signoj" +#, c-format +msgid "Font '%s' is not fixed-width" +msgstr "Tiparo '%s' ne estas egallarĝa" -msgid "E78: Unknown mark" -msgstr "E78: Nekonata marko" +#, c-format +msgid "E253: Fontset name: %s" +msgstr "E253: Nomo de tiparo: %s" -msgid "E79: Cannot expand wildcards" -msgstr "E79: Ne eblas malvolvi ĵokerojn" +#, c-format +msgid "Font0: %s" +msgstr "Font0: %s" -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" -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" -msgid "E80: Error while writing" -msgstr "E80: Eraro dum skribado" +#, c-format +msgid "Font0 width: %ld" +msgstr "Larĝo de font0: %ld" -msgid "Zero count" -msgstr "Nul kvantoro" +#, c-format +msgid "Font1 width: %ld" +msgstr "Larĝo de Font1: %ld" -msgid "E81: Using not in a script context" -msgstr "E81: Uzo de ekster kunteksto de skripto" +msgid "Invalid font specification" +msgstr "Nevalida tiparo specifita" -#, c-format -msgid "E685: Internal error: %s" -msgstr "E685: Interna eraro: %s" +msgid "&Dismiss" +msgstr "&Forlasi" -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" -msgid "E749: empty buffer" -msgstr "E749: malplena bufro" +msgid "Vim - Font Selector" +msgstr "Vim - Elektilo de tiparo" -#, c-format -msgid "E86: Buffer % does not exist" -msgstr "E86: La bufro % ne ekzistas" +msgid "Name:" +msgstr "Nomo:" -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" -msgid "E139: File is loaded in another buffer" -msgstr "E139: Dosiero estas ŝargita en alia bufro" +msgid "Encoding:" +msgstr "Kodoprezento:" -#, c-format -msgid "E764: Option '%s' is not set" -msgstr "E764: La opcio '%s' ne estas ŝaltita" +msgid "Font:" +msgstr "Tiparo:" -msgid "E850: Invalid register name" -msgstr "E850: Nevalida nomo de reĝistro" +msgid "Style:" +msgstr "Stilo:" -msgid "search hit TOP, continuing at BOTTOM" -msgstr "serĉo atingis SUPRON, daŭrigonte al SUBO" +msgid "Size:" +msgstr "Grando:" -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" msgid "E550: Missing colon" msgstr "E550: Mankas dupunkto" @@ -2551,7 +2459,7 @@ msgid "Sending to printer..." msgstr "Sendas al presilo..." msgid "E365: Failed to print PostScript file" -msgstr "E365: Presado de PostSkripta dosiero fiaskis" +msgstr "E365: Presado de PostSkripta dosiero malsukcesis" msgid "Print job sent." msgstr "Laboro de presado sendita." @@ -2591,6 +2499,9 @@ msgstr "E257: cstag: etikedo netrovita" msgid "E563: stat(%s) error: %d" msgstr "E563: Eraro de stat(%s): %d" +msgid "E563: stat error" +msgstr "E563: Eraro de stat" + #, c-format msgid "E564: %s is not a directory or a valid cscope database" msgstr "E564: %s ne estas dosierujo aŭ valida datumbazo de cscope" @@ -2600,8 +2511,8 @@ msgid "Added cscope database %s" msgstr "Aldonis datumbazon de cscope %s" #, c-format -msgid "E262: error reading cscope connection %" -msgstr "E262: eraro dum legado de konekto de cscope %" +msgid "E262: error reading cscope connection %ld" +msgstr "E262: eraro dum legado de konekto de cscope %ld" msgid "E561: unknown cscope search type" msgstr "E561: nekonata tipo de serĉo de cscope" @@ -2612,18 +2523,17 @@ msgstr "E566: Ne eblis krei duktojn de cscope" msgid "E622: Could not fork for cscope" msgstr "E622: Ne eblis forki cscope" -#, fuzzy -#~ msgid "cs_create_connection setpgid failed" -#~ msgstr "plenumo de cs_create_connection fiaskis" +msgid "cs_create_connection setpgid failed" +msgstr "plenumo de cs_create_connection-setgpid malsukcesis" msgid "cs_create_connection exec failed" -msgstr "plenumo de cs_create_connection fiaskis" +msgstr "plenumo de cs_create_connection malsukcesis" 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" 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" msgid "E623: Could not spawn cscope process" msgstr "E623: Ne eblis naskigi procezon cscope" @@ -2669,6 +2579,13 @@ msgstr "" " s: Trovi tiun C-simbolon\n" " t: Trovi tiun ĉenon\n" +#, c-format +msgid "E625: cannot open cscope database: %s" +msgstr "E625: ne eblas malfermi datumbazon de cscope: %s" + +msgid "E626: cannot get cscope database information" +msgstr "E626: ne eblas akiri informojn pri la datumbazo de cscope" + msgid "E568: duplicate cscope database not added" msgstr "E568: ripetita datumbazo de cscope ne aldonita" @@ -2711,6 +2628,222 @@ msgstr "neniu konekto de cscope\n" msgid " # pid database name prepend path\n" msgstr " # pid nomo de datumbazo prefiksa vojo\n" +msgid "Lua library cannot be loaded." +msgstr "La biblioteko Lua no ŝargeblis." + +msgid "cannot save undo information" +msgstr "ne eblas konservi informojn de malfaro" + +msgid "" +"E815: Sorry, this command is disabled, the MzScheme libraries could not be " +"loaded." +msgstr "" +"E815: Bedaŭrinde, tiu komando estas malŝaltita, ne eblis ŝargi la " +"bibliotekojn." + +msgid "" +"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" @@ -2741,6 +2874,15 @@ msgstr "Nevalida argumento por" msgid "%d files to edit\n" msgstr "%d redaktendaj dosieroj\n" +msgid "netbeans is not supported with this GUI\n" +msgstr "netbeans ne estas subtenata kun tiu grafika interfaco\n" + +msgid "'-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: \"" @@ -2750,6 +2892,12 @@ msgstr "Ne eblas malfermi en lega reĝimo: \"" msgid "Cannot open for script output: \"" msgstr "Ne eblas malfermi por eligo de skripto: \"" +msgid "Vim: Error: Failure to start gvim from NetBeans\n" +msgstr "Vim: Eraro: 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" @@ -2803,6 +2951,13 @@ msgstr "" "\n" " aŭ:" +msgid "" +"\n" +"Where case is ignored prepend / to make flag upper case" +msgstr "" +"\n" +"Kie uskleco estas ignorita antaŭaldonu / por igi flagon majuskla" + msgid "" "\n" "\n" @@ -2818,6 +2973,18 @@ msgstr "--\t\t\tNur dosiernomoj post tio" msgid "--literal\t\tDon't expand wildcards" msgstr "--literal\t\tNe malvolvi ĵokerojn" +msgid "-register\t\tRegister this gvim for OLE" +msgstr "-register\t\tRegistri tiun gvim al OLE" + +msgid "-unregister\t\tUnregister gvim for OLE" +msgstr "-unregister\t\tMalregistri gvim de OLE" + +msgid "-g\t\t\tRun using GUI (like \"gvim\")" +msgstr "-g\t\t\tRuli per grafika interfaco (kiel \"gvim\")" + +msgid "-f or --nofork\tForeground: Don't fork when starting GUI" +msgstr "-f aŭ --nofork\tMalfono: ne forki kiam lanĉas grafikan interfacon" + msgid "-v\t\t\tVi mode (like \"vi\")" msgstr "-v\t\t\tReĝimo Vi (kiel \"vi\")" @@ -2879,6 +3046,12 @@ msgstr "-r (kun dosiernomo)\tRestaŭri kolapsintan seancon" msgid "-L\t\t\tSame as -r" msgstr "-L\t\t\tKiel -r" +msgid "-f\t\t\tDon't use newcli to open window" +msgstr "-f\t\t\tNe uzi newcli por malfermi fenestrojn" + +msgid "-dev \t\tUse for I/O" +msgstr "-dev \t\tUzi -n por eneligo" + msgid "-A\t\t\tstart in Arabic mode" msgstr "-A\t\t\tKomenci en araba reĝimo" @@ -2891,9 +3064,20 @@ msgstr "-F\t\t\tKomenci en persa reĝimo" msgid "-T \tSet terminal type to " msgstr "-T \tAgordi terminalon al " +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 \t\tUse instead of any .vimrc" msgstr "-u \t\tUzi anstataŭ iun ajn .vimrc" +msgid "-U \t\tUse instead of any .gvimrc" +msgstr "-U \t\tUzi anstataŭ iun ajn .gvimrc" + msgid "--noplugin\t\tDon't load plugin scripts" msgstr "--noplugin\t\tNe ŝargi kromaĵajn skriptojn" @@ -2935,19 +3119,175 @@ msgid "-W \tWrite all typed commands to file " msgstr "" "-W \tSkribi ĉiujn tajpitajn komandojn al dosiero " -msgid "--startuptime \tWrite startup timing messages to " -msgstr "" -"--startuptime Skribi mesaĝojn de komenca tempomezurado al " -"" +msgid "-x\t\t\tEdit encrypted files" +msgstr "-x\t\t\tRedakti ĉifradan dosieron" -msgid "-i \t\tUse instead of .viminfo" -msgstr "-i \t\tUzi anstataŭ .viminfo" +msgid "-display \tConnect vim to this particular X-server" +msgstr "-display \tKonekti Vim al tiu X-servilo" -msgid "-h or --help\tPrint Help (this message) and exit" -msgstr "-h aŭ --help\tAfiŝi Helpon (tiun mesaĝon) kaj eliri" +msgid "-X\t\t\tDo not connect to X server" +msgstr "-X\t\t\tNe konekti al X-servilo" -msgid "--version\t\tPrint version information and exit" -msgstr "--version\t\tAfiŝi informon de versio kaj eliri" +msgid "--remote \tEdit in a Vim server if possible" +msgstr "--remote \tRedakti -n en Vim-servilo se eblas" + +msgid "--remote-silent Same, don't complain if there is no server" +msgstr "--remote-silent Same, sed ne plendi se ne estas servilo" + +msgid "" +"--remote-wait As --remote but wait for files to have been edited" +msgstr "" +"--remote-wait Kiel --remote sed atendi ĝis dosieroj estas " +"redaktitaj" + +msgid "" +"--remote-wait-silent Same, don't complain if there is no server" +msgstr "" +"--remote-wait-silent Same, sed ne plendi se ne estas servilo" + +msgid "" +"--remote-tab[-wait][-silent] As --remote but use tab page per file" +msgstr "" +"--remote-tab[-wait][-silent] Kiel --remote sed uzi langeton por " +"ĉiu dosiero" + +msgid "--remote-send \tSend to a Vim server and exit" +msgstr "--remote-send Sendi -n al Vim-servilo kaj eliri" + +msgid "--remote-expr \tEvaluate in a Vim server and print result" +msgstr "--remote-expr \tKomputi 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 \tSend to/become the Vim server " +msgstr "--servername \tSendu al/iĝi la Vim-servilo " + +msgid "--startuptime \tWrite startup timing messages to " +msgstr "" +"--startuptime Skribi mesaĝojn de komenca tempomezurado al " +"" + +msgid "-i \t\tUse instead of .viminfo" +msgstr "-i \t\tUzi anstataŭ .viminfo" + +msgid "-h or --help\tPrint Help (this message) and exit" +msgstr "-h aŭ --help\tAfiŝi Helpon (tiun mesaĝon) kaj eliri" + +msgid "--version\t\tPrint version information and exit" +msgstr "--version\t\tAfiŝi informon de versio kaj eliri" + +msgid "" +"\n" +"Arguments recognised by gvim (Motif version):\n" +msgstr "" +"\n" +"Argumentoj agnoskitaj de gvim (versio Motif):\n" + +msgid "" +"\n" +"Arguments recognised by gvim (neXtaw version):\n" +msgstr "" +"\n" +"Argumentoj agnoskitaj de gvim (versio neXtaw):\n" + +msgid "" +"\n" +"Arguments recognised by gvim (Athena version):\n" +msgstr "" +"\n" +"Argumentoj agnoskitaj de gvim (versio Athena):\n" + +msgid "-display \tRun vim on " +msgstr "-display \tLanĉi vim sur " + +msgid "-iconic\t\tStart vim iconified" +msgstr "-iconic\t\tLanĉi vim piktograme" + +msgid "-background \tUse for the background (also: -bg)" +msgstr "-background \tUzi -n por la fona koloro (ankaŭ: -bg)" + +msgid "-foreground \tUse for normal text (also: -fg)" +msgstr "" +"-foreground \tUzi -n por la malfona koloro (ankaŭ: -fg)" + +msgid "-font \t\tUse for normal text (also: -fn)" +msgstr "-font \tUzi -n por normala teksto (ankaŭ: -fn)" + +msgid "-boldfont \tUse for bold text" +msgstr "-boldfont \tUzi -n por grasa teksto" + +msgid "-italicfont \tUse for italic text" +msgstr "-italicfont \tUzi -n por kursiva teksto" + +msgid "-geometry \tUse for initial geometry (also: -geom)" +msgstr "-geometry \tUzi kiel komenca geometrio (ankaŭ: -geom)" + +msgid "-borderwidth \tUse a border width of (also: -bw)" +msgstr "-borderwidth \tUzi -n kiel larĝo de bordero (ankaŭ: -bw)" + +msgid "-scrollbarwidth Use a scrollbar width of (also: -sw)" +msgstr "" +"-scrollbarwidth Uzi -n kiel larĝo de rulumskalo (ankaŭ: -sw)" + +msgid "-menuheight \tUse a menu bar height of (also: -mh)" +msgstr "" +"-menuheight \tUzi -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 \tSet the specified resource" +msgstr "-xrm \tAgordi la specifitan -n" + +msgid "" +"\n" +"Arguments recognised by gvim (GTK+ version):\n" +msgstr "" +"\n" +"Argumentoj agnoskitaj de gvim (versio GTK+):\n" + +msgid "-display \tRun vim on (also: --display)" +msgstr "-display \tLanĉi Vim sur tiu (ankaŭ: --display)" + +msgid "--role \tSet a unique role to identify the main window" +msgstr "--role \tDoni unikan rolon por identigi la ĉefan fenestron" + +msgid "--socketid \tOpen Vim inside another GTK widget" +msgstr "--socketid \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 \tOpen Vim inside parent application" +msgstr "-P \tMalfermi Vim en gepatra aplikaĵo" + +msgid "--windowid \tOpen Vim inside another win32 widget" +msgstr "--windowid \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" @@ -3005,6 +3345,28 @@ msgstr "" msgid "Missing '>'" msgstr "Mankas '>'" +msgid "E543: Not a valid codepage" +msgstr "E543: Nevalida kodpaĝo" + +msgid "E284: Cannot set IC values" +msgstr "E284: Ne eblas agordi valorojn de IC" + +msgid "E285: Failed to create input context" +msgstr "E285: 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" @@ -3032,6 +3394,9 @@ msgstr "E298: Ĉu ne akiris blokon n-ro 1?" msgid "E298: Didn't get block nr 2?" msgstr "E298: Ĉu ne akiris blokon n-ro 2?" +msgid "E843: Error while updating swap file crypt" +msgstr "E843: Eraro dum ĝisdatigo de ĉifrada permutodosiero .swp" + #. could not (re)open the swap file, what can we do???? msgid "E301: Oops, lost the swap file!!!" msgstr "E301: Ve, perdis la permutodosieron .swp!!!" @@ -3047,7 +3412,6 @@ msgstr "" msgid "E304: ml_upd_block0(): Didn't get block 0??" msgstr "E304: ml_upd_block0(): Ne akiris blokon 0??" -#. no swap files found #, c-format msgid "E305: No swap file found for %s" msgstr "E305: Neniu permutodosiero .swp trovita por %s" @@ -3092,6 +3456,11 @@ msgstr "" ",\n" "aŭ la dosiero estas difekta." +#, c-format +msgid "" +"E833: %s is encrypted and this version of Vim does not support encryption" +msgstr "E833: %s estas ĉifrata kaj tiu versio de Vim ne subtenas ĉifradon" + msgid " has been damaged (page size is smaller than minimum value).\n" msgstr " difektiĝis (paĝa grando pli malgranda ol minimuma valoro).\n" @@ -3106,6 +3475,39 @@ msgstr "Originala dosiero \"%s\"" msgid "E308: Warning: Original file may have been changed" msgstr "E308: Averto: Originala dosiero eble ŝanĝiĝis" +#, c-format +msgid "Swap file is encrypted: \"%s\"" +msgstr "Perumutodosiero .swp estas ĉifrata: \"%s\"" + +msgid "" +"\n" +"If you entered a new crypt key but did not write the text file," +msgstr "" +"\n" +"Se vi tajpis novan ŝlosilon de ĉifrado sed ne skribis la tekstan dosieron," + +msgid "" +"\n" +"enter the new crypt key." +msgstr "" +"\n" +"tajpu la novan ŝlosilon de ĉifrado." + +msgid "" +"\n" +"If you wrote the text file after changing the crypt key press enter" +msgstr "" +"\n" +"Se vi skribis la tekstan dosieron post ŝanĝo de la ŝlosilo de ĉifrado, premu " +"enenklavon" + +msgid "" +"\n" +"to use the same key for text file and swap file" +msgstr "" +"\n" +"por uzi la saman ŝlosilon por la teksta dosiero kaj permuto dosiero .swp" + #, c-format msgid "E309: Unable to read block 1 from %s" msgstr "E309: Ne eblas legi blokon 1 de %s" @@ -3175,6 +3577,10 @@ 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 msgid "Swap files found:" msgstr "Permutodosiero .swp trovita:" @@ -3249,6 +3655,13 @@ msgstr "" msgid " (still running)" msgstr " (ankoraŭ ruliĝas)" +msgid "" +"\n" +" [not usable with this version of Vim]" +msgstr "" +"\n" +" [ne uzebla per tiu versio de Vim]" + msgid "" "\n" " [not usable on this computer]" @@ -3269,15 +3682,15 @@ msgid "File preserved" msgstr "Dosiero konservita" msgid "E314: Preserve failed" -msgstr "E314: Konservo fiaskis" +msgstr "E314: Konservo malsukcesis" #, c-format -msgid "E315: ml_get: invalid lnum: %" -msgstr "E315: ml_get: nevalida lnum: %" +msgid "E315: ml_get: invalid lnum: %ld" +msgstr "E315: ml_get: nevalida lnum: %ld" #, c-format -msgid "E316: ml_get: cannot find line %" -msgstr "E316: ml_get: ne eblas trovi linion %" +msgid "E316: ml_get: cannot find line %ld" +msgstr "E316: ml_get: ne eblas trovi linion %ld" msgid "E317: pointer block id wrong 3" msgstr "E317: nevalida referenco de bloko id 3" @@ -3295,8 +3708,8 @@ msgid "deleted block 1?" msgstr "ĉu forviŝita bloko 1?" #, c-format -msgid "E320: Cannot find line %" -msgstr "E320: Ne eblas trovi linion %" +msgid "E320: Cannot find line %ld" +msgstr "E320: Ne eblas trovi linion %ld" msgid "E317: pointer block id wrong" msgstr "E317: nevalida referenco de bloko id" @@ -3305,12 +3718,12 @@ msgid "pe_line_count is zero" msgstr "pe_line_count estas nul" #, c-format -msgid "E322: line number out of range: % past the end" -msgstr "E322: numero de linio ekster limoj: % 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" #, c-format -msgid "E323: line count wrong in block %" -msgstr "E323: nevalida nombro de linioj en bloko %" +msgid "E323: line count wrong in block %ld" +msgstr "E323: nevalida nombro de linioj en bloko %ld" msgid "Stack size increases" msgstr "Stako pligrandiĝas" @@ -3338,6 +3751,8 @@ msgstr "Dum malfermo de dosiero \"" msgid " NEWER than swap file!\n" msgstr " PLI NOVA ol permutodosiero .swp!\n" +#. Some of these messages are long to allow translation to +#. * other languages. msgid "" "\n" "(1) Another program may be editing the same file. If this is the case,\n" @@ -3349,9 +3764,6 @@ msgstr "" " por ne havi du malsamajn aperojn de la sama dosiero, kiam vi faros\n" " ŝanĝojn. Eliru aŭ daŭrigu singarde.\n" -msgid " Quit, or continue with caution.\n" -msgstr " Eliru, aŭ daŭrigu singarde.\n" - msgid "(2) An edit session for this file crashed.\n" msgstr "(2) Redakta seanco de tiu dosiero kolapsis.\n" @@ -3417,21 +3829,9 @@ 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 msgid "E326: Too many swap files found" msgstr "E326: Tro da dosieroj trovitaj" -#, c-format -msgid "E342: Out of memory! (allocating % bytes)" -msgstr "E342: Ne plu restas memoro! (disponigo de % bajtoj)" - msgid "E327: Part of menu-item path is not sub-menu" msgstr "E327: Parto de vojo de menuero ne estas sub-menuo" @@ -3464,6 +3864,9 @@ msgstr "" "\n" "--- Menuoj ---" +msgid "Tear off this menu" +msgstr "Disigi tiun menuon" + msgid "E333: Menu path must lead to a menu item" msgstr "E333: Vojo de menuo devas konduki al menuero" @@ -3493,6 +3896,9 @@ msgstr "linio %4ld:" msgid "E354: Invalid register name: '%s'" msgstr "E354: Nevalida nomo de reĝistro: '%s'" +msgid "Messages maintainer: Bram Moolenaar " +msgstr "Flegado de mesaĝoj: Dominique PELLÉ " + msgid "Interrupt: " msgstr "Interrompo: " @@ -3500,8 +3906,8 @@ msgid "Press ENTER or type command to continue" msgstr "Premu ENEN-KLAVON aŭ tajpu komandon por daŭrigi" #, c-format -msgid "%s line %" -msgstr "%s linio %" +msgid "%s line %ld" +msgstr "%s linio %ld" msgid "-- More --" msgstr "-- Pli --" @@ -3519,15 +3925,6 @@ msgstr "" "&Jes\n" "&Ne" -msgid "" -"&Yes\n" -"&No\n" -"&Cancel" -msgstr "" -"&Jes\n" -"&Ne\n" -"&Rezigni" - # AM: ĉu Vim konvertos unuliterajn respondojn? # DP: jes, '&' bone funkcias (mi kontrolis) msgid "" @@ -3543,11 +3940,24 @@ msgstr "" "&Forlasi Ĉion\n" "&Rezigni" +msgid "Select Directory dialog" +msgstr "Dialogujo de dosiera elekto" + +msgid "Save File dialog" +msgstr "Dialogujo de dosiera konservo" + +msgid "Open File dialog" +msgstr "Dialogujo de dosiera malfermo" + +#. TODO: non-GUI file selector here +msgid "E338: Sorry, no file browser in console mode" +msgstr "E338: Bedaŭrinde ne estas dosierfoliumilo en konzola reĝimo" + msgid "E766: Insufficient arguments for printf()" msgstr "E766: Ne sufiĉaj argumentoj por printf()" msgid "E807: Expected Float argument for printf()" -msgstr "E807: Atendis Glitpunktnombron kiel argumento de printf()" +msgstr "E807: Atendis Glitpunktnombron kiel argumenton de printf()" msgid "E767: Too many arguments to printf()" msgstr "E767: Tro da argumentoj al printf()" @@ -3569,12 +3979,12 @@ msgid "1 line less" msgstr "1 malplia linio" #, c-format -msgid "% more lines" -msgstr "% pliaj linioj" +msgid "%ld more lines" +msgstr "%ld pliaj linioj" #, c-format -msgid "% fewer lines" -msgstr "% malpliaj linioj" +msgid "%ld fewer lines" +msgstr "%ld malpliaj linioj" msgid " (Interrupted)" msgstr " (Interrompita)" @@ -3582,16 +3992,112 @@ msgstr " (Interrompita)" msgid "Beep!" msgstr "Bip!" +msgid "ERROR: " +msgstr "ERARO: " + +#, c-format +msgid "" +"\n" +"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n" +msgstr "" +"\n" +"[bajtoj] totalaj disponigitaj/maldisponigitaj %lu-%lu, nun uzataj %lu, " +"kulmina uzo %lu\n" + +#, c-format +msgid "" +"[calls] total re/malloc()'s %lu, total free()'s %lu\n" +"\n" +msgstr "" +"[alvokoj] totalaj re/malloc() %lu, totalaj free() %lu\n" +"\n" + +msgid "E340: Line is becoming too long" +msgstr "E340: Linio iĝas tro longa" + +#, c-format +msgid "E341: Internal error: lalloc(%ld, )" +msgstr "E341: Interna eraro: lalloc(%ld, )" + +#, c-format +msgid "E342: Out of memory! (allocating %lu bytes)" +msgstr "E342: Ne plu restas memoro! (disponigo de %lu bajtoj)" + #, c-format msgid "Calling shell to execute: \"%s\"" msgstr "Alvokas ŝelon por plenumi: \"%s\"" +msgid "E545: Missing colon" +msgstr "E545: Mankas dupunkto" + +msgid "E546: Illegal mode" +msgstr "E546: Reĝimo nepermesata" + +msgid "E547: Illegal mouseshape" +msgstr "E547: Nevalida formo de muskursoro" + +msgid "E548: digit expected" +msgstr "E548: cifero atendata" + +msgid "E549: Illegal percentage" +msgstr "E549: Nevalida procento" + +msgid "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" msgid "E774: 'operatorfunc' is empty" msgstr "E774: 'operatorfunc' estas malplena" +# DP: ĉu Eval devas esti tradukita? +msgid "E775: Eval feature not available" +msgstr "E775: Eval eblo ne disponeblas" + msgid "Warning: terminal cannot highlight" msgstr "Averto: terminalo ne povas emfazi" @@ -3610,7 +4116,7 @@ msgstr "E662: Ĉe komenco de ŝanĝlisto" msgid "E663: At end of changelist" msgstr "E663: Ĉe fino de ŝanĝlisto" -msgid "Type :quit to exit Nvim" +msgid "Type :quit to exit Vim" msgstr "Tajpu \":quit\" por eliri el Vim" #, c-format @@ -3622,37 +4128,41 @@ msgid "1 line %sed %d times" msgstr "1 linio %sita %d foje" #, c-format -msgid "% lines %sed 1 time" -msgstr "% linio %sita 1 foje" +msgid "%ld lines %sed 1 time" +msgstr "%ld linio %sita 1 foje" #, c-format -msgid "% lines %sed %d times" -msgstr "% linioj %sitaj %d foje" +msgid "%ld lines %sed %d times" +msgstr "%ld linioj %sitaj %d foje" #, c-format -msgid "% lines to indent... " -msgstr "% krommarĝenendaj linioj... " +msgid "%ld lines to indent... " +msgstr "%ld krommarĝenendaj linioj... " msgid "1 line indented " msgstr "1 linio krommarĝenita " #, c-format -msgid "% lines indented " -msgstr "% linioj krommarĝenitaj " +msgid "%ld lines indented " +msgstr "%ld linioj krommarĝenitaj " msgid "E748: No previously used register" msgstr "E748: Neniu reĝistro antaŭe uzata" #. must display the prompt msgid "cannot yank; delete anyway" -msgstr "ne eblas kopii; forviŝi tamene" +msgstr "ne eblas kopii; tamen forviŝi" msgid "1 line changed" msgstr "1 linio ŝanĝita" #, c-format -msgid "% lines changed" -msgstr "% linioj ŝanĝitaj" +msgid "%ld lines changed" +msgstr "%ld linioj ŝanĝitaj" + +#, c-format +msgid "freeing %ld lines" +msgstr "malokupas %ld liniojn" msgid "block of 1 line yanked" msgstr "bloko de 1 linio kopiita" @@ -3661,12 +4171,12 @@ msgid "1 line yanked" msgstr "1 linio kopiita" #, c-format -msgid "block of % lines yanked" -msgstr "bloko de % linioj kopiita" +msgid "block of %ld lines yanked" +msgstr "bloko de %ld linioj kopiita" #, c-format -msgid "% lines yanked" -msgstr "% linioj kopiitaj" +msgid "%ld lines yanked" +msgstr "%ld linioj kopiitaj" #, c-format msgid "E353: Nothing in register %s" @@ -3694,45 +4204,44 @@ msgstr "" msgid "E574: Unknown register type %d" msgstr "E574: Nekonata tipo de reĝistro %d" +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 "% Cols; " -msgstr "% Kolumnoj; " +msgid "%ld Cols; " +msgstr "%ld Kolumnoj; " #, c-format -msgid "" -"Selected %s% of % Lines; % of % Words; " -"% of % Bytes" +msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes" msgstr "" -"Apartigis %s% de % Linioj; % de % Vortoj; " -"% de % Bajtoj" +"Apartigis %s%ld de %ld Linioj; %lld de %lld Vortoj; %lld de %lld Bajtoj" #, c-format msgid "" -"Selected %s% of % Lines; % of % Words; " -"% of % Chars; % of % Bytes" +"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of " +"%lld Bytes" msgstr "" -"Apartigis %s% de % Linioj; % de % Vortoj; " -"% de % Signoj; % de % Bajtoj" +"Apartigis %s%ld de %ld Linioj; %lld de %lld Vortoj; %lld de %lld Signoj; " +"%lld de %lld Bajtoj" #, c-format -msgid "" -"Col %s of %s; Line % of %; Word % of %; Byte " -"% of %" -msgstr "" -"Kol %s de %s; Linio % de %; Vorto % de %; " -"Bajto % de %" +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" #, c-format msgid "" -"Col %s of %s; Line % of %; Word % of %; Char " -"% of %; Byte % of %" +"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 % de %; Vorto % de %; " -"Signo % de %; Bajto % de %" +"Kol %s de %s; Linio %ld de %ld; Vorto %lld de %lld; Signo %lld de %lld; " +"Bajto %lld de %lld" #, c-format -msgid "(+% for BOM)" -msgstr "(+% por BOM)" +msgid "(+%ld for BOM)" +msgstr "(+%ld por BOM)" msgid "%<%f%h%m%=Page %N" msgstr "%<%f%h%m%=Folio %N" @@ -3740,7 +4249,6 @@ msgstr "%<%f%h%m%=Folio %N" msgid "Thanks for flying Vim" msgstr "Dankon pro flugi per Vim" -#. found a mismatch: skip msgid "E518: Unknown option" msgstr "E518: Nekonata opcio" @@ -3770,6 +4278,12 @@ msgstr "Por opcio %s" msgid "E529: Cannot set 'term' to empty string" msgstr "E529: Ne eblas agordi 'term' al malplena ĉeno" +msgid "E530: Cannot change term in GUI" +msgstr "E530: term ne ŝanĝeblas en grafika interfaco" + +msgid "E531: Use \":gui\" to start the GUI" +msgstr "E531: Uzu \":gui\" por lanĉi la grafikan interfacon" + msgid "E589: 'backupext' and 'patchmode' are equal" msgstr "E589: 'backupext' kaj 'patchmode' estas egalaj" @@ -3779,6 +4293,9 @@ msgstr "E834: Konfliktoj kun la valoro de 'listchars'" msgid "E835: Conflicts with value of 'fillchars'" msgstr "E835: Konfliktoj kun la valoro de 'fillchars'" +msgid "E617: Cannot be changed in the GTK+ 2 GUI" +msgstr "E617: Ne ŝanĝeblas en la grafika interfaco GTK+ 2" + msgid "E524: Missing colon" msgstr "E524: Mankas dupunkto" @@ -3798,6 +4315,21 @@ msgstr "E528: Devas specifi ' valoron" msgid "E595: contains unprintable or wide character" msgstr "E595: enhavas nepreseblan aŭ plurĉellarĝan signon" +msgid "E596: Invalid font(s)" +msgstr "E596: Nevalida(j) tiparo(j)" + +msgid "E597: can't select fontset" +msgstr "E597: ne eblas elekti tiparon" + +msgid "E598: Invalid fontset" +msgstr "E598: Nevalida tiparo" + +msgid "E533: can't select wide font" +msgstr "E533: ne eblas elekti larĝan tiparon" + +msgid "E534: Invalid wide font" +msgstr "E534: Nevalida larĝa tiparo" + #, c-format msgid "E535: Illegal character after <%c>" msgstr "E535: Nevalida signo post <%c>" @@ -3809,6 +4341,9 @@ msgstr "E536: komo bezonata" msgid "E537: 'commentstring' must be empty or contain %s" msgstr "E537: 'commentstring' devas esti malplena aŭ enhavi %s" +msgid "E538: No mouse support" +msgstr "E538: Neniu muso subtenata" + msgid "E540: Unclosed expression sequence" msgstr "E540: '}' mankas" @@ -3816,7 +4351,7 @@ msgid "E541: too many items" msgstr "E541: tro da elementoj" msgid "E542: unbalanced groups" -msgstr "E542: misekvilibritaj grupoj" +msgstr "E542: misekvilibraj grupoj" msgid "E590: A preview window already exists" msgstr "E590: Antaŭvida fenestro jam ekzistas" @@ -3882,50 +4417,237 @@ msgstr "E357: 'langmap': Kongrua signo mankas por %s" msgid "E358: 'langmap': Extra characters after semicolon: %s" msgstr "E358: 'langmap': Ekstraj signoj post punktokomo: %s" -msgid "" -"\n" -"Cannot execute shell " -msgstr "" -"\n" -"Ne eblas plenumi ŝelon " - -msgid "" -"\n" -"shell returned " -msgstr "" -"\n" -"ŝelo liveris " +msgid "cannot open " +msgstr "ne eblas malfermi " -msgid "" -"\n" -"Could not get security context for " -msgstr "" -"\n" -"Ne povis akiri kuntekston de sekureco por " +msgid "VIM: Can't open window!\n" +msgstr "VIM: Ne eblas malfermi fenestron!\n" -msgid "" -"\n" -"Could not set security context for " -msgstr "" -"\n" -"Ne povis ŝalti kuntekston de sekureco por " +msgid "Need Amigados version 2.04 or later\n" +msgstr "Bezonas version 2.04 de Amigados aŭ pli novan\n" #, c-format -msgid "Could not set security context %s for %s" -msgstr "Ne povis ŝalti kuntekston de sekureco %s por %s" +msgid "Need %s version %ld\n" +msgstr "Bezonas %s-on versio %ld\n" -#, c-format -msgid "Could not get security context %s for %s. Removing it!" -msgstr "" -"Ne povis akiri kuntekston de sekureco %s por %s. Gi nun estas forigata!" +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" + +msgid "" +"\n" +"Vim: Got X error\n" +msgstr "" +"\n" +"Vim: Alvenis X eraro\n" + +msgid "Testing the X display failed" +msgstr "Testo de la vidigo X malsukcesis" + +msgid "Opening the X display timed out" +msgstr "Tempolimo okazis dum malfermo de vidigo X" + +msgid "" +"\n" +"Could not get security context for " +msgstr "" +"\n" +"Ne povis akiri kuntekston de sekureco por " + +msgid "" +"\n" +"Could not set security context for " +msgstr "" +"\n" +"Ne povis ŝalti kuntekston de sekureco por " + +#, c-format +msgid "Could not set security context %s for %s" +msgstr "Ne povis ŝalti kuntekston de sekureco %s por %s" + +#, c-format +msgid "Could not get security context %s for %s. Removing it!" +msgstr "" +"Ne povis akiri kuntekston de sekureco %s por %s. Gi nun estas forigata!" + +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\"" +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" #, c-format msgid "E372: Too many %%%c in format string" @@ -3960,6 +4682,15 @@ msgstr "E379: Nomo de dosierujo mankas aŭ estas malplena" msgid "E553: No more items" msgstr "E553: Ne plu estas eroj" +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: " @@ -3983,6 +4714,9 @@ msgstr "Neniu ano" msgid "E382: Cannot write, 'buftype' option is set" msgstr "E382: Ne eblas skribi, opcio 'buftype' estas ŝaltita" +msgid "Error file" +msgstr "Erara Dosiero" + msgid "E683: File name missing or invalid pattern" msgstr "E683: Dosiernomo mankas aŭ nevalida ŝablono" @@ -4017,7 +4751,7 @@ msgid "E55: Unmatched %s)" msgstr "E55: Neekvilibra %s" 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. msgid "E67: \\z1 et al. not allowed here" @@ -4088,6 +4822,10 @@ msgstr "E554: Sintaksa eraro en %s{...}" msgid "External submatches:\n" msgstr "Eksteraj subkongruoj:\n" +#, 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 " @@ -4095,6 +4833,9 @@ msgstr "" "E864: \\%#= povas nur esti sekvita de 0, 1, aŭ 2. La aŭtomata motoro de " "regulesprimo estos uzata " +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" @@ -4102,17 +4843,21 @@ msgstr "E865: (NFA) Trovis finon de regulesprimo tro frue" msgid "E866: (NFA regexp) Misplaced %c" msgstr "E866: (NFA-regulesprimo) Mispoziciigita %c" -#, fuzzy, c-format -#~ msgid "E877: (NFA regexp) Invalid character class: %" -#~ 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" #, c-format msgid "E867: (NFA) Unknown operator '\\z%c'" msgstr "E867: (NFA) Nekonata operatoro '\\z%c'" -#, fuzzy, c-format -#~ msgid "E867: (NFA) Unknown operator '\\%%%c'" -#~ msgstr "E867: (NFA) Nekonata operatoro '\\z%c'" +#, c-format +msgid "E867: (NFA) Unknown operator '\\%%%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!" #, c-format msgid "E869: (NFA) Unknown operator '\\@%c'" @@ -4131,9 +4876,8 @@ msgstr "" msgid "E872: (NFA regexp) Too many '('" msgstr "E872: (NFA-regulesprimo) tro da '('" -#, fuzzy -#~ msgid "E879: (NFA regexp) Too many \\z(" -#~ msgstr "E872: (NFA-regulesprimo) tro da '('" +msgid "E879: (NFA regexp) Too many \\z(" +msgstr "E879: (NFA-regulesprimo) tro da \\z(" msgid "E873: (NFA regexp) proper termination error" msgstr "E873: (NFA-regulesprimo) propra end-eraro" @@ -4151,6 +4895,9 @@ msgstr "" msgid "E876: (NFA regexp) Not enough space to store the whole NFA " msgstr "E876: (NFA-regulesprimo) ne sufiĉa spaco por enmomorigi la tutan NFA " +msgid "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 "" @@ -4347,13 +5094,6 @@ msgstr "E762: Signo en FOL, LOW aŭ UPP estas ekster limoj" msgid "Compressing word tree..." msgstr "Densigas arbon de vortoj..." -msgid "E756: Spell checking is not enabled" -msgstr "E756: Literumilo ne estas ŝaltita" - -#, c-format -msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\"" -msgstr "Averto: Ne eblas trovi vortliston \"%s.%s.spl\" aŭ \"%s.ascii.spl\"" - #, c-format msgid "Reading spell file \"%s\"" msgstr "Legado de literuma dosiero \"%s\"" @@ -4402,6 +5142,10 @@ msgstr "Malsukceso dum konverto de vorto en %s linio %d: %s" msgid "Conversion in %s not supported: from %s to %s" msgstr "Konverto en %s nesubtenata: de %s al %s" +#, c-format +msgid "Conversion in %s not supported" +msgstr "Konverto en %s nesubtenata" + #, c-format msgid "Invalid value for FLAG in %s line %d: %s" msgstr "Nevalida valoro de FLAG en %s linio %d: %s" @@ -4586,6 +5330,9 @@ msgstr "Nekonata flago en %s linio %d: %s" msgid "Ignored %d words with non-ASCII characters" msgstr "Ignoris %d vorto(j)n kun neaskiaj signoj" +msgid "E845: Insufficient memory, word list will be incomplete" +msgstr "E845: Ne sufiĉe da memoro, vortlisto estos nekompleta." + #, c-format msgid "Compressed %d of %d nodes; %d (%d%%) remaining" msgstr "Densigis %d de %d nodoj; %d (%d%%) restantaj" @@ -4593,14 +5340,16 @@ msgstr "Densigis %d de %d nodoj; %d (%d%%) restantaj" msgid "Reading back spell file..." msgstr "Relegas la dosieron de literumo..." -#. Go through the trie of good words, soundfold each word and add it to -#. the soundfold trie. +#. +#. * Go through the trie of good words, soundfold each word and add it to +#. * the soundfold trie. +#. msgid "Performing soundfolding..." msgstr "Fonetika analizado..." #, c-format -msgid "Number of words after soundfolding: %" -msgstr "Nombro de vortoj post fonetika analizado: %" +msgid "Number of words after soundfolding: %ld" +msgstr "Nombro de vortoj post fonetika analizado: %ld" #, c-format msgid "Total number of words: %d" @@ -4635,66 +5384,22 @@ msgid "Done!" msgstr "Farita!" #, c-format -msgid "E765: 'spellfile' does not have % entries" -msgstr "E765: 'spellfile' ne havas % rikordojn" - -#, fuzzy, c-format -#~ msgid "Word '%.*s' removed from %s" -#~ msgstr "Vorto fortirita el %s" - -#, fuzzy, c-format -#~ msgid "Word '%.*s' added to %s" -#~ msgstr "Vorto aldonita al %s" - -msgid "E763: Word characters differ between spell files" -msgstr "E763: Signoj de vorto malsamas tra literumaj dosieroj" - -msgid "Sorry, no suggestions" -msgstr "Bedaŭrinde ne estas sugestoj" - -#, c-format -msgid "Sorry, only % suggestions" -msgstr "Bedaŭrinde estas nur % sugestoj" - -#. for when 'cmdheight' > 1 -#. avoid more prompt -#, c-format -msgid "Change \"%.*s\" to:" -msgstr "Anstataŭigi \"%.*s\" per:" - -#, c-format -msgid " < \"%.*s\"" -msgstr " < \"%.*s\"" - -msgid "E752: No previous spell replacement" -msgstr "E752: Neniu antaŭa literuma anstataŭigo" - -#, c-format -msgid "E753: Not found: %s" -msgstr "E753: Netrovita: %s" - -#, c-format -msgid "E778: This does not look like a .sug file: %s" -msgstr "E778: Tio ne ŝajnas esti dosiero .sug: %s" - -#, c-format -msgid "E779: Old .sug file, needs to be updated: %s" -msgstr "E779: Malnova dosiero .sug, bezonas ĝisdatigon: %s" +msgid "E765: 'spellfile' does not have %ld entries" +msgstr "E765: 'spellfile' ne havas %ld rikordojn" #, c-format -msgid "E780: .sug file is for newer version of Vim: %s" -msgstr "E780: Dosiero .sug estas por pli nova versio de Vim: %s" +msgid "Word '%.*s' removed from %s" +msgstr "Vorto '%.*s' fortirita el %s" #, c-format -msgid "E781: .sug file doesn't match .spl file: %s" -msgstr "E781: Dosiero .sug ne kongruas kun dosiero .spl: %s" +msgid "Word '%.*s' added to %s" +msgstr "Vorto '%.*s' aldonita al %s" -#, c-format -msgid "E782: error while reading .sug file: %s" -msgstr "E782: eraro dum legado de dosiero .sug: %s" +msgid "E763: Word characters differ between spell files" +msgstr "E763: Signoj de vorto malsamas tra literumaj dosieroj" #. This should have been checked when generating the .spl -#. file. +#. * file. msgid "E783: duplicate char in MAP entry" msgstr "E783: ripetita signo en rikordo MAP" @@ -4802,7 +5507,6 @@ msgstr "E848: Tro da sintaksaj grupoj" msgid "E400: No cluster specified" msgstr "E400: Neniu fasko specifita" -#. end delimiter not found #, c-format msgid "E401: Pattern delimiter not found: %s" msgstr "E401: Disigilo de ŝablono netrovita: %s" @@ -4842,9 +5546,10 @@ msgstr "E409: Nekonata nomo de grupo: %s" msgid "E410: Invalid :syntax subcommand: %s" msgstr "E410: Nevalida \":syntax\" subkomando: %s" -#~ msgid "" -#~ " TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN" -#~ msgstr "" +msgid "" +" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN" +msgstr "" +" TOTALO NOMBRO KONGRUO PLEJ MALRAPID MEZA NOMO ŜABLONO" msgid "E679: recursive loop loading syncolor.vim" msgstr "E679: rekursia buklo dum ŝargo de syncolor.vim" @@ -4859,7 +5564,7 @@ msgstr "E412: Ne sufiĉaj argumentoj: \":highlight link %s\"" #, c-format msgid "E413: Too many arguments: \":highlight link %s\"" -msgstr "E413: Tro argumentoj: \":highlight link %s\"" +msgstr "E413: Tro da argumentoj: \":highlight link %s\"" msgid "E414: group has settings, highlight link ignored" msgstr "E414: grupo havas agordojn, ligilo de emfazo ignorita" @@ -4967,6 +5672,10 @@ msgstr "" msgid "Searching tags file %s" msgstr "Serĉado de dosiero de etikedoj %s" +#, c-format +msgid "E430: Tag file path truncated for %s\n" +msgstr "E430: Vojo de etikeda dosiero trunkita por %s\n" + msgid "Ignoring long line in tags file" msgstr "Ignoro de longa linio en etikeda dosiero" @@ -4975,8 +5684,8 @@ msgid "E431: Format error in tags file \"%s\"" msgstr "E431: Eraro de formato en etikeda dosiero \"%s\"" #, c-format -msgid "Before byte %" -msgstr "Antaŭ bajto %" +msgid "Before byte %ld" +msgstr "Antaŭ bajto %ld" #, c-format msgid "E432: Tags file not sorted: %s" @@ -5026,14 +5735,26 @@ msgstr "" "\n" "--- Klavoj de terminalo ---" +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. -#, fuzzy -#~ msgid "E881: Line count changed unexpectedly" -#~ msgstr "E834: Nombro de linioj ŝanĝiĝis neatendite" +msgid "E881: Line count changed unexpectedly" +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" #, c-format msgid "E828: Cannot open undo file for writing: %s" @@ -5081,6 +5802,18 @@ msgstr "E822: Ne eblas malfermi malfaran dosieron por legi: %s" msgid "E823: Not an undo file: %s" msgstr "E823: Ne estas malfara dosiero: %s" +#, c-format +msgid "E832: Non-encrypted file has encrypted undo file: %s" +msgstr "E832: Ne ĉifrata dosiero havas ĉifratan malfaran dosieron: %s" + +#, c-format +msgid "E826: Undo file decryption failed: %s" +msgstr "E826: Malĉifrado de malfara dosiero 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" @@ -5099,8 +5832,8 @@ msgid "Already at newest change" msgstr "Jam al la plej nova ŝanĝo" #, c-format -msgid "E830: Undo number % not found" -msgstr "E830: Malfara numero % netrovita" +msgid "E830: Undo number %ld not found" +msgstr "E830: Malfara numero %ld netrovita" msgid "E438: u_undo: line numbers wrong" msgstr "E438: u_undo: nevalidaj numeroj de linioj" @@ -5124,8 +5857,8 @@ msgid "changes" msgstr "ŝanĝoj" #, c-format -msgid "% %s; %s #% %s" -msgstr "% %s; %s #% %s" +msgid "%ld %s; %s #%ld %s" +msgstr "%ld %s; %s #%ld %s" msgid "before" msgstr "antaŭ" @@ -5140,8 +5873,8 @@ msgid "number changes when saved" msgstr "numero ŝanĝoj tempo konservita" #, c-format -msgid "% seconds ago" -msgstr "antaŭ % sekundoj" +msgid "%ld seconds ago" +msgstr "antaŭ %ld sekundoj" msgid "E790: undojoin is not allowed after undo" msgstr "E790: undojoin estas nepermesebla post malfaro" @@ -5152,51 +5885,295 @@ msgstr "E439: listo de malfaro estas difekta" msgid "E440: undo line missing" msgstr "E440: linio de malfaro mankas" -msgid "" -"\n" -"Included patches: " -msgstr "" -"\n" -"Flikaĵoj inkluzivitaj: " +#, 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 "" -"\n" -"Extra patches: " -msgstr "" -"\n" -"Ekstraj flikaĵoj: " +msgid "E717: Dictionary entry already exists" +msgstr "E717: Rikordo de vortaro jam ekzistas" -msgid "Modified by " -msgstr "Modifita de " +msgid "E718: Funcref required" +msgstr "E718: Funcref bezonata" -msgid "" -"\n" -"Compiled " -msgstr "" -"\n" -"Kompilita " +#, c-format +msgid "E130: Unknown function: %s" +msgstr "E130: Nekonata funkcio: %s" -msgid "by " -msgstr "de " +#, c-format +msgid "E125: Illegal argument: %s" +msgstr "E125: Nevalida argumento: %s" -msgid "" -"\n" -"Huge version " -msgstr "" -"\n" -"Grandega versio " +#, c-format +msgid "E853: Duplicate argument name: %s" +msgstr "E853: Ripetita nomo de argumento: %s" -msgid "without GUI." -msgstr "sen grafika interfaco." +#, c-format +msgid "E740: Too many arguments for function %s" +msgstr "E740: Tro da argumentoj por funkcio: %s" -msgid " Features included (+) or not (-):\n" -msgstr " Ebloj inkluzivitaj (+) aŭ ne (-):\n" +#, c-format +msgid "E116: Invalid arguments for function %s" +msgstr "E116: Nevalidaj argumentoj por funkcio: %s" -msgid " system vimrc file: \"" -msgstr " sistema dosiero vimrc: \"" +msgid "E132: Function call depth is higher than 'maxfuncdepth'" +msgstr "E132: Profundo de funkcia alvoko superas 'maxfuncdepth'" -msgid " user vimrc file: \"" -msgstr " dosiero vimrc de uzanto: \"" +#, 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 not in a script context: %s" +msgstr "E120: 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: " +msgstr "" +"\n" +"Flikaĵoj inkluzivitaj: " + +msgid "" +"\n" +"Extra patches: " +msgstr "" +"\n" +"Ekstraj flikaĵoj: " + +msgid "Modified by " +msgstr "Modifita de " + +msgid "" +"\n" +"Compiled " +msgstr "" +"\n" +"Kompilita " + +msgid "by " +msgstr "de " + +msgid "" +"\n" +"Huge version " +msgstr "" +"\n" +"Grandega versio " + +msgid "" +"\n" +"Big version " +msgstr "" +"\n" +"Granda versio " + +msgid "" +"\n" +"Normal version " +msgstr "" +"\n" +"Normala versio " + +msgid "" +"\n" +"Small version " +msgstr "" +"\n" +"Malgranda versio " + +msgid "" +"\n" +"Tiny version " +msgstr "" +"\n" +"Malgrandega versio " + +msgid "without GUI." +msgstr "sen grafika interfaco." + +msgid "with 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" + +msgid " system vimrc file: \"" +msgstr " sistema dosiero vimrc: \"" + +msgid " user vimrc file: \"" +msgstr " dosiero vimrc de uzanto: \"" msgid " 2nd user vimrc file: \"" msgstr " 2-a dosiero vimrc de uzanto: \"" @@ -5210,6 +6187,24 @@ msgstr " dosiero exrc de uzanto: \"" msgid " 2nd user exrc file: \"" msgstr " 2-a dosiero exrc de uzanto: \"" +msgid " system gvimrc file: \"" +msgstr " sistema dosiero gvimrc: \"" + +msgid " user gvimrc file: \"" +msgstr " dosiero gvimrc de uzanto: \"" + +msgid "2nd user gvimrc file: \"" +msgstr " 2-a dosiero gvimrc de uzanto: \"" + +msgid "3rd user gvimrc file: \"" +msgstr " 3-a dosiero gvimrc de uzanto: \"" + +msgid " 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: \"" @@ -5219,6 +6214,9 @@ msgstr " defaŭlto de VIMRUNTIME: \"" msgid "Compilation: " msgstr "Kompilado: " +msgid "Compiler: " +msgstr "Kompililo: " + msgid "Linking: " msgstr "Ligado: " @@ -5254,8 +6252,8 @@ msgid "type :help or for on-line help" msgstr "tajpu :help por aliri la helpon " # DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon -msgid "type :help version7 for version info" -msgstr "tajpu :help version7 por informo de versio" +msgid "type :help version8 for version info" +msgstr "tajpu :help version8 por informo de versio" msgid "Running in Vi compatible mode" msgstr "Ruliĝas en reĝimo kongrua kun Vi" @@ -5268,6 +6266,30 @@ msgstr "tajpu :set nocp por Vim defaŭltoj " msgid "type :help cp-default for info on this" msgstr "tajpu :help cp-default por pliaj informoj " +# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon +msgid "menu Help->Orphans for information " +msgstr "menuo Help->Orfinoj por pliaj informoj " + +msgid "Running modeless, typed text is inserted" +msgstr "Ruliĝas senreĝime, tajpita teksto estas enmetita" + +# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon +msgid "menu Edit->Global Settings->Toggle Insert Mode " +msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi Enmetan Reĝimon" + +# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon +msgid " for two modes " +msgstr " por du reĝimoj " + +# DP: tiu ĉeno pli longas (mi ne volas igi ĉiujn aliajn ĉenojn +# pli longajn) +msgid "menu Edit->Global Settings->Toggle Vi Compatible" +msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi Reĝimon Kongruan kun Vi" + +# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon +msgid " for Vim defaults " +msgstr " por defaŭltoj de Vim " + msgid "Sponsor Vim development!" msgstr "Subtenu la programadon de Vim!" @@ -5313,1737 +6335,703 @@ msgstr "E445: La alia fenestro enhavas ŝanĝojn" 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 " " -#~ msgstr " " - -#~ 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% width is not twice that of font0\n" -#~ msgstr "Font% ne estas duoble pli larĝa ol font0\n" - -#~ msgid "Font0 width: %\n" -#~ msgstr "Larĝo de font0: %\n" - -#~ msgid "" -#~ "Font1 width: %\n" -#~ "\n" -#~ msgstr "" -#~ "Larĝo de Font1: %\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 \t\tUse for I/O" -#~ msgstr "-dev \t\tUzi -n por eneligo" - -#~ msgid "-U \t\tUse instead of any .gvimrc" -#~ msgstr "-U \t\tUzi anstataŭ iun ajn .gvimrc" - -#~ msgid "-x\t\t\tEdit encrypted files" -#~ msgstr "-x\t\t\tRedakti ĉifradan dosieron" - -#~ msgid "-display \tConnect vim to this particular X-server" -#~ msgstr "-display \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 \tEdit in a Vim server if possible" -#~ msgstr "--remote \tRedakti -n en Vim-servilo se eblas" - -#~ msgid "--remote-silent Same, don't complain if there is no server" -#~ msgstr "--remote-silent Same, sed ne plendi se ne estas servilo" - -#~ msgid "" -#~ "--remote-wait As --remote but wait for files to have been edited" -#~ msgstr "" -#~ "--remote-wait Kiel --remote sed atendi ĝis dosieroj estas " -#~ "redaktitaj" - -#~ msgid "" -#~ "--remote-wait-silent Same, don't complain if there is no server" -#~ msgstr "" -#~ "--remote-wait-silent Same, sed ne plendi se ne estas servilo" - -#~ msgid "" -#~ "--remote-tab[-wait][-silent] As --remote but use tab page per " -#~ "file" -#~ msgstr "" -#~ "--remote-tab[-wait][-silent] Kiel --remote sed uzi langeton " -#~ "por ĉiu dosiero" - -#~ msgid "--remote-send \tSend to a Vim server and exit" -#~ msgstr "--remote-send Sendi -n al Vim-servilo kaj eliri" - -#~ msgid "" -#~ "--remote-expr \tEvaluate in a Vim server and print result" -#~ msgstr "" -#~ "--remote-expr \tKomputi 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 \tSend to/become the Vim server " -#~ msgstr "--servername \tSendu al/iĝi la Vim-servilo " - -#~ 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 \tRun vim on " -#~ msgstr "-display \tLanĉi vim sur " - -#~ msgid "-iconic\t\tStart vim iconified" -#~ msgstr "-iconic\t\tLanĉi vim piktograme" - -#~ msgid "-background \tUse for the background (also: -bg)" -#~ msgstr "" -#~ "-background \tUzi -n por la fona koloro (ankaŭ: -bg)" - -#~ msgid "-foreground \tUse for normal text (also: -fg)" -#~ msgstr "" -#~ "-foreground \tUzi -n por la malfona koloro (ankaŭ: -fg)" - -#~ msgid "-font \t\tUse for normal text (also: -fn)" -#~ msgstr "-font \tUzi -n por normala teksto (ankaŭ: -fn)" - -#~ msgid "-boldfont \tUse for bold text" -#~ msgstr "-boldfont \tUzi -n por grasa teksto" - -#~ msgid "-italicfont \tUse for italic text" -#~ msgstr "-italicfont \tUzi -n por kursiva teksto" - -#~ msgid "-geometry \tUse for initial geometry (also: -geom)" -#~ msgstr "-geometry \tUzi kiel komenca geometrio (ankaŭ: -geom)" - -#~ msgid "-borderwidth \tUse a border width of (also: -bw)" -#~ msgstr "" -#~ "-borderwidth \tUzi -n kiel larĝo de bordero (ankaŭ: -bw)" - -#~ msgid "" -#~ "-scrollbarwidth Use a scrollbar width of (also: -sw)" -#~ msgstr "" -#~ "-scrollbarwidth Uzi -n kiel larĝo de rulumskalo (ankaŭ: -" -#~ "sw)" - -#~ msgid "-menuheight \tUse a menu bar height of (also: -mh)" -#~ msgstr "" -#~ "-menuheight \tUzi -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 \tSet the specified resource" -#~ msgstr "-xrm \tAgordi la specifitan -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 \tRun vim on (also: --display)" -#~ msgstr "-display \tLanĉi Vim sur tiu (ankaŭ: --display)" +msgid "List or number required" +msgstr "Listo aŭ nombro bezonata" -#~ msgid "--role \tSet a unique role to identify the main window" -#~ msgstr "--role \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 \tOpen Vim inside another GTK widget" -#~ msgstr "--socketid \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 \tOpen Vim inside parent application" -#~ msgstr "-P \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 \tOpen Vim inside another win32 widget" -#~ msgstr "--windowid \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; executes, CTRL-C quits" +msgstr "" +"E11: Nevalida en fenestro de komanda linio; 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 %-%, in use %, peak use " -#~ "%\n" -#~ msgstr "" -#~ "\n" -#~ "[bajtoj] totalaj disponigitaj/maldisponigitaj %-%, nun " -#~ "uzataj %, kulmina uzo %\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 %, total free()'s %\n" -#~ "\n" -#~ msgstr "" -#~ "[alvokoj] totalaj re/malloc() %, totalaj free() %\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(%, )" -#~ msgstr "E341: Interna eraro: lalloc(%, )" +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 %" -#~ msgstr "E658: Konekto de NetBeans perdita por bufro %" +#, 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 % lines" -#~ msgstr "malokupas % 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 %\n" -#~ msgstr "Bezonas %s-on versio %\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 % msec" -#~ msgstr "Malfermo de vidigo X daŭris % 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 for info on this" -#~ msgstr "tajpu :help windows95 por pliaj informoj " +msgid "E81: Using not in a script context" +msgstr "E81: Uzo de 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 "" -#~ msgstr "" +#, c-format +msgid "failed to run function %s" +msgstr "malsukcesis ruli funkcion %s" -#~ msgid "" -#~ msgstr "" +msgid "unable to get option value" +msgstr "malsukcesis akiri valoron de opcio" -#~ msgid "" -#~ msgstr "" +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 "" -#~ msgstr "" +msgid "no such tab page" +msgstr "ne estas tia langeto" -#~ msgid "" -#~ msgstr "" +msgid "attempt to refer to deleted window" +msgstr "provo de referenco al forviŝita fenestro" -#~ msgid "" -#~ msgstr "" +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 "" -#~ msgstr "" +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/fr.po b/src/nvim/po/fr.po index 4b1b0476ca..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 2000. # SECOND AUTHOR Adrien Beau 2002, 2003. # THIRD AUTHOR David Blanchet 2006, 2008. -# FOURTH AUTHOR Dominique Pell 2008, 2015. +# FOURTH AUTHOR Dominique Pell 2008, 2017. # # Latest translation available at: # http://dominique.pelle.free.fr/vim-fr.php @@ -15,8 +16,8 @@ msgid "" msgstr "" "Project-Id-Version: Vim(Franais)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-08-26 20:54+0200\n" -"PO-Revision-Date: 2016-08-26 20:34+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 \n" "Language-Team: \n" "Language: fr\n" @@ -24,13 +25,20 @@ msgstr "" "Content-Type: text/plain; charset=ISO_8859-15\n" "Content-Transfer-Encoding: 8bit\n" -#, 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() appele 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" -#, fuzzy -#~ msgid "internal error: unknown option type" -#~ msgstr "erreur interne : pas d'lment de liste vim" +msgid "E819: Blowfish test failed" +msgstr "E819: le test de blowfish a chou" # DB - TODO : Trouver une traduction valable et atteste pour "location". msgid "[Location List]" @@ -56,6 +64,9 @@ msgstr "" 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 dcharg" @@ -106,20 +117,18 @@ msgid "E88: Cannot go before first buffer" msgstr "E88: Impossible d'aller avant le premier tampon" #, c-format -msgid "" -"E89: No write since last change for buffer % (add ! to override)" +msgid "E89: No write since last change for buffer %ld (add ! to override)" msgstr "" -"E89: Le tampon % 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) msgid "W14: Warning: List of file names overflow" msgstr "W14: Alerte : La liste des noms de fichier dborde" # AB - Vu le code source, la version franaise est meilleure que la # version anglaise. Ce message est similaire au message E86. #, c-format -msgid "E92: Buffer % not found" -msgstr "E92: Le tampon % 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. #, c-format @@ -131,8 +140,8 @@ msgid "E94: No matching buffer for %s" msgstr "E94: Aucun tampon ne correspond %s" #, c-format -msgid "line %" -msgstr "ligne %" +msgid "line %ld" +msgstr "ligne %ld" msgid "E95: Buffer with this name already exists" msgstr "E95: Un tampon porte dj ce nom" @@ -163,14 +172,14 @@ msgid "1 line --%d%%--" msgstr "1 ligne --%d%%--" #, c-format -msgid "% lines --%d%%--" -msgstr "% lignes --%d%%--" +msgid "%ld lines --%d%%--" +msgstr "%ld lignes --%d%%--" # AB - Faut-il remplacer "sur" par "de" ? # DB - Mon avis : oui. #, c-format -msgid "line % of % --%d%%-- col " -msgstr "ligne % sur % --%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 @@ -223,6 +232,13 @@ msgstr "" msgid "Signs for %s:" msgstr "Symboles dans %s :" +#, c-format +msgid " line=%ld id=%d name=%s" +msgstr " ligne=%ld id=%d nom=%s" + +msgid "E902: Cannot connect to port" +msgstr "E902: Impossible de se connecter au port" + msgid "E901: gethostbyname() in channel_open()" msgstr "E901: gethostbyname() dans channel_open()" @@ -230,7 +246,7 @@ msgid "E898: socket() in channel_open()" msgstr "E898: socket() dans channel_open()" msgid "E903: received command with non-string argument" -msgstr "E903: commande reue avec une argument qui n'est pas une chane" +msgstr "E903: commande reue avec un argument qui n'est pas une chane" msgid "E904: last argument for expr/call must be a number" msgstr "E904: le dernier argument de expr/call doit tre un nombre" @@ -251,28 +267,72 @@ msgid "E631: %s(): write failed" msgstr "E631: %s() : erreur d'criture" #, c-format -msgid " line=% id=%d name=%s" -msgstr " ligne=% id=%d nom=%s" +msgid "E917: Cannot use a callback with %s()" +msgstr "E917: Impossible d'utiliser un callback avec %s()" -msgid "E545: Missing colon" -msgstr "E545: ':' manquant" +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 "E546: Illegal mode" -msgstr "E546: Mode non autoris" +msgid "E906: not an open channel" +msgstr "E906: pas un canal ouvert" -msgid "E548: digit expected" -msgstr "E548: chiffre attendu" +msgid "E920: _io file requires _name to be set" +msgstr "E920: fichier _io ncessite _name" -msgid "E549: Illegal percentage" -msgstr "E549: Pourcentage non autoris" +msgid "E915: in_io buffer requires in_buf or in_name to be set" +msgstr "E915: tampon in_io ncessite 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 mthode inconnue" + +msgid "Warning: Using a weak encryption method; see :help 'cm'" +msgstr "" +"Alerte : utilisation d'une mthode 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 cls ne correspondent pas !" + +msgid "[crypted]" +msgstr "[chiffr]" + +#, c-format +msgid "E720: Missing colon in Dictionary: %s" +msgstr "E720: Il manque ':' dans le Dictionnaire %s" + +#, c-format +msgid "E721: Duplicate key in Dictionary: \"%s\"" +msgstr "E721: Cl duplique 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 dj : %s" -# AB - Je n'ai pas trouv de traduction satisfaisante au verbe "diff". Comme -# Vim fait en pratique appel au programme "diff" pour evaluer les -# diffrences entre fichiers, "to diff" a t traduit par "utiliser diff" -# et d'autres expressions appropries. #, c-format -msgid "E96: Can not diff more than % buffers" -msgstr "E96: Impossible d'utiliser diff sur plus de % tampons" +msgid "E96: Cannot diff more than %ld buffers" +msgstr "E96: Impossible d'utiliser diff sur plus de %ld tampons" msgid "E810: Cannot read or write temp files" msgstr "E810: Impossible de lire ou crire des fichiers temporaires" @@ -281,6 +341,9 @@ msgstr "E810: Impossible de lire ou msgid "E97: Cannot create diffs" msgstr "E97: diff ne fonctionne pas" +msgid "Patch file" +msgstr "Fichier rustine" + msgid "E816: Cannot read patch output" msgstr "E816: Le fichier intermdiaire produit par patch n'a pu tre lu" @@ -459,13 +522,10 @@ msgstr "Correspondance %d sur %d" msgid "match %d" msgstr "Correspondance %d" +#. maximum nesting of lists and dicts msgid "E18: Unexpected characters in :let" msgstr "E18: Caractres inattendus avant '='" -#, c-format -msgid "E684: list index out of range: %" -msgstr "E684: index de Liste hors limites : % au-del de la fin" - #, c-format msgid "E121: Undefined variable: %s" msgstr "E121: Variable non dfinie : %s" @@ -473,45 +533,6 @@ msgstr "E121: Variable non d msgid "E111: Missing ']'" msgstr "E111: ']' manquant" -#, c-format -msgid "E686: Argument of %s must be a List" -msgstr "E686: L'argument de %s doit tre une Liste" - -#, c-format -msgid "E712: Argument of %s must be a List or Dictionary" -msgstr "E712: L'argument de %s doit tre une Liste ou un Dictionnaire" - -msgid "E713: Cannot use empty key for Dictionary" -msgstr "E713: Impossible d'utiliser une cl vide dans un Dictionnaire" - -msgid "E714: List required" -msgstr "E714: Liste requise" - -msgid "E715: Dictionary required" -msgstr "E715: Dictionnaire requis" - -msgid "E928: String required" -msgstr "E928: Chaine requis" - -# DB : Suggestion -#, c-format -msgid "E118: Too many arguments for function: %s" -msgstr "E118: La fonction %s a reu trop d'arguments" - -#, c-format -msgid "E716: Key not present in Dictionary: %s" -msgstr "E716: La cl %s n'existe pas dans le Dictionnaire" - -#, c-format -msgid "E122: Function %s already exists, add ! to replace it" -msgstr "E122: La fonction %s existe dj (ajoutez ! pour la remplacer)" - -msgid "E717: Dictionary entry already exists" -msgstr "E717: Une entre du Dictionnaire porte dj ce nom" - -msgid "E718: Funcref required" -msgstr "E718: Rfrence de fonction (Funcref) requise" - msgid "E719: Cannot use [:] with a Dictionary" msgstr "E719: Utilisation de [:] impossible avec un Dictionnaire" @@ -548,7 +569,7 @@ msgid "E708: [:] must come last" msgstr "E708: [:] ne peut tre spcifi qu'en dernier" msgid "E709: [:] requires a List value" -msgstr "E709: [:] n?cessite une Liste" +msgstr "E709: [:] ncessite une Liste" msgid "E710: List value has more items than target" msgstr "E710: La Liste a plus d'lments que la destination" @@ -574,8 +595,8 @@ msgstr "E109: Il manque ':' apr msgid "E691: Can only compare List with List" msgstr "E691: Une Liste ne peut tre compare qu'avec une Liste" -msgid "E692: Invalid operation for Lists" -msgstr "E692: Opration invalide avec les Listes" +msgid "E692: Invalid operation for List" +msgstr "E692: Opration invalide avec les Liste" msgid "E735: Can only compare Dictionary with Dictionary" msgstr "E735: Un Dictionnaire ne peut tre compar qu'avec un Dictionnaire" @@ -583,10 +604,6 @@ msgstr "E735: Un Dictionnaire ne peut msgid "E736: Invalid operation for Dictionary" msgstr "E736: Opration invalide avec les Dictionnaires" -# DB - todo : Traduction valable (et courte) pour Funcref ? -msgid "E693: Can only compare Funcref with Funcref" -msgstr "E693: Une Funcref ne peut tre compare qu' une Funcref" - msgid "E694: Invalid operation for Funcrefs" msgstr "E694: Opration invalide avec les Funcrefs" @@ -599,6 +616,9 @@ msgstr "E110: ')' manquant" 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 spciale" + # AB - La version franaise est meilleure que la version anglaise. #, c-format msgid "E112: Option name missing: %s" @@ -745,30 +765,39 @@ msgstr "E785: complete() n'est utilisable que dans le mode Insertion" # AB - Texte par dfaut du bouton de la bote de dialogue affiche par la # fonction confirm(). +#. +#. * Yes this is ugly, I don't particularly like it either. But doing it +#. * this way has the compelling advantage that translations need not to +#. * be touched at all. See below what 'ok' and 'ync' are used for. +#. msgid "&Ok" msgstr "&Ok" -msgid "extend() argument" -msgstr "argument de extend()" - -#, c-format -msgid "E737: Key already exists: %s" -msgstr "E737: un mappage existe dj pour %s" - -msgid "map() argument" -msgstr "argument de map()" - -msgid "filter() argument" -msgstr "argument de filter()" - #, c-format -msgid "+-%s%3ld lines: " -msgstr "+-%s%3ld lignes : " +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld ligne : " +msgstr[1] "+-%s%3ld lignes : " #, 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 bote de dialogue affiche par inputdialog(). +msgid "" +"&OK\n" +"&Cancel" +msgstr "" +"&Ok\n" +"&Annuler" + # AB - La version franaise est meilleure que la version anglaise. msgid "called inputrestore() more often than inputsave()" msgstr "inputrestore() a t appel plus de fois qu'inputsave()" @@ -779,6 +808,9 @@ msgstr "argument de insert()" msgid "E786: Range not allowed" msgstr "E786: Les plages ne sont pas autorises" +msgid "E916: not a valid job" +msgstr "E916: tche invalide" + msgid "E701: Invalid type for len()" msgstr "E701: Type invalide avec len()" @@ -795,6 +827,19 @@ msgstr "E727: D msgid "" msgstr "" +# AB - mon avis, la version anglaise est errone. +# DB : Vrifier +msgid "E240: No connection to Vim server" +msgstr "E240: Pas de connexion au serveur X" + +# AB - La version franaise 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 rponse du serveur" + msgid "remove() argument" msgstr "argument de remove()" @@ -804,6 +849,10 @@ msgstr "E655: Trop de liens symboliques (cycle ?)" msgid "reverse() argument" msgstr "argument de reverse()" +# AB - La version franaise est meilleure que la version anglaise. +msgid "E258: Unable to send to client" +msgstr "E258: La rponse n'a pas pu tre envoye au client" + #, c-format msgid "E927: Invalid action: '%s'" msgstr "E927: Action invalide : %s " @@ -811,290 +860,140 @@ msgstr "E927: Action invalide : msgid "sort() argument" msgstr "argument de sort()" -#, fuzzy -#~ msgid "uniq() argument" -#~ msgstr "argument de add()" +msgid "uniq() argument" +msgstr "argument de uniq()" msgid "E702: Sort compare function failed" msgstr "E702: La fonction de comparaison de sort() a chou" -#, fuzzy -#~ msgid "E882: Uniq compare function failed" -#~ msgstr "E702: La fonction de comparaison de sort() a chou" +msgid "E882: Uniq compare function failed" +msgstr "E882: La fonction de comparaison de uniq() a chou" msgid "(Invalid)" msgstr "(Invalide)" +#, c-format +msgid "E935: invalid submatch number: %d" +msgstr "E935: numro de submatch invalide : %d" + msgid "E677: Error writing temp file" msgstr "E677: Erreur lors de l'criture du fichier temporaire" -msgid "E805: Using a Float as a Number" -msgstr "E805: Utilisation d'un Flottant comme un Nombre" - -msgid "E703: Using a Funcref as a Number" -msgstr "E703: Utilisation d'une Funcref comme un Nombre" +msgid "E921: Invalid callback argument" +msgstr "E921: Argument de callback invalide" -msgid "E745: Using a List as a Number" -msgstr "E745: Utilisation d'une Liste comme un Nombre" +#, c-format +msgid "<%s>%s%s %d, Hex %02x, Octal %03o" +msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o" -msgid "E728: Using a Dictionary as a Number" -msgstr "E728: Utilisation d'un Dictionnaire comme un Nombre" +#, c-format +msgid "> %d, Hex %04x, Octal %o" +msgstr "> %d, Hexa %04x, Octal %o" -msgid "E729: using Funcref as a String" -msgstr "E729: Utilisation d'une Funcref comme une Chane" +#, c-format +msgid "> %d, Hex %08x, Octal %o" +msgstr "> %d, Hexa %08x, Octal %o" -msgid "E730: using List as a String" -msgstr "E730: Utilisation d'une Liste comme une Chane" +# AB - La version anglaise est trs mauvaise, ce qui m'oblige a inventer une +# version franaise. +msgid "E134: Move lines into themselves" +msgstr "E134: La destination est dans la plage d'origine" -msgid "E731: using Dictionary as a String" -msgstr "E731: Utilisation d'un Dictionnaire comme une Chane" +msgid "1 line moved" +msgstr "1 ligne dplace" -# DB : On doit pouvoir trouver nettement mieux que a. #, c-format -msgid "E706: Variable type mismatch for: %s" -msgstr "E706: Type de variable incohrent pour %s" +msgid "%ld lines moved" +msgstr "%ld lignes dplaces" #, c-format -msgid "E795: Cannot delete variable %s" -msgstr "E795: Impossible de supprimer la variable %s" +msgid "%ld lines filtered" +msgstr "%ld lignes filtres" -#, 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" +# AB - J'ai volontairement omis l'astrisque initiale car je pense que le +# motif "Filter*" dcrit plus clairement les quatre autocommandes lies +# au filtrage (FilterReadPre, FilterReadPost, FilterWritePre et +# FilterWritePost) que "*Filter*" que l'on confond avec une tentative de +# mise en valeur. +msgid "E135: *Filter* Autocommands must not change current buffer" +msgstr "" +"E135: Les autocommandes Filter* ne doivent pas changer le tampon courant" -#, 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" +# AB - Il faut respecter l'esprit plus que la lettre. Dans le cas prsent, +# nettement plus. +msgid "[No write since last change]\n" +msgstr "[Attention : tout n'est pas enregistr]\n" +# AB - Le numro et le message d'erreur (%s ci-dessous) et le "numro" de ligne +# sont des chanes de caractres dont le contenu est la discrtion de +# l'appelant de la fonction viminfo_error(). #, c-format -msgid "E741: Value is locked: %s" -msgstr "E741: La valeur de %s est verrouille" +msgid "%sviminfo: %s in line: " +msgstr "%sviminfo : %s la ligne " -msgid "Unknown" -msgstr "Inconnu" +# AB - La version franaise est meilleure que la version anglaise. +msgid "E136: viminfo: Too many errors, skipping rest of file" +msgstr "" +"E136: Il y a trop d'erreurs ; interruption de la lecture du fichier viminfo" +# AB - Ce texte fait partie d'un message de dbogage. +# DB - ... dont les valeurs possibles sont les messages +# qui suivent. #, c-format -msgid "E742: Cannot change value of %s" -msgstr "E742: Impossible de modifier la valeur de %s" +msgid "Reading viminfo file \"%s\"%s%s%s" +msgstr "Lecture du fichier viminfo \"%s\"%s%s%s" -msgid "E698: variable nested too deep for making a copy" -msgstr "E698: variable trop imbrique pour en faire une copie" +# AB - Ce texte fait partie d'un message de dbogage. +# DB - Voir ci-dessus. +msgid " info" +msgstr " info" -#, c-format -msgid "E123: Undefined function: %s" -msgstr "E123: Fonction non dfinie : %s" +# AB - Ce texte fait partie d'un message de dbogage. +# DB - Voir ci-dessus. +msgid " marks" +msgstr " marques" -# AB - La version franaise est plus consistante que la version anglaise. -# AB - Je suis partag entre la concision d'une traduction assez littrale et -# la lourdeur d'une traduction plus correcte. -#, c-format -msgid "E124: Missing '(': %s" -msgstr "E124: Il manque '(' aprs %s" +msgid " oldfiles" +msgstr " vieux fichiers" -msgid "E862: Cannot use g: here" -msgstr "E862: Impossible d'utiliser g: ici" +# AB - Ce texte fait partie d'un message de dbogage. +# DB - Voir ci-dessus. +msgid " FAILED" +msgstr " CHEC" +# AB - J'espre que la plupart des utilisateurs aura l'ide d'aller vrifier +# ses droits d'accs. +# AB - Le mot "viminfo" a t retir pour que le message ne dpasse pas 80 +# caractres dans le cas courant o %s = /home/12345678/.viminfo +#. avoid a wait_return for this message, it's annoying #, c-format -msgid "E125: Illegal argument: %s" -msgstr "E125: Argument invalide : %s" +msgid "E137: Viminfo file is not writable: %s" +msgstr "E137: L'criture dans le fichier %s est interdite" #, c-format -msgid "E853: Duplicate argument name: %s" -msgstr "E853: Nom d'argument dupliqu : %s" - -msgid "E126: Missing :endfunction" -msgstr "E126: Il manque :endfunction" +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 dpasse pas 80 +# caractres dans le cas courant o %s = /home/12345678/.viminfo #, c-format -msgid "E707: Function name conflicts with variable: %s" -msgstr "E707: Le nom de fonction entre en conflit avec la variable : %s" +msgid "E138: Can't write viminfo file %s!" +msgstr "E138: Impossible d'crire le fichier %s" +# AB - Ce texte est un message de dbogage. #, c-format -msgid "E127: Cannot redefine function %s: It is in use" -msgstr "E127: Impossible de redfinir fonction %s : dj utilise" +msgid "Writing viminfo file \"%s\"" +msgstr "criture du fichier viminfo \"%s\"" -# DB - Le contenu du "c-format" est le nom de la fonction. #, c-format -msgid "E746: Function name does not match script file name: %s" -msgstr "E746: Le nom de la fonction %s ne correspond pas le nom du script" +msgid "E886: Can't rename viminfo file to %s!" +msgstr "E886: Impossible de renommer viminfo en %s" -msgid "E129: Function name required" -msgstr "E129: Nom de fonction requis" - -#, 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 ':'" - -#, 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 crer une version franaise qui fasse moins de 80 -# caractres de long, nom de la fonction compris : "It is in use" est une -# expression trs dense. Traductions possibles : "elle est utilise", -# "elle s'excute" ou "elle est occupe". -#, c-format -msgid "E131: Cannot delete function %s: It is in use" -msgstr "E131: Impossible d'effacer %s : cette fonction est utilise" - -# AB - Vrifier dans la littrature 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 suprieure 'maxfuncdepth'" - -# AB - Ce texte fait partie d'un message de dbogage. -#, c-format -msgid "calling %s" -msgstr "appel de %s" - -# AB - Vrifier. -#, c-format -msgid "%s aborted" -msgstr "%s annule" - -# AB - Ce texte fait partie d'un message de dbogage. -#, c-format -msgid "%s returning #%" -msgstr "%s a retourn #%" - -# AB - Ce texte fait partie d'un message de dbogage. -#, c-format -msgid "%s returning %s" -msgstr "%s a retourn \"%s\"" - -# AB - Ce texte fait partie d'un message de dbogage. -#, c-format -msgid "continuing in %s" -msgstr "de retour dans %s" - -msgid "E133: :return not inside a function" -msgstr "E133: :return en dehors d'une fonction" - -# AB - La version franaise est capitalise pour tre en accord avec les autres -# commentaires enregistrs dans le fichier viminfo. -msgid "" -"\n" -"# global variables:\n" -msgstr "" -"\n" -"# Variables globales:\n" - -# DB - Plus prcis ("la dernire fois") ? -msgid "" -"\n" -"\tLast set from " -msgstr "" -"\n" -"\tModifi la dernire fois dans " - -msgid "No old files" -msgstr "Aucun vieux fichier" - -#, c-format -msgid "<%s>%s%s %d, Hex %02x, Octal %03o" -msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o" - -#, c-format -msgid "> %d, Hex %04x, Octal %o" -msgstr "> %d, Hexa %04x, Octal %o" - -#, c-format -msgid "> %d, Hex %08x, Octal %o" -msgstr "> %d, Hexa %08x, Octal %o" - -# AB - La version anglaise est trs mauvaise, ce qui m'oblige a inventer une -# version franaise. -msgid "E134: Move lines into themselves" -msgstr "E134: La destination est dans la plage d'origine" - -msgid "1 line moved" -msgstr "1 ligne dplace" - -#, c-format -msgid "% lines moved" -msgstr "% lignes dplaces" - -#, c-format -msgid "% lines filtered" -msgstr "% lignes filtres" - -# AB - J'ai volontairement omis l'astrisque initiale car je pense que le -# motif "Filter*" dcrit plus clairement les quatre autocommandes lies -# au filtrage (FilterReadPre, FilterReadPost, FilterWritePre et -# FilterWritePost) que "*Filter*" que l'on confond avec une tentative de -# mise en valeur. -msgid "E135: *Filter* Autocommands must not change current buffer" -msgstr "" -"E135: Les autocommandes Filter* ne doivent pas changer le tampon courant" - -# AB - Il faut respecter l'esprit plus que la lettre. Dans le cas prsent, -# nettement plus. -msgid "[No write since last change]\n" -msgstr "[Attention : tout n'est pas enregistr]\n" - -# AB - Le numro et le message d'erreur (%s ci-dessous) et le "numro" de ligne -# sont des chanes de caractres dont le contenu est la discrtion de -# l'appelant de la fonction viminfo_error(). -#, c-format -msgid "%sviminfo: %s in line: " -msgstr "%sviminfo : %s la ligne " - -# AB - La version franaise est meilleure que la version anglaise. -msgid "E136: viminfo: Too many errors, skipping rest of file" -msgstr "" -"E136: Il y a trop d'erreurs ; interruption de la lecture du fichier viminfo" - -# AB - Ce texte fait partie d'un message de dbogage. -# DB - ... dont les valeurs possibles sont les messages -# qui suivent. -#, c-format -msgid "Reading viminfo file \"%s\"%s%s%s" -msgstr "Lecture du fichier viminfo \"%s\"%s%s%s" - -# AB - Ce texte fait partie d'un message de dbogage. -# DB - Voir ci-dessus. -msgid " info" -msgstr " info" - -# AB - Ce texte fait partie d'un message de dbogage. -# DB - Voir ci-dessus. -msgid " marks" -msgstr " marques" - -msgid " oldfiles" -msgstr " vieux fichiers" - -# AB - Ce texte fait partie d'un message de dbogage. -# DB - Voir ci-dessus. -msgid " FAILED" -msgstr " CHEC" - -# AB - J'espre que la plupart des utilisateurs aura l'ide d'aller vrifier -# ses droits d'accs. -# AB - Le mot "viminfo" a t retir pour que le message ne dpasse pas 80 -# caractres dans le cas courant o %s = /home/12345678/.viminfo -#. avoid a wait_return for this message, it's annoying -#, c-format -msgid "E137: Viminfo file is not writable: %s" -msgstr "E137: L'criture dans le fichier %s est interdite" - -# AB - Le point d'exclamation est superflu. -# AB - Le mot "viminfo" a t retir pour que le message ne dpasse pas 80 -# caractres dans le cas courant o %s = /home/12345678/.viminfo -#, c-format -msgid "E138: Can't write viminfo file %s!" -msgstr "E138: Impossible d'crire le fichier %s" - -# AB - Ce texte est un message de dbogage. -#, c-format -msgid "Writing viminfo file \"%s\"" -msgstr "criture du fichier viminfo \"%s\"" - -#. Write the info: -#, c-format -msgid "# This viminfo file was generated by Vim %s.\n" -msgstr "# Ce fichier viminfo a t gnr par Vim %s.\n" +#. Write the info: +#, c-format +msgid "# This viminfo file was generated by Vim %s.\n" +msgstr "# Ce fichier viminfo a t gnr par Vim %s.\n" # AB - Les deux versions, bien que diffrentes, se valent. msgid "" @@ -1112,6 +1011,19 @@ msgstr "# 'encoding' dans lequel ce fichier a msgid "Illegal starting char" msgstr "Caractre initial non valide" +msgid "" +"\n" +"# Bar lines, copied verbatim:\n" +msgstr "" +"\n" +"# Lignes commenant par |, copies littralement :\n" + +# AB - Ceci est un titre de bote de dialogue. Vrifier que la version +# franaise est correcte pour les trois rfrences ; j'ai un doute quant +# la troisime. +msgid "Save As" +msgstr "Enregistrer sous - Vim" + # AB - Ceci est un contenu de bote de dialogue (ventuellement en mode texte). # AB - La version franaise est meilleure que la version anglaise. msgid "Write partial file?" @@ -1136,8 +1048,8 @@ msgid "E768: Swap file exists: %s (:silent! overrides)" msgstr "E768: Le fichier d'change %s existe dj (:silent! pour passer outre)" #, c-format -msgid "E141: No file name for buffer %" -msgstr "E141: Pas de nom de fichier pour le tampon %" +msgid "E141: No file name for buffer %ld" +msgstr "E141: Pas de nom de fichier pour le tampon %ld" # AB - Il faut respecter l'esprit plus que la lettre. msgid "E142: File not written: Writing is disabled by 'write' option" @@ -1168,6 +1080,10 @@ msgstr "" 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 bote de dialogue. +msgid "Edit File" +msgstr "Ouvrir un fichier - Vim" + # AB - Il faut respecter l'esprit plus que la lettre. # AB - J'hsite ajouter " sa cration" aprs le nom du tampon. Ce message # devrait n'tre affich qu'aprs une tentative d'ouverture de fichier, @@ -1205,19 +1121,19 @@ msgid "1 substitution" msgstr "1 substitution" #, c-format -msgid "% matches" -msgstr "% correspondances" +msgid "%ld matches" +msgstr "%ld correspondances" #, c-format -msgid "% substitutions" -msgstr "% substitutions" +msgid "%ld substitutions" +msgstr "%ld substitutions" msgid " on 1 line" msgstr " sur 1 ligne" #, c-format -msgid " on % lines" -msgstr " sur % 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 rfrence :vglobal. @@ -1270,10 +1186,6 @@ msgstr "E149: D msgid "Sorry, help file \"%s\" not found" msgstr "Dsol, le fichier d'aide \"%s\" est introuvable" -#, c-format -msgid "E150: Not a directory: %s" -msgstr "E150: %s n'est pas un rpertoire" - #, c-format msgid "E151: No match: %s" msgstr "E151: Aucune correspondance : %s" @@ -1299,6 +1211,10 @@ msgstr "E670: Encodages diff 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 rpertoire" + # AB - Il faut respecter l'esprit plus que la lettre. #, c-format msgid "E160: Unknown sign command: %s" @@ -1337,8 +1253,15 @@ msgstr "E934: Impossible de sauter # AB - Vu le code source, la version franaise est meilleure que la # version anglaise. #, c-format -msgid "E157: Invalid sign ID: %" -msgstr "E157: Le symbole % 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)" msgid " (not supported)" msgstr " (non support)" @@ -1355,16 +1278,23 @@ msgid "Entering Debug mode. Type \"cont\" to continue." msgstr "Mode dbogage activ. Tapez \"cont\" pour continuer." #, c-format -msgid "line %: %s" -msgstr "ligne % : %s" +msgid "line %ld: %s" +msgstr "ligne %ld : %s" #, c-format msgid "cmd: %s" msgstr "cmde : %s" +msgid "frame is zero" +msgstr "le cadre de pile est zro" + #, c-format -msgid "Breakpoint in \"%s%s\" line %" -msgstr "Point d'arrt dans %s%s ligne %" +msgid "frame at highest level: %d" +msgstr "cadre de pile au niveau le plus haut : %d" + +#, c-format +msgid "Breakpoint in \"%s%s\" line %ld" +msgstr "Point d'arrt dans %s%s ligne %ld" #, c-format msgid "E161: Breakpoint not found: %s" @@ -1376,8 +1306,8 @@ msgstr "Aucun point d'arr # AB - Le deuxime %s est remplac par "func" ou "file" sans que l'on puisse # traduire ces mots. #, c-format -msgid "%3d %s %s line %" -msgstr "%3d %s %s ligne %" +msgid "%3d %s %s line %ld" +msgstr "%3d %s %s ligne %ld" msgid "E750: First use \":profile start {fname}\"" msgstr "E750: Utilisez d'abord \":profile start {nomfichier}\"" @@ -1427,6 +1357,9 @@ msgstr "Recherche de \"%s\"" msgid "not found in '%s': \"%s\"" msgstr "introuvable dans '%s' : \"%s\"" +msgid "Source Vim script" +msgstr "Sourcer un script - Vim" + #, c-format msgid "Cannot source a directory: \"%s\"" msgstr "Impossible de sourcer un rpertoire : \"%s\"" @@ -1436,16 +1369,16 @@ msgid "could not source \"%s\"" msgstr "impossible de sourcer \"%s\"" #, c-format -msgid "line %: could not source \"%s\"" -msgstr "ligne % : impossible de sourcer \"%s\"" +msgid "line %ld: could not source \"%s\"" +msgstr "ligne %ld : impossible de sourcer \"%s\"" #, c-format msgid "sourcing \"%s\"" msgstr "sourcement \"%s\"" #, c-format -msgid "line %: sourcing \"%s\"" -msgstr "ligne % : sourcement de \"%s\"" +msgid "line %ld: sourcing \"%s\"" +msgstr "ligne %ld : sourcement de \"%s\"" #, c-format msgid "finished sourcing %s" @@ -1490,8 +1423,6 @@ msgstr "Langue courante pour %s : \"%s\"" 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 msgid "Entering Ex mode. Type \"visual\" to go to Normal mode." msgstr "Mode Ex activ. Tapez \"visual\" pour passer en mode Normal." @@ -1523,12 +1454,10 @@ msgstr "E493: La plage sp msgid "Backwards range given, OK to swap" msgstr "La plage spcifie est inverse, OK pour l'inverser" -#. append -#. typed wrong msgid "E494: Use w or w>>" msgstr "E494: Utilisez w ou w>>" -msgid "E319: The command is not available in this version" +msgid "E319: Sorry, the command is not available in this version" msgstr "E319: Dsol, cette commande n'est pas disponible dans cette version" msgid "E172: Only one file name allowed" @@ -1545,8 +1474,8 @@ msgid "E173: 1 more file to edit" msgstr "E173: encore 1 fichier diter" #, c-format -msgid "E173: % more files to edit" -msgstr "E173: encore % fichiers diter" +msgid "E173: %ld more files to edit" +msgstr "E173: encore %ld fichiers diter" msgid "E174: Command already exists: add ! to replace it" msgstr "E174: La commande existe dj : ajoutez ! pour la redfinir" @@ -1609,7 +1538,10 @@ msgid "E468: Completion argument only allowed for custom completion" msgstr "E468: Seul le compltement personnalis accepte un argument" msgid "E467: Custom completion requires a function argument" -msgstr "E467: Le compltement personnalis requiert une fonction en argument" +msgstr "E467: Le compltement personnalis ncessite une fonction en argument" + +msgid "unknown" +msgstr "inconnu" #, c-format msgid "E185: Cannot find color scheme '%s'" @@ -1624,6 +1556,9 @@ msgstr "E784: Impossible de fermer le dernier onglet" msgid "Already only one tab page" msgstr "Il ne reste dj plus qu'un seul onglet" +msgid "Edit File in new window" +msgstr "Ouvrir un fichier dans une nouvelle fentre - Vim" + #, c-format msgid "Tab page %d" msgstr "Onglet %d" @@ -1631,6 +1566,9 @@ msgstr "Onglet %d" msgid "No swap file" msgstr "Pas de fichier d'change" +msgid "Append File" +msgstr "Ajouter fichier" + msgid "E747: Cannot change directory, buffer is modified (add ! to override)" msgstr "" "E747: Tampon modifi : impossible de changer de rpertoire (ajoutez ! pour " @@ -1643,7 +1581,11 @@ msgid "E187: Unknown" msgstr "E187: Inconnu" msgid "E465: :winsize requires two number arguments" -msgstr "E465: :winsize requiert deux arguments numriques" +msgstr "E465: :winsize ncessite deux arguments numriques" + +#, c-format +msgid "Window position: X %d, Y %d" +msgstr "Position de la fentre : X %d, Y %d" # DB : Suggestion, sans doute perfectible. msgid "E188: Obtaining window position not implemented for this platform" @@ -1651,7 +1593,22 @@ msgstr "" "E188: Rcuprer la position de la fentre non implment dans cette version" msgid "E466: :winpos requires two number arguments" -msgstr "E466: :winpos requiert deux arguments numriques" +msgstr "E466: :winpos ncessite deux arguments numriques" + +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 rglages - Vim" #, c-format msgid "E739: Cannot create directory: %s" @@ -1672,6 +1629,9 @@ msgstr "E191: L'argument doit msgid "E192: Recursive use of :normal too deep" msgstr "E192: Appel rcursif de :normal trop important" +msgid "E809: #< is not available without the +eval feature" +msgstr "E809: #< n'est pas disponible sans la fonctionnalit +eval" + msgid "E194: No alternate file name to substitute for '#'" msgstr "E194: Aucun nom de fichier alternatif substituer '#'" @@ -1690,7 +1650,7 @@ msgstr "E498: Aucun nom de fichier :source msgid "E842: no line number to use for \"\"" msgstr "E842: aucun numro de ligne utiliser pour \"\"" -#, 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\"" @@ -1700,6 +1660,9 @@ msgstr "E500: msgid "E195: Cannot open viminfo file for reading" msgstr "E195: Impossible d'ouvrir le viminfo en lecture" +msgid "E196: No digraphs in this version" +msgstr "E196: Pas de digraphes dans cette version" + msgid "E608: Cannot :throw exceptions with 'Vim' prefix" msgstr "E608: Impossible d'mettre des exceptions avec 'Vim' comme prfixe" @@ -1717,8 +1680,8 @@ msgid "Exception discarded: %s" msgstr "Exception limine : %s" #, c-format -msgid "%s, line %" -msgstr "%s, ligne %" +msgid "%s, line %ld" +msgstr "%s, ligne %ld" #. always scroll up, don't overwrite #, c-format @@ -1858,33 +1821,6 @@ msgstr "E198: cmd_pchar au-del msgid "E199: Active window or buffer deleted" msgstr "E199: Fentre ou tampon actif effac" -msgid "E854: path too long for completion" -msgstr "E854: chemin trop long pour compltement" - -#, 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: Rpertoire \"%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 rpertoire \"%s\" dans 'cdpath'" - -#, c-format -msgid "E347: No more file \"%s\" found in path" -msgstr "E347: Plus de fichier \"%s\" dans 'path'" - msgid "E812: Autocommands changed buffer or buffer name" msgstr "E812: Des autocommandes ont chang le tampon ou le nom du tampon" @@ -1897,6 +1833,9 @@ msgstr "est un r msgid "is not a file" msgstr "n'est pas un fichier" +msgid "is a device (disabled with 'opendevice' option)" +msgstr "est un priphrique (dsactiv par l'option 'opendevice')" + msgid "[New File]" msgstr "[Nouveau fichier]" @@ -1917,26 +1856,25 @@ msgstr "" "E201: Autocommandes *ReadPre ne doivent pas modifier le contenu du tampon " "courant" -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! msgid "E202: Conversion made file unreadable!" msgstr "E202: La conversion a rendu le fichier illisible !" -#. fifo or socket msgid "[fifo/socket]" msgstr "[fifo/socket]" -#. fifo msgid "[fifo]" msgstr "[fifo]" -#. or socket msgid "[socket]" msgstr "[socket]" -#. or character special msgid "[character special]" msgstr "[caractre spcial]" @@ -1953,12 +1891,12 @@ msgid "[converted]" msgstr "[converti]" #, c-format -msgid "[CONVERSION ERROR in line %]" -msgstr "[ERREUR DE CONVERSION la ligne %]" +msgid "[CONVERSION ERROR in line %ld]" +msgstr "[ERREUR DE CONVERSION la ligne %ld]" #, c-format -msgid "[ILLEGAL BYTE in line %]" -msgstr "[OCTET INVALIDE la ligne %]" +msgid "[ILLEGAL BYTE in line %ld]" +msgstr "[OCTET INVALIDE la ligne %ld]" msgid "[READ ERRORS]" msgstr "[ERREURS DE LECTURE]" @@ -1983,9 +1921,18 @@ msgid "E204: Autocommand changed number of lines in unexpected way" msgstr "" "E204: L'autocommande a modifi le nombre de lignes de manire inattendue" +msgid "NetBeans disallows writes of unmodified buffers" +msgstr "NetBeans interdit l'criture des tampons non modifis" + +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 priphrique inscriptible" +msgid "writing to device disabled with 'opendevice' option" +msgstr "criture vers un priphrique dsactiv par l'option 'opendevice'" + msgid "is read-only (add ! to override)" msgstr "est en lecture seule (ajoutez ! pour passer outre)" @@ -2008,7 +1955,10 @@ msgid "E510: Can't make backup file (add ! to override)" msgstr "" "E510: Impossible de gnrer la copie de secours (ajoutez ! pour passer outre)" -#. Can't write without a tempfile! +msgid "E460: The resource fork would be lost (add ! to override)" +msgstr "" +"E460: Les ressources partages seraient perdues (ajoutez ! pour passer outre)" + msgid "E214: Can't find temp file for writing" msgstr "E214: Impossible de gnrer un fichier temporaire pour y crire" @@ -2033,11 +1983,11 @@ msgstr "" #, c-format msgid "" -"E513: write error, conversion failed in line % (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 % (videz " -"'fenc' pour passer outre)" +"E513: Erreur d'criture, chec de conversion la ligne %ld (videz 'fenc' " +"pour passer outre)" msgid "E514: write error (file system full?)" msgstr "E514: erreur d'criture (systme de fichiers plein ?)" @@ -2046,8 +1996,8 @@ msgid " CONVERSION ERROR" msgstr " ERREUR DE CONVERSION" #, c-format -msgid " in line %;" -msgstr " la ligne %" +msgid " in line %ld;" +msgstr " la ligne %ld" msgid "[Device]" msgstr "[Priph.]" @@ -2111,15 +2061,15 @@ msgid "1 line, " msgstr "1 ligne, " #, c-format -msgid "% lines, " -msgstr "% lignes, " +msgid "%ld lines, " +msgstr "%ld lignes, " msgid "1 character" msgstr "1 caractre" #, c-format -msgid "% characters" -msgstr "% caractres" +msgid "%lld characters" +msgstr "%lld caractres" msgid "[noeol]" msgstr "[noeol]" @@ -2204,6 +2154,9 @@ msgstr "E462: Impossible de pr msgid "E321: Could not reload \"%s\"" msgstr "E321: Impossible de recharger \"%s\"" +msgid "--Deleted--" +msgstr "--Effac--" + #, c-format msgid "auto-removing autocommand: %s " msgstr "Autocommandes marques pour auto-suppression : %s " @@ -2213,12 +2166,12 @@ msgstr "Autocommandes marqu msgid "E367: No such group: \"%s\"" msgstr "E367: Aucun groupe \"%s\"" +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" -msgid "--Deleted--" -msgstr "--Effac--" - #, c-format msgid "E215: Illegal character after *: %s" msgstr "E215: Caractre non valide aprs * : %s" @@ -2286,7 +2239,6 @@ msgid_plural "+--%3ld lines folded " msgstr[0] "+--%3ld ligne replie " msgstr[1] "+--%3ld lignes replies " -#. buffer has already been read msgid "E222: Add to read buffer" msgstr "E222: Ajout au tampon de lecture" @@ -2318,333 +2270,308 @@ msgstr "Aucun mappage trouv 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 -msgid "--No lines in buffer--" -msgstr "--Le tampon est vide--" +msgid "E851: Failed to create a new process for the GUI" +msgstr "" +"E851: chec lors de la cration d'un nouveau processus pour l'interface " +"graphique" -#. -#. * 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 annule" +msgid "E852: The child process failed to start the GUI" +msgstr "" +"E852: Le processus fils n'a pas russi dmarrer l'interface graphique" -msgid "E471: Argument required" -msgstr "E471: Argument requis" +msgid "E229: Cannot start the GUI" +msgstr "E229: Impossible de dmarrer l'interface graphique" -msgid "E10: \\ should be followed by /, ? or &" -msgstr "E10: \\ devrait tre suivi de /, ? ou &" - -msgid "E11: Invalid in command-line window; executes, CTRL-C quits" -msgstr "" -"E11: Invalide dans la fentre ligne-de-commande ; excute, CTRL-C quitte" +#, c-format +msgid "E230: Cannot read from \"%s\"" +msgstr "E230: Impossible de lire \"%s\"" -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: commande non autorise depuis un exrc/vimrc dans rpertoire courant ou " -"une recherche de marqueur" - -msgid "E171: Missing :endif" -msgstr "E171: :endif manquant" - -msgid "E600: Missing :endtry" -msgstr "E600: :endtry manquant" - -msgid "E170: Missing :endwhile" -msgstr "E170: :endwhile manquant" - -msgid "E170: Missing :endfor" -msgstr "E170: :endfor manquant" - -msgid "E588: :endwhile without :while" -msgstr "E588: :endwhile sans :while" - -msgid "E588: :endfor without :for" -msgstr "E588: :endfor sans :for" - -msgid "E13: File exists (add ! to override)" -msgstr "E13: Le fichier existe dj (ajoutez ! pour passer outre)" - -msgid "E472: Command failed" -msgstr "E472: La commande a chou" - -msgid "E473: Internal error" -msgstr "E473: Erreur interne" - -msgid "Interrupted" -msgstr "Interrompu" - -msgid "E14: Invalid address" -msgstr "E14: Adresse invalide" +"E665: Impossible de dmarrer l'IHM graphique, aucune police valide trouve" -msgid "E474: Invalid argument" -msgstr "E474: Argument invalide" +msgid "E231: 'guifontwide' invalid" +msgstr "E231: 'guifontwide' est invalide" -#, 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" #, 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" -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" -msgid "E476: Invalid command" -msgstr "E476: Commande invalide" +msgid " " +msgstr " " #, c-format -msgid "E17: \"%s\" is a directory" -msgstr "E17: \"%s\" est un rpertoire" +msgid "E616: vim_SelFile: can't get font %s" +msgstr "E616: vim_SelFile : impossible d'obtenir la police %s" -#, fuzzy -#~ msgid "E900: Invalid job id" -#~ msgstr "E49: Valeur de dfilement invalide" +msgid "E614: vim_SelFile: can't return to current directory" +msgstr "E614: vim_SelFile : impossible de revenir dans le rpertoire courant" -#~ msgid "E901: Job table is full" -#~ msgstr "" +msgid "Pathname:" +msgstr "Chemin :" -#, c-format -msgid "E364: Library call failed for \"%s()\"" -msgstr "E364: L'appel la bibliothque a chou pour \"%s()\"" +msgid "E615: vim_SelFile: can't get current directory" +msgstr "E615: vim_SelFile : impossible d'obtenir le rpertoire courant" -msgid "E19: Mark has invalid line number" -msgstr "E19: La marque a un numro de ligne invalide" +msgid "OK" +msgstr "Ok" -msgid "E20: Mark not set" -msgstr "E20: Marque non positionne" +msgid "Cancel" +msgstr "Annuler" -msgid "E21: Cannot make changes, 'modifiable' is off" -msgstr "E21: Impossible de modifier, 'modifiable' est dsactiv" +msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." +msgstr "Widget scrollbar : Impossible d'obtenir la gomtrie du pixmap 'thumb'" -msgid "E22: Scripts nested too deep" -msgstr "E22: Trop de rcursion dans les scripts" +msgid "Vim dialog" +msgstr "Vim" -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 crer un BalloonEval avec message ET callback" -msgid "E24: No such abbreviation" -msgstr "E24: Cette abrviation n'existe pas" +msgid "_Cancel" +msgstr "_Annuler" -msgid "E477: No ! allowed" -msgstr "E477: Le ! n'est pas autoris" +msgid "_Save" +msgstr "_Enregistrer" -msgid "E25: Nvim does not have a built-in GUI" -msgstr "E25: L'interface graphique n'a pas t compile dans cette version" +msgid "_Open" +msgstr "_Ouvrir" -#, c-format -msgid "E28: No such highlight group name: %s" -msgstr "E28: Aucun nom de groupe de surbrillance %s" +msgid "_OK" +msgstr "_Ok" -msgid "E29: No inserted text yet" -msgstr "E29: Pas encore de texte insr" +msgid "" +"&Yes\n" +"&No\n" +"&Cancel" +msgstr "" +"&Oui\n" +"&Non\n" +"&Annuler" -msgid "E30: No previous command line" -msgstr "E30: Aucune ligne de commande prcdente" +msgid "Yes" +msgstr "Oui" -msgid "E31: No such mapping" -msgstr "E31: Mappage inexistant" +msgid "No" +msgstr "Non" -msgid "E479: No match" -msgstr "E479: Aucune correspondance" +# todo '_' is for hotkey, i guess? +msgid "Input _Methods" +msgstr "_Mthodes de saisie" -#, c-format -msgid "E480: No match: %s" -msgstr "E480: Aucune correspondance : %s" +msgid "VIM - Search and Replace..." +msgstr "Remplacer - Vim" -msgid "E32: No file name" -msgstr "E32: Aucun nom de fichier" +msgid "VIM - Search..." +msgstr "Rechercher - Vim" -msgid "E33: No previous substitute regular expression" -msgstr "E33: Aucune expression rgulire de substitution prcdente" +msgid "Find what:" +msgstr "Rechercher :" -msgid "E34: No previous command" -msgstr "E34: Aucune commande prcdente" +msgid "Replace with:" +msgstr "Remplacer par :" -msgid "E35: No previous regular expression" -msgstr "E35: Aucune expression rgulire prcdente" +#. whole word only button +msgid "Match whole word only" +msgstr "Mots entiers seulement" -msgid "E481: No range allowed" -msgstr "E481: Les plages ne sont pas autorises" +#. match case button +msgid "Match case" +msgstr "Respecter la casse" -msgid "E36: Not enough room" -msgstr "E36: Pas assez de place" +msgid "Direction" +msgstr "Direction" -#, c-format -msgid "E482: Can't create file %s" -msgstr "E482: Impossible de crer le fichier %s" +#. 'Up' and 'Down' buttons +msgid "Up" +msgstr "Haut" -msgid "E483: Can't get temp file name" -msgstr "E483: Impossible d'obtenir un nom de fichier temporaire" +msgid "Down" +msgstr "Bas" -#, c-format -msgid "E484: Can't open file %s" -msgstr "E484: Impossible d'ouvrir le fichier \"%s\"" +msgid "Find Next" +msgstr "Suivant" -#, c-format -msgid "E485: Can't read file %s" -msgstr "E485: Impossible de lire le fichier %s" +msgid "Replace" +msgstr "Remplacer" -msgid "E37: No write since last change (add ! to override)" -msgstr "E37: Modifications non enregistres (ajoutez ! pour passer outre)" +msgid "Replace All" +msgstr "Remplacer tout" -# AB - Il faut respecter l'esprit plus que la lettre. Dans le cas prsent, -# nettement plus. -#, fuzzy -#~ msgid "E37: No write since last change" -#~ msgstr "[Attention : tout n'est pas enregistr]\n" +msgid "_Close" +msgstr "_Fermer" -msgid "E38: Null argument" -msgstr "E38: Argument null" +msgid "Vim: Received \"die\" request from session manager\n" +msgstr "Vim : Une requte \"die\" a t reue par le gestionnaire de session\n" -msgid "E39: Number expected" -msgstr "E39: Nombre attendu" +msgid "Close tab" +msgstr "Fermer l'onglet" -#, 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" -msgid "E41: Out of memory!" -msgstr "E41: Mmoire puise" +# DB - todo : un peu long. Cet entre de menu permet d'ouvrir un fichier +# dans un nouvel onglet via le slecteur de fichiers graphique. +msgid "Open Tab..." +msgstr "Ouvrir dans un onglet..." -msgid "Pattern not found" -msgstr "Motif introuvable" +msgid "Vim: Main window unexpectedly destroyed\n" +msgstr "Vim : Fentre principale dtruite inopinment\n" -#, c-format -msgid "E486: Pattern not found: %s" -msgstr "E486: Motif introuvable : %s" +msgid "&Filter" +msgstr "&Filtrer" -msgid "E487: Argument must be positive" -msgstr "E487: L'argument doit tre positif" +msgid "&Cancel" +msgstr "&Annuler" -msgid "E459: Cannot go back to previous directory" -msgstr "E459: Impossible de retourner au rpertoire prcdent" +msgid "Directories" +msgstr "Rpertoires" -msgid "E42: No Errors" -msgstr "E42: Aucune erreur" +msgid "Filter" +msgstr "Filtre" -# DB - TODO : trouver une traduction valable et atteste pour "location". -msgid "E776: No location list" -msgstr "E776: Aucune liste d'emplacements" +msgid "&Help" +msgstr "&Aide" -msgid "E43: Damaged match string" -msgstr "E43: La chane de recherche est endommage" +msgid "Files" +msgstr "Fichiers" -msgid "E44: Corrupted regexp program" -msgstr "E44: L'automate de regexp est corrompu" +msgid "&OK" +msgstr "&Ok" -msgid "E45: 'readonly' option is set (add ! to override)" -msgstr "E45: L'option 'readonly' est active (ajoutez ! pour passer outre)" +msgid "Selection" +msgstr "Slection" -#, 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" -#, 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" -msgid "E47: Error while reading errorfile" -msgstr "E47: Erreur lors de la lecture du fichier d'erreurs" +msgid "Replace &All" +msgstr "Rempl&acer tout" -msgid "E48: Not allowed in sandbox" -msgstr "E48: Opration interdite dans le bac sable" +msgid "&Undo" +msgstr "Ann&uler" -msgid "E523: Not allowed here" -msgstr "E523: Interdit cet endroit" +msgid "Open tab..." +msgstr "Ouvrir dans un onglet..." -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 chane (utilisez '\\\\' pour chercher un '\\')" -msgid "E49: Invalid scroll size" -msgstr "E49: Valeur de dfilement invalide" +msgid "Find & Replace (use '\\\\' to find a '\\')" +msgstr "Chercher et remplacer (utilisez '\\\\' pour trouver un '\\')" -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 +# paramtrage bidon afin de slectionner un rpertoire plutt 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" -msgid "E255: Couldn't read in sign data!" -msgstr "E255: Impossible de lire les donnes du symbole !" +# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un +# paramtrage bidon afin de slectionner un rpertoire plutt qu'un +# fichier. +msgid "Directory\t*.nothing\n" +msgstr "Rpertoire\t*.rien\n" -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 fentre \"%s\" introuvable" -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." -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 fentre dans une application MDI" -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" -msgid "E76: Too many [" -msgstr "E76: Trop de [" +# DB - todo : La VF est-elle comprhensible ? +#, 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 caractres suivants :" -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" -msgid "E488: Trailing characters" -msgstr "E488: Caractres surnumraires" +#, c-format +msgid "Font '%s' is not fixed-width" +msgstr "La police '%s' n'a pas une largeur fixe" -msgid "E78: Unknown mark" -msgstr "E78: Marque inconnue" +#, c-format +msgid "E253: Fontset name: %s" +msgstr "E253: Nom du jeu de polices : %s" -msgid "E79: Cannot expand wildcards" -msgstr "E79: Impossible de dvelopper les mtacaractres" +#, c-format +msgid "Font0: %s" +msgstr "Font0: %s" -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" -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" -msgid "E80: Error while writing" -msgstr "E80: Erreur lors de l'criture" +#, c-format +msgid "Font0 width: %ld" +msgstr "Largeur de Font0 : %ld" -msgid "Zero count" -msgstr "Le quantificateur est nul" +#, c-format +msgid "Font1 width: %ld" +msgstr "Largeur de Font1 : %ld" -msgid "E81: Using not in a script context" -msgstr "E81: utilis en dehors d'un script" +# DB - todo : Pas certain de mon coup, ici... +msgid "Invalid font specification" +msgstr "La spcification de la police est invalide" -#, c-format -msgid "E685: Internal error: %s" -msgstr "E685: Erreur interne : %s" +msgid "&Dismiss" +msgstr "Aban&donner" -msgid "E363: pattern uses more memory than 'maxmempattern'" -msgstr "E363: le motif utilise plus de mmoire que 'maxmempattern'" +# DB - todo : Pas certain de mon coup, ici... +msgid "no specific match" +msgstr "aucune correspondance particulire" -msgid "E749: empty buffer" -msgstr "E749: tampon vide" +msgid "Vim - Font Selector" +msgstr "Choisir une police - Vim" -#, c-format -msgid "E86: Buffer % does not exist" -msgstr "E86: Le tampon % n'existe pas" +msgid "Name:" +msgstr "Nom :" -msgid "E682: Invalid search pattern or delimiter" -msgstr "E682: Dlimiteur ou motif de recherche invalide" +#. create toggle button +msgid "Show size in Points" +msgstr "Afficher la taille en Points" -msgid "E139: File is loaded in another buffer" -msgstr "E139: Le fichier est charg dans un autre tampon" +msgid "Encoding:" +msgstr "Encodage :" -#, c-format -msgid "E764: Option '%s' is not set" -msgstr "E764: L'option '%s' n'est pas active" +msgid "Font:" +msgstr "Police :" -msgid "E850: Invalid register name" -msgstr "E850: Nom de registre invalide" +msgid "Style:" +msgstr "Style :" -msgid "search hit TOP, continuing at BOTTOM" -msgstr "La recherche a atteint le HAUT, et continue en BAS" +msgid "Size:" +msgstr "Taille :" -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" msgid "E550: Missing colon" msgstr "E550: ':' manquant" @@ -2778,6 +2705,9 @@ msgstr "E257: cstag : marqueur introuvable" msgid "E563: stat(%s) error: %d" msgstr "E563: Erreur stat(%s) : %d" +msgid "E563: stat error" +msgstr "E563: Erreur stat" + #, c-format msgid "E564: %s is not a directory or a valid cscope database" msgstr "E564: %s n'est pas un rpertoire ou une base de donnes cscope valide" @@ -2787,8 +2717,8 @@ msgid "Added cscope database %s" msgstr "Base de donnes cscope %s ajoute" #, c-format -msgid "E262: error reading cscope connection %" -msgstr "E262: erreur lors de la lecture de la connexion cscope %" +msgid "E262: error reading cscope connection %ld" +msgstr "E262: erreur lors de la lecture de la connexion cscope %ld" msgid "E561: unknown cscope search type" msgstr "E561: type de recherche cscope inconnu" @@ -2799,9 +2729,8 @@ msgstr "E566: Impossible de cr msgid "E622: Could not fork for cscope" msgstr "E622: Impossible de forker pour cscope" -#, fuzzy -#~ msgid "cs_create_connection setpgid failed" -#~ msgstr "exec de cs_create_connection a chou" +msgid "cs_create_connection setpgid failed" +msgstr "cs_create_connection setpgid a chou" msgid "cs_create_connection exec failed" msgstr "exec de cs_create_connection a chou" @@ -2857,7 +2786,15 @@ msgstr "" " s: Trouver ce symbole C\n" " t: Trouver cette chane\n" -msgid "E568: duplicate cscope database not added" +#, c-format +msgid "E625: cannot open cscope database: %s" +msgstr "E625: impossible d'ouvrir la base de donnes cscope %s" + +msgid "E626: cannot get cscope database information" +msgstr "" +"E626: impossible d'obtenir des informations sur la base de donnes cscope" + +msgid "E568: duplicate cscope database not added" msgstr "E568: base de donnes cscope redondante non ajoute" #, c-format @@ -2900,6 +2837,221 @@ msgstr "aucune connexion cscope\n" msgid " # pid database name prepend path\n" msgstr " # pid nom de la base de donnes chemin\n" +msgid "Lua library cannot be loaded." +msgstr "La bibliothque Lua n'a pas pu tre charge." + +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: Dsol, cette commande est dsactive : les bibliothques MzScheme " +"n'ont pas pu tre charges." + +msgid "" +"E895: Sorry, this command is disabled, the MzScheme's racket/base module " +"could not be loaded." +msgstr "" +"E895: Dsol, cette commande est dsactive : le module MzScheme racket/base " +"ne peut pas tre charg." + +msgid "invalid expression" +msgstr "expression invalide" + +msgid "expressions disabled at compile time" +msgstr "expressions dsactives lors de la compilation" + +msgid "hidden option" +msgstr "option cache" + +msgid "unknown option" +msgstr "option inconnue" + +msgid "window index is out of range" +msgstr "numro de fentre 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'insrer la ligne" + +msgid "string cannot contain newlines" +msgstr "une chane 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 "fentre invalide" + +msgid "linenr out of range" +msgstr "numro 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 excuter :python aprs avoir utilis :py3" + +msgid "" +"E263: Sorry, this command is disabled, the Python library could not be " +"loaded." +msgstr "" +"E263: Dsol, commande dsactive : la bibliothque Python n'a pas pu tre " +"charge." + +msgid "" +"E887: Sorry, this command is disabled, the Python's site module could not be " +"loaded." +msgstr "" +"E887: Dsol, commande dsactive : la bibliothque Python n'a pas pu tre " +"charge." + +msgid "E659: Cannot invoke Python recursively" +msgstr "E659: Impossible d'invoquer Python rcursivement" + +msgid "E837: This Vim cannot execute :py3 after using :python" +msgstr "E837: Vim ne peut pas excuter :py3 aprs avoir utilis :python" + +msgid "E265: $_ must be an instance of String" +msgstr "E265: $_ doit tre une instance de chane (String)" + +msgid "" +"E266: Sorry, this command is disabled, the Ruby library could not be loaded." +msgstr "" +"E266: Dsol, commande dsactive : la bibliothque Ruby n'a pas pu tre " +"charge." + +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 "numro de tampon invalide" + +msgid "not implemented yet" +msgstr "pas encore implment" + +# 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 positionne" + +#, c-format +msgid "row %d column %d" +msgstr "ligne %d colonne %d" + +msgid "cannot insert/append line" +msgstr "Impossible d'insrer/ajouter de lignes" + +msgid "line number out of range" +msgstr "numro 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 crer commande de tampon/fentre : 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/fentre 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 : rf. tampon/fentre introuvable" + +msgid "" +"E571: Sorry, this command is disabled: the Tcl library could not be loaded." +msgstr "" +"E571: Dsol, commande dsactive: la bibliothque Tcl n'a pas pu tre " +"charge." + +#, 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: Entre registre de l'instance de Vim mal formate. Suppression !" + +#, c-format +msgid "E938: Duplicate key in JSON: \"%s\"" +msgstr "E938: Cl duplique dans le document JSON : \"%s\"" + #, c-format msgid "E696: Missing comma in List: %s" msgstr "E696: Il manque une virgule dans la Liste %s" @@ -2930,6 +3082,15 @@ msgstr "Argument invalide pour" msgid "%d files to edit\n" msgstr "%d fichiers diter\n" +msgid "netbeans is not supported with this GUI\n" +msgstr "netbeans n'est pas support avec cette interface graphique\n" + +msgid "'-nb' cannot be used: not enabled at compile time\n" +msgstr "'-nb' ne peut pas tre utilis : dsactiv 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 : \"" @@ -2939,6 +3100,14 @@ msgstr "Impossible d'ouvrir en lecture : \"" msgid "Cannot open for script output: \"" msgstr "Impossible d'ouvrir pour la sortie script : \"" +msgid "Vim: Error: Failure to start gvim from NetBeans\n" +msgstr "Vim : Erreur : Impossible de dmarrer 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" @@ -2991,6 +3160,15 @@ msgstr "" "\n" " ou :" +# DB - todo (VMS uniquement). +msgid "" +"\n" +"Where case is ignored prepend / to make flag upper case" +msgstr "" +"\n" +"pour lesquels la casse est indiffrente (/ pour que le drapeau soit " +"majuscule)" + msgid "" "\n" "\n" @@ -3006,6 +3184,20 @@ msgstr "--\t\tSeuls des noms de fichier sont sp msgid "--literal\t\tDon't expand wildcards" msgstr "--literal\tNe pas dvelopper les mtacaractres" +msgid "-register\t\tRegister this gvim for OLE" +msgstr "-register\tInscrire ce gvim pour OLE" + +msgid "-unregister\t\tUnregister gvim for OLE" +msgstr "-unregister\tDsinscrire 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 dtacher l'interface graphique du " +"terminal" + msgid "-v\t\t\tVi mode (like \"vi\")" msgstr "-v\t\tMode Vi (comme \"vi\")" @@ -3066,6 +3258,12 @@ msgstr "-r \tR msgid "-L\t\t\tSame as -r" msgstr "-L\t\tComme -r" +msgid "-f\t\t\tDon't use newcli to open window" +msgstr "-f\t\tNe pas utiliser newcli pour l'ouverture des fentres" + +msgid "-dev \t\tUse for I/O" +msgstr "-dev \tUtiliser pour les E/S" + msgid "-A\t\t\tstart in Arabic mode" msgstr "-A\t\tDmarrer en mode arabe" @@ -3078,9 +3276,20 @@ msgstr "-F\t\tD msgid "-T \tSet terminal type to " msgstr "-T \tRgler le type du terminal sur " +msgid "--not-a-term\t\tSkip warning for input/output not being a terminal" +msgstr "" +"--no-a-term\t\tAucun avertissement si l'entre/sortie n'est pas un terminal" + +msgid "--ttyfail\t\tExit if input or output is not a terminal" +msgstr "" +"--ttyfail\t\tQuitte si l'entre ou la sortie ne sont pas un terminal" + msgid "-u \t\tUse instead of any .vimrc" msgstr "-u \tUtiliser au lieu du vimrc habituel" +msgid "-U \t\tUse instead of any .gvimrc" +msgstr "-U \tUtiliser au lieu du gvimrc habituel" + msgid "--noplugin\t\tDon't load plugin scripts" msgstr "--noplugin\tNe charger aucun greffon" @@ -3118,6 +3327,53 @@ msgstr "-w \tAjouter toutes les commandes tap msgid "-W \tWrite all typed commands to file " msgstr "-W \tcrire toutes les commandes tapes dans le fichier " +msgid "-x\t\t\tEdit encrypted files" +msgstr "-x\t\t\tditer des fichiers chiffrs" + +msgid "-display \tConnect vim to this particular X-server" +msgstr "-display \tConnecter Vim au serveur X spcifi" + +msgid "-X\t\t\tDo not connect to X server" +msgstr "-X\t\t\tNe pas se connecter un serveur X" + +msgid "--remote \tEdit in a Vim server if possible" +msgstr "--remote \tditer les dans un serveur Vim si possible" + +msgid "--remote-silent 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 As --remote but wait for files to have been edited" +msgstr "" +"--remote-wait \tComme --remote mais ne quitter qu' la fin de l'dition" + +msgid "" +"--remote-wait-silent 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] As --remote but use tab page per file" +msgstr "" +"--remote-tab[-wait][-silent] \tComme --remote mais ouvrir un onglet " +"pour chaque fichier" + +msgid "--remote-send \tSend to a Vim server and exit" +msgstr "--remote-send \tEnvoyer un serveur Vim puis quitter" + +msgid "--remote-expr \tEvaluate in a Vim server and print result" +msgstr "" +"--remote-expr \tvaluer dans un serveur Vim, afficher le " +"rsultat" + +msgid "--serverlist\t\tList available Vim server names and exit" +msgstr "" +"--serverlist\t\tLister les noms des serveurs Vim disponibles et quitter" + +msgid "--servername \tSend to/become the Vim server " +msgstr "--servername \tEnvoyer au/devenir le serveur Vim nomm " + msgid "--startuptime \tWrite startup timing messages to " msgstr "" "--startuptime \tcrire les messages d'horodatage au dmarrage dans " @@ -3132,6 +3388,120 @@ msgstr "-h ou --help\t\tAfficher l'aide (ce message) puis quitter" msgid "--version\t\tPrint version information and exit" msgstr "--version\t\tAfficher les informations de version et quitter" +msgid "" +"\n" +"Arguments recognised by gvim (Motif version):\n" +msgstr "" +"\n" +"Arguments reconnus par gvim (version Motif) :\n" + +msgid "" +"\n" +"Arguments recognised by gvim (neXtaw version):\n" +msgstr "" +"\n" +"Arguments reconnus par gvim (version neXtaw) :\n" + +msgid "" +"\n" +"Arguments recognised by gvim (Athena version):\n" +msgstr "" +"\n" +"Arguments reconnus par gvim (version Athena) :\n" + +msgid "-display \tRun vim on " +msgstr "-display \tLancer Vim sur ce " + +msgid "-iconic\t\tStart vim iconified" +msgstr "-iconic\t\tIconifier Vim au dmarrage" + +msgid "-background \tUse for the background (also: -bg)" +msgstr "" +"-background \tUtiliser pour l'arrire-plan\t (abrv : -bg)" + +msgid "-foreground \tUse for normal text (also: -fg)" +msgstr "" +"-foreground \tUtiliser pour le texte normal\t (abrv : -fg)" + +msgid "-font \t\tUse for normal text (also: -fn)" +msgstr "-font \tUtiliser pour le texte normal\t (abrv : -fn)" + +msgid "-boldfont \tUse for bold text" +msgstr "-boldfont \tUtiliser pour le texte gras" + +msgid "-italicfont \tUse for italic text" +msgstr "-italicfont \tUtiliser pour le texte italique" + +msgid "-geometry \tUse for initial geometry (also: -geom)" +msgstr "-geometry \tUtiliser cette initiale\t (abrv : -geom)" + +msgid "-borderwidth \tUse a border width of (also: -bw)" +msgstr "" +"-borderwidth \tUtiliser cette de bordure\t (abrv : -bw)" + +msgid "-scrollbarwidth Use a scrollbar width of (also: -sw)" +msgstr "" +"-scrollbarwidth \tUtiliser cette de barre de dfil. (abrv: -sw)" + +msgid "-menuheight \tUse a menu bar height of (also: -mh)" +msgstr "-menuheight \tUtiliser cette de menu\t (abrv : -mh)" + +msgid "-reverse\t\tUse reverse video (also: -rv)" +msgstr "-reverse\t\tUtiliser la vido inverse\t\t (abrv : -rv)" + +msgid "+reverse\t\tDon't use reverse video (also: +rv)" +msgstr "+reverse\t\tNe pas utiliser de vido inverse\t (abrv : +rv)" + +msgid "-xrm \tSet the specified resource" +msgstr "-xrm \tConfigurer la spcifie" + +msgid "" +"\n" +"Arguments recognised by gvim (GTK+ version):\n" +msgstr "" +"\n" +"Arguments reconnus par gvim (version GTK+) :\n" + +msgid "-display \tRun vim on (also: --display)" +msgstr "" +"-display \tLancer Vim sur ce \t(galement : --display)" + +msgid "--role \tSet a unique role to identify the main window" +msgstr "--role \tDonner un rle pour identifier la fentre principale" + +msgid "--socketid \tOpen Vim inside another GTK widget" +msgstr "--socketid \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 fentre sur stdout" + +msgid "-P \tOpen Vim inside parent application" +msgstr "-P \tOuvrir Vim dans une application parente" + +msgid "--windowid \tOpen Vim inside another win32 widget" +msgstr "--windowid \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'excution locale\n" + +#, c-format +msgid "%d of %d edited" +msgstr "%d dits 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 positionne" @@ -3188,6 +3558,30 @@ msgstr "" msgid "Missing '>'" msgstr "'>' manquant" +msgid "E543: Not a valid codepage" +msgstr "E543: Page de codes non valide" + +msgid "E284: Cannot set IC values" +msgstr "E284: Impossible de rgler les valeurs IC" + +msgid "E285: Failed to create input context" +msgstr "E285: chec de la cration du contexte de saisie" + +msgid "E286: Failed to open input method" +msgstr "E286: chec de l'ouverture de la mthode 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 mthode de saisie ne supporte aucun style" + +msgid "E289: input method doesn't support my preedit type" +msgstr "" +"E289: le type de prdition de Vim n'est pas support par la mthode de " +"saisie" + msgid "E293: block was not locked" msgstr "E293: le bloc n'tait pas verrouill" @@ -3215,6 +3609,9 @@ msgstr "E298: Bloc n msgid "E298: Didn't get block nr 2?" msgstr "E298: Bloc n2 non rcupr ?" +msgid "E843: Error while updating swap file crypt" +msgstr "E843: Erreur lors de la mise jour du fichier d'change crypt" + #. could not (re)open the swap file, what can we do???? msgid "E301: Oops, lost the swap file!!!" msgstr "E301: Oups, le fichier d'change a disparu !" @@ -3229,7 +3626,6 @@ msgstr "E303: Impossible d'ouvrir fichier .swp pour \"%s\", r msgid "E304: ml_upd_block0(): Didn't get block 0??" msgstr "E304: ml_upd_block0() : bloc 0 non rcupr ?!" -#. no swap files found #, c-format msgid "E305: No swap file found for %s" msgstr "E305: Aucun fichier d'change trouv pour %s" @@ -3275,6 +3671,12 @@ msgstr "" ",\n" "ou le fichier a t endommag." +#, c-format +msgid "" +"E833: %s is encrypted and this version of Vim does not support encryption" +msgstr "" +"E833: %s est chiffr et cette version de Vim ne supporte pas le chiffrement" + msgid " has been damaged (page size is smaller than minimum value).\n" msgstr " a t endommag (taille de page infrieure la valeur minimale).\n" @@ -3289,6 +3691,40 @@ msgstr "Fichier original \"%s\"" msgid "E308: Warning: Original file may have been changed" msgstr "E308: Alerte : Le fichier original a pu tre modifi" +#, c-format +msgid "Swap file is encrypted: \"%s\"" +msgstr "Fichier d'change chiffr : \"%s\"" + +msgid "" +"\n" +"If you entered a new crypt key but did not write the text file," +msgstr "" +"\n" +"Si vous avez tap une nouvelle cl de chiffrement mais n'avez pas enregistr " +"le fichier texte," + +msgid "" +"\n" +"enter the new crypt key." +msgstr "" +"\n" +"tapez la nouvelle cl de chiffrement." + +msgid "" +"\n" +"If you wrote the text file after changing the crypt key press enter" +msgstr "" +"\n" +"Si vous avez crit le fichier texte aprs avoir chang la cl de " +"chiffrement, appuyez sur entre" + +msgid "" +"\n" +"to use the same key for text file and swap file" +msgstr "" +"\n" +"afin d'utiliser la mme 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" @@ -3360,6 +3796,11 @@ 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 msgid "Swap files found:" msgstr "Fichiers d'change trouvs :" @@ -3434,6 +3875,13 @@ msgstr "" msgid " (still running)" msgstr " (en cours d'excution)" +msgid "" +"\n" +" [not usable with this version of Vim]" +msgstr "" +"\n" +" [inutilisable avec cette version de Vim]" + msgid "" "\n" " [not usable on this computer]" @@ -3457,12 +3905,12 @@ msgid "E314: Preserve failed" msgstr "E314: chec de la prservation" #, c-format -msgid "E315: ml_get: invalid lnum: %" -msgstr "E315: ml_get : numro de ligne invalide : %" +msgid "E315: ml_get: invalid lnum: %ld" +msgstr "E315: ml_get : numro de ligne invalide : %ld" #, c-format -msgid "E316: ml_get: cannot find line %" -msgstr "E316: ml_get : ligne % introuvable" +msgid "E316: ml_get: cannot find line %ld" +msgstr "E316: ml_get : ligne %ld introuvable" msgid "E317: pointer block id wrong 3" msgstr "E317: mauvais id de pointeur de bloc 3" @@ -3480,8 +3928,8 @@ msgid "deleted block 1?" msgstr "bloc 1 effac ?" #, c-format -msgid "E320: Cannot find line %" -msgstr "E320: Ligne % introuvable" +msgid "E320: Cannot find line %ld" +msgstr "E320: Ligne %ld introuvable" msgid "E317: pointer block id wrong" msgstr "E317: mauvais id de pointeur de bloc" @@ -3490,12 +3938,12 @@ msgid "pe_line_count is zero" msgstr "pe_line_count vaut zro" #, c-format -msgid "E322: line number out of range: % past the end" -msgstr "E322: numro de ligne hors limites : % au-del de la fin" +msgid "E322: line number out of range: %ld past the end" +msgstr "E322: numro de ligne hors limites : %ld au-del de la fin" #, c-format -msgid "E323: line count wrong in block %" -msgstr "E323: nombre de lignes erron dans le bloc %" +msgid "E323: line count wrong in block %ld" +msgstr "E323: nombre de lignes erron dans le bloc %ld" msgid "Stack size increases" msgstr "La taille de la pile s'accrot" @@ -3523,19 +3971,19 @@ msgstr "Lors de l'ouverture du fichier \"" msgid " NEWER than swap file!\n" msgstr " PLUS RCENT que le fichier d'change !\n" +#. Some of these messages are long to allow translation to +#. * other languages. msgid "" "\n" "(1) Another program may be editing the same file. If this is the case,\n" " be careful not to end up with two different instances of the same\n" -" file when making changes." +" 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 diffrentes du mme fichier en faisant des modifications." - -msgid " Quit, or continue with caution.\n" -msgstr " Quittez, ou continuez prudemment.\n" +" deux versions diffrentes du mme fichier en faisant des modifications.\n" +" Quitter ou continuer avec attention.\n" msgid "(2) An edit session for this file crashed.\n" msgstr "(2) Une session d'dition de ce fichier a plant.\n" @@ -3600,21 +4048,9 @@ 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 msgid "E326: Too many swap files found" msgstr "E326: Trop de fichiers d'change trouvs" -#, c-format -msgid "E342: Out of memory! (allocating % bytes)" -msgstr "E342: Mmoire puise ! (allocation de % octets)" - msgid "E327: Part of menu-item path is not sub-menu" msgstr "E327: Une partie du chemin de l'lment de menu n'est pas un sous-menu" @@ -3649,6 +4085,9 @@ msgstr "" "\n" "--- Menus ---" +msgid "Tear off this menu" +msgstr "Dtacher ce menu" + msgid "E333: Menu path must lead to a menu item" msgstr "E333: Le chemin du menu doit conduire un lment de menu" @@ -3679,6 +4118,9 @@ msgid "E354: Invalid register name: '%s'" msgstr "E354: Nom de registre invalide : '%s'" # DB - todo : mettre jour ? +msgid "Messages maintainer: Bram Moolenaar " +msgstr "Maintenance des messages : Dominique Pell " + msgid "Interrupt: " msgstr "Interruption : " @@ -3686,8 +4128,8 @@ msgid "Press ENTER or type command to continue" msgstr "Appuyez sur ENTRE ou tapez une commande pour continuer" #, c-format -msgid "%s line %" -msgstr "%s, ligne %" +msgid "%s line %ld" +msgstr "%s, ligne %ld" msgid "-- More --" msgstr "-- Plus --" @@ -3706,15 +4148,6 @@ msgstr "" "&Oui\n" "&Non" -msgid "" -"&Yes\n" -"&No\n" -"&Cancel" -msgstr "" -"&Oui\n" -"&Non\n" -"&Annuler" - msgid "" "&Yes\n" "&No\n" @@ -3728,6 +4161,21 @@ msgstr "" "Tout aban&donner\n" "&Annuler" +# DB : Les trois messages qui suivent sont des titres de botes +# de dialogue par dfaut. +msgid "Select Directory dialog" +msgstr "Slecteur de rpertoire" + +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: Dsol, pas de slecteur de fichiers en mode console" + msgid "E766: Insufficient arguments for printf()" msgstr "E766: Pas assez d'arguments pour printf()" @@ -3753,12 +4201,12 @@ msgid "1 line less" msgstr "1 ligne en moins" #, c-format -msgid "% more lines" -msgstr "% lignes en plus" +msgid "%ld more lines" +msgstr "%ld lignes en plus" #, c-format -msgid "% fewer lines" -msgstr "% lignes en moins" +msgid "%ld fewer lines" +msgstr "%ld lignes en moins" msgid " (Interrupted)" msgstr " (Interrompu)" @@ -3766,16 +4214,111 @@ msgstr " (Interrompu)" msgid "Beep!" msgstr "Bip !" -#, c-format -msgid "Calling shell to execute: \"%s\"" -msgstr "Appel du shell pour excuter : \"%s\"" +msgid "ERROR: " +msgstr "ERREUR : " -msgid "E349: No identifier under cursor" -msgstr "E349: Aucun identifiant sous le curseur" +#, c-format +msgid "" +"\n" +"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n" +msgstr "" +"\n" +"[octets] total allou-libr %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: Mmoire puise ! (allocation de %lu octets)" + +#, c-format +msgid "Calling shell to execute: \"%s\"" +msgstr "Appel du shell pour excuter : \"%s\"" + +msgid "E545: Missing colon" +msgstr "E545: ':' manquant" + +msgid "E546: Illegal mode" +msgstr "E546: Mode non autoris" + +msgid "E547: Illegal mouseshape" +msgstr "E547: Forme de curseur invalide" + +msgid "E548: digit expected" +msgstr "E548: chiffre attendu" + +msgid "E549: Illegal percentage" +msgstr "E549: Pourcentage non autoris" + +msgid "E854: path too long for completion" +msgstr "E854: chemin trop long pour compltement" + +#, 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: Rpertoire \"%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 rpertoire \"%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'accs 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 dj connect" + +#, c-format +msgid "E505: %s is read-only (add ! to override)" +msgstr "E505: %s est en lecture seule (ajoutez ! pour passer outre)" + +msgid "E349: No identifier under cursor" +msgstr "E349: Aucun identifiant sous le curseur" msgid "E774: 'operatorfunc' is empty" msgstr "E774: 'operatorfunc' est vide" +msgid "E775: Eval feature not available" +msgstr "E775: La fonctionnalit d'valuation n'est pas disponible" + # DB : Il est ici question du mode Visuel. msgid "Warning: terminal cannot highlight" msgstr "Alerte : le terminal ne peut pas surligner" @@ -3795,7 +4338,7 @@ msgstr "E662: Au d msgid "E663: At end of changelist" msgstr "E663: la fin de la liste des modifications" -msgid "Type :quit to exit Nvim" +msgid "Type :quit to exit Vim" msgstr "tapez :q pour quitter Vim" #, c-format @@ -3807,23 +4350,23 @@ msgid "1 line %sed %d times" msgstr "1 ligne %se %d fois" #, c-format -msgid "% lines %sed 1 time" -msgstr "% lignes %ses 1 fois" +msgid "%ld lines %sed 1 time" +msgstr "%ld lignes %ses 1 fois" #, c-format -msgid "% lines %sed %d times" -msgstr "% lignes %ses %d fois" +msgid "%ld lines %sed %d times" +msgstr "%ld lignes %ses %d fois" #, c-format -msgid "% lines to indent... " -msgstr "% lignes indenter... " +msgid "%ld lines to indent... " +msgstr "%ld lignes indenter... " msgid "1 line indented " msgstr "1 ligne indente " #, c-format -msgid "% lines indented " -msgstr "% lignes indentes " +msgid "%ld lines indented " +msgstr "%ld lignes indentes " msgid "E748: No previously used register" msgstr "E748: Aucun registre n'a t prcdemment utilis" @@ -3837,8 +4380,12 @@ msgid "1 line changed" msgstr "1 ligne modifie" #, c-format -msgid "% lines changed" -msgstr "% lignes modifies" +msgid "%ld lines changed" +msgstr "%ld lignes modifies" + +#, c-format +msgid "freeing %ld lines" +msgstr "libration de %ld lignes" msgid "block of 1 line yanked" msgstr "bloc de 1 ligne copi" @@ -3847,12 +4394,12 @@ msgid "1 line yanked" msgstr "1 ligne copie" #, c-format -msgid "block of % lines yanked" -msgstr "bloc de % lignes copi" +msgid "block of %ld lines yanked" +msgstr "bloc de %ld lignes copi" #, c-format -msgid "% lines yanked" -msgstr "% lignes copies" +msgid "%ld lines yanked" +msgstr "%ld lignes copies" #, c-format msgid "E353: Nothing in register %s" @@ -3880,45 +4427,47 @@ msgstr "" msgid "E574: Unknown register type %d" msgstr "E574: Type de registre %d inconnu" +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 "% Cols; " -msgstr "% Colonnes ; " +msgid "%ld Cols; " +msgstr "%ld Colonnes ; " #, c-format -msgid "" -"Selected %s% of % Lines; % of % Words; " -"% of % Bytes" +msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes" msgstr "" -"%s% sur % Lignes ; % sur % Mots ; % " -"sur % Octets slectionns" +"%s%ld sur %ld Lignes ; %lld sur %lld Mots ; %lld sur %lld Octets slectionns" #, c-format msgid "" -"Selected %s% of % Lines; % of % Words; " -"% of % Chars; % of % Bytes" +"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of " +"%lld Bytes" msgstr "" -"%s% sur % Lignes ; % sur % Mots ; % " -"sur % Caractres ; % sur % octets slectionns" +"%s%ld sur %ld Lignes ; %lld sur %lld Mots ; %lld sur %lld Caractres ; %lld " +"sur %lld octets slectionns" #, c-format -msgid "" -"Col %s of %s; Line % of %; Word % of %; Byte " -"% of %" +msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld" msgstr "" -"Colonne %s sur %s ; Ligne % sur % ; Mot % sur " -"% ; Octet % sur %" +"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %lld sur %lld ; Octet %lld sur " +"%lld" #, c-format msgid "" -"Col %s of %s; Line % of %; Word % of %; Char " -"% of %; Byte % of %" +"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 % sur % ; Mot % sur " -"% ; Caractre % sur % ; Octet % sur %" +"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %lld sur %lld ; Caractre %lld " +"sur %lld ; Octet %lld sur %lld" #, c-format -msgid "(+% for BOM)" -msgstr "(+% pour le BOM)" +msgid "(+%ld for BOM)" +msgstr "(+%ld pour le BOM)" msgid "%<%f%h%m%=Page %N" msgstr "%<%f%h%m%=Page %N" @@ -3926,7 +4475,6 @@ msgstr "%<%f%h%m%=Page %N" msgid "Thanks for flying Vim" msgstr "Merci d'avoir choisi Vim" -#. found a mismatch: skip msgid "E518: Unknown option" msgstr "E518: Option inconnue" @@ -3956,6 +4504,12 @@ msgstr "Pour l'option %s" msgid "E529: Cannot set 'term' to empty string" msgstr "E529: 'term' ne doit pas tre une chane vide" +msgid "E530: Cannot change term in GUI" +msgstr "E530: Impossible de modifier term dans l'interface graphique" + +msgid "E531: Use \":gui\" to start the GUI" +msgstr "E531: Utilisez \":gui\" pour dmarrer l'interface graphique" + msgid "E589: 'backupext' and 'patchmode' are equal" msgstr "E589: 'backupext' et 'patchmode' sont gaux" @@ -3965,6 +4519,9 @@ msgstr "E834: Conflits avec la valeur de 'listchars'" msgid "E835: Conflicts with value of 'fillchars'" msgstr "E835: Conflits avec la valeur de 'fillchars'" +msgid "E617: Cannot be changed in the GTK+ 2 GUI" +msgstr "E617: Non modifiable dans l'interface graphique GTK+ 2" + msgid "E524: Missing colon" msgstr "E524: ':' manquant" @@ -3984,6 +4541,21 @@ msgstr "E528: Une valeur ' doit msgid "E595: contains unprintable or wide character" msgstr "E595: contient des caractres largeur double non-imprimables" +msgid "E596: Invalid font(s)" +msgstr "E596: Police(s) invalide(s)" + +msgid "E597: can't select fontset" +msgstr "E597: Impossible de slectionner 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 slectionner 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: Caractre invalide aprs <%c>" @@ -3995,6 +4567,9 @@ msgstr "E536: virgule requise" 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 supporte" + # DB - Le code est sans ambigut sur le caractre manquant. # dfaut d'une traduction valable, au moins comprend-on # ce qui se passe. @@ -4011,7 +4586,7 @@ msgid "E590: A preview window already exists" msgstr "E590: Il existe dj une fentre de prvisualisation" 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 ncessite l'UTF-8, tapez ':set encoding=utf-8'" #, c-format msgid "E593: Need at least %d lines" @@ -4071,12 +4646,135 @@ msgstr "E357: 'langmap' : Aucun caract msgid "E358: 'langmap': Extra characters after semicolon: %s" msgstr "E358: 'langmap' : Caractres surnumraires aprs point-virgule : %s" +msgid "cannot open " +msgstr "impossible d'ouvrir " + +msgid "VIM: Can't open window!\n" +msgstr "VIM : Impossible d'ouvrir la fentre !\n" + +msgid "Need Amigados version 2.04 or later\n" +msgstr "Amigados version 2.04 ou ultrieure est ncessaire\n" + +#, c-format +msgid "Need %s version %ld\n" +msgstr "%s version %ld est ncessaire\n" + +msgid "Cannot open NIL:\n" +msgstr "Impossible d'ouvrir NIL :\n" + +msgid "Cannot create " +msgstr "Impossible de crer " + +#, 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'excuter un shell avec l'option -f" + +msgid "Cannot execute " +msgstr "Impossible d'excuter " + +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 slection 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 caractres \"%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: Caractre '%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'excuter le shell " +"Vim : Rception 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 dpass le dlai d'attente" + +msgid "" +"\n" +"Could not get security context for " +msgstr "" +"\n" +"Impossible d'obtenir le contexte de scurit pour " + +msgid "" +"\n" +"Could not set security context for " +msgstr "" +"\n" +"Impossible de modifier le contexte de scurit pour " + +#, c-format +msgid "Could not set security context %s for %s" +msgstr "Impossible d'initialiser le contexte de scurit %s pour %s" + +#, c-format +msgid "Could not get security context %s for %s. Removing it!" +msgstr "" +"Impossible d'obtenir le contexte de scurit %s pour %s. Il sera supprim !" + +msgid "" +"\n" +"Cannot execute shell sh\n" +msgstr "" +"\n" +"Impossible d'excuter le shell sh\n" msgid "" "\n" @@ -4087,25 +4785,99 @@ msgstr "" msgid "" "\n" -"Could not get security context for " +"Cannot create pipes\n" msgstr "" "\n" -"Impossible d'obtenir le contexte de scurit pour " +"Impossible de crer des tuyaux (pipes)\n" msgid "" "\n" -"Could not set security context for " +"Cannot fork\n" msgstr "" "\n" -"Impossible de modifier le contexte de scurit pour " +"Impossible de forker\n" + +msgid "" +"\n" +"Cannot execute shell " +msgstr "" +"\n" +"Impossible d'excuter le shell " + +msgid "" +"\n" +"Command terminated\n" +msgstr "" +"\n" +"Commande interrompue\n" + +msgid "XSMP lost ICE connection" +msgstr "XSMP a perdu la connexion ICE" #, c-format msgid "dlerror = \"%s\"" msgstr "dlerror = \"%s\"" +msgid "Opening the X display failed" +msgstr "L'ouverture du display X a chou" + +msgid "XSMP handling save-yourself request" +msgstr "XSMP : prise en charge d'une requte 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 vnements en question sont ceux des messages qui suivent. +#, c-format +msgid "Vim: Caught %s event\n" +msgstr "Vim : vnement %s intercept\n" + +msgid "close" +msgstr "de fermeture" + +msgid "logoff" +msgstr "de dconnexion" + +msgid "shutdown" +msgstr "d'arrt" + +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 termines.\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" #, c-format msgid "E372: Too many %%%c in format string" @@ -4140,6 +4912,15 @@ msgstr "E379: Nom de r msgid "E553: No more items" msgstr "E553: Plus d'lments" +msgid "E924: Current window was closed" +msgstr "E924: La fentre courante doit tre ferme" + +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 : " @@ -4163,6 +4944,9 @@ msgstr "Aucune entr msgid "E382: Cannot write, 'buftype' option is set" msgstr "E382: criture impossible, l'option 'buftype' est active" +msgid "Error file" +msgstr "Fichier d'erreurs" + msgid "E683: File name missing or invalid pattern" msgstr "E683: Nom de fichier manquant ou motif invalide" @@ -4267,6 +5051,10 @@ msgstr "E554: Erreur de syntaxe dans %s{...}" msgid "External submatches:\n" msgstr "Sous-correspondances externes :\n" +#, c-format +msgid "E888: (NFA regexp) cannot repeat %s" +msgstr "E888: (regexp NFA) %s ne peut pas tre rpt" + msgid "" "E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be " "used " @@ -4274,6 +5062,9 @@ msgstr "" "E864: \\%#= peut tre suivi uniquement de 0, 1 ou 2. Le moteur automatique " "sera utilis " +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 rencontre prmaturment" @@ -4281,17 +5072,21 @@ msgstr "E865: (NFA) Fin de regexp rencontr msgid "E866: (NFA regexp) Misplaced %c" msgstr "E866: (regexp NFA) %c au mauvais endroit" -#, fuzzy, c-format -#~ msgid "E877: (NFA regexp) Invalid character class: %" -#~ msgstr "E877: (regexp NFA) Classe de caractre invalide " +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %ld" +msgstr "E877: (regexp NFA) Classe de caractre invalide : %ld" #, c-format msgid "E867: (NFA) Unknown operator '\\z%c'" msgstr "E867: (NFA) Oprateur inconnu '\\z%c'" -#, fuzzy, c-format -#~ msgid "E867: (NFA) Unknown operator '\\%%%c'" -#~ msgstr "E867: (NFA) Oprateur inconnu '\\z%c'" +#, c-format +msgid "E867: (NFA) Unknown operator '\\%%%c'" +msgstr "E867: (NFA) Oprateur 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" #, c-format msgid "E869: (NFA) Unknown operator '\\@%c'" @@ -4308,9 +5103,8 @@ msgstr "E871: (regexp NFA) Un multi ne peut pas suivre un multi !" msgid "E872: (NFA regexp) Too many '('" msgstr "E872: (regexp NFA) Trop de '('" -#, fuzzy -#~ msgid "E879: (NFA regexp) Too many \\z(" -#~ msgstr "E872: (regexp NFA) Trop de '('" +msgid "E879: (NFA regexp) Too many \\z(" +msgstr "E879: (regexp NFA) Trop de \\z(" msgid "E873: (NFA regexp) proper termination error" msgstr "E873: (NFA regexp) erreur de terminaison" @@ -4328,6 +5122,10 @@ msgstr "" msgid "E876: (NFA regexp) Not enough space to store the whole NFA " msgstr "E876: (regexp NFA) Pas assez de mmoire pour stocker le NFA" +msgid "E878: (NFA) Could not allocate memory for branch traversal!" +msgstr "" +"E878: (NFA) Impossible d'allouer la mmoire pour parcourir les branches !" + msgid "" "Could not open temporary log file for writing, displaying on stderr ... " msgstr "" @@ -4526,13 +5324,6 @@ msgstr "E762: Un caract msgid "Compressing word tree..." msgstr "Compression de l'arbre des mots" -msgid "E756: Spell checking is not enabled" -msgstr "E756: La vrification orthographique n'est pas active" - -#, c-format -msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\"" -msgstr "Alerte : Liste de mots \"%s.%s.spl\" ou \"%s.ascii.spl\" introuvable" - #, c-format msgid "Reading spell file \"%s\"" msgstr "Lecture du fichier orthographique \"%s\"" @@ -4581,6 +5372,10 @@ msgstr " msgid "Conversion in %s not supported: from %s to %s" msgstr "La conversion dans %s non supporte : de %s vers %s" +#, c-format +msgid "Conversion in %s not supported" +msgstr "La conversion dans %s non supporte" + #, c-format msgid "Invalid value for FLAG in %s line %d: %s" msgstr "Valeur de FLAG invalide dans %s ligne %d : %s" @@ -4769,6 +5564,9 @@ msgstr "Drapeaux non reconnus dans %s ligne %d : %s" msgid "Ignored %d words with non-ASCII characters" msgstr "%d mot(s) ignor(s) avec des caractres non-ASCII" +msgid "E845: Insufficient memory, word list will be incomplete" +msgstr "E845: mmoire insuffisante, liste de mots peut-tre incomplte" + #, c-format msgid "Compressed %d of %d nodes; %d (%d%%) remaining" msgstr "%d noeuds compresss sur %d ; %d (%d%%) restants " @@ -4776,14 +5574,16 @@ msgstr "%d noeuds compress 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. +#. +#. * Go through the trie of good words, soundfold each word and add it to +#. * the soundfold trie. +#. msgid "Performing soundfolding..." msgstr "Analyse phontique en cours..." #, c-format -msgid "Number of words after soundfolding: %" -msgstr "Nombre de mots aprs l'analyse phontique : %" +msgid "Number of words after soundfolding: %ld" +msgstr "Nombre de mots aprs l'analyse phontique : %ld" #, c-format msgid "Total number of words: %d" @@ -4819,87 +5619,45 @@ msgstr "Termin # DB - todo : perfectible. #, c-format -msgid "E765: 'spellfile' does not have % entries" -msgstr "E765: 'spellfile' n'a pas % entres" +msgid "E765: 'spellfile' does not have %ld entries" +msgstr "E765: 'spellfile' n'a pas %ld entres" -#, fuzzy, c-format -#~ msgid "Word '%.*s' removed from %s" -#~ msgstr "Mot retir de %s" +#, c-format +msgid "Word '%.*s' removed from %s" +msgstr "Mot '%.*s' retir de %s" -#, fuzzy, c-format -#~ msgid "Word '%.*s' added to %s" -#~ msgstr "Mot ajout dans %s" +#, c-format +msgid "Word '%.*s' added to %s" +msgstr "Mot '%.*s' ajout dans %s" msgid "E763: Word characters differ between spell files" msgstr "" "E763: Les caractres de mots diffrent entre les fichiers orthographiques" -msgid "Sorry, no suggestions" -msgstr "Dsol, aucune suggestion" - -#, c-format -msgid "Sorry, only % suggestions" -msgstr "Dsol, seulement % suggestions" +#. This should have been checked when generating the .spl +#. * file. +msgid "E783: duplicate char in MAP entry" +msgstr "E783: caractre dupliqu dans l'entre MAP" -#. for when 'cmdheight' > 1 -#. avoid more prompt -#, c-format -msgid "Change \"%.*s\" to:" -msgstr "Remplacer \"%.*s\" par :" +msgid "No Syntax items defined for this buffer" +msgstr "Aucun lment de syntaxe dfini pour ce tampon" -# DB - todo : l'intrt de traduire ce message m'chappe. #, c-format -msgid " < \"%.*s\"" -msgstr " < \"%.*s\"" +msgid "E390: Illegal argument: %s" +msgstr "E390: Argument invalide : %s" -msgid "E752: No previous spell replacement" -msgstr "E752: Pas de suggestion orthographique prcdente" +msgid "syntax iskeyword " +msgstr "syntaxe iskeyword " #, c-format -msgid "E753: Not found: %s" -msgstr "E753: Introuvable : %s" +msgid "E391: No such syntax cluster: %s" +msgstr "E391: Aucune grappe de syntaxe %s" -#, c-format -msgid "E778: This does not look like a .sug file: %s" -msgstr "E778: %s ne semble pas tre un fichier .sug" +msgid "syncing on C-style comments" +msgstr "synchronisation sur les commentaires de type C" -#, c-format -msgid "E779: Old .sug file, needs to be updated: %s" -msgstr "E779: Fichier de suggestions obsolte, mise jour ncessaire : %s" - -#, c-format -msgid "E780: .sug file is for newer version of Vim: %s" -msgstr "E780: Fichier .sug prvu pour une version de Vim plus rcente : %s" - -#, c-format -msgid "E781: .sug file doesn't match .spl file: %s" -msgstr "E781: Le fichier .sug ne correspond pas au fichier .spl : %s" - -#, c-format -msgid "E782: error while reading .sug file: %s" -msgstr "E782: Erreur lors de la lecture de fichier de suggestions : %s" - -#. This should have been checked when generating the .spl -#. file. -msgid "E783: duplicate char in MAP entry" -msgstr "E783: caractres dupliqu dans l'entre MAP" - -msgid "No Syntax items defined for this buffer" -msgstr "Aucun lment de syntaxe dfini pour ce tampon" - -#, c-format -msgid "E390: Illegal argument: %s" -msgstr "E390: Argument invalide : %s" - -#, c-format -msgid "E391: No such syntax cluster: %s" -msgstr "E391: Aucune grappe de syntaxe %s" - -msgid "syncing on C-style comments" -msgstr "synchronisation sur les commentaires de type C" - -msgid "no syncing" -msgstr "Aucune synchronisation" +msgid "no syncing" +msgstr "Aucune synchronisation" # DB - Les deux messages qui suivent vont ensemble. msgid "syncing starts " @@ -4970,6 +5728,10 @@ msgstr "E847: Trop d'inclusions de syntaxe" msgid "E789: Missing ']': %s" msgstr "E789: ']' manquant : %s" +#, c-format +msgid "E890: trailing char after ']': %s]%s" +msgstr "E890: Caractre surnumraire aprs ']': %s]%s" + #, c-format msgid "E398: Missing '=': %s" msgstr "E398: '=' manquant : %s" @@ -4984,7 +5746,6 @@ msgstr "E848: Trop de grappes de syntaxe" msgid "E400: No cluster specified" msgstr "E400: Aucune grappe spcifie" -#. end delimiter not found #, c-format msgid "E401: Pattern delimiter not found: %s" msgstr "E401: Dlimiteur de motif introuvable : %s" @@ -5025,9 +5786,10 @@ msgstr "E409: Nom de groupe inconnu : %s" msgid "E410: Invalid :syntax subcommand: %s" msgstr "E410: Sous-commande de :syntax invalide : %s" -#~ msgid "" -#~ " TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN" -#~ msgstr "" +msgid "" +" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN" +msgstr "" +" TOTAL NOMBRE MATCH PLUS LENT MOYEN NOM MOTIF" msgid "E679: recursive loop loading syncolor.vim" msgstr "E679: boucle rcursive lors du chargement de syncolor.vim" @@ -5150,6 +5912,10 @@ msgstr "" msgid "Searching tags file %s" msgstr "Examen du fichier de marqueurs %s" +#, c-format +msgid "E430: Tag file path truncated for %s\n" +msgstr "E430: Chemin de fichiers de marqueurs tronqu pour %s\n" + msgid "Ignoring long line in tags file" msgstr "Ignore longue ligne dans le fichier de marqueurs" @@ -5158,8 +5924,8 @@ msgid "E431: Format error in tags file \"%s\"" msgstr "E431: Erreur de format dans le fichier de marqueurs \"%s\"" #, c-format -msgid "Before byte %" -msgstr "Avant l'octet %" +msgid "Before byte %ld" +msgstr "Avant l'octet %ld" #, c-format msgid "E432: Tags file not sorted: %s" @@ -5210,14 +5976,28 @@ msgstr "" "\n" "--- Touches du terminal ---" +msgid "Cannot open $VIMRUNTIME/rgb.txt" +msgstr "Impossible d'ouvrir $VIMRUNTIME/rgb.txt" + +msgid "new shell started\n" +msgstr "nouveau shell dmarr\n" + msgid "Vim: Error reading input, exiting...\n" msgstr "Vim : Erreur lors de la lecture de l'entre, sortie...\n" +# DB - Message de dbogage. +msgid "Used CUT_BUFFER0 instead of empty selection" +msgstr "CUT_BUFFER0 utilis plutt qu'une slection vide" + #. This happens when the FileChangedRO autocommand changes the #. * file in a way it becomes shorter. -#, fuzzy -#~ msgid "E881: Line count changed unexpectedly" -#~ msgstr "E834: Le nombre de lignes a t chang inopinment" +msgid "E881: Line count changed unexpectedly" +msgstr "E881: Le nombre de lignes a t chang inopinment" + +# DB - Question O/N. +#. must display the prompt +msgid "No undo possible; continue anyway" +msgstr "Annulation impossible ; continuer" #, c-format msgid "E828: Cannot open undo file for writing: %s" @@ -5267,6 +6047,18 @@ msgstr "E822: Impossible d'ouvrir le fichier d'annulations en lecture : %s" msgid "E823: Not an undo file: %s" msgstr "E823: Ce n'est pas un fichier d'annulations : %s" +#, c-format +msgid "E832: Non-encrypted file has encrypted undo file: %s" +msgstr "E832: Fichier non-chiffr a un fichier d'annulations chiffr : %s" + +#, c-format +msgid "E826: Undo file decryption failed: %s" +msgstr "E826: Dchiffrage 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" @@ -5287,8 +6079,8 @@ msgid "Already at newest change" msgstr "Dj la modification la plus rcente" #, c-format -msgid "E830: Undo number % not found" -msgstr "E830: Annulation n % introuvable" +msgid "E830: Undo number %ld not found" +msgstr "E830: Annulation n %ld introuvable" msgid "E438: u_undo: line numbers wrong" msgstr "E438: u_undo : numros de ligne errons" @@ -5312,8 +6104,8 @@ msgid "changes" msgstr "modifications" #, c-format -msgid "% %s; %s #% %s" -msgstr "% %s ; %s #% ; %s" +msgid "%ld %s; %s #%ld %s" +msgstr "%ld %s ; %s #%ld ; %s" msgid "before" msgstr "avant" @@ -5329,8 +6121,8 @@ msgid "number changes when saved" msgstr "numro modif. instant enregistr" #, c-format -msgid "% seconds ago" -msgstr "il y a % secondes" +msgid "%ld seconds ago" +msgstr "il y a %ld secondes" msgid "E790: undojoin is not allowed after undo" msgstr "E790: undojoin n'est pas autoris aprs une annulation" @@ -5341,6 +6133,208 @@ msgstr "E439: la liste d'annulation est corrompue" msgid "E440: undo line missing" msgstr "E440: ligne d'annulation manquante" +#, c-format +msgid "E122: Function %s already exists, add ! to replace it" +msgstr "E122: La fonction %s existe dj (ajoutez ! pour la remplacer)" + +msgid "E717: Dictionary entry already exists" +msgstr "E717: Une entre du Dictionnaire porte dj ce nom" + +msgid "E718: Funcref required" +msgstr "E718: Rfrence 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 - Vrifier dans la littrature 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 suprieure 'maxfuncdepth'" + +# AB - Ce texte fait partie d'un message de dbogage. +#, c-format +msgid "calling %s" +msgstr "appel de %s" + +# AB - Vrifier. +#, c-format +msgid "%s aborted" +msgstr "%s annule" + +# AB - Ce texte fait partie d'un message de dbogage. +#, c-format +msgid "%s returning #%ld" +msgstr "%s a retourn #%ld" + +# AB - Ce texte fait partie d'un message de dbogage. +#, 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 efface: %s" + +#, c-format +msgid "E119: Not enough arguments for function: %s" +msgstr "E119: La fonction %s n'a pas reu assez d'arguments" + +#, c-format +msgid "E120: Using not in a script context: %s" +msgstr "E120: 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 caractre deux-points : " +"%s" + +#, c-format +msgid "E123: Undefined function: %s" +msgstr "E123: Fonction non dfinie : %s" + +# AB - La version franaise est plus consistante que la version anglaise. +# AB - Je suis partag entre la concision d'une traduction assez littrale et +# la lourdeur d'une traduction plus correcte. +#, c-format +msgid "E124: Missing '(': %s" +msgstr "E124: Il manque '(' aprs %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 redfinir fonction %s : dj utilise" + +# 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 crer une version franaise qui fasse moins de 80 +# caractres de long, nom de la fonction compris : "It is in use" est une +# expression trs dense. Traductions possibles : "elle est utilise", +# "elle s'excute" ou "elle est occupe". +#, c-format +msgid "E131: Cannot delete function %s: It is in use" +msgstr "E131: Impossible d'effacer %s : cette fonction est utilise" + +msgid "E133: :return not inside a function" +msgstr "E133: :return en dehors d'une fonction" + +#, c-format +msgid "E107: Missing parentheses: %s" +msgstr "E107: Parenthses 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: " @@ -5375,9 +6369,70 @@ msgstr "" "\n" "norme version " +msgid "" +"\n" +"Big version " +msgstr "" +"\n" +"Grosse version " + +msgid "" +"\n" +"Normal version " +msgstr "" +"\n" +"Version normale " + +msgid "" +"\n" +"Small version " +msgstr "" +"\n" +"Petite version " + +msgid "" +"\n" +"Tiny version " +msgstr "" +"\n" +"Version minuscule " + msgid "without GUI." msgstr "sans interface graphique." +msgid "with 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 " Fonctionnalits incluses (+) ou non (-) :\n" @@ -5399,6 +6454,24 @@ msgstr " fichier exrc utilisateur : \"" msgid " 2nd user exrc file: \"" msgstr " 2me fichier exrc utilisateur : \"" +msgid " system gvimrc file: \"" +msgstr " fichier gvimrc systme : \"" + +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 dfaut : \"" + +msgid " system menu file: \"" +msgstr " fichier menu systme : \"" + msgid " fall-back for $VIM: \"" msgstr " $VIM par dfaut : \"" @@ -5408,6 +6481,9 @@ msgstr " $VIMRUNTIME par d msgid "Compilation: " msgstr "Compilation : " +msgid "Compiler: " +msgstr "Compilateur : " + msgid "Linking: " msgstr "dition de liens : " @@ -5429,26 +6505,17 @@ msgstr "Vim est un logiciel libre" msgid "Help poor children in Uganda!" msgstr "Aidez les enfants pauvres d'Ouganda !" -msgid "type :help nvim if you are new! " -msgstr "tapez :help nvim si vous tes nouveau! " - -msgid "type :CheckHealth to optimize Nvim" -msgstr "tapez :CheckHealth pour optimiser Nvim " +msgid "type :help iccf for information " +msgstr "tapez :help iccf pour plus d'informations " msgid "type :q to exit " msgstr "tapez :q pour sortir du programme " -msgid "type :help for help " -msgstr "tapez :help pour obtenir de l'aide " - -msgid "type :help iccf for information " -msgstr "tapez :help iccf pour plus d'informations " - msgid "type :help or for on-line help" msgstr "tapez :help ou pour accder l'aide en ligne " -msgid "type :help version7 for version info" -msgstr "tapez :help version7 pour lire les notes de mise jour" +msgid "type :help version8 for version info" +msgstr "tapez :help version8 pour lire les notes de mise jour" # DB - Pour les trois messages qui suivent : # :set cp @@ -5462,17 +6529,38 @@ msgstr "tapez :set nocp for info on this" msgstr "tapez :help cp-default pour plus d'info" -msgid "Sponsor Vim development!" -msgstr "Sponsorisez le dveloppement de Vim !" +msgid "menu Help->Orphans for information " +msgstr "menu Aide->Orphelins pour plus d'info" -msgid "Become a registered Vim user!" -msgstr "Devenez un utilisateur de Vim enregistr !" +msgid "Running modeless, typed text is inserted" +msgstr "Les modes sont dsactivs, le texte saisi est insr" -msgid "type :help sponsor for information " -msgstr "tapez :help sponsor pour plus d'informations " +msgid "menu Edit->Global Settings->Toggle Insert Mode " +msgstr "menu dition->Rglages Globaux->Insertion Permanente" -msgid "type :help register for information " -msgstr "tapez :help register pour plus d'informations " +# DB - todo +msgid " for two modes " +msgstr " pour les modes " + +# DB - todo +msgid "menu Edit->Global Settings->Toggle Vi Compatible" +msgstr "menu dition->Rglages Globaux->Compatibilit Vi" + +# DB - todo +msgid " for Vim defaults " +msgstr " pour df. de Vim " + +msgid "Sponsor Vim development!" +msgstr "Sponsorisez le dveloppement de Vim !" + +msgid "Become a registered Vim user!" +msgstr "Devenez un utilisateur de Vim enregistr !" + +msgid "type :help sponsor for information " +msgstr "tapez :help sponsor pour plus d'informations " + +msgid "type :help register for information " +msgstr "tapez :help register pour plus d'informations " msgid "menu Help->Sponsor/Register for information " msgstr "menu Aide->Sponsor/Enregistrement pour plus d'info" @@ -5506,1711 +6594,724 @@ msgstr "E445: Les modifications de l'autre fen 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() appele 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 bote de dialogue affiche par inputdialog(). -#~ msgid "" -#~ "&OK\n" -#~ "&Cancel" -#~ msgstr "" -#~ "&Ok\n" -#~ "&Annuler" - -# AB - mon avis, la version anglaise est errone. -# DB : Vrifier -#~ msgid "E240: No connection to Vim server" -#~ msgstr "E240: Pas de connexion au serveur X" - -# AB - La version franaise 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 rponse du serveur" - -# AB - La version franaise est meilleure que la version anglaise. -#~ msgid "E258: Unable to send to client" -#~ msgstr "E258: La rponse n'a pas pu tre envoye au client" - -# AB - Ceci est un titre de bote de dialogue. Vrifier que la version -# franaise est correcte pour les trois rfrences ; j'ai un doute quant -# la troisime. -#~ msgid "Save As" -#~ msgstr "Enregistrer sous - Vim" - -# AB - Ceci est un titre de bote 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 fentre - Vim" - -#~ msgid "Append File" -#~ msgstr "Ajouter fichier" - -#~ msgid "Window position: X %d, Y %d" -#~ msgstr "Position de la fentre : 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 rglages - 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 priphrique (dsactiv 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 mthode inconnue" - -#~ msgid "NetBeans disallows writes of unmodified buffers" -#~ msgstr "NetBeans interdit l'criture des tampons non modifis" - -#~ 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 priphrique dsactiv par l'option 'opendevice'" - -#~ msgid "E460: The resource fork would be lost (add ! to override)" -#~ msgstr "" -#~ "E460: Les ressources partages seraient perdues (ajoutez ! pour passer " -#~ "outre)" - -#~ msgid "E851: Failed to create a new process for the GUI" -#~ msgstr "" -#~ "E851: chec lors de la cration 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 russi dmarrer l'interface graphique" - -#~ msgid "E229: Cannot start the GUI" -#~ msgstr "E229: Impossible de dmarrer 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 dmarrer l'IHM graphique, aucune police valide trouve" - -#~ 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 " " -#~ msgstr " " - -#~ 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 rpertoire courant" - -#~ msgid "Pathname:" -#~ msgstr "Chemin :" - -#~ msgid "E615: vim_SelFile: can't get current directory" -#~ msgstr "E615: vim_SelFile : impossible d'obtenir le rpertoire 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 gomtrie du pixmap 'thumb'" - -#~ msgid "Vim dialog" -#~ msgstr "Vim" - -#~ msgid "E232: Cannot create BalloonEval with both message and callback" -#~ msgstr "E232: Impossible de crer un BalloonEval avec message ET callback" - -msgid "Yes" -msgstr "Oui" - -msgid "No" -msgstr "Non" - -# todo '_' is for hotkey, i guess? -#~ msgid "Input _Methods" -#~ msgstr "_Mthodes 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 requte \"die\" a t reue 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 entre de menu permet d'ouvrir un fichier -# dans un nouvel onglet via le slecteur de fichiers graphique. -#~ msgid "Open Tab..." -#~ msgstr "Ouvrir dans un onglet..." - -#~ msgid "Vim: Main window unexpectedly destroyed\n" -#~ msgstr "Vim : Fentre principale dtruite inopinment\n" - -#~ msgid "&Filter" -#~ msgstr "&Filtrer" - -#~ msgid "&Cancel" -#~ msgstr "&Annuler" - -#~ msgid "Directories" -#~ msgstr "Rpertoires" - -#~ msgid "Filter" -#~ msgstr "Filtre" - -#~ msgid "&Help" -#~ msgstr "&Aide" - -#~ msgid "Files" -#~ msgstr "Fichiers" - -#~ msgid "&OK" -#~ msgstr "&Ok" - -#~ msgid "Selection" -#~ msgstr "Slection" - -#~ 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 fentre \"%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 fentre dans une application MDI" - -#~ msgid "Open tab..." -#~ msgstr "Ouvrir dans un onglet..." - -#~ msgid "Find string (use '\\\\' to find a '\\')" -#~ msgstr "Chercher une chane (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 -# paramtrage bidon afin de slectionner un rpertoire plutt qu'un -# fichier. -#~ msgid "Not Used" -#~ msgstr "Non utilis" - -# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un -# paramtrage bidon afin de slectionner un rpertoire plutt qu'un -# fichier. -#~ msgid "Directory\t*.nothing\n" -#~ msgstr "Rpertoire\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 comprhensible ? -#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:" -#~ msgstr "" -#~ "E250: Des polices manquent dans %s pour les jeux de caractres 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% width is not twice that of font0\n" -#~ msgstr "La largeur de Font% n'est pas le double de celle de Font0\n" - -#~ msgid "Font0 width: %\n" -#~ msgstr "Largeur de Font0 : %\n" - -#~ msgid "" -#~ "Font1 width: %\n" -#~ "\n" -#~ msgstr "" -#~ "Largeur de Font1 : %\n" -#~ "\n" - -# DB - todo : Pas certain de mon coup, ici... -#~ msgid "Invalid font specification" -#~ msgstr "La spcification 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 particulire" - -#~ 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 donnes cscope %s" - -#~ msgid "E626: cannot get cscope database information" -#~ msgstr "" -#~ "E626: impossible d'obtenir des informations sur la base de donnes cscope" - -#~ msgid "Lua library cannot be loaded." -#~ msgstr "La bibliothque Lua n'a pas pu tre charge." - -#~ 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: Dsol, cette commande est dsactive : les bibliothques MzScheme " -#~ "n'ont pas pu tre charges." - -#~ msgid "invalid expression" -#~ msgstr "expression invalide" - -#~ msgid "expressions disabled at compile time" -#~ msgstr "expressions dsactive lors de la compilation" - -#~ msgid "hidden option" -#~ msgstr "option cache" - -#~ msgid "unknown option" -#~ msgstr "option inconnue" - -#~ msgid "window index is out of range" -#~ msgstr "numro de fentre 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'insrer la ligne" - -#~ msgid "string cannot contain newlines" -#~ msgstr "une chane 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 "fentre invalide" - -#~ msgid "linenr out of range" -#~ msgstr "numro 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 excuter :python aprs avoir utilis :py3" - -#~ msgid "" -#~ "E263: Sorry, this command is disabled, the Python library could not be " -#~ "loaded." -#~ msgstr "" -#~ "E263: Dsol, commande dsactive : la bibliothque Python n'a pas pu " -#~ "tre charge." - -#~ msgid "E659: Cannot invoke Python recursively" -#~ msgstr "E659: Impossible d'invoquer Python rcursivement" - -#~ msgid "E837: This Vim cannot execute :py3 after using :python" -#~ msgstr "E837: Vim ne peut pas excuter :py3 aprs 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 chane (String)" - -#~ msgid "" -#~ "E266: Sorry, this command is disabled, the Ruby library could not be " -#~ "loaded." -#~ msgstr "" -#~ "E266: Dsol, commande dsactive : la bibliothque Ruby n'a pas pu tre " -#~ "charge." - -#~ 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 implmentation/dfinition" - -#~ msgid "Show base class of" -#~ msgstr "Montrer la classe de base de" - -#~ msgid "Show overridden member function" -#~ msgstr "Montrer les fonctions membres surcharges" - -#~ msgid "Retrieve from file" -#~ msgstr "Rcuprer du fichier" - -#~ msgid "Retrieve from project" -#~ msgstr "Rcuprer du projet" - -#~ msgid "Retrieve from all projects" -#~ msgstr "Rcuprer de tous les projets" - -#~ msgid "Retrieve" -#~ msgstr "Rcuprer" - -#~ 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 hirarchie" - -#~ msgid "Show class in restricted hierarchy" -#~ msgstr "Montrer classe dans hirarchie restreinte" - -# todo -#~ msgid "Xref refers to" -#~ msgstr "Xref rfrence" - -#~ msgid "Xref referred by" -#~ msgstr "Xref est rfrenc par" - -#~ msgid "Xref has a" -#~ msgstr "Xref a un(e)" - -#~ msgid "Xref used by" -#~ msgstr "Xref utilise par" - -#~ msgid "Show docu of" -#~ msgstr "Montrer doc de" - -#~ msgid "Generate docu for" -#~ msgstr "Gnrer la doc de" - -#~ msgid "" -#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in " -#~ "$PATH).\n" -#~ msgstr "" -#~ "Connexion SNiFF+ impossible. Vrifiez l'environnement (sniffemacs doit " -#~ "tre dans le $PATH).\n" - -#~ msgid "E274: Sniff: Error during read. Disconnected" -#~ msgstr "E274: Sniff : Erreur de lecture. Dconnexion" - -# 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: Requte 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. Dconnexion" - -#~ msgid "invalid buffer number" -#~ msgstr "numro de tampon invalide" - -#~ msgid "not implemented yet" -#~ msgstr "pas encore implment" - -# 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 positionne" - -#~ msgid "row %d column %d" -#~ msgstr "ligne %d colonne %d" - -#~ msgid "cannot insert/append line" -#~ msgstr "Impossible d'insrer/ajouter de lignes" - -#~ msgid "line number out of range" -#~ msgstr "numro 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 dj pris: %ld" -#~ msgid "cannot create buffer/window command: object is being deleted" -#~ msgstr "" -#~ "Impossible de crer commande de tampon/fentre : 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/fentre 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 : rf. tampon/fentre " -#~ "introuvable" +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: Impossible de charger la bibliothque %s" -#~ msgid "" -#~ "E571: Sorry, this command is disabled: the Tcl library could not be " -#~ "loaded." -#~ msgstr "" -#~ "E571: Dsol, commande dsactive: la bibliothque Tcl n'a pas pu tre " -#~ "charge." +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"Dsol, commande dsactive : la bibliothque Perl n'a pas pu tre charge." -#~ 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: Entre registre de l'instance de Vim mal formate. 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) slectionn(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 problme ! +msgid "Error creating process: Check if gvim is in your path!" +msgstr "" +"Erreur de cration du processus : vrifiez 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 : dsactiv 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 dmarrer 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 indiffrente (/ 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\tDsinscrire 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 dtacher 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 fentres" - -#~ msgid "-dev \t\tUse for I/O" -#~ msgstr "-dev \tUtiliser pour les E/S" - -#~ msgid "-U \t\tUse instead of any .gvimrc" -#~ msgstr "-U \tUtiliser au lieu du gvimrc habituel" - -#~ msgid "-x\t\t\tEdit encrypted files" -#~ msgstr "-x\t\t\tditer des fichiers chiffrs" - -#~ msgid "-display \tConnect vim to this particular X-server" -#~ msgstr "-display \tConnecter Vim au serveur X spcifi" - -#~ msgid "-X\t\t\tDo not connect to X server" -#~ msgstr "-X\t\t\tNe pas se connecter un serveur X" - -#~ msgid "--remote \tEdit in a Vim server if possible" -#~ msgstr "" -#~ "--remote \tditer les dans un serveur Vim si possible" - -#~ msgid "--remote-silent 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 As --remote but wait for files to have been edited" -#~ msgstr "" -#~ "--remote-wait \tComme --remote mais ne quitter qu' la fin de " -#~ "l'dition" - -#~ msgid "" -#~ "--remote-wait-silent 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] As --remote but use tab page per " -#~ "file" -#~ msgstr "" -#~ "--remote-tab[-wait][-silent] \tComme --remote mais ouvrir un onglet " -#~ "pour chaque fichier" - -#~ msgid "--remote-send \tSend to a Vim server and exit" -#~ msgstr "" -#~ "--remote-send \tEnvoyer un serveur Vim puis quitter" - -#~ msgid "" -#~ "--remote-expr \tEvaluate in a Vim server and print result" -#~ msgstr "" -#~ "--remote-expr \tvaluer dans un serveur Vim, afficher le " -#~ "rsultat" - -#~ msgid "--serverlist\t\tList available Vim server names and exit" -#~ msgstr "" -#~ "--serverlist\t\tLister les noms des serveurs Vim disponibles et quitter" - -#~ msgid "--servername \tSend to/become the Vim server " -#~ msgstr "--servername \tEnvoyer au/devenir le serveur Vim nomm " - -#~ 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 \tRun vim on " -#~ msgstr "-display \tLancer Vim sur ce " +#. +#. * 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 annule" -#~ msgid "-iconic\t\tStart vim iconified" -#~ msgstr "-iconic\t\tIconifier Vim au dmarrage" +msgid "E471: Argument required" +msgstr "E471: Argument requis" -#~ msgid "-background \tUse for the background (also: -bg)" -#~ msgstr "" -#~ "-background \tUtiliser pour l'arrire-plan\t (abrv : -" -#~ "bg)" +msgid "E10: \\ should be followed by /, ? or &" +msgstr "E10: \\ devrait tre suivi de /, ? ou &" -#~ msgid "-foreground \tUse for normal text (also: -fg)" -#~ msgstr "" -#~ "-foreground \tUtiliser pour le texte normal\t (abrv : -" -#~ "fg)" +msgid "E11: Invalid in command-line window; executes, CTRL-C quits" +msgstr "" +"E11: Invalide dans la fentre ligne-de-commande ; excute, CTRL-C quitte" -#~ msgid "-font \t\tUse for normal text (also: -fn)" -#~ msgstr "" -#~ "-font \tUtiliser 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 autorise depuis un exrc/vimrc dans rpertoire courant ou " +"une recherche de marqueur" -#~ msgid "-boldfont \tUse for bold text" -#~ msgstr "-boldfont \tUtiliser pour le texte gras" +msgid "E171: Missing :endif" +msgstr "E171: :endif manquant" -#~ msgid "-italicfont \tUse for italic text" -#~ msgstr "-italicfont \tUtiliser pour le texte italique" +msgid "E600: Missing :endtry" +msgstr "E600: :endtry manquant" -#~ msgid "-geometry \tUse for initial geometry (also: -geom)" -#~ msgstr "" -#~ "-geometry \tUtiliser cette initiale\t (abrv : -geom)" +msgid "E170: Missing :endwhile" +msgstr "E170: :endwhile manquant" -#~ msgid "-borderwidth \tUse a border width of (also: -bw)" -#~ msgstr "" -#~ "-borderwidth \tUtiliser cette de bordure\t (abrv : -" -#~ "bw)" +msgid "E170: Missing :endfor" +msgstr "E170: :endfor manquant" -#~ msgid "" -#~ "-scrollbarwidth Use a scrollbar width of (also: -sw)" -#~ msgstr "" -#~ "-scrollbarwidth \tUtiliser cette de barre de dfil. (abrv: -" -#~ "sw)" - -#~ msgid "-menuheight \tUse a menu bar height of (also: -mh)" -#~ msgstr "" -#~ "-menuheight \tUtiliser cette de menu\t (abrv : -mh)" - -#~ msgid "-reverse\t\tUse reverse video (also: -rv)" -#~ msgstr "-reverse\t\tUtiliser la vido inverse\t\t (abrv : -rv)" - -#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)" -#~ msgstr "+reverse\t\tNe pas utiliser de vido inverse\t (abrv : +rv)" - -#~ msgid "-xrm \tSet the specified resource" -#~ msgstr "-xrm \tConfigurer la spcifie" - -#~ msgid "" -#~ "\n" -#~ "Arguments recognised by gvim (GTK+ version):\n" -#~ msgstr "" -#~ "\n" -#~ "Arguments reconnus par gvim (version GTK+) :\n" - -#~ msgid "-display \tRun vim on (also: --display)" -#~ msgstr "" -#~ "-display \tLancer Vim sur ce \t(galement : --display)" - -#~ msgid "--role \tSet a unique role to identify the main window" -#~ msgstr "--role \tDonner un rle pour identifier la fentre principale" - -#~ msgid "--socketid \tOpen Vim inside another GTK widget" -#~ msgstr "--socketid \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 fentre sur stdout" - -#~ msgid "-P \tOpen Vim inside parent application" -#~ msgstr "-P \tOuvrir Vim dans une application parente" - -#~ msgid "--windowid \tOpen Vim inside another win32 widget" -#~ msgstr "--windowid \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'excution locale\n" - -#~ msgid "%d of %d edited" -#~ msgstr "%d dits 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 rgler les valeurs IC" - -#~ msgid "E285: Failed to create input context" -#~ msgstr "E285: chec de la cration du contexte de saisie" - -#~ msgid "E286: Failed to open input method" -#~ msgstr "E286: chec de l'ouverture de la mthode de saisie" +msgid "E13: File exists (add ! to override)" +msgstr "E13: Le fichier existe dj (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 mthode 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 prdition de Vim n'est pas support par la mthode 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 aprs avoir chang la cl de " -#~ "chiffrement, appuyez sur entre" +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 mme 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 "Dtacher ce menu" +#, c-format +msgid "E15: Invalid expression: %s" +msgstr "E15: Expression invalide : %s" -# DB : Les trois messages qui suivent sont des titres de botes -# de dialogue par dfaut. -#~ msgid "Select Directory dialog" -#~ msgstr "Slecteur de rpertoire" +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 rpertoire" -#~ msgid "E338: Sorry, no file browser in console mode" -#~ msgstr "E338: Dsol, pas de slecteur de fichiers en mode console" +#, c-format +msgid "E364: Library call failed for \"%s()\"" +msgstr "E364: L'appel la bibliothque 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 bibliothque" -#~ msgid "" -#~ "\n" -#~ "[bytes] total alloc-freed %-%, in use %, peak use " -#~ "%\n" -#~ msgstr "" -#~ "\n" -#~ "[octets] total allou-libr %-%, utilis %, pic " -#~ "%\n" +msgid "E19: Mark has invalid line number" +msgstr "E19: La marque a un numro de ligne invalide" -#~ msgid "" -#~ "[calls] total re/malloc()'s %, total free()'s %\n" -#~ "\n" -#~ msgstr "" -#~ "[appels] total re/malloc() %, total free() %\n" -#~ "\n" +msgid "E20: Mark not set" +msgstr "E20: Marque non positionne" -#~ 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 dsactiv" -#~ msgid "E341: Internal error: lalloc(%, )" -#~ msgstr "E341: Erreur interne : lalloc(%, )" +msgid "E22: Scripts nested too deep" +msgstr "E22: Trop de rcursion 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 mthode de chiffrage faible ; consultez :help 'cm'" +msgid "E24: No such abbreviation" +msgstr "E24: Cette abrviation 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 compile dans cette version" -#~ msgid "Keys don't match!" -#~ msgstr "Les cls ne correspondent pas !" +msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" +msgstr "E26: Le support de l'hbreu n'a pas t compil dans cette version\n" -#~ msgid "Cannot connect to Netbeans #2" -#~ msgstr "Impossible de se connecter Netbeans n2" +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'accs 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 insr" -#~ msgid "E658: NetBeans connection lost for buffer %" -#~ msgstr "E658: Connexion NetBeans perdue pour le tampon %" +msgid "E30: No previous command line" +msgstr "E30: Aucune ligne de commande prcdente" -#~ 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 dj 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 % lines" -#~ msgstr "libration de % lignes" +msgid "E33: No previous substitute regular expression" +msgstr "E33: Aucune expression rgulire de substitution prcdente" -#~ 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 prcdente" -#~ msgid "E531: Use \":gui\" to start the GUI" -#~ msgstr "E531: Utilisez \":gui\" pour dmarrer l'interface graphique" +msgid "E35: No previous regular expression" +msgstr "E35: Aucune expression rgulire prcdente" -#~ 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 autorises" -#~ 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 slectionner 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 crer le fichier %s" -#~ msgid "E533: can't select wide font" -#~ msgstr "E533: Impossible de slectionner 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 supporte" +#, 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 enregistres (ajoutez ! pour passer outre)" -#~ msgid "VIM: Can't open window!\n" -#~ msgstr "VIM : Impossible d'ouvrir la fentre !\n" +msgid "E37: No write since last change" +msgstr "E37: Modifications non enregistres" -#~ msgid "Need Amigados version 2.04 or later\n" -#~ msgstr "Amigados version 2.04 ou ultrieure est ncessaire\n" +msgid "E38: Null argument" +msgstr "E38: Argument null" -#~ msgid "Need %s version %\n" -#~ msgstr "%s version % est ncessaire\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 crer " +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: Mmoire puise" -#~ 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'excuter 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'excuter " +msgid "E459: Cannot go back to previous directory" +msgstr "E459: Impossible de retourner au rpertoire prcdent" -#~ 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 atteste 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 chane de recherche est endommage" -#~ 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 active (ajoutez ! pour passer outre)" -#~ msgid "'columns' is not 80, cannot execute external commands" -#~ msgstr "" -#~ "'columns' ne vaut pas 80, impossible d'excuter 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 slection 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 reu trop d'arguments" -#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\"" -#~ msgstr "E244: Jeu de caractres \"%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: Caractre '%c' invalide dans le nom de fonte \"%s\"" +msgid "E714: List required" +msgstr "E714: Liste requise" -#~ msgid "Opening the X display took % msec" -#~ msgstr "L'ouverture du display X a pris % 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 : Rception 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: Opration interdite dans le bac sable" -#~ msgid "Opening the X display timed out" -#~ msgstr "L'ouverture du display X a dpass le dlai d'attente" +msgid "E523: Not allowed here" +msgstr "E523: Interdit cet endroit" -#~ msgid "" -#~ "\n" -#~ "Cannot execute shell sh\n" -#~ msgstr "" -#~ "\n" -#~ "Impossible d'excuter 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 crer des tuyaux (pipes)\n" +msgid "E49: Invalid scroll size" +msgstr "E49: Valeur de dfilement 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 donnes 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 requte 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: Caractres surnumraires" -#~ 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 dvelopper les mtacaractres" -#~ 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 vnements en question sont ceux des messages qui suivent. -#~ msgid "Vim: Caught %s event\n" -#~ msgstr "Vim : vnement %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 dconnexion" +msgid "E81: Using not in a script context" +msgstr "E81: utilis en dehors d'un script" -#~ msgid "shutdown" -#~ msgstr "d'arrt" +msgid "E449: Invalid expression received" +msgstr "E449: Expression invalide reue" -#~ msgid "E371: Command not found" -#~ msgstr "E371: Commande introuvable" +msgid "E463: Region is guarded, cannot modify" +msgstr "E463: Cette zone est verrouille et ne peut pas tre modifie" -#~ 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 termines.\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 mmoire 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 mmoire pour parcourir les branches!" +msgid "E682: Invalid search pattern or delimiter" +msgstr "E682: Dlimiteur 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 supporte" +#, c-format +msgid "E764: Option '%s' is not set" +msgstr "E764: L'option '%s' n'est pas active" -#~ msgid "E845: Insufficient memory, word list will be incomplete" -#~ msgstr "E845: mmoire insuffisante, liste de mots peut-tre incomplte" +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: Rpertoire introuvable dans '%s' : \"%s\"" -#~ msgid "new shell started\n" -#~ msgstr "nouveau shell dmarr\n" +msgid "search hit TOP, continuing at BOTTOM" +msgstr "La recherche a atteint le HAUT, et continue en BAS" -# DB - Message de dbogage. -#~ msgid "Used CUT_BUFFER0 instead of empty selection" -#~ msgstr "CUT_BUFFER0 utilis plutt qu'une slection 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: Dchiffrage 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 " lance 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 systme : \"" - -#~ 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 systme : \"" - -#~ 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 cls vides ne sont pas autorises" -#~ msgid "Running modeless, typed text is inserted" -#~ msgstr "Les modes sont dsactivs, le texte saisi est insr" +msgid "dictionary is locked" +msgstr "dictionnaire est verrouill" -#~ msgid "menu Edit->Global Settings->Toggle Insert Mode " -#~ msgstr "menu dition->Rglages Globaux->Insertion Permanente" +msgid "list is locked" +msgstr "liste verrouille" -# 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->Rglages 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 df. de Vim " +#, c-format +msgid "expected str() or unicode() instance, but got %s" +msgstr "attendu instance de str() ou unicode(), mais reu %s" -#~ msgid "WARNING: Windows 95/98/ME detected" -#~ msgstr "ALERTE: Windows 95/98/ME dtect" +#, c-format +msgid "expected bytes() or str() instance, but got %s" +msgstr "attendu instance de bytes() ou str(), mais reu %s" -#~ msgid "type :help windows95 for info on this" -#~ msgstr "tapez :help windows95 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 reu %s" -#~ msgid "E370: Could not load library %s" -#~ msgstr "E370: Impossible de charger la bibliothque %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 reu " +"%s" -#~ msgid "" -#~ "Sorry, this command is disabled: the Perl library could not be loaded." -#~ msgstr "" -#~ "Dsol, commande dsactive : la bibliothque Perl n'a pas pu tre " -#~ "charge." +msgid "value is too large to fit into C int type" +msgstr "valeur trop grande pour tre stocke 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 stocke 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 zro" -#~ 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 zro" -#~ 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) slectionn(s) avec Vim" +msgid "failed to change directory" +msgstr "changement de rpertoire a chou" -# DB - MessageBox win32, la longueur n'est pas un problme ! -#~ msgid "Error creating process: Check if gvim is in your path!" -#~ msgstr "" -#~ "Erreur de cration du processus : vrifiez 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 rsultat de imp.find_module(), mais reu %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 rsultat de imp.find_module(), mais reu 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 bibliothque" +msgid "hashtab changed during iteration" +msgstr "la table de hachage a t change pendant une itration" -#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" -#~ msgstr "" -#~ "E26: Le support de l'hbreu 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 squence d'lments de taille 2, mais reu une squence 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 nomms" -#~ 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 : accs un lment %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 dcoupage en tranche ne peut pas tre zro" -#~ msgid "E449: Invalid expression received" -#~ msgstr "E449: Expression invalide reue" +#, c-format +msgid "attempt to assign sequence of size greater than %d to extended slice" +msgstr "" +"tentative d'assigner une squence de taille plus grande que %d un " +"dcoupage en tranche tendu " -#~ msgid "E463: Region is guarded, cannot modify" -#~ msgstr "E463: Cette zone est verrouille et ne peut pas tre modifie" +#, c-format +msgid "internal error: no vim list item %d" +msgstr "erreur interne : pas d'lment %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'lments 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'lment 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 squence de taille %d un dcoupage 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 cls vides ne sont pas autorises" +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 "excution 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 : accs un lment de liste a chou" +msgid "internal error: unknown option type" +msgstr "erreur interne : type d'option inconnu" -#~ msgid "list is locked" -#~ msgstr "liste verrouille" +msgid "problem while switching windows" +msgstr "problme lors du changement de fentres" -#~ 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 dsactiver une option globale %s" -#~ msgid "internal error: failed to add item to list" -#~ msgstr "erreur interne : ajout d'lment la liste a chou" +#, c-format +msgid "unable to unset option %s which does not have global value" +msgstr "impossible de dsactiver 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 rfrencer 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 rfrencer une fentre efface" -#~ msgid "failed to run function" -#~ msgstr "excution de la fonction a chou" +msgid "readonly attribute: buffer" +msgstr "attribut en lecture seule : tampon" -#~ msgid "unable to unset global option" -#~ msgstr "impossible de dsactiver 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 dsactiver une option sans une valeur globale" +msgid "no such window" +msgstr "Cette fentre n'existe pas" -#~ msgid "attempt to refer to deleted tab page" -#~ msgstr "tentative de rfrencer un onglet effac" +msgid "attempt to refer to deleted buffer" +msgstr "tentative de rfrencer 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 rfrencer une fentre efface" +msgid "mark name must be a single character" +msgstr "le nom de marque doit tre un seul caractre" -#~ 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 reu %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 dplacer au tampon %d" -#~ msgid "no such window" -#~ msgstr "Cette fentre n'existe pas" +#, c-format +msgid "expected vim.Window object, but got %s" +msgstr "attendu un objet vim.Window, mais reu %s" -#~ msgid "attempt to refer to deleted buffer" -#~ msgstr "tentative de rfrencer un tampon effac" +msgid "failed to find window in the current tab page" +msgstr "impossible de trouver une fentre 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 dplac la fentre spcifie" -#~ msgid "failed to switch to given buffer" -#~ msgstr "impossible de se dplacer au tampon donn" +#, c-format +msgid "expected vim.TabPage object, but got %s" +msgstr "attendu un objet vim.TabPage, mais reu %s" -#~ msgid "expected vim.window object" -#~ msgstr "objet vim.window attendu" +msgid "did not switch to the specified tab page" +msgstr "impossible de se dplacer l'onglet spcifi" -#~ msgid "failed to find window in the current tab page" -#~ msgstr "impossible de trouver une fentre dans l'onglet courant" +msgid "failed to run the code" +msgstr "excution du code a chou" -#~ msgid "did not switch to the specified window" -#~ msgstr "ne s'est pas dplac la fentre spcifie" +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 dplacer l'onglet spcifi" +#, 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 "excution 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 : rfrence NULL passe" -#~ 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 "rfrence NULL passe" +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/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 \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 % does not exist" -msgstr "E86: Хåե % Ϥޤ" - -#: ../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 % (add ! to override)" -msgstr "E89: Хåե % ѹ¸Ƥޤ (! ѹ˴)" +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 % not found" -msgstr "E92: Хåե % Ĥޤ" +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 %" -msgstr " %" +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 "% lines --%d%%--" -msgstr "% --%d%%--" +msgid "%ld lines --%d%%--" +msgstr "%ld --%d%%--" -#: ../buffer.c:2530 #, c-format -msgid "line % of % --%d%%-- col " -msgstr " % ( %) --%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=% id=%d name=%s" -msgstr " =% ̻=%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() ΰ" + +#, c-format +msgid "E737: Key already exists: %s" +msgstr "E737: ϴ¸ߤޤ: %s" -#: ../diff.c:146 #, c-format -msgid "E96: Can not diff more than % buffers" -msgstr "E96: % ʾΥХåեdiffǤޤ" +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,702 +438,447 @@ 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: %" -msgstr "E684: ꥹȤΥǥåϰϳǤ: %" - -#: ../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" +msgid "E724: variable nested too deep for displaying" +msgstr "E724: ɽˤѿҤ᤮ޤ" -#: ../eval.c:6499 -#, c-format -msgid "E721: Duplicate key in Dictionary: \"%s\"" -msgstr "E721: 񷿤˽ʣޤ: \"%s\"" +msgid "E805: Using a Float as a Number" +msgstr "E805: ưͤȤưäƤޤ" -#: ../eval.c:6517 -#, c-format -msgid "E722: Missing comma in Dictionary: %s" -msgstr "E722: 񷿤˥ޤޤ: %s" +msgid "E703: Using a Funcref as a Number" +msgstr "E703: ؿȷͤȤưäƤޤ" -#: ../eval.c:6524 -#, c-format -msgid "E723: Missing end of Dictionary '}': %s" -msgstr "E723: 񷿤κǸ '}' ޤ: %s" +msgid "E745: Using a List as a Number" +msgstr "E745: ꥹȷͤȤưäƤޤ" -#: ../eval.c:6555 -msgid "E724: variable nested too deep for displaying" -msgstr "E724: ɽˤѿҤ᤮ޤ" +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: ؿȷưȤưäƤޤ" + +msgid "E892: Using a String as a Float" +msgstr "E892: ʸưȤưäƤޤ" + +msgid "E893: Using a List as a Float" +msgstr "E893: ꥹȷưȤưäƤޤ" + +msgid "E894: Using a Dictionary as a Float" +msgstr "E894: 񷿤ưȤưäƤޤ" + +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: ؿȷʸȤưäƤޤ" + +msgid "E730: using List as a String" +msgstr "E730: ꥹȷʸȤưäƤޤ" + +msgid "E731: using Dictionary as a String" +msgstr "E731: 񷿤ʸȤưäƤޤ" + +msgid "E908: using an invalid value as a String" +msgstr "E908: ̵ͤʸȤưäƤޤ" -#: ../eval.c:7188 #, c-format -msgid "E740: Too many arguments for function %s" -msgstr "E740: ؿΰ¿᤮ޤ: %s" +msgid "E795: Cannot delete variable %s" +msgstr "E795: ѿ %s Ǥޤ" -#: ../eval.c:7190 #, c-format -msgid "E116: Invalid arguments for function %s" -msgstr "E116: ؿ̵ʰǤ: %s" +msgid "E704: Funcref variable name must start with a capital: %s" +msgstr "E704: ؿȷѿ̾ʸǻϤޤʤФʤޤ: %s" -#: ../eval.c:7377 #, c-format -msgid "E117: Unknown function: %s" -msgstr "E117: ̤ΤδؿǤ: %s" +msgid "E705: Variable name conflicts with existing function: %s" +msgstr "E705: ѿ̾¸δؿ̾Ⱦͤޤ: %s" -#: ../eval.c:7383 #, c-format -msgid "E119: Not enough arguments for function: %s" -msgstr "E119: ؿΰ­ޤ: %s" +msgid "E741: Value is locked: %s" +msgstr "E741: ͤåƤޤ: %s" + +msgid "Unknown" +msgstr "" -#: ../eval.c:7387 #, c-format -msgid "E120: Using not in a script context: %s" -msgstr "E120: ץȰʳȤޤ: %s" +msgid "E742: Cannot change value of %s" +msgstr "E742: %s ͤѹǤޤ" + +msgid "E698: variable nested too deep for making a copy" +msgstr "E698: ԡˤѿҤ᤮ޤ" + +msgid "" +"\n" +"# global variables:\n" +msgstr "" +"\n" +"# Хѿ:\n" + +msgid "" +"\n" +"\tLast set from " +msgstr "" +"\n" +"\tǸ˥åȤץ: " + +msgid "map() argument" +msgstr "map() ΰ" + +msgid "filter() argument" +msgstr "filter() ΰ" -#: ../eval.c:7391 #, c-format -msgid "E725: Calling dict function without Dictionary: %s" -msgstr "E725: ѴؿƤФޤ񤬤ޤ: %s" +msgid "E686: Argument of %s must be a List" +msgstr "E686: %s ΰϥꥹȷǤʤФʤޤ" + +msgid "E928: String required" +msgstr "E928: ʸɬפǤ" -#: ../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 +#. +#. * 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: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 : " +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld : " -#: ../eval.c:9291 #, c-format msgid "E700: Unknown function: %s" msgstr "E700: ̤ΤδؿǤ: %s" -#: ../eval.c:10729 +msgid "E922: expected a dict" +msgstr "E922: 񤬴ԤƤޤ" + +msgid "E923: Second argument of function() must be a list or a dict" +msgstr "E923: function() 2 ϥꥹȷޤϼ񷿤ǤʤФʤޤ" + +msgid "" +"&OK\n" +"&Cancel" +msgstr "" +"(&O)\n" +"󥻥(&C)" + 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 "E916: not a valid job" +msgstr "E916: ͭʥ֤ǤϤޤ" + msgid "E701: Invalid type for len()" msgstr "E701: len() ˤ̵ʷǤ" -#: ../eval.c:11980 +#, c-format +msgid "E798: ID is reserved for \":match\": %ld" +msgstr "E798: ID \":match\" Τͽ󤵤Ƥޤ: %ld" + 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 "" msgstr "<>" -#: ../eval.c:12282 +msgid "E240: No connection to Vim server" +msgstr "E240: Vim Сؤ³ޤ" + +#, c-format +msgid "E241: Unable to send to %s" +msgstr "E241: %s 뤳ȤǤޤ" + +msgid "E277: Unable to read a server reply" +msgstr "E277: Сαޤ" + msgid "remove() argument" msgstr "remove() ΰ" # Added at 10-Mar-2004. -#: ../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" +msgid "E258: Unable to send to client" +msgstr "E258: 饤Ȥ뤳ȤǤޤ" + +#, c-format +msgid "E927: Invalid action: '%s'" +msgstr "E927: ̵Ǥ: %s" + +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 "E891: Using a Funcref as a Float" -msgstr "E891: ؿȷưȤưäƤޤ" - -msgid "E892: Using a String as a Float" -msgstr "E892: ʸưȤưäƤޤ" - -msgid "E893: Using a List as a Float" -msgstr "E893: ꥹȷưȤưäƤޤ" - -msgid "E894: Using a Dictionary as a Float" -msgstr "E894: 񷿤ưȤưäƤޤ" - -#: ../eval.c:16259 -msgid "E729: using Funcref as a String" -msgstr "E729: ؿȷʸȤưäƤޤ" - -#: ../eval.c:16262 -msgid "E730: using List as a String" -msgstr "E730: ꥹȷʸȤưäƤޤ" - -#: ../eval.c:16265 -msgid "E731: using Dictionary as a String" -msgstr "E731: 񷿤ʸȤưäƤޤ" - -#: ../eval.c:16619 -#, c-format -msgid "E706: Variable type mismatch for: %s" -msgstr "E706: ѿηפޤ: %s" - -#: ../eval.c:16705 -#, c-format -msgid "E795: Cannot delete variable %s" -msgstr "E795: ѿ %s Ǥޤ" - -#: ../eval.c:16724 -#, c-format -msgid "E704: Funcref variable name must start with a capital: %s" -msgstr "E704: ؿȷѿ̾ʸǻϤޤʤФʤޤ: %s" - -#: ../eval.c:16732 -#, c-format -msgid "E705: Variable name conflicts with existing function: %s" -msgstr "E705: ѿ̾¸δؿ̾Ⱦͤޤ: %s" - -#: ../eval.c:16763 -#, c-format -msgid "E741: Value is locked: %s" -msgstr "E741: ͤåƤޤ: %s" - -#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839 -msgid "Unknown" -msgstr "" - -#: ../eval.c:16768 -#, c-format -msgid "E742: Cannot change value of %s" -msgstr "E742: %s ͤѹǤޤ" - -#: ../eval.c:16838 -msgid "E698: variable nested too deep for making a copy" -msgstr "E698: ԡˤѿҤ᤮ޤ" - -#: ../eval.c:17249 -#, c-format -msgid "E123: Undefined function: %s" -msgstr "E123: ̤δؿǤ: %s" - -#: ../eval.c:17260 -#, c-format -msgid "E124: Missing '(': %s" -msgstr "E124: '(' ޤ: %s" - -#: ../eval.c:17293 -msgid "E862: Cannot use g: here" -msgstr "E862: Ǥ g: ϻȤޤ" - -#: ../eval.c:17312 -#, c-format -msgid "E125: Illegal argument: %s" -msgstr "E125: ʰǤ: %s" - -#: ../eval.c:17323 -#, c-format -msgid "E853: Duplicate argument name: %s" -msgstr "E853: ̾ʣƤޤ: %s" - -#: ../eval.c:17416 -msgid "E126: Missing :endfunction" -msgstr "E126: :endfunction ޤ" - -#: ../eval.c:17537 -#, c-format -msgid "E707: Function name conflicts with variable: %s" -msgstr "E707: ؿ̾ѿ̾Ⱦͤޤ: %s" - -#: ../eval.c:17549 -#, c-format -msgid "E127: Cannot redefine function %s: It is in use" -msgstr "E127: ؿ %s Ǥޤ: Ǥ" - -#: ../eval.c:17604 -#, c-format -msgid "E746: Function name does not match script file name: %s" -msgstr "E746: ؿ̾ץȤΥե̾Ȱפޤ: %s" - -#: ../eval.c:17716 -msgid "E129: Function name required" -msgstr "E129: ؿ̾׵ᤵޤ" - -#: ../eval.c:17824 -#, c-format -msgid "E128: Function name must start with a capital or \"s:\": %s" -msgstr "E128: ؿ̾ʸ \"s:\" ǻϤޤʤФʤޤ: %s" - -#: ../eval.c:17833 -#, c-format -msgid "E884: Function name cannot contain a colon: %s" -msgstr "E884: ؿ̾ˤϥϴޤޤ: %s" - -#: ../eval.c:18336 -#, c-format -msgid "E131: Cannot delete function %s: It is in use" -msgstr "E131: ؿ %s Ǥޤ: Ǥ" - -#: ../eval.c:18441 -msgid "E132: Function call depth is higher than 'maxfuncdepth'" -msgstr "E132: ؿƽФҿ 'maxfuncdepth' Ķޤ" - -#: ../eval.c:18568 -#, c-format -msgid "calling %s" -msgstr "%s ¹Ǥ" - -#: ../eval.c:18651 -#, c-format -msgid "%s aborted" -msgstr "%s Ǥޤ" - -#: ../eval.c:18653 #, c-format -msgid "%s returning #%" -msgstr "%s #% ֤ޤ" +msgid "E935: invalid submatch number: %d" +msgstr "E935: ̵ʥ֥ޥåֹ: %d" -#: ../eval.c:18670 -#, c-format -msgid "%s returning %s" -msgstr "%s %s ֤ޤ" - -#: ../eval.c:18691 ../ex_cmds2.c:2695 -#, c-format -msgid "continuing in %s" -msgstr "%s μ¹Ԥ³Ǥ" - -#: ../eval.c:18795 -msgid "E133: :return not inside a function" -msgstr "E133: ؿ :return ޤ" - -#: ../eval.c:19159 -msgid "" -"\n" -"# global variables:\n" -msgstr "" -"\n" -"# Хѿ:\n" - -#: ../eval.c:19254 -msgid "" -"\n" -"\tLast set from " -msgstr "" -"\n" -"\tLast set from " +msgid "E677: Error writing temp file" +msgstr "E677: ե˥顼ȯޤ" -#: ../eval.c:19272 -msgid "No old files" -msgstr "ŤեϤޤ" +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 "% lines moved" -msgstr "% Ԥưޤ" +msgid "%ld lines moved" +msgstr "%ld Ԥưޤ" -#: ../ex_cmds.c:1175 #, c-format -msgid "% lines filtered" -msgstr "% Ԥե륿ޤ" +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 %" -msgstr "E141: Хåե % ˤ̾ޤ" +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 "% matches" -msgstr "% ս곺ޤ" +msgid "%ld matches" +msgstr "%ld ս곺ޤ" -#: ../ex_cmds.c:4388 #, c-format -msgid "% substitutions" -msgstr "% սִޤ" +msgid "%ld substitutions" +msgstr "%ld սִޤ" -#: ../ex_cmds.c:4392 msgid " on 1 line" msgstr " ( 1 )" -#: ../ex_cmds.c:4395 #, c-format -msgid " on % lines" -msgstr " ( % )" +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: %" -msgstr "E157: ̵sign̻ҤǤ: %" +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 %: %s" -msgstr " %: %s" +msgid "line %ld: %s" +msgstr " %ld: %s" -#: ../ex_cmds2.c:145 #, c-format msgid "cmd: %s" msgstr "ޥ: %s" @@ -1405,232 +1123,184 @@ msgstr " msgid "frame at highest level: %d" msgstr "ǹ٥Υե졼: %d" -#: ../ex_cmds2.c:322 #, c-format -msgid "Breakpoint in \"%s%s\" line %" -msgstr "֥졼ݥ \"%s%s\" %" +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 %" -msgstr "%3d %s %s %" +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 %: could not source \"%s\"" -msgstr " %: \"%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 %: sourcing \"%s\"" -msgstr " %: %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: % more files to edit" -msgstr "E173: Խ٤ե뤬 % Ĥޤ" +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: 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 \"\"" msgstr "E495: \"\"֤autocommandΥե̾ޤ" -#: ../ex_docmd.c:7850 msgid "E496: no autocommand buffer number to substitute for \"\"" msgstr "E496: \"\"֤autocommandХåեֹ椬ޤ" -#: ../ex_docmd.c:7861 msgid "E497: no autocommand match name to substitute for \"\"" msgstr "E497: \"\"֤autocommandγ̾ޤ" -#: ../ex_docmd.c:7870 msgid "E498: no :source file name to substitute for \"\"" msgstr "E498: \"\"֤ :source оݥե̾ޤ" -#: ../ex_docmd.c:7876 msgid "E842: no line number to use for \"\"" msgstr "E842: \"\"ֹ֤椬ޤ" -#: ../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 %" -msgstr "%s, %" +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' ץDzǤޤ)" + 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 %]" -msgstr "[% ܤѴ顼]" +msgid "[CONVERSION ERROR in line %ld]" +msgstr "[%ld ܤѴ顼]" -#: ../fileio.c:1835 #, c-format -msgid "[ILLEGAL BYTE in line %]" -msgstr "[% ܤʥХ]" +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 % (make 'fenc' empty to " +"E513: write error, conversion failed in line %ld (make 'fenc' empty to " "override)" msgstr "" -"E513: ߥ顼, Ѵ, Կ % (񤹤ˤ '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 %;" -msgstr " %;" +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 "% lines, " -msgstr "% , " +msgid "%ld lines, " +msgstr "%ld , " -#: ../fileio.c:3836 msgid "1 character" msgstr "1 ʸ" -#: ../fileio.c:3838 #, c-format -msgid "% characters" -msgstr "% ʸ" +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 " 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: : 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; executes, CTRL-C quits" -msgstr "E11: ޥɥ饤Ǥ̵Ǥ; Ǽ¹, 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 ޤ" - -#: ../globals.h:1005 -msgid "E170: Missing :endwhile" -msgstr "E170: :endwhile ޤ" +#, c-format +msgid "E254: Cannot allocate color %s" +msgstr "E254: %s οƤޤ" -#: ../globals.h:1006 -msgid "E170: Missing :endfor" -msgstr "E170: :endfor ޤ" +msgid "No match at cursor, finding next" +msgstr "ΰ֤˥ޥåϤޤ, 򸡺Ƥޤ" -#: ../globals.h:1007 -msgid "E588: :endwhile without :while" -msgstr "E588: :while Τʤ :endwhile ޤ" +msgid " " +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\"() Υ饤֥ƽФ˼Ԥޤ" - -#: ../globals.h:1026 -msgid "E19: Mark has invalid line number" -msgstr "E19: ޡ̵ʹֹ椬ꤵƤޤ" - -#: ../globals.h:1027 -msgid "E20: Mark not set" -msgstr "E20: ޡꤵƤޤ" +msgid "Yes" +msgstr "Ϥ" -#: ../globals.h:1029 -msgid "E21: Cannot make changes, 'modifiable' is off" -msgstr "E21: 'modifiable' դʤΤ, ѹǤޤ" +msgid "No" +msgstr "" -#: ../globals.h:1030 -msgid "E22: Scripts nested too deep" -msgstr "E22: ץȤҤ᤮ޤ" +msgid "Input _Methods" +msgstr "ץåȥ᥽å" -#: ../globals.h:1031 -msgid "E23: No alternate file" -msgstr "E23: եϤޤ" +msgid "VIM - Search and Replace..." +msgstr "VIM - ִ..." -#: ../globals.h:1032 -msgid "E24: No such abbreviation" -msgstr "E24: Τ褦ûϤϤޤ" +msgid "VIM - Search..." +msgstr "VIM - ..." -#: ../globals.h:1033 -msgid "E477: No ! allowed" -msgstr "E477: ! ϵĤƤޤ" +msgid "Find what:" +msgstr "ʸ:" -#: ../globals.h:1035 -msgid "E25: Nvim does not have a built-in GUI" -msgstr "E25: GUIϻԲǽǤ: ѥ̵ˤƤޤ" +msgid "Replace with:" +msgstr "ִʸ:" -#: ../globals.h:1036 -#, c-format -msgid "E28: No such highlight group name: %s" -msgstr "E28: Τ褦̾Υϥ饤ȥ롼פϤޤ: %s" +#. whole word only button +msgid "Match whole word only" +msgstr "Τ˳Τ" -#: ../globals.h:1037 -msgid "E29: No inserted text yet" -msgstr "E29: ޤƥȤƤޤ" +#. match case button +msgid "Match case" +msgstr "ʸ/ʸ̤" -#: ../globals.h:1038 -msgid "E30: No previous command line" -msgstr "E30: ˥ޥɹԤޤ" +msgid "Direction" +msgstr "" -#: ../globals.h:1039 -msgid "E31: No such mapping" -msgstr "E31: Τ褦ʥޥåԥ󥰤Ϥޤ" +#. 'Up' and 'Down' buttons +msgid "Up" +msgstr "" -#: ../globals.h:1040 -msgid "E479: No match" -msgstr "E479: Ϥޤ" +msgid "Down" +msgstr "" -#: ../globals.h:1041 -#, c-format -msgid "E480: No match: %s" -msgstr "E480: Ϥޤ: %s" +msgid "Find Next" +msgstr "򸡺" -#: ../globals.h:1042 -msgid "E32: No file name" -msgstr "E32: ե̾ޤ" +msgid "Replace" +msgstr "ִ" -#: ../globals.h:1044 -msgid "E33: No previous substitute regular expression" -msgstr "E33: ɽִޤ¹ԤƤޤ" +msgid "Replace All" +msgstr "ִ" -#: ../globals.h:1045 -msgid "E34: No previous command" -msgstr "E34: ޥɤޤ¹ԤƤޤ" +msgid "_Close" +msgstr "Ĥ(_C)" -#: ../globals.h:1046 -msgid "E35: No previous regular expression" -msgstr "E35: ɽޤ¹ԤƤޤ" +msgid "Vim: Received \"die\" request from session manager\n" +msgstr "Vim: åޥ͡㤫 \"die\" ׵ޤ\n" -#: ../globals.h:1047 -msgid "E481: No range allowed" -msgstr "E481: ϰϻϵĤƤޤ" +msgid "Close tab" +msgstr "֥ڡĤ" -#: ../globals.h:1048 -msgid "E36: Not enough room" -msgstr "E36: ɥ˽ʬʹ⤵⤷ޤ" +msgid "New tab" +msgstr "֥ڡ" -#: ../globals.h:1049 -#, c-format -msgid "E482: Can't create file %s" -msgstr "E482: ե %s Ǥޤ" +msgid "Open Tab..." +msgstr "֥ڡ򳫤..." -#: ../globals.h:1050 -msgid "E483: Can't get temp file name" -msgstr "E483: ե̾Ǥޤ" +msgid "Vim: Main window unexpectedly destroyed\n" +msgstr "Vim: ᥤ󥦥ɥ԰դ˲ޤ\n" -#: ../globals.h:1051 -#, c-format -msgid "E484: Can't open file %s" -msgstr "E484: ե \"%s\" 򳫤ޤ" +msgid "&Filter" +msgstr "ե륿(&F)" -#: ../globals.h:1052 -#, c-format -msgid "E485: Can't read file %s" -msgstr "E485: ե %s ɹޤ" +msgid "&Cancel" +msgstr "󥻥(&C)" -#: ../globals.h:1054 -msgid "E37: No write since last change (add ! to override)" -msgstr "E37: Ǹѹ¸Ƥޤ (! ɲäѹ˴)" +msgid "Directories" +msgstr "ǥ쥯ȥ" -#: ../globals.h:1055 -msgid "E37: No write since last change" -msgstr "E37: Ǹѹ¸Ƥޤ" +msgid "Filter" +msgstr "ե륿" -#: ../globals.h:1056 -msgid "E38: Null argument" -msgstr "E38: Ǥ" +msgid "&Help" +msgstr "إ(&H)" -#: ../globals.h:1057 -msgid "E39: Number expected" -msgstr "E39: ͤ׵ᤵƤޤ" +msgid "Files" +msgstr "ե" -#: ../globals.h:1058 -#, c-format -msgid "E40: Can't open errorfile %s" -msgstr "E40: 顼ե %s 򳫤ޤ" +msgid "&OK" +msgstr "&OK" -#: ../globals.h:1059 -msgid "E41: Out of memory!" -msgstr "E41: ꤬Ԥ̤Ƥޤ!" +msgid "Selection" +msgstr "" -#: ../globals.h:1060 -msgid "Pattern not found" -msgstr "ѥϸĤޤǤ" +msgid "Find &Next" +msgstr "򸡺(&N)" -#: ../globals.h:1061 -#, c-format -msgid "E486: Pattern not found: %s" -msgstr "E486: ѥϸĤޤǤ: %s" +msgid "&Replace" +msgstr "ִ(&R)" -#: ../globals.h:1062 -msgid "E487: Argument must be positive" -msgstr "E487: ͤǤʤФʤޤ" +msgid "Replace &All" +msgstr "ִ(&A)" -#: ../globals.h:1064 -msgid "E459: Cannot go back to previous directory" -msgstr "E459: Υǥ쥯ȥޤ" +msgid "&Undo" +msgstr "ɥ(&U)" -#: ../globals.h:1066 -msgid "E42: No Errors" -msgstr "E42: 顼Ϥޤ" +msgid "Open tab..." +msgstr "֥ڡ򳫤" -#: ../globals.h:1067 -msgid "E776: No location list" -msgstr "E776: ꥹȤϤޤ" +msgid "Find string (use '\\\\' to find a '\\')" +msgstr "ʸ ('\\' 򸡺ˤ '\\\\')" -#: ../globals.h:1068 -msgid "E43: Damaged match string" -msgstr "E43: ʸ»Ƥޤ" +msgid "Find & Replace (use '\\\\' to find a '\\')" +msgstr "ִ ('\\' 򸡺ˤ '\\\\')" -#: ../globals.h:1069 -msgid "E44: Corrupted regexp program" -msgstr "E44: ɽץǤ" +#. 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:1071 -msgid "E45: 'readonly' option is set (add ! to override)" -msgstr "E45: 'readonly' ץꤵƤޤ (! ɲäǾ)" +msgid "Directory\t*.nothing\n" +msgstr "ǥ쥯ȥ\t*.nothing\n" -#: ../globals.h:1073 #, c-format -msgid "E46: Cannot change read-only variable \"%s\"" -msgstr "E46: ɼѿ \"%s\" ˤͤǤޤ" +msgid "E671: Cannot find window title \"%s\"" +msgstr "E671: ȥ뤬 \"%s\" ΥɥϸĤޤ" -#: ../globals.h:1075 #, c-format -msgid "E794: Cannot set variable in the sandbox: \"%s\"" -msgstr "E794: ɥܥåǤѿ \"%s\" ͤǤޤ" - -#: ../globals.h:1076 -msgid "E47: Error while reading errorfile" -msgstr "E47: 顼եɹ˥顼ȯޤ" - -#: ../globals.h:1078 -msgid "E48: Not allowed in sandbox" -msgstr "E48: ɥܥåǤϵޤ" - -#: ../globals.h:1080 -msgid "E523: Not allowed here" -msgstr "E523: ǤϵĤޤ" - -#: ../globals.h:1082 -msgid "E359: Screen mode setting not supported" -msgstr "E359: ꡼⡼ɤˤбƤޤ" - -#: ../globals.h:1083 -msgid "E49: Invalid scroll size" -msgstr "E49: ̵ʥ̤Ǥ" - -#: ../globals.h:1084 -msgid "E91: 'shell' option is empty" -msgstr "E91: 'shell' ץ󤬶Ǥ" - -#: ../globals.h:1085 -msgid "E255: Couldn't read in sign data!" -msgstr "E255: sign ΥǡɹޤǤ" - -#: ../globals.h:1086 -msgid "E72: Close error on swap file" -msgstr "E72: åץեΥ顼Ǥ" +msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." +msgstr "E243: ϥݡȤޤ: \"-%s\"; OLEǤѤƤ." -#: ../globals.h:1087 -msgid "E73: tag stack empty" -msgstr "E73: åǤ" +msgid "E672: Unable to open window inside MDI application" +msgstr "E672: MDIץǤϥɥ򳫤ޤ" -#: ../globals.h:1088 -msgid "E74: Command too complex" -msgstr "E74: ޥɤʣ᤮ޤ" +msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" +msgstr "Vim E458: ꤬ʤΤǥȥƤޤ" -#: ../globals.h:1089 -msgid "E75: Name too long" -msgstr "E75: ̾Ĺ᤮ޤ" +#, c-format +msgid "E250: Fonts for the following charsets are missing in fontset %s:" +msgstr "E250: ʲʸåȤΥեȤޤ %s:" -#: ../globals.h:1090 -msgid "E76: Too many [" -msgstr "E76: [ ¿᤮ޤ" +#, c-format +msgid "E252: Fontset name: %s" +msgstr "E252: եȥå̾: %s" -#: ../globals.h:1091 -msgid "E77: Too many file names" -msgstr "E77: ե̾¿᤮ޤ" +#, c-format +msgid "Font '%s' is not fixed-width" +msgstr "ե '%s' ϸǤϤޤ" -#: ../globals.h:1092 -msgid "E488: Trailing characters" -msgstr "E488: ;ʬʸˤޤ" +#, c-format +msgid "E253: Fontset name: %s" +msgstr "E253: եȥå̾: %s" -#: ../globals.h:1093 -msgid "E78: Unknown mark" -msgstr "E78: ̤ΤΥޡ" +#, c-format +msgid "Font0: %s" +msgstr "ե0: %s" -#: ../globals.h:1094 -msgid "E79: Cannot expand wildcards" -msgstr "E79: 磻ɥɤŸǤޤ" +#, c-format +msgid "Font1: %s" +msgstr "ե1: %s" -#: ../globals.h:1096 -msgid "E591: 'winheight' cannot be smaller than 'winminheight'" -msgstr "E591: 'winheight' 'winminheight' 꾮Ǥޤ" +#, c-format +msgid "Font%ld width is not twice that of font0" +msgstr "ե%ld ե02ܤǤϤޤ" -#: ../globals.h:1098 -msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'" -msgstr "E592: 'winwidth' 'winminwidth' 꾮Ǥޤ" +#, c-format +msgid "Font0 width: %ld" +msgstr "ե0: %ld" -#: ../globals.h:1099 -msgid "E80: Error while writing" -msgstr "E80: Υ顼" +#, c-format +msgid "Font1 width: %ld" +msgstr "ե1: %ld" -#: ../globals.h:1100 -msgid "Zero count" -msgstr "" +msgid "Invalid font specification" +msgstr "̵ʥեȻǤ" -#: ../globals.h:1101 -msgid "E81: Using not in a script context" -msgstr "E81: ץȰʳȤޤ" +msgid "&Dismiss" +msgstr "Ѳ(&D)" -#: ../globals.h:1102 -#, c-format -msgid "E685: Internal error: %s" -msgstr "E685: 顼Ǥ: %s" +msgid "no specific match" +msgstr "ޥåΤޤ" -#: ../globals.h:1104 -msgid "E363: pattern uses more memory than 'maxmempattern'" -msgstr "E363: ѥ 'maxmempattern' ʾΥѤޤ" +msgid "Vim - Font Selector" +msgstr "Vim - ե" -#: ../globals.h:1105 -msgid "E749: empty buffer" -msgstr "E749: ХåեǤ" +msgid "Name:" +msgstr "̾:" -#: ../globals.h:1108 -msgid "E682: Invalid search pattern or delimiter" -msgstr "E682: ѥ󤫶ڤ국椬Ǥ" +#. create toggle button +msgid "Show size in Points" +msgstr "ݥȤɽ" -#: ../globals.h:1109 -msgid "E139: File is loaded in another buffer" -msgstr "E139: Ʊ̾Υե뤬¾ΥХåեɹޤƤޤ" +msgid "Encoding:" +msgstr "󥳡:" -#: ../globals.h:1110 -#, c-format -msgid "E764: Option '%s' is not set" -msgstr "E764: ץ '%s' ꤵƤޤ" +msgid "Font:" +msgstr "ե:" -#: ../globals.h:1111 -msgid "E850: Invalid register name" -msgstr "E850: ̵ʥ쥸̾Ǥ" +msgid "Style:" +msgstr ":" -#: ../globals.h:1114 -msgid "search hit TOP, continuing at BOTTOM" -msgstr "ޤǸΤDzޤ" +msgid "Size:" +msgstr ":" -#: ../globals.h:1115 -msgid "search hit BOTTOM, continuing at TOP" -msgstr "ޤǸΤǾޤ" +msgid "E256: Hangul automata ERROR" +msgstr "E256: ϥ󥰥륪ȥޥȥ󥨥顼" -#: ../hardcopy.c:240 msgid "E550: Missing colon" msgstr "E550: 󤬤ޤ" -#: ../hardcopy.c:252 msgid "E551: Illegal component" msgstr "E551: ʹʸǤǤ" -#: ../hardcopy.c:259 msgid "E552: digit expected" msgstr "E552: ͤɬפǤ" -#: ../hardcopy.c:473 #, c-format msgid "Page %d" msgstr "%d ڡ" -#: ../hardcopy.c:597 msgid "No text to be printed" msgstr "ƥȤޤ" -#: ../hardcopy.c:668 #, c-format msgid "Printing page %d (%d%%)" msgstr ": ڡ %d (%d%%)" -#: ../hardcopy.c:680 #, c-format msgid " Copy %d of %d" msgstr " ԡ %d ( %d )" -#: ../hardcopy.c:733 #, c-format msgid "Printed: %s" msgstr "ޤ: %s" -#: ../hardcopy.c:740 msgid "Printing aborted" msgstr "ߤޤ" -#: ../hardcopy.c:1365 msgid "E455: Error writing to PostScript output file" msgstr "E455: PostScriptϥեνߥ顼Ǥ" -#: ../hardcopy.c:1747 #, c-format msgid "E624: Can't open file \"%s\"" msgstr "E624: ե \"%s\" 򳫤ޤ" -#: ../hardcopy.c:1756 ../hardcopy.c:2470 #, c-format msgid "E457: Can't read PostScript resource file \"%s\"" msgstr "E457: PostScriptΥ꥽ե \"%s\" ɹޤ" -#: ../hardcopy.c:1772 #, c-format msgid "E618: file \"%s\" is not a PostScript resource file" msgstr "E618: ե \"%s\" PostScript ꥽եǤϤޤ" -#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844 #, c-format msgid "E619: file \"%s\" is not a supported PostScript resource file" msgstr "E619: ե \"%s\" бƤʤ PostScript ꥽եǤ" -#: ../hardcopy.c:1856 #, c-format msgid "E621: \"%s\" resource file has wrong version" msgstr "E621: ꥽ե \"%s\" ϥС󤬰ۤʤޤ" -#: ../hardcopy.c:2225 msgid "E673: Incompatible multi-byte encoding and character set." msgstr "E673: ߴ̵ޥХȥ󥳡ǥ󥰤ʸåȤǤ" -#: ../hardcopy.c:2238 msgid "E674: printmbcharset cannot be empty with multi-byte encoding." msgstr "E674: ޥХȥ󥳡ǥ󥰤Ǥ printmbcharset ˤǤޤ" -#: ../hardcopy.c:2254 msgid "E675: No default font specified for multi-byte printing." msgstr "" "E675: ޥХʸ뤿ΥǥեȥեȤꤵƤޤ" -#: ../hardcopy.c:2426 msgid "E324: Can't open PostScript output file" msgstr "E324: PostScriptѤΥե򳫤ޤ" -#: ../hardcopy.c:2458 #, c-format msgid "E456: Can't open file \"%s\"" msgstr "E456: ե \"%s\" 򳫤ޤ" -#: ../hardcopy.c:2583 msgid "E456: Can't find PostScript resource file \"prolog.ps\"" msgstr "E456: PostScriptΥ꥽ե \"prolog.ps\" Ĥޤ" -#: ../hardcopy.c:2593 msgid "E456: Can't find PostScript resource file \"cidfont.ps\"" msgstr "E456: PostScriptΥ꥽ե \"cidfont.ps\" Ĥޤ" -#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665 #, c-format msgid "E456: Can't find PostScript resource file \"%s.ps\"" msgstr "E456: PostScriptΥ꥽ե \"%s.ps\" Ĥޤ" -#: ../hardcopy.c:2654 #, c-format msgid "E620: Unable to convert to print encoding \"%s\"" msgstr "E620: 󥳡 \"%s\" ѴǤޤ" -#: ../hardcopy.c:2877 msgid "Sending to printer..." msgstr "ץ󥿤..." -#: ../hardcopy.c:2881 msgid "E365: Failed to print PostScript file" msgstr "E365: PostScriptեΰ˼Ԥޤ" -#: ../hardcopy.c:2883 msgid "Print job sent." msgstr "֤ޤ." -#: ../if_cscope.c:85 msgid "Add a new database" msgstr "ǡ١ɲ" -#: ../if_cscope.c:87 msgid "Query for a pattern" msgstr "ѥΥ꡼ɲ" -#: ../if_cscope.c:89 msgid "Show this message" msgstr "Υåɽ" -#: ../if_cscope.c:91 msgid "Kill a connection" msgstr "³λ" -#: ../if_cscope.c:93 msgid "Reinit all connections" msgstr "Ƥ³ƽ" -#: ../if_cscope.c:95 msgid "Show connections" msgstr "³ɽ" -#: ../if_cscope.c:101 #, c-format msgid "E560: Usage: cs[cope] %s" msgstr "E560: ˡ: cs[cope] %s" -#: ../if_cscope.c:225 msgid "This cscope command does not support splitting the window.\n" msgstr "cscopeޥɤʬ䥦ɥǤϥݡȤޤ.\n" -#: ../if_cscope.c:266 msgid "E562: Usage: cstag " msgstr "E562: ˡ: cstag " -#: ../if_cscope.c:313 msgid "E257: cstag: tag not found" msgstr "E257: cstag: Ĥޤ" -#: ../if_cscope.c:461 #, c-format msgid "E563: stat(%s) error: %d" msgstr "E563: stat(%s) 顼: %d" -#: ../if_cscope.c:551 +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 %" -msgstr "E262: cscope³ % ɹΥ顼Ǥ" +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,111 +2592,319 @@ 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 "Unknown option argument" -msgstr "̤ΤΥץǤ" +msgid "Lua library cannot be loaded." +msgstr "Lua饤֥ɤǤޤ." -#: ../main.c:146 -msgid "Too many edit arguments" -msgstr "Խ¿᤮ޤ" +msgid "cannot save undo information" +msgstr "ɥ¸Ǥޤ" -#: ../main.c:148 -msgid "Argument missing after" -msgstr "ޤ" +msgid "" +"E815: Sorry, this command is disabled, the MzScheme libraries could not be " +"loaded." +msgstr "E815: Υޥɤ̵Ǥ. MzScheme 饤֥ɤǤޤ." -#: ../main.c:150 -msgid "Garbage after option argument" -msgstr "ץθ˥ߤޤ" +msgid "" +"E895: Sorry, this command is disabled, the MzScheme's racket/base module " +"could not be loaded." +msgstr "" +"E895: Υޥɤ̵Ǥ,ʤ. MzScheme racket/base ⥸塼" +"ɤǤޤǤ." -#: ../main.c:152 -msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" -msgstr "\"+command\", \"-c command\", \"--cmd command\" ΰ¿᤮ޤ" +msgid "invalid expression" +msgstr "̵ʼǤ" -#: ../main.c:154 -msgid "Invalid argument for" -msgstr "̵ʰǤ: " +msgid "expressions disabled at compile time" +msgstr "ϥѥ̵ˤƤޤ" -#: ../main.c:294 -#, c-format -msgid "%d files to edit\n" -msgstr "%d ĤΥե뤬Խ򹵤Ƥޤ\n" +msgid "hidden option" +msgstr "ץ" -#: ../main.c:1342 -msgid "Attempt to open script file again: \"" -msgstr "ץȥեƤӳƤߤޤ: \"" +msgid "unknown option" +msgstr "̤ΤΥץǤ" -#: ../main.c:1350 -msgid "Cannot open for reading: \"" -msgstr "ɹѤȤƳޤ" +msgid "window index is out of range" +msgstr "ϰϳΥɥֹǤ" -#: ../main.c:1393 -msgid "Cannot open for script output: \"" -msgstr "ץȽѤ򳫤ޤ" +msgid "couldn't open buffer" +msgstr "Хåե򳫤ޤ" -#: ../main.c:1622 -msgid "Vim: Warning: Output is not to a terminal\n" -msgstr "Vim: ٹ: üؤνϤǤϤޤ\n" +msgid "cannot delete line" +msgstr "Ԥäޤ" -#: ../main.c:1624 -msgid "Vim: Warning: Input is not from a terminal\n" -msgstr "Vim: ٹ: üϤǤϤޤ\n" +msgid "cannot replace line" +msgstr "ԤִǤޤ" -#. just in case.. -#: ../main.c:1891 -msgid "pre-vimrc command line" -msgstr "vimrcΥޥɥ饤" +msgid "cannot insert line" +msgstr "ԤǤޤ" -#: ../main.c:1964 -#, c-format -msgid "E282: Cannot read from \"%s\"" -msgstr "E282: \"%s\"ɹळȤǤޤ" +msgid "string cannot contain newlines" +msgstr "ʸˤϲʸޤޤ" -#: ../main.c:2149 -msgid "" -"\n" +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 "̤ΤΥץǤ" + +msgid "Too many edit arguments" +msgstr "Խ¿᤮ޤ" + +msgid "Argument missing after" +msgstr "ޤ" + +msgid "Garbage after option argument" +msgstr "ץθ˥ߤޤ" + +msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" +msgstr "\"+command\", \"-c command\", \"--cmd command\" ΰ¿᤮ޤ" + +msgid "Invalid argument for" +msgstr "̵ʰǤ: " + +#, c-format +msgid "%d files to edit\n" +msgstr "%d ĤΥե뤬Խ򹵤Ƥޤ\n" + +msgid "netbeans is not supported with this GUI\n" +msgstr "netbeans ϤGUIǤѤǤޤ\n" + +msgid "'-nb' cannot be used: not enabled at compile time\n" +msgstr "'-nb' ԲǽǤ: ѥ̵ˤƤޤ\n" + +msgid "This Vim was not compiled with the diff feature." +msgstr "Vimˤdiffǽޤ(ѥ)." + +msgid "Attempt to open script file again: \"" +msgstr "ץȥեƤӳƤߤޤ: \"" + +msgid "Cannot open for reading: \"" +msgstr "ɹѤȤƳޤ" + +msgid "Cannot open for script output: \"" +msgstr "ץȽѤ򳫤ޤ" + +msgid "Vim: Error: Failure to start gvim from NetBeans\n" +msgstr "Vim: 顼: NetBeansgvim򥹥ȤǤޤ\n" + +msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n" +msgstr "Vim: 顼: ΥСVimCygwinüǤưޤ\n" + +msgid "Vim: Warning: Output is not to a terminal\n" +msgstr "Vim: ٹ: üؤνϤǤϤޤ\n" + +msgid "Vim: Warning: Input is not from a terminal\n" +msgstr "Vim: ٹ: üϤǤϤޤ\n" + +#. just in case.. +msgid "pre-vimrc command line" +msgstr "vimrcΥޥɥ饤" + +#, c-format +msgid "E282: Cannot read from \"%s\"" +msgstr "E282: \"%s\"ɹळȤǤޤ" + +msgid "" +"\n" "More info with: \"vim -h\"\n" msgstr "" "\n" "ܺ٤ʾ: \"vim -h\"\n" -#: ../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\tgvimOLEȤϿ" + +msgid "-unregister\t\tUnregister gvim for OLE" +msgstr "-unregister\t\tgvimOLEϿ" + +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\tEx⡼" -#: ../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 \t\tUse for I/O" +msgstr "-dev \t\tI/O Ѥ" + 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 \tSet terminal type to " msgstr "-T \tü ꤹ" -#: ../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 \t\tUse instead of any .vimrc" msgstr "-u \t\t.vimrc Ȥ" -#: ../main.c:2226 +msgid "-U \t\tUse instead of any .gvimrc" +msgstr "-U \t\t.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 "+\t\tStart at line " msgstr "+\t\t ԤϤ" -#: ../main.c:2232 msgid "--cmd \tExecute before loading any vimrc file" msgstr "--cmd \tvimrcɤ ¹Ԥ" -#: ../main.c:2233 msgid "-c \t\tExecute after loading the first file" msgstr "-c \t\tǽΥեɸ ¹Ԥ" -#: ../main.c:2235 msgid "-S \t\tSource file after loading the first file" msgstr "-S \t\tǽΥեɸե " -#: ../main.c:2236 msgid "-s \tRead Normal mode commands from file " msgstr "-s \tե Ρޥ륳ޥɤɹ" -#: ../main.c:2237 msgid "-w \tAppend all typed commands to file " msgstr "-w \tϤޥɤե ɲä" -#: ../main.c:2238 msgid "-W \tWrite all typed commands to file " msgstr "-W \tϤޥɤե ¸" -#: ../main.c:2240 +msgid "-x\t\t\tEdit encrypted files" +msgstr "-x\t\t\tŹ沽줿եԽ" + +msgid "-display \tConnect vim to this particular X-server" +msgstr "-display \tvimꤷ X С³" + +msgid "-X\t\t\tDo not connect to X server" +msgstr "-X\t\t\tXС³ʤ" + +msgid "--remote \tEdit in a Vim server if possible" +msgstr "--remote \tǽʤVimС Խ" + +msgid "--remote-silent Same, don't complain if there is no server" +msgstr "--remote-silent Ʊ, С̵ƤٹʸϤʤ" + +msgid "" +"--remote-wait As --remote but wait for files to have been edited" +msgstr "--remote-wait \t--remote եԽΤԤ" + +msgid "" +"--remote-wait-silent Same, don't complain if there is no server" +msgstr "" +"--remote-wait-silent Ʊ, С̵ƤٹʸϤʤ" + +msgid "" +"--remote-tab[-wait][-silent] As --remote but use tab page per file" +msgstr "" +"--remote-tab[-wait][-silent] --remoteǥե1ĤˤĤ1ĤΥ" +"ڡ򳫤" + +msgid "--remote-send \tSend to a Vim server and exit" +msgstr "--remote-send \tVimС ƽλ" + +msgid "--remote-expr \tEvaluate in a Vim server and print result" +msgstr "--remote-expr \tС ¹ԤƷ̤ɽ" + +msgid "--serverlist\t\tList available Vim server names and exit" +msgstr "--serverlist\t\tVimС̾ΰɽƽλ" + +msgid "--servername \tSend to/become the Vim server " +msgstr "--servername \tVimС /̾ꤹ" + msgid "--startuptime \tWrite startup timing messages to " msgstr "--startuptime \tưˤä֤ξܺ٤ ؽϤ" -#: ../main.c:2242 msgid "-i \t\tUse instead of .viminfo" msgstr "-i \t\t.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 \tRun vim on " +msgstr "-display \t vim¹Ԥ" + +msgid "-iconic\t\tStart vim iconified" +msgstr "-iconic\t\tǾ֤vimư" + +msgid "-background \tUse for the background (also: -bg)" +msgstr "-background \tطʿ Ȥ(Ʊ: -bg)" + +msgid "-foreground \tUse for normal text (also: -fg)" +msgstr "-foreground \tʿ Ȥ(Ʊ: -fg)" + +msgid "-font \t\tUse for normal text (also: -fn)" +msgstr "-font \t\tƥɽ Ȥ(Ʊ: -fn)" + +msgid "-boldfont \tUse for bold text" +msgstr "-boldfont \t Ȥ" + +msgid "-italicfont \tUse for italic text" +msgstr "-italicfont \tλ Ȥ" + +msgid "-geometry \tUse for initial geometry (also: -geom)" +msgstr "-geometry \t֤ Ȥ(Ʊ: -geom)" + +msgid "-borderwidth \tUse a border width of (also: -bw)" +msgstr "-borderwidth \t ˤ(Ʊ: -bw)" + +msgid "-scrollbarwidth Use a scrollbar width of (also: -sw)" +msgstr "" +"-scrollbarwidth С ˤ(Ʊ: -sw)" + +msgid "-menuheight \tUse a menu bar height of (also: -mh)" +msgstr "-menuheight \t˥塼Сι⤵ ˤ(Ʊ: -mh)" + +msgid "-reverse\t\tUse reverse video (also: -rv)" +msgstr "-reverse\t\tȿžѤ(Ʊ: -rv)" + +msgid "+reverse\t\tDon't use reverse video (also: +rv)" +msgstr "+reverse\t\tȿžѤʤ(Ʊ: +rv)" + +msgid "-xrm \tSet the specified resource" +msgstr "-xrm \tΥ꥽Ѥ" + +msgid "" +"\n" +"Arguments recognised by gvim (GTK+ version):\n" +msgstr "" +"\n" +"gvimˤäƲᤵ(GTK+С):\n" + +msgid "-display \tRun vim on (also: --display)" +msgstr "-display \t vim¹Ԥ(Ʊ: --display)" + +msgid "--role \tSet a unique role to identify the main window" +msgstr "--role \tᥤ󥦥ɥ̤դ(role)ꤹ" + +msgid "--socketid \tOpen Vim inside another GTK widget" +msgstr "--socketid \tۤʤGTK widgetVim򳫤" + +msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout" +msgstr "--echo-wid\t\tɥIDɸϤ˽Ϥ" + +msgid "-P \tOpen Vim inside parent application" +msgstr "-P <ƤΥȥ>\tVimƥץꥱǵư" + +msgid "--windowid \tOpen Vim inside another win32 widget" +msgstr "--windowid \tۤʤWin32 widgetVim򳫤" + +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: %" -msgstr "E315: ml_get: ̵lnumǤ: %" +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 %" -msgstr "E316: ml_get: % 򸫤Ĥޤ" +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 %" -msgstr "E320: % Ĥޤ" +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: % past the end" -msgstr "E322: ֹ椬ϰϳǤ: % ĶƤޤ" +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 %" -msgstr "E323: ֥å % ιԥȤְäƤޤ" +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 % bytes)" -msgstr "E342: ꤬­ޤ! (% ХȤ׵)" - -#: ../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 " +msgstr "ܸå/ƽ: ¼ Ϻ " + msgid "Interrupt: " msgstr ": " -#: ../message.c:988 msgid "Press ENTER or type command to continue" msgstr "³ˤENTER򲡤ޥɤϤƤ" -#: ../message.c:1843 #, c-format -msgid "%s line %" -msgstr "%s %" +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,199 +3876,260 @@ msgstr "" "Ϥ(&Y)\n" "(&N)" -#: ../message.c:3033 msgid "" "&Yes\n" "&No\n" +"Save &All\n" +"&Discard All\n" "&Cancel" msgstr "" "Ϥ(&Y)\n" "(&N)\n" +"¸(&A)\n" +"(&D)\n" "󥻥(&C)" -#: ../message.c:3045 -msgid "" -"&Yes\n" -"&No\n" -"Save &All\n" -"&Discard All\n" -"&Cancel" -msgstr "" -"Ϥ(&Y)\n" -"(&N)\n" -"¸(&A)\n" -"(&D)\n" -"󥻥(&C)" +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: 󥽡⡼ɤǤϥե֥饦Ȥޤ, ʤ" -#: ../message.c:3058 msgid "E766: Insufficient arguments for printf()" msgstr "E766: printf() ΰԽʬǤ" -#: ../message.c:3119 msgid "E807: Expected Float argument for printf()" msgstr "E807: printf() ΰˤưԤƤޤ" -#: ../message.c:3873 msgid "E767: Too many arguments to printf()" msgstr "E767: printf() ΰ¿᤮ޤ" -#: ../misc1.c:2256 msgid "W10: Warning: Changing a readonly file" msgstr "W10: ٹ: ɹѥեѹޤ" -#: ../misc1.c:2537 msgid "Type number and or click with mouse (empty cancels): " msgstr "" "ֹϤ뤫ޥǥåƤ (ǥ󥻥): " -#: ../misc1.c:2539 msgid "Type number and (empty cancels): " msgstr "ֹϤƤ (ǥ󥻥): " -#: ../misc1.c:2585 msgid "1 more line" msgstr "1 ɲäޤ" -#: ../misc1.c:2588 msgid "1 line less" msgstr "1 ޤ" -#: ../misc1.c:2593 #, c-format -msgid "% more lines" -msgstr "% ɲäޤ" +msgid "%ld more lines" +msgstr "%ld ɲäޤ" -#: ../misc1.c:2596 #, c-format -msgid "% fewer lines" -msgstr "% ޤ" +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 to exit Nvim" +msgid "Type :quit to exit Vim" msgstr "Vimλˤ :quit ϤƤ" -#: ../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 "% lines %sed 1 time" -msgstr "% Ԥ %s 1 ޤ" +msgid "%ld lines %sed 1 time" +msgstr "%ld Ԥ %s 1 ޤ" -#: ../ops.c:256 #, c-format -msgid "% lines %sed %d times" -msgstr "% Ԥ %s %d ޤ" +msgid "%ld lines %sed %d times" +msgstr "%ld Ԥ %s %d ޤ" -#: ../ops.c:592 #, c-format -msgid "% lines to indent... " -msgstr "% ԤǥȤޤ... " +msgid "%ld lines to indent... " +msgstr "%ld ԤǥȤޤ... " -#: ../ops.c:634 msgid "1 line indented " msgstr "1 Ԥ򥤥ǥȤޤ " -#: ../ops.c:636 #, c-format -msgid "% lines indented " -msgstr "% Ԥ򥤥ǥȤޤ " +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 "% lines changed" -msgstr "% Ԥѹޤ" +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 % lines yanked" -msgstr "% ԤΥ֥å󥯤ޤ" +msgid "block of %ld lines yanked" +msgstr "%ld ԤΥ֥å󥯤ޤ" -#: ../ops.c:2528 #, c-format -msgid "% lines yanked" -msgstr "% Ԥ󥯤ޤ" +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 "% Cols; " -msgstr "% ; " +msgid "%ld Cols; " +msgstr "%ld ; " -#: ../ops.c:5097 #, c-format -msgid "" -"Selected %s% of % Lines; % of % Words; " -"% of % Bytes" -msgstr "" -" %s% / % ; % / % ñ; % / " -"% Х" +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% of % Lines; % of % Words; " -"% of % Chars; % of % Bytes" +"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of " +"%lld Bytes" msgstr "" -" %s% / % ; % / % ñ; % / " -"% ʸ; % / % Х" +" %s%ld / %ld ; %lld / %lld ñ; %lld / %lld ʸ; %lld / %lld Х" -#: ../ops.c:5123 #, c-format -msgid "" -"Col %s of %s; Line % of %; Word % of %; Byte " -"% of %" -msgstr "" -" %s / %s; % of %; ñ % / %; Х " -"% / %" +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 % of %; Word % of %; Char " -"% of %; Byte % of %" +"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte " +"%lld of %lld" msgstr "" -" %s / %s; % / %; ñ % / %; ʸ " -"% / %; Х % of %" +" %s / %s; %ld / %ld; ñ %lld / %lld; ʸ %lld / %lld; Х %lld of " +"%lld" -#: ../ops.c:5146 #, c-format -msgid "(+% for BOM)" -msgstr "(+% 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: 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: ̤ #. 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 " 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 " 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: %" -msgstr "E877: (NFA ɽ) ̵ʸ饹: %" +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: %" -msgstr "߸ñ: %" +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 % entries" -msgstr "E765: 'spellfile' ˤ % ĤΥȥϤޤ" +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 % suggestions" -msgstr "ǰǤ, % Ĥޤ" - -#. 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: 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: ']' 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 %" -msgstr "ľ % Х" +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 % not found" -msgstr "E830: ɥֹ % ϸĤޤ" +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 "% %s; %s #% %s" -msgstr "% %s; %s #% %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 "% seconds ago" -msgstr "% ÷вᤷƤޤ" +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 not in a script context: %s" +msgstr "E120: ץȰʳȤޤ: %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 "without GUI." -msgstr "without GUI." - -#: ../version.c:662 -msgid " Features included (+) or not (-):\n" -msgstr " ǽΰ ͭ(+)/̵(-)\n" +msgid "" +"\n" +"Big version " +msgstr "" +"\n" +"Big " -#: ../version.c:667 -msgid " system vimrc file: \"" -msgstr " ƥ vimrc: \"" +msgid "" +"\n" +"Normal version " +msgstr "" +"\n" +"̾ " -#: ../version.c:672 -msgid " user vimrc file: \"" +msgid "" +"\n" +"Small version " +msgstr "" +"\n" +"Small " + +msgid "" +"\n" +"Tiny version " +msgstr "" +"\n" +"Tiny " + +msgid "without GUI." +msgstr "without GUI." + +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" + +msgid " system vimrc file: \"" +msgstr " ƥ vimrc: \"" + +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 for information " msgstr "ܺ٤ʾ :help iccf " -#: ../version.c:779 msgid "type :q to exit " msgstr "λˤ :q " -#: ../version.c:780 msgid "type :help or for on-line help" msgstr "饤إפ :help " -#: ../version.c:781 -msgid "type :help version7 for version info" -msgstr "С :help version7 " +msgid "type :help version8 for version info" +msgstr "С :help version8 " -#: ../version.c:784 msgid "Running in Vi compatible mode" msgstr "Viߴ⡼ɤư" -#: ../version.c:785 msgid "type :set nocp for Vim defaults" msgstr "Vim侩ͤˤˤ :set nocp " -#: ../version.c:786 msgid "type :help cp-default for info on this" msgstr "ܺ٤ʾ :help cp-default" -#: ../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 for information " msgstr "ܺ٤ʾ :help sponsor " -#: ../version.c:832 msgid "type :help register for information " msgstr "ܺ٤ʾ :help register " -#: ../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 for info on this" +msgstr "ܺ٤ʾ :help windows95" + 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 "ꥹȤͤɬפǤ" +#, c-format +msgid "E447: Can't find file \"%s\" in path" +msgstr "E447: pathˤ \"%s\" Ȥե뤬ޤ" -#~ msgid "E831: bf_key_init() called with empty password" -#~ msgstr "E831: bf_key_init() ѥɤǸƤӽФޤ" +#, c-format +msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E799: ̵ ID: %ld (1 ʾǤʤФʤޤ)" -#~ msgid "E820: sizeof(uint32_t) != 4" -#~ msgstr "E820: sizeof(uint32_t) != 4" +#, c-format +msgid "E801: ID already taken: %ld" +msgstr "E801: ID ϤǤǤ: %ld" -#~ msgid "E817: Blowfish big/little endian use wrong" -#~ msgstr "E817: BlowfishŹΥӥå/ȥ륨ǥ󤬴ְäƤޤ" +msgid "List or number required" +msgstr "ꥹȤͤɬפǤ" -#~ msgid "E818: sha256 test failed" -#~ msgstr "E818: sha256ΥƥȤ˼Ԥޤ" +#, c-format +msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E802: ̵ ID: %ld (1 ʾǤʤФʤޤ)" -#~ msgid "E819: Blowfish test failed" -#~ msgstr "E819: BlowfishŹΥƥȤ˼Ԥޤ" +#, c-format +msgid "E803: ID not found: %ld" +msgstr "E803: ID Ϥޤ: %ld" -#~ msgid "Patch file" -#~ msgstr "ѥåե" +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: 饤֥ %s ɤǤޤǤ" -#~ msgid "" -#~ "&OK\n" -#~ "&Cancel" -#~ msgstr "" -#~ "(&O)\n" -#~ "󥻥(&C)" +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"Υޥɤ̵Ǥ, ʤ: Perl饤֥ɤǤޤǤ." -#~ msgid "E240: No connection to Vim server" -#~ msgstr "E240: Vim Фؤ³ޤ" +msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" +msgstr "" +"E299: ɥܥåǤ Safe ⥸塼ѤʤPerlץȤ϶ؤ" +"Ƥޤ" -#~ msgid "E241: Unable to send to %s" -#~ msgstr "E241: %s 뤳ȤǤޤ" +msgid "Edit with &multiple Vims" +msgstr "ʣVimԽ (&M)" -#~ msgid "E277: Unable to read a server reply" -#~ msgstr "E277: Фαޤ" +msgid "Edit with single &Vim" +msgstr "1ĤVimԽ (&V)" -#~ msgid "E258: Unable to send to client" -#~ msgstr "E258: 饤Ȥ뤳ȤǤޤ" +msgid "Diff with Vim" +msgstr "VimǺʬɽ" -#~ msgid "Save As" -#~ msgstr "̾¸" +msgid "Edit with &Vim" +msgstr "VimԽ (&V)" -#~ msgid "Edit File" -#~ msgstr "եԽ" +#. Now concatenate +msgid "Edit with existing Vim - " +msgstr "ưѤVimԽ - " -# Added at 27-Jan-2004. -#~ msgid " (NOT FOUND)" -#~ msgstr " (Ĥޤ)" +msgid "Edits the selected file(s) with Vim" +msgstr "򤷤եVimԽ" -#~ msgid "Source Vim script" -#~ msgstr "VimץȤμ" +msgid "Error creating process: Check if gvim is in your path!" +msgstr "ץκ˼: gvimĶѿPATHˤ뤫ǧƤ!" -#~ msgid "unknown" -#~ msgstr "" +msgid "gvimext.dll error" +msgstr "gvimext.dll 顼" -#~ msgid "Edit File in new window" -#~ msgstr "ɥǥեԽޤ" +msgid "Path length too long!" +msgstr "ѥĹ᤮ޤ!" -#~ msgid "Append File" -#~ msgstr "ɲåե" +msgid "--No lines in buffer--" +msgstr "--Хåե˹Ԥޤ--" -#~ msgid "Window position: X %d, Y %d" -#~ msgstr "ɥ: X %d, Y %d" +#. +#. * 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 "Save Redirection" -#~ msgstr "쥯Ȥ¸ޤ" +msgid "E471: Argument required" +msgstr "E471: ɬפǤ" -#~ msgid "Save View" -#~ msgstr "ӥ塼¸ޤ" +msgid "E10: \\ should be followed by /, ? or &" +msgstr "E10: \\ θ / ? & ǤʤФʤޤ" -#~ msgid "Save Session" -#~ msgstr "å¸ޤ" +msgid "E11: Invalid in command-line window; executes, CTRL-C quits" +msgstr "E11: ޥɥ饤Ǥ̵Ǥ; Ǽ¹, CTRL-CǤ" -#~ msgid "Save Setup" -#~ msgstr "¸ޤ" +msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search" +msgstr "" +"E12: ߤΥǥ쥯ȥ䥿Ǥexrc/vimrcΥޥɤϵĤޤ" -#~ msgid "E809: #< is not available without the +eval feature" -#~ msgstr "E809: #< +eval ǽ̵ѤǤޤ" +msgid "E171: Missing :endif" +msgstr "E171: :endif ޤ" -#~ msgid "E196: No digraphs in this version" -#~ msgstr "E196: ΥС˹Ϥޤ" +msgid "E600: Missing :endtry" +msgstr "E600: :endtry ޤ" -#~ msgid "is a device (disabled with 'opendevice' option)" -#~ msgstr " ϥǥХǤ ('opendevice' ץDzǤޤ)" +msgid "E170: Missing :endwhile" +msgstr "E170: :endwhile ޤ" -#~ msgid "Reading from stdin..." -#~ msgstr "ɸϤɹ..." +msgid "E170: Missing :endfor" +msgstr "E170: :endfor ޤ" -#~ msgid "[blowfish]" -#~ msgstr "[blowfishŹ沽]" +msgid "E588: :endwhile without :while" +msgstr "E588: :while Τʤ :endwhile ޤ" -#~ msgid "[crypted]" -#~ msgstr "[Ź沽]" +msgid "E588: :endfor without :for" +msgstr "E588: :endfor Τʤ :for ޤ" -#~ msgid "E821: File is encrypted with unknown method" -#~ msgstr "E821: ե뤬̤ΤˡǰŹ沽Ƥޤ" +msgid "E13: File exists (add ! to override)" +msgstr "E13: ե뤬¸ߤޤ (! ɲäǾ)" -# Added at 19-Jan-2004. -#~ msgid "NetBeans disallows writes of unmodified buffers" -#~ msgstr "NetBeans̤ѹΥХåե񤹤뤳ȤϵĤƤޤ" +msgid "E472: Command failed" +msgstr "E472: ޥɤԤޤ" -#~ msgid "Partial writes disallowed for NetBeans buffers" -#~ msgstr "NetBeansХåեΰ񤭽ФȤϤǤޤ" +#, c-format +msgid "E234: Unknown fontset: %s" +msgstr "E234: ̤ΤΥեȥå: %s" -#~ msgid "writing to device disabled with 'opendevice' option" -#~ msgstr "'opendevice' ץˤǥХؤν񤭹ߤϤǤޤ" +#, c-format +msgid "E235: Unknown font: %s" +msgstr "E235: ̤ΤΥե: %s" -#~ msgid "E460: The resource fork would be lost (add ! to override)" -#~ msgstr "E460: ꥽ե뤫⤷ޤ (! ɲäǶ)" +#, c-format +msgid "E236: Font \"%s\" is not fixed-width" +msgstr "E236: ե \"%s\" ϸǤϤޤ" -#~ msgid "E851: Failed to create a new process for the GUI" -#~ msgstr "E851: GUIѤΥץεư˼Ԥޤ" +msgid "E473: Internal error" +msgstr "E473: 顼Ǥ" -#~ msgid "E852: The child process failed to start the GUI" -#~ msgstr "E852: ҥץGUIεư˼Ԥޤ" +msgid "Interrupted" +msgstr "ޤޤ" -#~ msgid "E229: Cannot start the GUI" -#~ msgstr "E229: GUI򳫻ϤǤޤ" +msgid "E14: Invalid address" +msgstr "E14: ̵ʥɥ쥹Ǥ" -#~ msgid "E230: Cannot read from \"%s\"" -#~ msgstr "E230: \"%s\"ɹळȤǤޤ" +msgid "E474: Invalid argument" +msgstr "E474: ̵ʰǤ" -#~ msgid "E665: Cannot start GUI, no valid font found" -#~ msgstr "E665: ͭʥեȤĤʤΤ, GUI򳫻ϤǤޤ" +#, c-format +msgid "E475: Invalid argument: %s" +msgstr "E475: ̵ʰǤ: %s" -#~ msgid "E231: 'guifontwide' invalid" -#~ msgstr "E231: 'guifontwide' ̵Ǥ" +#, c-format +msgid "E15: Invalid expression: %s" +msgstr "E15: ̵ʼǤ: %s" -#~ msgid "E599: Value of 'imactivatekey' is invalid" -#~ msgstr "E599: 'imactivatekey' ꤵ줿̵ͤǤ" +msgid "E16: Invalid range" +msgstr "E16: ̵ϰϤǤ" -#~ msgid "E254: Cannot allocate color %s" -#~ msgstr "E254: %s οƤޤ" +msgid "E476: Invalid command" +msgstr "E476: ̵ʥޥɤǤ" -#~ msgid "No match at cursor, finding next" -#~ msgstr "ΰ֤˥ޥåϤޤ, 򸡺Ƥޤ" +#, c-format +msgid "E17: \"%s\" is a directory" +msgstr "E17: \"%s\" ϥǥ쥯ȥǤ" -#~ msgid " " -#~ msgstr "<ޤ> " +#, c-format +msgid "E364: Library call failed for \"%s()\"" +msgstr "E364: \"%s\"() Υ饤֥ƽФ˼Ԥޤ" -#~ msgid "E616: vim_SelFile: can't get font %s" -#~ msgstr "E616: vim_SelFile: ե %s Ǥޤ" +#, c-format +msgid "E448: Could not load library function %s" +msgstr "E448: 饤֥δؿ %s ɤǤޤǤ" -#~ msgid "E614: vim_SelFile: can't return to current directory" -#~ msgstr "E614: vim_SelFile: ߤΥǥ쥯ȥޤ" +msgid "E19: Mark has invalid line number" +msgstr "E19: ޡ̵ʹֹ椬ꤵƤޤ" -#~ msgid "Pathname:" -#~ msgstr "ѥ̾:" +msgid "E20: Mark not set" +msgstr "E20: ޡꤵƤޤ" -#~ msgid "E615: vim_SelFile: can't get current directory" -#~ msgstr "E615: vim_SelFile: ߤΥǥ쥯ȥǤޤ" +msgid "E21: Cannot make changes, 'modifiable' is off" +msgstr "E21: 'modifiable' դʤΤ, ѹǤޤ" -#~ msgid "OK" -#~ msgstr "OK" +msgid "E22: Scripts nested too deep" +msgstr "E22: ץȤҤ᤮ޤ" -#~ msgid "Cancel" -#~ msgstr "󥻥" +msgid "E23: No alternate file" +msgstr "E23: եϤޤ" -#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." -#~ msgstr "С: ǤޤǤ." +msgid "E24: No such abbreviation" +msgstr "E24: Τ褦ûϤϤޤ" -#~ msgid "Vim dialog" -#~ msgstr "Vim " +msgid "E477: No ! allowed" +msgstr "E477: ! ϵĤƤޤ" -#~ msgid "E232: Cannot create BalloonEval with both message and callback" -#~ msgstr "E232: åȥХåΤ BalloonEval Ǥޤ" +msgid "E25: GUI cannot be used: Not enabled at compile time" +msgstr "E25: GUIϻԲǽǤ: ѥ̵ˤƤޤ" -#~ msgid "Input _Methods" -#~ msgstr "ץåȥ᥽å" +msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" +msgstr "E26: إ֥饤ϻԲǽǤ: ѥ̵ˤƤޤ\n" -#~ msgid "VIM - Search and Replace..." -#~ msgstr "VIM - ִ..." +msgid "E27: Farsi cannot be used: Not enabled at compile time\n" +msgstr "E27: ڥ륷ϻԲǽǤ: ѥ̵ˤƤޤ\n" -#~ msgid "VIM - Search..." -#~ msgstr "VIM - ..." +msgid "E800: Arabic cannot be used: Not enabled at compile time\n" +msgstr "E800: ӥϻԲǽǤ: ѥ̵ˤƤޤ\n" -#~ msgid "Find what:" -#~ msgstr "ʸ:" +#, c-format +msgid "E28: No such highlight group name: %s" +msgstr "E28: Τ褦̾Υϥ饤ȥ롼פϤޤ: %s" -#~ msgid "Replace with:" -#~ msgstr "ִʸ:" +msgid "E29: No inserted text yet" +msgstr "E29: ޤƥȤƤޤ" -#~ msgid "Match whole word only" -#~ msgstr "Τ˳Τ" +msgid "E30: No previous command line" +msgstr "E30: ˥ޥɹԤޤ" -#~ msgid "Match case" -#~ msgstr "ʸ/ʸ̤" +msgid "E31: No such mapping" +msgstr "E31: Τ褦ʥޥåԥ󥰤Ϥޤ" -#~ msgid "Direction" -#~ msgstr "" +msgid "E479: No match" +msgstr "E479: Ϥޤ" -#~ msgid "Up" -#~ msgstr "" +#, c-format +msgid "E480: No match: %s" +msgstr "E480: Ϥޤ: %s" -#~ msgid "Down" -#~ msgstr "" +msgid "E32: No file name" +msgstr "E32: ե̾ޤ" -#~ msgid "Find Next" -#~ msgstr "򸡺" +msgid "E33: No previous substitute regular expression" +msgstr "E33: ɽִޤ¹ԤƤޤ" -#~ msgid "Replace" -#~ msgstr "ִ" +msgid "E34: No previous command" +msgstr "E34: ޥɤޤ¹ԤƤޤ" -#~ msgid "Replace All" -#~ msgstr "ִ" +msgid "E35: No previous regular expression" +msgstr "E35: ɽޤ¹ԤƤޤ" -#~ msgid "Vim: Received \"die\" request from session manager\n" -#~ msgstr "Vim: åޥ͡㤫 \"die\" ׵ޤ\n" +msgid "E481: No range allowed" +msgstr "E481: ϰϻϵĤƤޤ" -#~ msgid "Close" -#~ msgstr "Ĥ" +msgid "E36: Not enough room" +msgstr "E36: ɥ˽ʬʹ⤵⤷ޤ" -#~ msgid "New tab" -#~ msgstr "֥ڡ" +#, c-format +msgid "E247: no registered server named \"%s\"" +msgstr "E247: %s Ȥ̾Ͽ줿СϤޤ" -#~ msgid "Open Tab..." -#~ msgstr "֥ڡ򳫤..." +#, c-format +msgid "E482: Can't create file %s" +msgstr "E482: ե %s Ǥޤ" -#~ msgid "Vim: Main window unexpectedly destroyed\n" -#~ msgstr "Vim: ᥤ󥦥ɥ԰դ˲ޤ\n" +msgid "E483: Can't get temp file name" +msgstr "E483: ե̾Ǥޤ" -#~ msgid "&Filter" -#~ msgstr "ե륿(&F)" +#, c-format +msgid "E484: Can't open file %s" +msgstr "E484: ե \"%s\" 򳫤ޤ" -#~ msgid "&Cancel" -#~ msgstr "󥻥(&C)" +#, c-format +msgid "E485: Can't read file %s" +msgstr "E485: ե %s ɹޤ" -#~ msgid "Directories" -#~ msgstr "ǥ쥯ȥ" +msgid "E37: No write since last change (add ! to override)" +msgstr "E37: Ǹѹ¸Ƥޤ (! ɲäѹ˴)" -#~ msgid "Filter" -#~ msgstr "ե륿" +msgid "E37: No write since last change" +msgstr "E37: Ǹѹ¸Ƥޤ" -#~ msgid "&Help" -#~ msgstr "إ(&H)" +msgid "E38: Null argument" +msgstr "E38: Ǥ" -#~ msgid "Files" -#~ msgstr "ե" +msgid "E39: Number expected" +msgstr "E39: ͤ׵ᤵƤޤ" -#~ msgid "&OK" -#~ msgstr "&OK" +#, c-format +msgid "E40: Can't open errorfile %s" +msgstr "E40: 顼ե %s 򳫤ޤ" -#~ msgid "Selection" -#~ msgstr "" +msgid "E233: cannot open display" +msgstr "E233: ǥץ쥤򳫤ޤ" -#~ msgid "Find &Next" -#~ msgstr "򸡺(&N)" +msgid "E41: Out of memory!" +msgstr "E41: ꤬Ԥ̤Ƥޤ!" -#~ msgid "&Replace" -#~ msgstr "ִ(&R)" +msgid "Pattern not found" +msgstr "ѥϸĤޤǤ" -#~ msgid "Replace &All" -#~ msgstr "ִ(&A)" +#, c-format +msgid "E486: Pattern not found: %s" +msgstr "E486: ѥϸĤޤǤ: %s" -#~ msgid "&Undo" -#~ msgstr "ɥ(&U)" +msgid "E487: Argument must be positive" +msgstr "E487: ͤǤʤФʤޤ" -#~ msgid "E671: Cannot find window title \"%s\"" -#~ msgstr "E671: ȥ뤬 \"%s\" ΥɥϸĤޤ" +msgid "E459: Cannot go back to previous directory" +msgstr "E459: Υǥ쥯ȥޤ" -#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." -#~ msgstr "E243: ϥݡȤޤ: \"-%s\"; OLEǤѤƤ." +msgid "E42: No Errors" +msgstr "E42: 顼Ϥޤ" -#~ msgid "E672: Unable to open window inside MDI application" -#~ msgstr "E672: MDIץǤϥɥ򳫤ޤ" +msgid "E776: No location list" +msgstr "E776: ꥹȤϤޤ" -#~ msgid "Close tab" -#~ msgstr "֥ڡĤ" +msgid "E43: Damaged match string" +msgstr "E43: ʸ»Ƥޤ" -#~ msgid "Open tab..." -#~ msgstr "֥ڡ򳫤" +msgid "E44: Corrupted regexp program" +msgstr "E44: ɽץǤ" -#~ msgid "Find string (use '\\\\' to find a '\\')" -#~ msgstr "ʸ ('\\' 򸡺ˤ '\\\\')" +msgid "E45: 'readonly' option is set (add ! to override)" +msgstr "E45: 'readonly' ץꤵƤޤ (! ɲäǾ)" -#~ msgid "Find & Replace (use '\\\\' to find a '\\')" -#~ msgstr "ִ ('\\' 򸡺ˤ '\\\\')" +#, c-format +msgid "E46: Cannot change read-only variable \"%s\"" +msgstr "E46: ɼѿ \"%s\" ˤͤǤޤ" -#~ msgid "Not Used" -#~ msgstr "Ȥޤ" +#, c-format +msgid "E794: Cannot set variable in the sandbox: \"%s\"" +msgstr "E794: ɥܥåǤѿ \"%s\" ͤǤޤ" -#~ msgid "Directory\t*.nothing\n" -#~ msgstr "ǥ쥯ȥ\t*.nothing\n" +msgid "E713: Cannot use empty key for Dictionary" +msgstr "E713: 񷿤˶ΥȤȤϤǤޤ" -#~ msgid "" -#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" -#~ msgstr "Vim E458: ꤬ʤΤǥȥƤޤ" +msgid "E715: Dictionary required" +msgstr "E715: 񷿤ɬפǤ" -#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:" -#~ msgstr "E250: ʲʸåȤΥեȤޤ %s:" +#, c-format +msgid "E684: list index out of range: %ld" +msgstr "E684: ꥹȤΥǥåϰϳǤ: %ld" -#~ msgid "E252: Fontset name: %s" -#~ msgstr "E252: եȥå̾: %s" +#, c-format +msgid "E118: Too many arguments for function: %s" +msgstr "E118: ؿΰ¿᤮ޤ: %s" -#~ msgid "Font '%s' is not fixed-width" -#~ msgstr "ե '%s' ϸǤϤޤ" +#, c-format +msgid "E716: Key not present in Dictionary: %s" +msgstr "E716: 񷿤˥¸ߤޤ: %s" -#~ msgid "E253: Fontset name: %s" -#~ msgstr "E253: եȥå̾: %s" +msgid "E714: List required" +msgstr "E714: ꥹȷɬפǤ" -#~ msgid "Font0: %s" -#~ msgstr "ե0: %s" +#, c-format +msgid "E712: Argument of %s must be a List or Dictionary" +msgstr "E712: %s ΰϥꥹȷޤϼ񷿤ǤʤФʤޤ" -#~ msgid "Font1: %s" -#~ msgstr "ե1: %s" +msgid "E47: Error while reading errorfile" +msgstr "E47: 顼եɹ˥顼ȯޤ" -#~ msgid "Font% width is not twice that of font0" -#~ msgstr "ե% ե02ܤǤϤޤ" +msgid "E48: Not allowed in sandbox" +msgstr "E48: ɥܥåǤϵޤ" -#~ msgid "Font0 width: %" -#~ msgstr "ե0: %" +msgid "E523: Not allowed here" +msgstr "E523: ǤϵĤޤ" -#~ msgid "Font1 width: %" -#~ msgstr "ե1: %" +msgid "E359: Screen mode setting not supported" +msgstr "E359: ꡼⡼ɤˤбƤޤ" -#~ msgid "Invalid font specification" -#~ msgstr "̵ʥեȻǤ" +msgid "E49: Invalid scroll size" +msgstr "E49: ̵ʥ̤Ǥ" -#~ msgid "&Dismiss" -#~ msgstr "Ѳ(&D)" +msgid "E91: 'shell' option is empty" +msgstr "E91: 'shell' ץ󤬶Ǥ" -#~ msgid "no specific match" -#~ msgstr "ޥåΤޤ" +msgid "E255: Couldn't read in sign data!" +msgstr "E255: sign ΥǡɹޤǤ" -#~ msgid "Vim - Font Selector" -#~ msgstr "Vim - ե" +msgid "E72: Close error on swap file" +msgstr "E72: åץեΥ顼Ǥ" -#~ msgid "Name:" -#~ msgstr "̾:" +msgid "E73: tag stack empty" +msgstr "E73: åǤ" -#~ msgid "Show size in Points" -#~ msgstr "ݥȤɽ" +msgid "E74: Command too complex" +msgstr "E74: ޥɤʣ᤮ޤ" -#~ msgid "Encoding:" -#~ msgstr "󥳡:" +msgid "E75: Name too long" +msgstr "E75: ̾Ĺ᤮ޤ" -#~ msgid "Font:" -#~ msgstr "ե:" +msgid "E76: Too many [" +msgstr "E76: [ ¿᤮ޤ" -#~ msgid "Style:" -#~ msgstr ":" +msgid "E77: Too many file names" +msgstr "E77: ե̾¿᤮ޤ" -#~ 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: 顼: NetBeansgvim򥹥ȤǤޤ\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\tgvimOLEȤϿ" - -#~ msgid "-unregister\t\tUnregister gvim for OLE" -#~ msgstr "-unregister\t\tgvimOLEϿ" - -#~ 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 \t\tUse for I/O" -#~ msgstr "-dev \t\tI/O Ѥ" - -#~ msgid "-U \t\tUse instead of any .gvimrc" -#~ msgstr "-U \t\t.gvimrc Ȥ" - -#~ msgid "-x\t\t\tEdit encrypted files" -#~ msgstr "-x\t\t\tŹ沽줿եԽ" - -#~ msgid "-display \tConnect vim to this particular X-server" -#~ msgstr "-display \tvimꤷ X Ф³" - -#~ msgid "-X\t\t\tDo not connect to X server" -#~ msgstr "-X\t\t\tXФ³ʤ" - -#~ msgid "--remote \tEdit in a Vim server if possible" -#~ msgstr "--remote \tǽʤVimФ Խ" - -#~ msgid "--remote-silent Same, don't complain if there is no server" -#~ msgstr "--remote-silent Ʊ, Ф̵ƤٹʸϤʤ" - -#~ msgid "" -#~ "--remote-wait As --remote but wait for files to have been edited" -#~ msgstr "--remote-wait \t--remote եԽΤԤ" - -#~ msgid "" -#~ "--remote-wait-silent Same, don't complain if there is no server" -#~ msgstr "" -#~ "--remote-wait-silent Ʊ, Ф̵ƤٹʸϤʤ" - -#~ msgid "" -#~ "--remote-tab[-wait][-silent] As --remote but use tab page per " -#~ "file" -#~ msgstr "" -#~ "--remote-tab[-wait][-silent] --remoteǥե1ĤˤĤ1ĤΥ" -#~ "ڡ򳫤" - -#~ msgid "--remote-send \tSend to a Vim server and exit" -#~ msgstr "--remote-send \tVimФ ƽλ" - -#~ msgid "" -#~ "--remote-expr \tEvaluate in a Vim server and print result" -#~ msgstr "--remote-expr \tФ ¹ԤƷ̤ɽ" - -#~ msgid "--serverlist\t\tList available Vim server names and exit" -#~ msgstr "--serverlist\t\tVim̾ΰɽƽλ" - -#~ msgid "--servername \tSend to/become the Vim server " -#~ msgstr "--servername \tVim /̾ꤹ" - -#~ 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 \tRun vim on " -#~ msgstr "-display \t vim¹Ԥ" - -#~ msgid "-iconic\t\tStart vim iconified" -#~ msgstr "-iconic\t\tǾ֤vimư" - -#~ msgid "-background \tUse for the background (also: -bg)" -#~ msgstr "-background \tطʿ Ȥ(Ʊ: -bg)" - -#~ msgid "-foreground \tUse for normal text (also: -fg)" -#~ msgstr "-foreground \tʿ Ȥ(Ʊ: -fg)" - -#~ msgid "-font \t\tUse for normal text (also: -fn)" -#~ msgstr "-font \t\tƥɽ Ȥ(Ʊ: -fn)" - -#~ msgid "-boldfont \tUse for bold text" -#~ msgstr "-boldfont \t Ȥ" - -#~ msgid "-italicfont \tUse for italic text" -#~ msgstr "-italicfont \tλ Ȥ" - -#~ msgid "-geometry \tUse for initial geometry (also: -geom)" -#~ msgstr "-geometry \t֤ Ȥ(Ʊ: -geom)" - -#~ msgid "-borderwidth \tUse a border width of (also: -bw)" -#~ msgstr "-borderwidth \t ˤ(Ʊ: -bw)" - -#~ msgid "" -#~ "-scrollbarwidth Use a scrollbar width of (also: -sw)" -#~ msgstr "" -#~ "-scrollbarwidth С ˤ(Ʊ: -sw)" - -#~ msgid "-menuheight \tUse a menu bar height of (also: -mh)" -#~ msgstr "" -#~ "-menuheight \t˥塼Сι⤵ ˤ(Ʊ: -mh)" - -#~ msgid "-reverse\t\tUse reverse video (also: -rv)" -#~ msgstr "-reverse\t\tȿžѤ(Ʊ: -rv)" - -#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)" -#~ msgstr "+reverse\t\tȿžѤʤ(Ʊ: +rv)" - -#~ msgid "-xrm \tSet the specified resource" -#~ msgstr "-xrm \tΥ꥽Ѥ" - -#~ msgid "" -#~ "\n" -#~ "Arguments recognised by gvim (GTK+ version):\n" -#~ msgstr "" -#~ "\n" -#~ "gvimˤäƲᤵ(GTK+С):\n" - -#~ msgid "-display \tRun vim on (also: --display)" -#~ msgstr "-display \t vim¹Ԥ(Ʊ: --display)" - -#~ msgid "--role \tSet a unique role to identify the main window" -#~ msgstr "--role \tᥤ󥦥ɥ̤դ(role)ꤹ" - -#~ msgid "--socketid \tOpen Vim inside another GTK widget" -#~ msgstr "--socketid \tۤʤGTK widgetVim򳫤" - -#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout" -#~ msgstr "--echo-wid\t\tɥIDɸϤ˽Ϥ" - -#~ msgid "-P \tOpen Vim inside parent application" -#~ msgstr "-P <ƤΥȥ>\tVimƥץꥱǵư" - -#~ msgid "--windowid \tOpen Vim inside another win32 widget" -#~ msgstr "--windowid \tۤʤWin32 widgetVim򳫤" - -#~ 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 򥵥ݡȤޤ" - -#~ msgid "E843: Error while updating swap file crypt" -#~ msgstr "E843: åץեΰŹ򹹿˥顼ȯޤ" - -#~ msgid "" -#~ "E833: %s is encrypted and this version of Vim does not support encryption" -#~ msgstr "" -#~ "E833: %s ϤΥСVimǥݡȤƤʤǰŹ沽Ƥޤ" - -#~ msgid "Swap file is encrypted: \"%s\"" -#~ msgstr "åץեϰŹ沽Ƥޤ: \"%s\"" - -#~ msgid "" -#~ "\n" -#~ "If you entered a new crypt key but did not write the text file," -#~ msgstr "" -#~ "\n" -#~ "Ź業ϤȤ˥ƥȥե¸Ƥʤ," - -#~ msgid "" -#~ "\n" -#~ "enter the new crypt key." -#~ msgstr "" -#~ "\n" -#~ "Ź業ϤƤ." - -#~ msgid "" -#~ "\n" -#~ "If you wrote the text file after changing the crypt key press enter" -#~ msgstr "" -#~ "\n" -#~ "Ź業ѤȤ˥ƥȥե¸, ƥȥե" - -#~ msgid "" -#~ "\n" -#~ "to use the same key for text file and swap file" -#~ msgstr "" -#~ "\n" -#~ "åץեƱŹ業Ȥenter򲡤Ƥ." - -#~ msgid "Using crypt key from swap file for the text file.\n" -#~ msgstr "åץե뤫Ź業ƥȥե˻Ȥޤ.\n" - -#~ msgid "" -#~ "\n" -#~ " [not usable with this version of Vim]" -#~ msgstr "" -#~ "\n" -#~ " [VimСǤϻѤǤޤ]" - -#~ msgid "Tear off this menu" -#~ msgstr "Υ˥塼ڤ" - -#~ msgid "Select Directory dialog" -#~ msgstr "ǥ쥯ȥ" - -#~ msgid "Save File dialog" -#~ msgstr "ե¸" - -#~ msgid "Open File dialog" -#~ msgstr "եɹ" - -#~ msgid "E338: Sorry, no file browser in console mode" -#~ msgstr "" -#~ "E338: 󥽡⡼ɤǤϥե֥饦Ȥޤ, ʤ" - -#~ msgid "Vim: preserving files...\n" -#~ msgstr "Vim: ե¸...\n" - -#~ msgid "Vim: Finished.\n" -#~ msgstr "Vim: λޤ.\n" - -#~ msgid "ERROR: " -#~ msgstr "顼: " - -#~ msgid "" -#~ "\n" -#~ "[bytes] total alloc-freed %-%, in use %, peak use " -#~ "%\n" -#~ msgstr "" -#~ "\n" -#~ "[(Х)] - %-%, %, ԡ" -#~ " %\n" - -#~ msgid "" -#~ "[calls] total re/malloc()'s %, total free()'s %\n" -#~ "\n" -#~ msgstr "" -#~ "[ƽ] re/malloc() %, free() %\n" -#~ "\n" - -#~ msgid "E340: Line is becoming too long" -#~ msgstr "E340: ԤĹʤ᤮ޤ" - -#~ msgid "E341: Internal error: lalloc(%, )" -#~ msgstr "E341: 顼: lalloc(%,)" - -#~ msgid "E547: Illegal mouseshape" -#~ msgstr "E547: 'mouseshape' Ǥ" - -#~ msgid "Enter encryption key: " -#~ msgstr "Ź沽ѤΥϤƤ: " - -#~ msgid "Enter same key again: " -#~ msgstr "⤦ƱϤƤ: " - -#~ msgid "Keys don't match!" -#~ msgstr "פޤ" - -#~ msgid "Cannot connect to Netbeans #2" -#~ msgstr "Netbeans #2 ³Ǥޤ" - -#~ msgid "Cannot connect to Netbeans" -#~ msgstr "Netbeans ³Ǥޤ" - -#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\"" -#~ msgstr "" -#~ "E668: NetBeans³եΥ⡼ɤ꤬ޤ: \"%s\"" - -#~ msgid "read from Netbeans socket" -#~ msgstr "Netbeans ΥåȤɹ" - -#~ msgid "E658: NetBeans connection lost for buffer %" -#~ msgstr "E658: Хåե % NetBeans ³ޤ" - -#~ msgid "E838: netbeans is not supported with this GUI" -#~ msgstr "E838: NetBeansϤGUIˤбƤޤ" - -#~ msgid "E511: netbeans already connected" -#~ msgstr "E511: NetBeansϴ³Ƥޤ" - -#~ msgid "E505: %s is read-only (add ! to override)" -#~ msgstr "E505: %s ɹѤǤ (ˤ ! ɲ)" - -#~ msgid "E775: Eval feature not available" -#~ msgstr "E775: ɾǽ̵ˤʤäƤޤ" - -#~ msgid "freeing % lines" -#~ msgstr "% Ԥ" - -#~ msgid "E530: Cannot change term in GUI" -#~ msgstr "E530: GUIǤ 'term' ѹǤޤ" - -#~ msgid "E531: Use \":gui\" to start the GUI" -#~ msgstr "E531: GUI򥹥Ȥˤ \":gui\" ѤƤ" - -#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI" -#~ msgstr "E617: GTK+2 GUIǤѹǤޤ" - -#~ msgid "E596: Invalid font(s)" -#~ msgstr "E596: ̵ʥեȤǤ" - -#~ msgid "E597: can't select fontset" -#~ msgstr "E597: եȥåȤǤޤ" - -#~ msgid "E598: Invalid fontset" -#~ msgstr "E598: ̵ʥեȥåȤǤ" - -#~ msgid "E533: can't select wide font" -#~ msgstr "E533: 磻ɥեȤǤޤ" - -#~ msgid "E534: Invalid wide font" -#~ msgstr "E534: ̵ʥ磻ɥեȤǤ" - -#~ msgid "E538: No mouse support" -#~ msgstr "E538: ޥϥݡȤޤ" - -#~ msgid "cannot open " -#~ msgstr "ޤ " - -#~ msgid "VIM: Can't open window!\n" -#~ msgstr "VIM: ɥ򳫤ޤ!\n" - -#~ msgid "Need Amigados version 2.04 or later\n" -#~ msgstr "AmigadosΥС 2.04ʹߤɬפǤ\n" - -#~ msgid "Need %s version %\n" -#~ msgstr "%s ΥС % ɬפǤ\n" - -#~ msgid "Cannot open NIL:\n" -#~ msgstr "NIL򳫤ޤ:\n" - -#~ msgid "Cannot create " -#~ msgstr "Ǥޤ " - -#~ msgid "Vim exiting with %d\n" -#~ msgstr "Vim %d ǽλޤ\n" - -#~ msgid "cannot change console mode ?!\n" -#~ msgstr "󥽡⡼ɤѹǤޤ?!\n" - -#~ msgid "mch_get_shellsize: not a console??\n" -#~ msgstr "mch_get_shellsize: 󥽡ǤϤʤ??\n" - -#~ msgid "E360: Cannot execute shell with -f option" -#~ msgstr "E360: -f ץǥ¹ԤǤޤ" - -#~ msgid "Cannot execute " -#~ msgstr "¹ԤǤޤ " - -#~ msgid "shell " -#~ msgstr " " - -#~ msgid " returned\n" -#~ msgstr " ޤ\n" - -#~ msgid "ANCHOR_BUF_SIZE too small." -#~ msgstr "ANCHOR_BUF_SIZE ᤮ޤ." - -#~ msgid "I/O ERROR" -#~ msgstr "ϥ顼" - -#~ msgid "Message" -#~ msgstr "å" - -#~ msgid "'columns' is not 80, cannot execute external commands" -#~ msgstr "'columns' 80ǤϤʤ, ޥɤ¹ԤǤޤ" - -#~ msgid "E237: Printer selection failed" -#~ msgstr "E237: ץ󥿤˼Ԥޤ" - -#~ msgid "to %s on %s" -#~ msgstr "%s (%s )" - -#~ msgid "E613: Unknown printer font: %s" -#~ msgstr "E613: ̤ΤΥץ󥿥ץǤ: %s" - -#~ msgid "E238: Print error: %s" -#~ msgstr "E238: 顼: %s" - -#~ msgid "Printing '%s'" -#~ msgstr "Ƥޤ: '%s'" - -#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\"" -#~ msgstr "E244: ʸå̾ \"%s\" Ǥ (ե̾ \"%s\")" - -#~ msgid "E245: Illegal char '%c' in font name \"%s\"" -#~ msgstr "E245: '%c' ʸǤ (ե̾ \"%s\")" - -#~ msgid "Vim: Double signal, exiting\n" -#~ msgstr "Vim: 2ŤΥʥΤ, λޤ\n" - -#~ msgid "Vim: Caught deadly signal %s\n" -#~ msgstr "Vim: ̿Ūʥ %s Τޤ\n" - -#~ msgid "Vim: Caught deadly signal\n" -#~ msgstr "Vim: ̿ŪʥΤޤ\n" - -#~ msgid "Opening the X display took % msec" -#~ msgstr "XФؤ³ % ߥäޤ" - -#~ msgid "" -#~ "\n" -#~ "Vim: Got X error\n" -#~ msgstr "" -#~ "\n" -#~ "Vim: X Υ顼򸡽Фޤr\n" - -#~ msgid "Testing the X display failed" -#~ msgstr "X display Υå˼Ԥޤ" - -#~ msgid "Opening the X display timed out" -#~ msgstr "X display open ॢȤޤ" - -#~ msgid "" -#~ "\n" -#~ "Cannot execute shell sh\n" -#~ msgstr "" -#~ "\n" -#~ "sh ¹ԤǤޤ\n" - -#~ msgid "" -#~ "\n" -#~ "Cannot create pipes\n" -#~ msgstr "" -#~ "\n" -#~ "ѥפǤޤ\n" - -#~ msgid "" -#~ "\n" -#~ "Cannot fork\n" -#~ msgstr "" -#~ "\n" -#~ "fork Ǥޤ\n" - -#~ msgid "" -#~ "\n" -#~ "Command terminated\n" -#~ msgstr "" -#~ "\n" -#~ "ޥɤǤޤ\n" - -#~ msgid "XSMP lost ICE connection" -#~ msgstr "XSMP ICE³򼺤ޤ" - -#~ msgid "Opening the X display failed" -#~ msgstr "X 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³Ԥ褦Ǥ" - -#~ msgid "XSMP SmcOpenConnection failed: %s" -#~ msgstr "XSMP SmcOpenConnectionԤޤ: %s" - -#~ msgid "At line" -#~ msgstr "" - -#~ msgid "Could not load vim32.dll!" -#~ msgstr "vim32.dll ɤǤޤǤ" - -#~ msgid "VIM Error" -#~ msgstr "VIM顼" - -#~ msgid "Could not fix up function pointers to the DLL!" -#~ msgstr "DLLؿݥ󥿤ǤޤǤ" - -#~ msgid "shell returned %d" -#~ msgstr "뤬 %d ǽλޤ" - -#~ msgid "Vim: Caught %s event\n" -#~ msgstr "Vim: ٥ %s \n" - -#~ msgid "close" -#~ msgstr "Ĥ" - -#~ msgid "logoff" -#~ msgstr "" - -#~ msgid "shutdown" -#~ msgstr "åȥ" - -#~ msgid "E371: Command not found" -#~ msgstr "E371: ޥɤޤ" - -#~ msgid "" -#~ "VIMRUN.EXE not found in your $PATH.\n" -#~ "External commands will not pause after completion.\n" -#~ "See :help win32-vimrun for more information." -#~ msgstr "" -#~ "VIMRUN.EXE $PATH ˸Ĥޤ.\n" -#~ "ޥɤνλ˰ߤ򤷤ޤ.\n" -#~ "ܺ٤ :help win32-vimrun 򻲾ȤƤ." - -#~ msgid "Vim Warning" -#~ msgstr "Vimηٹ" - -#~ msgid "Error file" -#~ msgstr "顼ե" - -#~ msgid "E868: Error building NFA with equivalence class!" -#~ msgstr "E868: 饹ޤNFAۤ˼Ԥޤ!" - -#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!" -#~ msgstr "E878: (NFA) ߲Υ֥˽ʬʥƤޤ!" - -#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\"" -#~ msgstr "" -#~ "ٹ: ñꥹ \"%s_%s.spl\" \"%s_ascii.spl\" ϸĤޤ" - -#~ msgid "Conversion in %s not supported" -#~ msgstr "%s ѴϥݡȤƤޤ" - -#~ msgid "E845: Insufficient memory, word list will be incomplete" -#~ msgstr "E845: ꤬­ʤΤǡñꥹȤԴǤ" - -#~ msgid "E430: Tag file path truncated for %s\n" -#~ msgstr "E430: եΥѥ %s ڤΤƤޤ\n" - -#~ msgid "new shell started\n" -#~ msgstr "ưޤ\n" - -#~ msgid "Used CUT_BUFFER0 instead of empty selection" -#~ msgstr "ΰΤCUT_BUFFER0Ѥޤ" - -#~ msgid "No undo possible; continue anyway" -#~ msgstr "ǽʥɥϤޤ: Ȥꤢ³ޤ" - -#~ msgid "E832: Non-encrypted file has encrypted undo file: %s" -#~ msgstr "" -#~ "E832: Ź沽ե뤬Ź沽줿ɥեȤäƤޤ: %s" - -#~ msgid "E826: Undo file decryption failed: %s" -#~ msgstr "E826: Ź沽줿ɥեβɤ˼Ԥޤ: %s" - -#~ msgid "E827: Undo file is encrypted: %s" -#~ msgstr "E827: ɥե뤬Ź沽Ƥޤ: %s" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 16/32-bit GUI version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 16/32 ӥå GUI " - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 64-bit GUI version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 64 ӥå GUI " - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 32-bit GUI version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 32 ӥå GUI " - -#~ msgid " in Win32s mode" -#~ msgstr " in Win32s ⡼" - -#~ msgid " with OLE support" -#~ msgstr " with OLE ݡ" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 64-bit console version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 64 ӥå 󥽡 " - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 32-bit console version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 32 ӥå 󥽡 " - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 16-bit version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 16 ӥå " - -#~ msgid "" -#~ "\n" -#~ "32-bit MS-DOS version" -#~ msgstr "" -#~ "\n" -#~ "32 ӥå MS-DOS " - -#~ msgid "" -#~ "\n" -#~ "16-bit MS-DOS version" -#~ msgstr "" -#~ "\n" -#~ "16 ӥå MS-DOS " - -#~ msgid "" -#~ "\n" -#~ "MacOS X (unix) version" -#~ msgstr "" -#~ "\n" -#~ "MacOS X (unix) " - -#~ msgid "" -#~ "\n" -#~ "MacOS X version" -#~ msgstr "" -#~ "\n" -#~ "MacOS X " - -#~ msgid "" -#~ "\n" -#~ "MacOS version" -#~ msgstr "" -#~ "\n" -#~ "MacOS " - -#~ msgid "" -#~ "\n" -#~ "OpenVMS version" -#~ msgstr "" -#~ "\n" -#~ "OpenVMS " - -#~ msgid "" -#~ "\n" -#~ "Big version " -#~ msgstr "" -#~ "\n" -#~ "Big " - -#~ msgid "" -#~ "\n" -#~ "Normal version " -#~ msgstr "" -#~ "\n" -#~ "̾ " - -#~ msgid "" -#~ "\n" -#~ "Small version " -#~ msgstr "" -#~ "\n" -#~ "Small " - -#~ msgid "" -#~ "\n" -#~ "Tiny version " -#~ msgstr "" -#~ "\n" -#~ "Tiny " - -#~ msgid "with GTK2-GNOME GUI." -#~ msgstr "with GTK2-GNOME GUI." - -#~ msgid "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 " system gvimrc file: \"" -#~ msgstr " ƥ gvimrc: \"" - -#~ msgid " user gvimrc file: \"" -#~ msgstr " 桼 gvimrc: \"" - -#~ msgid "2nd user gvimrc file: \"" -#~ msgstr " 2桼 gvimrc: \"" - -#~ msgid "3rd user gvimrc file: \"" -#~ msgstr " 3桼 gvimrc: \"" - -#~ msgid " system menu file: \"" -#~ msgstr " ƥ˥塼: \"" - -#~ msgid "Compiler: " -#~ msgstr "ѥ: " - -#~ msgid "menu Help->Orphans for information " -#~ msgstr "ܺ٤ϥ˥塼 إעɻ 򻲾ȤƲ " - -#~ 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 for info on this" -#~ msgstr " ܺ٤ʾ :help windows95 " +msgid "Zero count" +msgstr "" -#~ msgid "Edit with &multiple Vims" -#~ msgstr "ʣVimԽ (&M)" +msgid "E81: Using not in a script context" +msgstr "E81: ץȰʳȤޤ" -#~ 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 "ޤǸΤDzޤ" -#~ 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 \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 % does not exist" -msgstr "E86: バッファ % はありません" - -#: ../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 % (add ! to override)" -msgstr "E89: バッファ % の変更は保存されていません (! で変更を破棄)" +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 % not found" -msgstr "E92: バッファ % が見つかりません" +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 %" -msgstr "行 %" +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 "% lines --%d%%--" -msgstr "% 行 --%d%%--" +msgid "%ld lines --%d%%--" +msgstr "%ld 行 --%d%%--" -#: ../buffer.c:2530 #, c-format -msgid "line % of % --%d%%-- col " -msgstr "行 % (全体 %) --%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=% id=%d name=%s" -msgstr " 行=% 識別子=%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() の引数" + +#, c-format +msgid "E737: Key already exists: %s" +msgstr "E737: キーは既に存在します: %s" -#: ../diff.c:146 #, c-format -msgid "E96: Can not diff more than % buffers" -msgstr "E96: % 以上のバッファはdiffできません" +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,701 +438,447 @@ 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: %" -msgstr "E684: リストのインデックスが範囲外です: %" - -#: ../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" +msgid "E724: variable nested too deep for displaying" +msgstr "E724: 表示するには変数の入れ子が深過ぎます" -#: ../eval.c:6499 -#, c-format -msgid "E721: Duplicate key in Dictionary: \"%s\"" -msgstr "E721: 辞書型に重複キーがあります: \"%s\"" +msgid "E805: Using a Float as a Number" +msgstr "E805: 浮動小数点数を数値として扱っています" -#: ../eval.c:6517 -#, c-format -msgid "E722: Missing comma in Dictionary: %s" -msgstr "E722: 辞書型にカンマがありません: %s" +msgid "E703: Using a Funcref as a Number" +msgstr "E703: 関数参照型を数値として扱っています。" -#: ../eval.c:6524 -#, c-format -msgid "E723: Missing end of Dictionary '}': %s" -msgstr "E723: 辞書型の最後に '}' がありません: %s" +msgid "E745: Using a List as a Number" +msgstr "E745: リスト型を数値として扱っています" -#: ../eval.c:6555 -msgid "E724: variable nested too deep for displaying" -msgstr "E724: 表示するには変数の入れ子が深過ぎます" +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: 関数参照型を浮動小数点数として扱っています。" + +msgid "E892: Using a String as a Float" +msgstr "E892: 文字列を浮動小数点数として扱っています" + +msgid "E893: Using a List as a Float" +msgstr "E893: リスト型を浮動小数点数として扱っています" + +msgid "E894: Using a Dictionary as a Float" +msgstr "E894: 辞書型を浮動小数点数として扱っています" + +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: 関数参照型を文字列として扱っています" + +msgid "E730: using List as a String" +msgstr "E730: リスト型を文字列として扱っています" + +msgid "E731: using Dictionary as a String" +msgstr "E731: 辞書型を文字列として扱っています" + +msgid "E908: using an invalid value as a String" +msgstr "E908: 無効な値を文字列として扱っています" -#: ../eval.c:7188 #, c-format -msgid "E740: Too many arguments for function %s" -msgstr "E740: 関数の引数が多過ぎます: %s" +msgid "E795: Cannot delete variable %s" +msgstr "E795: 変数 %s を削除できません" -#: ../eval.c:7190 #, c-format -msgid "E116: Invalid arguments for function %s" -msgstr "E116: 関数の無効な引数です: %s" +msgid "E704: Funcref variable name must start with a capital: %s" +msgstr "E704: 関数参照型変数名は大文字で始まらなければなりません: %s" -#: ../eval.c:7377 #, c-format -msgid "E117: Unknown function: %s" -msgstr "E117: 未知の関数です: %s" +msgid "E705: Variable name conflicts with existing function: %s" +msgstr "E705: 変数名が既存の関数名と衝突します: %s" -#: ../eval.c:7383 #, c-format -msgid "E119: Not enough arguments for function: %s" -msgstr "E119: 関数の引数が足りません: %s" +msgid "E741: Value is locked: %s" +msgstr "E741: 値がロックされています: %s" + +msgid "Unknown" +msgstr "不明" -#: ../eval.c:7387 #, c-format -msgid "E120: Using not in a script context: %s" -msgstr "E120: スクリプト以外でが使われました: %s" +msgid "E742: Cannot change value of %s" +msgstr "E742: %s の値を変更できません" + +msgid "E698: variable nested too deep for making a copy" +msgstr "E698: コピーを取るには変数の入れ子が深過ぎます" + +msgid "" +"\n" +"# global variables:\n" +msgstr "" +"\n" +"# グローバル変数:\n" + +msgid "" +"\n" +"\tLast set from " +msgstr "" +"\n" +"\t最後にセットしたスクリプト: " + +msgid "map() argument" +msgstr "map() の引数" + +msgid "filter() argument" +msgstr "filter() の引数" -#: ../eval.c:7391 #, c-format -msgid "E725: Calling dict function without Dictionary: %s" -msgstr "E725: 辞書用関数が呼ばれましたが辞書がありません: %s" +msgid "E686: Argument of %s must be a List" +msgstr "E686: %s の引数はリスト型でなければなりません" + +msgid "E928: String required" +msgstr "E928: 文字列が必要です" -#: ../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 +#. +#. * 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: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 行: " +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld 行: " -#: ../eval.c:9291 #, c-format msgid "E700: Unknown function: %s" msgstr "E700: 未知の関数です: %s" -#: ../eval.c:10729 +msgid "E922: expected a dict" +msgstr "E922: 辞書が期待されています" + +msgid "E923: Second argument of function() must be a list or a dict" +msgstr "E923: function() の第 2 引数はリスト型または辞書型でなければなりません" + +msgid "" +"&OK\n" +"&Cancel" +msgstr "" +"決定(&O)\n" +"キャンセル(&C)" + 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 "E916: not a valid job" +msgstr "E916: 有効なジョブではありません" + msgid "E701: Invalid type for len()" msgstr "E701: len() には無効な型です" -#: ../eval.c:11980 +#, c-format +msgid "E798: ID is reserved for \":match\": %ld" +msgstr "E798: ID は \":match\" のために予約されています: %ld" + 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 "" msgstr "<空>" -#: ../eval.c:12282 +msgid "E240: No connection to Vim server" +msgstr "E240: Vim サーバーへの接続がありません" + +#, c-format +msgid "E241: Unable to send to %s" +msgstr "E241: %s へ送ることができません" + +msgid "E277: Unable to read a server reply" +msgstr "E277: サーバーの応答がありません" + msgid "remove() argument" msgstr "remove() の引数" # Added at 10-Mar-2004. -#: ../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" +msgid "E258: Unable to send to client" +msgstr "E258: クライアントへ送ることができません" + +#, c-format +msgid "E927: Invalid action: '%s'" +msgstr "E927: 無効な操作です: %s" + +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 "E891: Using a Funcref as a Float" -msgstr "E891: 関数参照型を浮動小数点数として扱っています。" - -msgid "E892: Using a String as a Float" -msgstr "E892: 文字列を浮動小数点数として扱っています" - -msgid "E893: Using a List as a Float" -msgstr "E893: リスト型を浮動小数点数として扱っています" - -msgid "E894: Using a Dictionary as a Float" -msgstr "E894: 辞書型を浮動小数点数として扱っています" - -#: ../eval.c:16259 -msgid "E729: using Funcref as a String" -msgstr "E729: 関数参照型を文字列として扱っています" - -#: ../eval.c:16262 -msgid "E730: using List as a String" -msgstr "E730: リスト型を文字列として扱っています" - -#: ../eval.c:16265 -msgid "E731: using Dictionary as a String" -msgstr "E731: 辞書型を文字列として扱っています" - -#: ../eval.c:16619 -#, c-format -msgid "E706: Variable type mismatch for: %s" -msgstr "E706: 変数の型が一致しません: %s" - -#: ../eval.c:16705 -#, c-format -msgid "E795: Cannot delete variable %s" -msgstr "E795: 変数 %s を削除できません" - -#: ../eval.c:16724 -#, c-format -msgid "E704: Funcref variable name must start with a capital: %s" -msgstr "E704: 関数参照型変数名は大文字で始まらなければなりません: %s" - -#: ../eval.c:16732 -#, c-format -msgid "E705: Variable name conflicts with existing function: %s" -msgstr "E705: 変数名が既存の関数名と衝突します: %s" - -#: ../eval.c:16763 -#, c-format -msgid "E741: Value is locked: %s" -msgstr "E741: 値がロックされています: %s" - -#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839 -msgid "Unknown" -msgstr "不明" - -#: ../eval.c:16768 -#, c-format -msgid "E742: Cannot change value of %s" -msgstr "E742: %s の値を変更できません" - -#: ../eval.c:16838 -msgid "E698: variable nested too deep for making a copy" -msgstr "E698: コピーを取るには変数の入れ子が深過ぎます" - -#: ../eval.c:17249 -#, c-format -msgid "E123: Undefined function: %s" -msgstr "E123: 未定義の関数です: %s" - -#: ../eval.c:17260 -#, c-format -msgid "E124: Missing '(': %s" -msgstr "E124: '(' がありません: %s" - -#: ../eval.c:17293 -msgid "E862: Cannot use g: here" -msgstr "E862: ここでは g: は使えません" - -#: ../eval.c:17312 -#, c-format -msgid "E125: Illegal argument: %s" -msgstr "E125: 不正な引数です: %s" - -#: ../eval.c:17323 -#, c-format -msgid "E853: Duplicate argument name: %s" -msgstr "E853: 引数名が重複しています: %s" - -#: ../eval.c:17416 -msgid "E126: Missing :endfunction" -msgstr "E126: :endfunction がありません" - -#: ../eval.c:17537 -#, c-format -msgid "E707: Function name conflicts with variable: %s" -msgstr "E707: 関数名が変数名と衝突します: %s" - -#: ../eval.c:17549 -#, c-format -msgid "E127: Cannot redefine function %s: It is in use" -msgstr "E127: 関数 %s を再定義できません: 使用中です" - -#: ../eval.c:17604 -#, c-format -msgid "E746: Function name does not match script file name: %s" -msgstr "E746: 関数名がスクリプトのファイル名と一致しません: %s" - -#: ../eval.c:17716 -msgid "E129: Function name required" -msgstr "E129: 関数名が要求されます" - -#: ../eval.c:17824 -#, c-format -msgid "E128: Function name must start with a capital or \"s:\": %s" -msgstr "E128: 関数名は大文字か \"s:\" で始まらなければなりません: %s" - -#: ../eval.c:17833 -#, c-format -msgid "E884: Function name cannot contain a colon: %s" -msgstr "E884: 関数名にはコロンは含められません: %s" - -#: ../eval.c:18336 -#, c-format -msgid "E131: Cannot delete function %s: It is in use" -msgstr "E131: 関数 %s を削除できません: 使用中です" - -#: ../eval.c:18441 -msgid "E132: Function call depth is higher than 'maxfuncdepth'" -msgstr "E132: 関数呼出の入れ子数が 'maxfuncdepth' を超えました" - -#: ../eval.c:18568 -#, c-format -msgid "calling %s" -msgstr "%s を実行中です" - -#: ../eval.c:18651 -#, c-format -msgid "%s aborted" -msgstr "%s が中断されました" - -#: ../eval.c:18653 #, c-format -msgid "%s returning #%" -msgstr "%s が #% を返しました" +msgid "E935: invalid submatch number: %d" +msgstr "E935: 無効なサブマッチ番号: %d" -#: ../eval.c:18670 -#, c-format -msgid "%s returning %s" -msgstr "%s が %s を返しました" - -#: ../eval.c:18691 ../ex_cmds2.c:2695 -#, c-format -msgid "continuing in %s" -msgstr "%s の実行を継続中です" - -#: ../eval.c:18795 -msgid "E133: :return not inside a function" -msgstr "E133: 関数外に :return がありました" - -#: ../eval.c:19159 -msgid "" -"\n" -"# global variables:\n" -msgstr "" -"\n" -"# グローバル変数:\n" - -#: ../eval.c:19254 -msgid "" -"\n" -"\tLast set from " -msgstr "" -"\n" -"\tLast set from " +msgid "E677: Error writing temp file" +msgstr "E677: 一時ファイル書込中にエラーが発生しました" -#: ../eval.c:19272 -msgid "No old files" -msgstr "古いファイルはありません" +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 "% lines moved" -msgstr "% 行が移動されました" +msgid "%ld lines moved" +msgstr "%ld 行が移動されました" -#: ../ex_cmds.c:1175 #, c-format -msgid "% lines filtered" -msgstr "% 行がフィルタ処理されました" +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 %" -msgstr "E141: バッファ % には名前がありません" +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 "% matches" -msgstr "% 箇所該当しました" +msgid "%ld matches" +msgstr "%ld 箇所該当しました" -#: ../ex_cmds.c:4388 #, c-format -msgid "% substitutions" -msgstr "% 箇所置換しました" +msgid "%ld substitutions" +msgstr "%ld 箇所置換しました" -#: ../ex_cmds.c:4392 msgid " on 1 line" msgstr " (計 1 行内)" -#: ../ex_cmds.c:4395 #, c-format -msgid " on % lines" -msgstr " (計 % 行内)" +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: %" -msgstr "E157: 無効なsign識別子です: %" +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 %: %s" -msgstr "行 %: %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 %" -msgstr "ブレークポイント \"%s%s\" 行 %" +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 %" -msgstr "%3d %s %s 行 %" +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 %: could not source \"%s\"" -msgstr "行 %: \"%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 %: sourcing \"%s\"" -msgstr "行 %: %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: % more files to edit" -msgstr "E173: 編集すべきファイルがあと % 個あります" +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 \"\"" msgstr "E495: \"\"を置き換えるautocommandのファイル名がありません" -#: ../ex_docmd.c:7850 msgid "E496: no autocommand buffer number to substitute for \"\"" msgstr "E496: \"\"を置き換えるautocommandバッファ番号がありません" -#: ../ex_docmd.c:7861 msgid "E497: no autocommand match name to substitute for \"\"" msgstr "E497: \"\"を置き換えるautocommandの該当名がありません" -#: ../ex_docmd.c:7870 msgid "E498: no :source file name to substitute for \"\"" msgstr "E498: \"\"を置き換える :source 対象ファイル名がありません" -#: ../ex_docmd.c:7876 msgid "E842: no line number to use for \"\"" msgstr "E842: \"\"を置き換える行番号がありません" -#: ../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 %" -msgstr "%s, 行 %" +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 %]" -msgstr "[% 行目で変換エラー]" +msgid "[CONVERSION ERROR in line %ld]" +msgstr "[%ld 行目で変換エラー]" -#: ../fileio.c:1835 #, c-format -msgid "[ILLEGAL BYTE in line %]" -msgstr "[% 行目の不正なバイト]" +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 % (make 'fenc' empty to " +"E513: write error, conversion failed in line %ld (make 'fenc' empty to " "override)" msgstr "" -"E513: 書込みエラー, 変換失敗, 行数 % (上書するには '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 %;" -msgstr " 行 %;" +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 "% lines, " -msgstr "% 行, " +msgid "%ld lines, " +msgstr "%ld 行, " -#: ../fileio.c:3836 msgid "1 character" msgstr "1 文字" -#: ../fileio.c:3838 #, c-format -msgid "% characters" -msgstr "% 文字" +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 " 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: : 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; executes, CTRL-C quits" -msgstr "E11: コマンドラインでは無効です; で実行, 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 がありません" - -#: ../globals.h:1005 -msgid "E170: Missing :endwhile" -msgstr "E170: :endwhile がありません" +#, c-format +msgid "E254: Cannot allocate color %s" +msgstr "E254: %s の色を割り当てられません" -#: ../globals.h:1006 -msgid "E170: Missing :endfor" -msgstr "E170: :endfor がありません" +msgid "No match at cursor, finding next" +msgstr "カーソルの位置にマッチはありません, 次を検索しています" -#: ../globals.h:1007 -msgid "E588: :endwhile without :while" -msgstr "E588: :while のない :endwhile があります" +msgid " " +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\"() のライブラリ呼出に失敗しました" - -#: ../globals.h:1026 -msgid "E19: Mark has invalid line number" -msgstr "E19: マークに無効な行番号が指定されていました" - -#: ../globals.h:1027 -msgid "E20: Mark not set" -msgstr "E20: マークは設定されていません" +msgid "Yes" +msgstr "はい" -#: ../globals.h:1029 -msgid "E21: Cannot make changes, 'modifiable' is off" -msgstr "E21: 'modifiable' がオフなので, 変更できません" +msgid "No" +msgstr "いいえ" -#: ../globals.h:1030 -msgid "E22: Scripts nested too deep" -msgstr "E22: スクリプトの入れ子が深過ぎます" +msgid "Input _Methods" +msgstr "インプットメソッド" -#: ../globals.h:1031 -msgid "E23: No alternate file" -msgstr "E23: 副ファイルはありません" +msgid "VIM - Search and Replace..." +msgstr "VIM - 検索と置換..." -#: ../globals.h:1032 -msgid "E24: No such abbreviation" -msgstr "E24: そのような短縮入力はありません" +msgid "VIM - Search..." +msgstr "VIM - 検索..." -#: ../globals.h:1033 -msgid "E477: No ! allowed" -msgstr "E477: ! は許可されていません" +msgid "Find what:" +msgstr "検索文字列:" -#: ../globals.h:1035 -msgid "E25: Nvim does not have a built-in GUI" -msgstr "E25: GUIは使用不可能です: コンパイル時に無効にされています" +msgid "Replace with:" +msgstr "置換文字列:" -#: ../globals.h:1036 -#, c-format -msgid "E28: No such highlight group name: %s" -msgstr "E28: そのような名のハイライトグループはありません: %s" +#. whole word only button +msgid "Match whole word only" +msgstr "正確に該当するものだけ" -#: ../globals.h:1037 -msgid "E29: No inserted text yet" -msgstr "E29: まだテキストが挿入されていません" +#. match case button +msgid "Match case" +msgstr "大文字/小文字を区別する" -#: ../globals.h:1038 -msgid "E30: No previous command line" -msgstr "E30: 以前にコマンド行がありません" +msgid "Direction" +msgstr "方向" -#: ../globals.h:1039 -msgid "E31: No such mapping" -msgstr "E31: そのようなマッピングはありません" +#. 'Up' and 'Down' buttons +msgid "Up" +msgstr "上" -#: ../globals.h:1040 -msgid "E479: No match" -msgstr "E479: 該当はありません" +msgid "Down" +msgstr "下" -#: ../globals.h:1041 -#, c-format -msgid "E480: No match: %s" -msgstr "E480: 該当はありません: %s" +msgid "Find Next" +msgstr "次を検索" -#: ../globals.h:1042 -msgid "E32: No file name" -msgstr "E32: ファイル名がありません" +msgid "Replace" +msgstr "置換" -#: ../globals.h:1044 -msgid "E33: No previous substitute regular expression" -msgstr "E33: 正規表現置換がまだ実行されていません" +msgid "Replace All" +msgstr "全て置換" -#: ../globals.h:1045 -msgid "E34: No previous command" -msgstr "E34: コマンドがまだ実行されていません" +msgid "_Close" +msgstr "閉じる(_C)" -#: ../globals.h:1046 -msgid "E35: No previous regular expression" -msgstr "E35: 正規表現がまだ実行されていません" +msgid "Vim: Received \"die\" request from session manager\n" +msgstr "Vim: セッションマネージャから \"die\" 要求を受け取りました\n" -#: ../globals.h:1047 -msgid "E481: No range allowed" -msgstr "E481: 範囲指定は許可されていません" +msgid "Close tab" +msgstr "タブページを閉じる" -#: ../globals.h:1048 -msgid "E36: Not enough room" -msgstr "E36: ウィンドウに十分な高さもしくは幅がありません" +msgid "New tab" +msgstr "新規タブページ" -#: ../globals.h:1049 -#, c-format -msgid "E482: Can't create file %s" -msgstr "E482: ファイル %s を作成できません" +msgid "Open Tab..." +msgstr "タブページを開く..." -#: ../globals.h:1050 -msgid "E483: Can't get temp file name" -msgstr "E483: 一時ファイルの名前を取得できません" +msgid "Vim: Main window unexpectedly destroyed\n" +msgstr "Vim: メインウィンドウが不意に破壊されました\n" -#: ../globals.h:1051 -#, c-format -msgid "E484: Can't open file %s" -msgstr "E484: ファイル \"%s\" を開けません" +msgid "&Filter" +msgstr "フィルタ(&F)" -#: ../globals.h:1052 -#, c-format -msgid "E485: Can't read file %s" -msgstr "E485: ファイル %s を読込めません" +msgid "&Cancel" +msgstr "キャンセル(&C)" -#: ../globals.h:1054 -msgid "E37: No write since last change (add ! to override)" -msgstr "E37: 最後の変更が保存されていません (! を追加で変更を破棄)" +msgid "Directories" +msgstr "ディレクトリ" -#: ../globals.h:1055 -msgid "E37: No write since last change" -msgstr "E37: 最後の変更が保存されていません" +msgid "Filter" +msgstr "フィルタ" -#: ../globals.h:1056 -msgid "E38: Null argument" -msgstr "E38: 引数が空です" +msgid "&Help" +msgstr "ヘルプ(&H)" -#: ../globals.h:1057 -msgid "E39: Number expected" -msgstr "E39: 数値が要求されています" +msgid "Files" +msgstr "ファイル" -#: ../globals.h:1058 -#, c-format -msgid "E40: Can't open errorfile %s" -msgstr "E40: エラーファイル %s を開けません" +msgid "&OK" +msgstr "&OK" -#: ../globals.h:1059 -msgid "E41: Out of memory!" -msgstr "E41: メモリが尽き果てました!" +msgid "Selection" +msgstr "選択" -#: ../globals.h:1060 -msgid "Pattern not found" -msgstr "パターンは見つかりませんでした" +msgid "Find &Next" +msgstr "次を検索(&N)" -#: ../globals.h:1061 -#, c-format -msgid "E486: Pattern not found: %s" -msgstr "E486: パターンは見つかりませんでした: %s" +msgid "&Replace" +msgstr "置換(&R)" -#: ../globals.h:1062 -msgid "E487: Argument must be positive" -msgstr "E487: 引数は正の値でなければなりません" +msgid "Replace &All" +msgstr "全て置換(&A)" -#: ../globals.h:1064 -msgid "E459: Cannot go back to previous directory" -msgstr "E459: 前のディレクトリに戻れません" +msgid "&Undo" +msgstr "アンドゥ(&U)" -#: ../globals.h:1066 -msgid "E42: No Errors" -msgstr "E42: エラーはありません" +msgid "Open tab..." +msgstr "タブページを開く" -#: ../globals.h:1067 -msgid "E776: No location list" -msgstr "E776: ロケーションリストはありません" +msgid "Find string (use '\\\\' to find a '\\')" +msgstr "検索文字列 ('\\' を検索するには '\\\\')" -#: ../globals.h:1068 -msgid "E43: Damaged match string" -msgstr "E43: 該当文字列が破損しています" +msgid "Find & Replace (use '\\\\' to find a '\\')" +msgstr "検索・置換 ('\\' を検索するには '\\\\')" -#: ../globals.h:1069 -msgid "E44: Corrupted regexp program" -msgstr "E44: 不正な正規表現プログラムです" +#. 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:1071 -msgid "E45: 'readonly' option is set (add ! to override)" -msgstr "E45: 'readonly' オプションが設定されています (! を追加で上書き)" +msgid "Directory\t*.nothing\n" +msgstr "ディレクトリ\t*.nothing\n" -#: ../globals.h:1073 #, c-format -msgid "E46: Cannot change read-only variable \"%s\"" -msgstr "E46: 読取専用変数 \"%s\" には値を設定できません" +msgid "E671: Cannot find window title \"%s\"" +msgstr "E671: タイトルが \"%s\" のウィンドウは見つかりません" -#: ../globals.h:1075 #, c-format -msgid "E794: Cannot set variable in the sandbox: \"%s\"" -msgstr "E794: サンドボックスでは変数 \"%s\" に値を設定できません" - -#: ../globals.h:1076 -msgid "E47: Error while reading errorfile" -msgstr "E47: エラーファイルの読込中にエラーが発生しました" - -#: ../globals.h:1078 -msgid "E48: Not allowed in sandbox" -msgstr "E48: サンドボックスでは許されません" - -#: ../globals.h:1080 -msgid "E523: Not allowed here" -msgstr "E523: ここでは許可されません" - -#: ../globals.h:1082 -msgid "E359: Screen mode setting not supported" -msgstr "E359: スクリーンモードの設定には対応していません" - -#: ../globals.h:1083 -msgid "E49: Invalid scroll size" -msgstr "E49: 無効なスクロール量です" - -#: ../globals.h:1084 -msgid "E91: 'shell' option is empty" -msgstr "E91: 'shell' オプションが空です" - -#: ../globals.h:1085 -msgid "E255: Couldn't read in sign data!" -msgstr "E255: sign のデータを読込めませんでした" - -#: ../globals.h:1086 -msgid "E72: Close error on swap file" -msgstr "E72: スワップファイルのクローズ時エラーです" +msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." +msgstr "E243: 引数はサポートされません: \"-%s\"; OLE版を使用してください." -#: ../globals.h:1087 -msgid "E73: tag stack empty" -msgstr "E73: タグスタックが空です" +msgid "E672: Unable to open window inside MDI application" +msgstr "E672: MDIアプリの中ではウィンドウを開けません" -#: ../globals.h:1088 -msgid "E74: Command too complex" -msgstr "E74: コマンドが複雑過ぎます" +msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" +msgstr "Vim E458: 色指定が正しくないのでエントリを割り当てられません" -#: ../globals.h:1089 -msgid "E75: Name too long" -msgstr "E75: 名前が長過ぎます" +#, c-format +msgid "E250: Fonts for the following charsets are missing in fontset %s:" +msgstr "E250: 以下の文字セットのフォントがありません %s:" -#: ../globals.h:1090 -msgid "E76: Too many [" -msgstr "E76: [ が多過ぎます" +#, c-format +msgid "E252: Fontset name: %s" +msgstr "E252: フォントセット名: %s" -#: ../globals.h:1091 -msgid "E77: Too many file names" -msgstr "E77: ファイル名が多過ぎます" +#, c-format +msgid "Font '%s' is not fixed-width" +msgstr "フォント '%s' は固定幅ではありません" -#: ../globals.h:1092 -msgid "E488: Trailing characters" -msgstr "E488: 余分な文字が後ろにあります" +#, c-format +msgid "E253: Fontset name: %s" +msgstr "E253: フォントセット名: %s" -#: ../globals.h:1093 -msgid "E78: Unknown mark" -msgstr "E78: 未知のマーク" +#, c-format +msgid "Font0: %s" +msgstr "フォント0: %s" -#: ../globals.h:1094 -msgid "E79: Cannot expand wildcards" -msgstr "E79: ワイルドカードを展開できません" +#, c-format +msgid "Font1: %s" +msgstr "フォント1: %s" -#: ../globals.h:1096 -msgid "E591: 'winheight' cannot be smaller than 'winminheight'" -msgstr "E591: 'winheight' は 'winminheight' より小さくできません" +#, c-format +msgid "Font%ld width is not twice that of font0" +msgstr "フォント%ld の幅がフォント0の2倍ではありません" -#: ../globals.h:1098 -msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'" -msgstr "E592: 'winwidth' は 'winminwidth' より小さくできません" +#, c-format +msgid "Font0 width: %ld" +msgstr "フォント0の幅: %ld" -#: ../globals.h:1099 -msgid "E80: Error while writing" -msgstr "E80: 書込み中のエラー" +#, c-format +msgid "Font1 width: %ld" +msgstr "フォント1の幅: %ld" -#: ../globals.h:1100 -msgid "Zero count" -msgstr "ゼロカウント" +msgid "Invalid font specification" +msgstr "無効なフォント指定です" -#: ../globals.h:1101 -msgid "E81: Using not in a script context" -msgstr "E81: スクリプト以外でが使われました" +msgid "&Dismiss" +msgstr "却下する(&D)" -#: ../globals.h:1102 -#, c-format -msgid "E685: Internal error: %s" -msgstr "E685: 内部エラーです: %s" +msgid "no specific match" +msgstr "マッチするものがありません" -#: ../globals.h:1104 -msgid "E363: pattern uses more memory than 'maxmempattern'" -msgstr "E363: パターンが 'maxmempattern' 以上のメモリを使用します" +msgid "Vim - Font Selector" +msgstr "Vim - フォント選択" -#: ../globals.h:1105 -msgid "E749: empty buffer" -msgstr "E749: バッファが空です" +msgid "Name:" +msgstr "名前:" -#: ../globals.h:1108 -msgid "E682: Invalid search pattern or delimiter" -msgstr "E682: 検索パターンか区切り記号が不正です" +#. create toggle button +msgid "Show size in Points" +msgstr "サイズをポイントで表示する" -#: ../globals.h:1109 -msgid "E139: File is loaded in another buffer" -msgstr "E139: 同じ名前のファイルが他のバッファで読込まれています" +msgid "Encoding:" +msgstr "エンコード:" -#: ../globals.h:1110 -#, c-format -msgid "E764: Option '%s' is not set" -msgstr "E764: オプション '%s' は設定されていません" +msgid "Font:" +msgstr "フォント:" -#: ../globals.h:1111 -msgid "E850: Invalid register name" -msgstr "E850: 無効なレジスタ名です" +msgid "Style:" +msgstr "スタイル:" -#: ../globals.h:1114 -msgid "search hit TOP, continuing at BOTTOM" -msgstr "上まで検索したので下に戻ります" +msgid "Size:" +msgstr "サイズ:" -#: ../globals.h:1115 -msgid "search hit BOTTOM, continuing at TOP" -msgstr "下まで検索したので上に戻ります" +msgid "E256: Hangul automata ERROR" +msgstr "E256: ハングルオートマトンエラー" -#: ../hardcopy.c:240 msgid "E550: Missing colon" msgstr "E550: コロンがありません" -#: ../hardcopy.c:252 msgid "E551: Illegal component" msgstr "E551: 不正な構文要素です" -#: ../hardcopy.c:259 msgid "E552: digit expected" msgstr "E552: 数値が必要です" -#: ../hardcopy.c:473 #, c-format msgid "Page %d" msgstr "%d ページ" -#: ../hardcopy.c:597 msgid "No text to be printed" msgstr "印刷するテキストがありません" -#: ../hardcopy.c:668 #, c-format msgid "Printing page %d (%d%%)" msgstr "印刷中: ページ %d (%d%%)" -#: ../hardcopy.c:680 #, c-format msgid " Copy %d of %d" msgstr " コピー %d (全 %d 中)" -#: ../hardcopy.c:733 #, c-format msgid "Printed: %s" msgstr "印刷しました: %s" -#: ../hardcopy.c:740 msgid "Printing aborted" msgstr "印刷が中止されました" -#: ../hardcopy.c:1365 msgid "E455: Error writing to PostScript output file" msgstr "E455: PostScript出力ファイルの書込みエラーです" -#: ../hardcopy.c:1747 #, c-format msgid "E624: Can't open file \"%s\"" msgstr "E624: ファイル \"%s\" を開けません" -#: ../hardcopy.c:1756 ../hardcopy.c:2470 #, c-format msgid "E457: Can't read PostScript resource file \"%s\"" msgstr "E457: PostScriptのリソースファイル \"%s\" を読込めません" -#: ../hardcopy.c:1772 #, c-format msgid "E618: file \"%s\" is not a PostScript resource file" msgstr "E618: ファイル \"%s\" は PostScript リソースファイルではありません" -#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844 #, c-format msgid "E619: file \"%s\" is not a supported PostScript resource file" msgstr "E619: ファイル \"%s\" は対応していない PostScript リソースファイルです" -#: ../hardcopy.c:1856 #, c-format msgid "E621: \"%s\" resource file has wrong version" msgstr "E621: リソースファイル \"%s\" はバージョンが異なります" -#: ../hardcopy.c:2225 msgid "E673: Incompatible multi-byte encoding and character set." msgstr "E673: 互換性の無いマルチバイトエンコーディングと文字セットです" -#: ../hardcopy.c:2238 msgid "E674: printmbcharset cannot be empty with multi-byte encoding." msgstr "E674: マルチバイトエンコーディングでは printmbcharset を空にできません" -#: ../hardcopy.c:2254 msgid "E675: No default font specified for multi-byte printing." msgstr "" "E675: マルチバイト文字を印刷するためのデフォルトフォントが指定されていません" -#: ../hardcopy.c:2426 msgid "E324: Can't open PostScript output file" msgstr "E324: PostScript出力用のファイルを開けません" -#: ../hardcopy.c:2458 #, c-format msgid "E456: Can't open file \"%s\"" msgstr "E456: ファイル \"%s\" を開けません" -#: ../hardcopy.c:2583 msgid "E456: Can't find PostScript resource file \"prolog.ps\"" msgstr "E456: PostScriptのリソースファイル \"prolog.ps\" が見つかりません" -#: ../hardcopy.c:2593 msgid "E456: Can't find PostScript resource file \"cidfont.ps\"" msgstr "E456: PostScriptのリソースファイル \"cidfont.ps\" が見つかりません" -#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665 #, c-format msgid "E456: Can't find PostScript resource file \"%s.ps\"" msgstr "E456: PostScriptのリソースファイル \"%s.ps\" が見つかりません" -#: ../hardcopy.c:2654 #, c-format msgid "E620: Unable to convert to print encoding \"%s\"" msgstr "E620: 印刷エンコード \"%s\" へ変換できません" -#: ../hardcopy.c:2877 msgid "Sending to printer..." msgstr "プリンタに送信中..." -#: ../hardcopy.c:2881 msgid "E365: Failed to print PostScript file" msgstr "E365: PostScriptファイルの印刷に失敗しました" -#: ../hardcopy.c:2883 msgid "Print job sent." msgstr "印刷ジョブを送信しました." -#: ../if_cscope.c:85 msgid "Add a new database" msgstr "新データベースを追加" -#: ../if_cscope.c:87 msgid "Query for a pattern" msgstr "パターンのクエリーを追加" -#: ../if_cscope.c:89 msgid "Show this message" msgstr "このメッセージを表示する" -#: ../if_cscope.c:91 msgid "Kill a connection" msgstr "接続を終了する" -#: ../if_cscope.c:93 msgid "Reinit all connections" msgstr "全ての接続を再初期化する" -#: ../if_cscope.c:95 msgid "Show connections" msgstr "接続を表示する" -#: ../if_cscope.c:101 #, c-format msgid "E560: Usage: cs[cope] %s" msgstr "E560: 使用方法: cs[cope] %s" -#: ../if_cscope.c:225 msgid "This cscope command does not support splitting the window.\n" msgstr "このcscopeコマンドは分割ウィンドウではサポートされません.\n" -#: ../if_cscope.c:266 msgid "E562: Usage: cstag " msgstr "E562: 使用法: cstag " -#: ../if_cscope.c:313 msgid "E257: cstag: tag not found" msgstr "E257: cstag: タグが見つかりません" -#: ../if_cscope.c:461 #, c-format msgid "E563: stat(%s) error: %d" msgstr "E563: stat(%s) エラー: %d" -#: ../if_cscope.c:551 +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 %" -msgstr "E262: cscopeの接続 % を読込み中のエラーです" +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,111 +2592,319 @@ 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 "Unknown option argument" -msgstr "未知のオプション引数です" +msgid "Lua library cannot be loaded." +msgstr "Luaライブラリをロードできません." -#: ../main.c:146 -msgid "Too many edit arguments" -msgstr "編集引数が多過ぎます" +msgid "cannot save undo information" +msgstr "アンドゥ情報が保存できません" -#: ../main.c:148 -msgid "Argument missing after" -msgstr "引数がありません" +msgid "" +"E815: Sorry, this command is disabled, the MzScheme libraries could not be " +"loaded." +msgstr "E815: このコマンドは無効です. MzScheme ライブラリをロードできません." -#: ../main.c:150 -msgid "Garbage after option argument" -msgstr "オプション引数の後にゴミがあります" +msgid "" +"E895: Sorry, this command is disabled, the MzScheme's racket/base module " +"could not be loaded." +msgstr "" +"E895: このコマンドは無効です,ごめんなさい. MzScheme の racket/base モジュール" +"がロードできませんでした." -#: ../main.c:152 -msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" -msgstr "\"+command\", \"-c command\", \"--cmd command\" の引数が多過ぎます" +msgid "invalid expression" +msgstr "無効な式です" -#: ../main.c:154 -msgid "Invalid argument for" -msgstr "無効な引数です: " +msgid "expressions disabled at compile time" +msgstr "式はコンパイル時に無効にされています" -#: ../main.c:294 -#, c-format -msgid "%d files to edit\n" -msgstr "%d 個のファイルが編集を控えています\n" +msgid "hidden option" +msgstr "隠しオプション" -#: ../main.c:1342 -msgid "Attempt to open script file again: \"" -msgstr "スクリプトファイルを再び開いてみます: \"" +msgid "unknown option" +msgstr "未知のオプションです" -#: ../main.c:1350 -msgid "Cannot open for reading: \"" -msgstr "読込用として開けません" +msgid "window index is out of range" +msgstr "範囲外のウィンドウ番号です" -#: ../main.c:1393 -msgid "Cannot open for script output: \"" -msgstr "スクリプト出力用を開けません" +msgid "couldn't open buffer" +msgstr "バッファを開けません" -#: ../main.c:1622 -msgid "Vim: Warning: Output is not to a terminal\n" -msgstr "Vim: 警告: 端末への出力ではありません\n" +msgid "cannot delete line" +msgstr "行を消せません" -#: ../main.c:1624 -msgid "Vim: Warning: Input is not from a terminal\n" -msgstr "Vim: 警告: 端末からの入力ではありません\n" +msgid "cannot replace line" +msgstr "行を置換できません" -#. just in case.. -#: ../main.c:1891 -msgid "pre-vimrc command line" -msgstr "vimrc前のコマンドライン" +msgid "cannot insert line" +msgstr "行を挿入できません" -#: ../main.c:1964 -#, c-format -msgid "E282: Cannot read from \"%s\"" -msgstr "E282: \"%s\"から読込むことができません" +msgid "string cannot contain newlines" +msgstr "文字列には改行文字を含められません" -#: ../main.c:2149 -msgid "" -"\n" +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 "未知のオプション引数です" + +msgid "Too many edit arguments" +msgstr "編集引数が多過ぎます" + +msgid "Argument missing after" +msgstr "引数がありません" + +msgid "Garbage after option argument" +msgstr "オプション引数の後にゴミがあります" + +msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" +msgstr "\"+command\", \"-c command\", \"--cmd command\" の引数が多過ぎます" + +msgid "Invalid argument for" +msgstr "無効な引数です: " + +#, c-format +msgid "%d files to edit\n" +msgstr "%d 個のファイルが編集を控えています\n" + +msgid "netbeans is not supported with this GUI\n" +msgstr "netbeans はこのGUIでは利用できません\n" + +msgid "'-nb' cannot be used: not enabled at compile time\n" +msgstr "'-nb' 使用不可能です: コンパイル時に無効にされています\n" + +msgid "This Vim was not compiled with the diff feature." +msgstr "このVimにはdiff機能がありません(コンパイル時設定)." + +msgid "Attempt to open script file again: \"" +msgstr "スクリプトファイルを再び開いてみます: \"" + +msgid "Cannot open for reading: \"" +msgstr "読込用として開けません" + +msgid "Cannot open for script output: \"" +msgstr "スクリプト出力用を開けません" + +msgid "Vim: Error: Failure to start gvim from NetBeans\n" +msgstr "Vim: エラー: 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" + +msgid "Vim: Warning: Input is not from a terminal\n" +msgstr "Vim: 警告: 端末からの入力ではありません\n" + +#. just in case.. +msgid "pre-vimrc command line" +msgstr "vimrc前のコマンドライン" + +#, c-format +msgid "E282: Cannot read from \"%s\"" +msgstr "E282: \"%s\"から読込むことができません" + +msgid "" +"\n" "More info with: \"vim -h\"\n" msgstr "" "\n" "より詳細な情報は: \"vim -h\"\n" -#: ../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 \t\tUse for I/O" +msgstr "-dev \t\tI/Oに を使用する" + 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 \tSet terminal type to " msgstr "-T \t端末を に設定する" -#: ../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 \t\tUse instead of any .vimrc" msgstr "-u \t\t.vimrcの代わりに を使う" -#: ../main.c:2226 +msgid "-U \t\tUse instead of any .gvimrc" +msgstr "-U \t\t.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 "+\t\tStart at line " msgstr "+\t\t 行からはじめる" -#: ../main.c:2232 msgid "--cmd \tExecute before loading any vimrc file" msgstr "--cmd \tvimrcをロードする前に を実行する" -#: ../main.c:2233 msgid "-c \t\tExecute after loading the first file" msgstr "-c \t\t最初のファイルをロード後 を実行する" -#: ../main.c:2235 msgid "-S \t\tSource file after loading the first file" msgstr "-S \t\t最初のファイルをロード後ファイル を取込む" -#: ../main.c:2236 msgid "-s \tRead Normal mode commands from file " msgstr "-s \tファイル からノーマルコマンドを読込む" -#: ../main.c:2237 msgid "-w \tAppend all typed commands to file " msgstr "-w \t入力した全コマンドをファイル に追加する" -#: ../main.c:2238 msgid "-W \tWrite all typed commands to file " msgstr "-W \t入力した全コマンドをファイル に保存する" -#: ../main.c:2240 +msgid "-x\t\t\tEdit encrypted files" +msgstr "-x\t\t\t暗号化されたファイルを編集する" + +msgid "-display \tConnect vim to this particular X-server" +msgstr "-display \tvimを指定した X サーバーに接続する" + +msgid "-X\t\t\tDo not connect to X server" +msgstr "-X\t\t\tXサーバーに接続しない" + +msgid "--remote \tEdit in a Vim server if possible" +msgstr "--remote \t可能ならばVimサーバーで を編集する" + +msgid "--remote-silent Same, don't complain if there is no server" +msgstr "--remote-silent 同上, サーバーが無くても警告文を出力しない" + +msgid "" +"--remote-wait As --remote but wait for files to have been edited" +msgstr "--remote-wait \t--remote後 ファイルの編集が終わるのを待つ" + +msgid "" +"--remote-wait-silent Same, don't complain if there is no server" +msgstr "" +"--remote-wait-silent 同上, サーバーが無くても警告文を出力しない" + +msgid "" +"--remote-tab[-wait][-silent] As --remote but use tab page per file" +msgstr "" +"--remote-tab[-wait][-silent] --remoteでファイル1つにつき1つのタブ" +"ページを開く" + +msgid "--remote-send \tSend to a Vim server and exit" +msgstr "--remote-send \tVimサーバーに を送信して終了する" + +msgid "--remote-expr \tEvaluate in a Vim server and print result" +msgstr "--remote-expr \tサーバーで を実行して結果を表示する" + +msgid "--serverlist\t\tList available Vim server names and exit" +msgstr "--serverlist\t\tVimサーバー名の一覧を表示して終了する" + +msgid "--servername \tSend to/become the Vim server " +msgstr "--servername \tVimサーバー に送信/名前設定する" + msgid "--startuptime \tWrite startup timing messages to " msgstr "--startuptime \t起動にかかった時間の詳細を へ出力する" -#: ../main.c:2242 msgid "-i \t\tUse instead of .viminfo" msgstr "-i \t\t.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 \tRun vim on " +msgstr "-display \t でvimを実行する" + +msgid "-iconic\t\tStart vim iconified" +msgstr "-iconic\t\t最小化した状態でvimを起動する" + +msgid "-background \tUse for the background (also: -bg)" +msgstr "-background \t背景色に を使う(同義: -bg)" + +msgid "-foreground \tUse for normal text (also: -fg)" +msgstr "-foreground \t前景色に を使う(同義: -fg)" + +msgid "-font \t\tUse for normal text (also: -fn)" +msgstr "-font \t\tテキスト表示に を使う(同義: -fn)" + +msgid "-boldfont \tUse for bold text" +msgstr "-boldfont \t太字に を使う" + +msgid "-italicfont \tUse for italic text" +msgstr "-italicfont \t斜体字に を使う" + +msgid "-geometry \tUse for initial geometry (also: -geom)" +msgstr "-geometry \t初期配置に を使う(同義: -geom)" + +msgid "-borderwidth \tUse a border width of (also: -bw)" +msgstr "-borderwidth \t境界の幅を にする(同義: -bw)" + +msgid "-scrollbarwidth Use a scrollbar width of (also: -sw)" +msgstr "" +"-scrollbarwidth スクロールバーの幅を にする(同義: -sw)" + +msgid "-menuheight \tUse a menu bar height of (also: -mh)" +msgstr "-menuheight \tメニューバーの高さを にする(同義: -mh)" + +msgid "-reverse\t\tUse reverse video (also: -rv)" +msgstr "-reverse\t\t反転映像を使用する(同義: -rv)" + +msgid "+reverse\t\tDon't use reverse video (also: +rv)" +msgstr "+reverse\t\t反転映像を使用しない(同義: +rv)" + +msgid "-xrm \tSet the specified resource" +msgstr "-xrm \t特定のリソースを使用する" + +msgid "" +"\n" +"Arguments recognised by gvim (GTK+ version):\n" +msgstr "" +"\n" +"gvimによって解釈される引数(GTK+バージョン):\n" + +msgid "-display \tRun vim on (also: --display)" +msgstr "-display \t でvimを実行する(同義: --display)" + +msgid "--role \tSet a unique role to identify the main window" +msgstr "--role \tメインウィンドウを識別する一意な役割(role)を設定する" + +msgid "--socketid \tOpen Vim inside another GTK widget" +msgstr "--socketid \t異なるGTK widgetでVimを開く" + +msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout" +msgstr "--echo-wid\t\tウィンドウIDを標準出力に出力する" + +msgid "-P \tOpen Vim inside parent application" +msgstr "-P <親のタイトル>\tVimを親アプリケーションの中で起動する" + +msgid "--windowid \tOpen Vim inside another win32 widget" +msgstr "--windowid \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: %" -msgstr "E315: ml_get: 無効なlnumです: %" +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 %" -msgstr "E316: ml_get: 行 % を見つけられません" +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 %" -msgstr "E320: 行 % が見つかりません" +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: % past the end" -msgstr "E322: 行番号が範囲外です: % 超えています" +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 %" -msgstr "E323: ブロック % の行カウントが間違っています" +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 % bytes)" -msgstr "E342: メモリが足りません! (% バイトを割当要求)" - -#: ../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 " +msgstr "日本語メッセージ翻訳/監修: 村岡 太郎 " + msgid "Interrupt: " msgstr "割込み: " -#: ../message.c:988 msgid "Press ENTER or type command to continue" msgstr "続けるにはENTERを押すかコマンドを入力してください" -#: ../message.c:1843 #, c-format -msgid "%s line %" -msgstr "%s 行 %" +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,199 +3876,260 @@ msgstr "" "はい(&Y)\n" "いいえ(&N)" -#: ../message.c:3033 msgid "" "&Yes\n" "&No\n" +"Save &All\n" +"&Discard All\n" "&Cancel" msgstr "" "はい(&Y)\n" "いいえ(&N)\n" +"全て保存(&A)\n" +"全て放棄(&D)\n" "キャンセル(&C)" -#: ../message.c:3045 -msgid "" -"&Yes\n" -"&No\n" -"Save &All\n" -"&Discard All\n" -"&Cancel" -msgstr "" -"はい(&Y)\n" -"いいえ(&N)\n" -"全て保存(&A)\n" -"全て放棄(&D)\n" -"キャンセル(&C)" +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: コンソールモードではファイルブラウザを使えません, ごめんなさい" -#: ../message.c:3058 msgid "E766: Insufficient arguments for printf()" msgstr "E766: printf() の引数が不十分です" -#: ../message.c:3119 msgid "E807: Expected Float argument for printf()" msgstr "E807: printf() の引数には浮動少数点数が期待されています" -#: ../message.c:3873 msgid "E767: Too many arguments to printf()" msgstr "E767: printf() の引数が多過ぎます" -#: ../misc1.c:2256 msgid "W10: Warning: Changing a readonly file" msgstr "W10: 警告: 読込専用ファイルを変更します" -#: ../misc1.c:2537 msgid "Type number and or click with mouse (empty cancels): " msgstr "" "番号とを入力するかマウスでクリックしてください (空でキャンセル): " -#: ../misc1.c:2539 msgid "Type number and (empty cancels): " msgstr "番号とを入力してください (空でキャンセル): " -#: ../misc1.c:2585 msgid "1 more line" msgstr "1 行 追加しました" -#: ../misc1.c:2588 msgid "1 line less" msgstr "1 行 削除しました" -#: ../misc1.c:2593 #, c-format -msgid "% more lines" -msgstr "% 行 追加しました" +msgid "%ld more lines" +msgstr "%ld 行 追加しました" -#: ../misc1.c:2596 #, c-format -msgid "% fewer lines" -msgstr "% 行 削除しました" +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 to exit Nvim" +msgid "Type :quit to exit Vim" msgstr "Vimを終了するには :quit と入力してください" -#: ../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 "% lines %sed 1 time" -msgstr "% 行が %s で 1 回処理されました" +msgid "%ld lines %sed 1 time" +msgstr "%ld 行が %s で 1 回処理されました" -#: ../ops.c:256 #, c-format -msgid "% lines %sed %d times" -msgstr "% 行が %s で %d 回処理されました" +msgid "%ld lines %sed %d times" +msgstr "%ld 行が %s で %d 回処理されました" -#: ../ops.c:592 #, c-format -msgid "% lines to indent... " -msgstr "% 行がインデントされます... " +msgid "%ld lines to indent... " +msgstr "%ld 行がインデントされます... " -#: ../ops.c:634 msgid "1 line indented " msgstr "1 行をインデントしました " -#: ../ops.c:636 #, c-format -msgid "% lines indented " -msgstr "% 行をインデントしました " +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 "% lines changed" -msgstr "% 行が変更されました" +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 % lines yanked" -msgstr "% 行のブロックがヤンクされました" +msgid "block of %ld lines yanked" +msgstr "%ld 行のブロックがヤンクされました" -#: ../ops.c:2528 #, c-format -msgid "% lines yanked" -msgstr "% 行がヤンクされました" +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 "% Cols; " -msgstr "% 列; " +msgid "%ld Cols; " +msgstr "%ld 列; " -#: ../ops.c:5097 #, c-format -msgid "" -"Selected %s% of % Lines; % of % Words; " -"% of % Bytes" -msgstr "" -"選択 %s% / % 行; % / % 単語; % / " -"% バイト" +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% of % Lines; % of % Words; " -"% of % Chars; % of % Bytes" +"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of " +"%lld Bytes" msgstr "" -"選択 %s% / % 行; % / % 単語; % / " -"% 文字; % / % バイト" +"選択 %s%ld / %ld 行; %lld / %lld 単語; %lld / %lld 文字; %lld / %lld バイト" -#: ../ops.c:5123 #, c-format -msgid "" -"Col %s of %s; Line % of %; Word % of %; Byte " -"% of %" -msgstr "" -"列 %s / %s; 行 % of %; 単語 % / %; バイト " -"% / %" +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 % of %; Word % of %; Char " -"% of %; Byte % of %" +"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte " +"%lld of %lld" msgstr "" -"列 %s / %s; 行 % / %; 単語 % / %; 文字 " -"% / %; バイト % of %" +"列 %s / %s; 行 %ld / %ld; 単語 %lld / %lld; 文字 %lld / %lld; バイト %lld of " +"%lld" -#: ../ops.c:5146 #, c-format -msgid "(+% for BOM)" -msgstr "(+% 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: %" -msgstr "E877: (NFA 正規表現) 無効な文字クラス: %" +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: %" -msgstr "音声畳込み後の総単語数: %" +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 % entries" -msgstr "E765: 'spellfile' には % 個のエントリはありません" +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 % suggestions" -msgstr "残念ですが, 修正候補は % 個しかありません" - -#. 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 %" -msgstr "直前の % バイト" +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 % not found" -msgstr "E830: アンドゥ番号 % は見つかりません" +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 "% %s; %s #% %s" -msgstr "% %s; %s #% %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 "% seconds ago" -msgstr "% 秒経過しています" +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 not in a script context: %s" +msgstr "E120: スクリプト以外でが使われました: %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 "without GUI." -msgstr "without GUI." - -#: ../version.c:662 -msgid " Features included (+) or not (-):\n" -msgstr " 機能の一覧 有効(+)/無効(-)\n" +msgid "" +"\n" +"Big version " +msgstr "" +"\n" +"Big 版 " -#: ../version.c:667 -msgid " system vimrc file: \"" -msgstr " システム vimrc: \"" +msgid "" +"\n" +"Normal version " +msgstr "" +"\n" +"通常 版 " -#: ../version.c:672 -msgid " user vimrc file: \"" +msgid "" +"\n" +"Small version " +msgstr "" +"\n" +"Small 版 " + +msgid "" +"\n" +"Tiny version " +msgstr "" +"\n" +"Tiny 版 " + +msgid "without GUI." +msgstr "without GUI." + +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" + +msgid " system vimrc file: \"" +msgstr " システム vimrc: \"" + +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 for information " msgstr "詳細な情報は :help iccf " -#: ../version.c:779 msgid "type :q to exit " msgstr "終了するには :q " -#: ../version.c:780 msgid "type :help or for on-line help" msgstr "オンラインヘルプは :help " -#: ../version.c:781 -msgid "type :help version7 for version info" -msgstr "バージョン情報は :help version7 " +msgid "type :help version8 for version info" +msgstr "バージョン情報は :help version8 " -#: ../version.c:784 msgid "Running in Vi compatible mode" msgstr "Vi互換モードで動作中" -#: ../version.c:785 msgid "type :set nocp for Vim defaults" msgstr "Vim推奨値にするには :set nocp " -#: ../version.c:786 msgid "type :help cp-default for info on this" msgstr "詳細な情報は :help cp-default" -#: ../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 for information " msgstr "詳細な情報は :help sponsor " -#: ../version.c:832 msgid "type :help register for information " msgstr "詳細な情報は :help register " -#: ../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 for info on this" +msgstr "詳細な情報は :help windows95" + 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 "リストか数値が必要です" +#, c-format +msgid "E447: Can't find file \"%s\" in path" +msgstr "E447: pathには \"%s\" というファイルがありません" -#~ msgid "E831: bf_key_init() called with empty password" -#~ msgstr "E831: bf_key_init() が空パスワードで呼び出されました" +#, c-format +msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E799: 無効な ID: %ld (1 以上でなければなりません)" -#~ msgid "E820: sizeof(uint32_t) != 4" -#~ msgstr "E820: sizeof(uint32_t) != 4" +#, c-format +msgid "E801: ID already taken: %ld" +msgstr "E801: ID はすでに利用中です: %ld" -#~ msgid "E817: Blowfish big/little endian use wrong" -#~ msgstr "E817: Blowfish暗号のビッグ/リトルエンディアンが間違っています" +msgid "List or number required" +msgstr "リストか数値が必要です" -#~ msgid "E818: sha256 test failed" -#~ msgstr "E818: sha256のテストに失敗しました" +#, c-format +msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E802: 無効な ID: %ld (1 以上でなければなりません)" -#~ msgid "E819: Blowfish test failed" -#~ msgstr "E819: Blowfish暗号のテストに失敗しました" +#, c-format +msgid "E803: ID not found: %ld" +msgstr "E803: ID はありません: %ld" -#~ msgid "Patch file" -#~ msgstr "パッチファイル" +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: ライブラリ %s をロードできませんでした" -#~ msgid "" -#~ "&OK\n" -#~ "&Cancel" -#~ msgstr "" -#~ "決定(&O)\n" -#~ "キャンセル(&C)" +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"このコマンドは無効です, ごめんなさい: Perlライブラリをロードできませんでした." -#~ msgid "E240: No connection to Vim server" -#~ msgstr "E240: Vim サーバへの接続がありません" +msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" +msgstr "" +"E299: サンドボックスでは Safe モジュールを使用しないPerlスクリプトは禁じられ" +"ています" -#~ msgid "E241: Unable to send to %s" -#~ msgstr "E241: %s へ送ることができません" +msgid "Edit with &multiple Vims" +msgstr "複数のVimで編集する (&M)" -#~ msgid "E277: Unable to read a server reply" -#~ msgstr "E277: サーバの応答がありません" +msgid "Edit with single &Vim" +msgstr "1つのVimで編集する (&V)" -#~ msgid "E258: Unable to send to client" -#~ msgstr "E258: クライアントへ送ることができません" +msgid "Diff with Vim" +msgstr "Vimで差分を表示する" -#~ msgid "Save As" -#~ msgstr "別名で保存" +msgid "Edit with &Vim" +msgstr "Vimで編集する (&V)" -#~ msgid "Edit File" -#~ msgstr "ファイルを編集" +#. Now concatenate +msgid "Edit with existing Vim - " +msgstr "起動済のVimで編集する - " -# Added at 27-Jan-2004. -#~ msgid " (NOT FOUND)" -#~ msgstr " (見つかりません)" +msgid "Edits the selected file(s) with Vim" +msgstr "選択したファイルをVimで編集する" -#~ msgid "Source Vim script" -#~ msgstr "Vimスクリプトの取込み" +msgid "Error creating process: Check if gvim is in your path!" +msgstr "プロセスの作成に失敗: gvimが環境変数PATH上にあるか確認してください!" -#~ msgid "unknown" -#~ msgstr "不明" +msgid "gvimext.dll error" +msgstr "gvimext.dll エラー" -#~ msgid "Edit File in new window" -#~ msgstr "新しいウィンドウでファイルを編集します" +msgid "Path length too long!" +msgstr "パスが長過ぎます!" -#~ msgid "Append File" -#~ msgstr "追加ファイル" +msgid "--No lines in buffer--" +msgstr "--バッファに行がありません--" -#~ msgid "Window position: X %d, Y %d" -#~ msgstr "ウィンドウ位置: X %d, Y %d" +#. +#. * 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 "Save Redirection" -#~ msgstr "リダイレクトを保存します" +msgid "E471: Argument required" +msgstr "E471: 引数が必要です" -#~ msgid "Save View" -#~ msgstr "ビューを保存します" +msgid "E10: \\ should be followed by /, ? or &" +msgstr "E10: \\ の後は / か ? か & でなければなりません" -#~ msgid "Save Session" -#~ msgstr "セッション情報を保存します" +msgid "E11: Invalid in command-line window; executes, CTRL-C quits" +msgstr "E11: コマンドラインでは無効です; で実行, CTRL-Cでやめる" -#~ msgid "Save Setup" -#~ msgstr "設定を保存します" +msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search" +msgstr "" +"E12: 現在のディレクトリやタグ検索ではexrc/vimrcのコマンドは許可されません" -#~ msgid "E809: #< is not available without the +eval feature" -#~ msgstr "E809: #< は +eval 機能が無いと利用できません" +msgid "E171: Missing :endif" +msgstr "E171: :endif がありません" -#~ msgid "E196: No digraphs in this version" -#~ msgstr "E196: このバージョンに合字はありません" +msgid "E600: Missing :endtry" +msgstr "E600: :endtry がありません" -#~ msgid "is a device (disabled with 'opendevice' option)" -#~ msgstr " はデバイスです ('opendevice' オプションで回避できます)" +msgid "E170: Missing :endwhile" +msgstr "E170: :endwhile がありません" -#~ msgid "Reading from stdin..." -#~ msgstr "標準入力から読込み中..." +msgid "E170: Missing :endfor" +msgstr "E170: :endfor がありません" -#~ msgid "[blowfish]" -#~ msgstr "[blowfish暗号化]" +msgid "E588: :endwhile without :while" +msgstr "E588: :while のない :endwhile があります" -#~ msgid "[crypted]" -#~ msgstr "[暗号化]" +msgid "E588: :endfor without :for" +msgstr "E588: :endfor のない :for があります" -#~ msgid "E821: File is encrypted with unknown method" -#~ msgstr "E821: ファイルが未知の方法で暗号化されています" +msgid "E13: File exists (add ! to override)" +msgstr "E13: ファイルが存在します (! を追加で上書)" -# Added at 19-Jan-2004. -#~ msgid "NetBeans disallows writes of unmodified buffers" -#~ msgstr "NetBeansは未変更のバッファを上書することは許可していません" +msgid "E472: Command failed" +msgstr "E472: コマンドが失敗しました" -#~ msgid "Partial writes disallowed for NetBeans buffers" -#~ msgstr "NetBeansバッファの一部を書き出すことはできません" +#, c-format +msgid "E234: Unknown fontset: %s" +msgstr "E234: 未知のフォントセット: %s" -#~ msgid "writing to device disabled with 'opendevice' option" -#~ msgstr "'opendevice' オプションによりデバイスへの書き込みはできません" +#, c-format +msgid "E235: Unknown font: %s" +msgstr "E235: 未知のフォント: %s" -#~ msgid "E460: The resource fork would be lost (add ! to override)" -#~ msgstr "E460: リソースフォークが失われるかもしれません (! を追加で強制)" +#, c-format +msgid "E236: Font \"%s\" is not fixed-width" +msgstr "E236: フォント \"%s\" は固定幅ではありません" -#~ msgid "E851: Failed to create a new process for the GUI" -#~ msgstr "E851: GUI用のプロセスの起動に失敗しました" +msgid "E473: Internal error" +msgstr "E473: 内部エラーです" -#~ msgid "E852: The child process failed to start the GUI" -#~ msgstr "E852: 子プロセスがGUIの起動に失敗しました" +msgid "Interrupted" +msgstr "割込まれました" -#~ msgid "E229: Cannot start the GUI" -#~ msgstr "E229: GUIを開始できません" +msgid "E14: Invalid address" +msgstr "E14: 無効なアドレスです" -#~ msgid "E230: Cannot read from \"%s\"" -#~ msgstr "E230: \"%s\"から読込むことができません" +msgid "E474: Invalid argument" +msgstr "E474: 無効な引数です" -#~ msgid "E665: Cannot start GUI, no valid font found" -#~ msgstr "E665: 有効なフォントが見つからないので, GUIを開始できません" +#, c-format +msgid "E475: Invalid argument: %s" +msgstr "E475: 無効な引数です: %s" -#~ msgid "E231: 'guifontwide' invalid" -#~ msgstr "E231: 'guifontwide' が無効です" +#, c-format +msgid "E15: Invalid expression: %s" +msgstr "E15: 無効な式です: %s" -#~ msgid "E599: Value of 'imactivatekey' is invalid" -#~ msgstr "E599: 'imactivatekey' に設定された値が無効です" +msgid "E16: Invalid range" +msgstr "E16: 無効な範囲です" -#~ msgid "E254: Cannot allocate color %s" -#~ msgstr "E254: %s の色を割り当てられません" +msgid "E476: Invalid command" +msgstr "E476: 無効なコマンドです" -#~ msgid "No match at cursor, finding next" -#~ msgstr "カーソルの位置にマッチはありません, 次を検索しています" +#, c-format +msgid "E17: \"%s\" is a directory" +msgstr "E17: \"%s\" はディレクトリです" -#~ msgid " " -#~ msgstr "<開けません> " +#, c-format +msgid "E364: Library call failed for \"%s()\"" +msgstr "E364: \"%s\"() のライブラリ呼出に失敗しました" -#~ msgid "E616: vim_SelFile: can't get font %s" -#~ msgstr "E616: vim_SelFile: フォント %s を取得できません" +#, c-format +msgid "E448: Could not load library function %s" +msgstr "E448: ライブラリの関数 %s をロードできませんでした" -#~ msgid "E614: vim_SelFile: can't return to current directory" -#~ msgstr "E614: vim_SelFile: 現在のディレクトリに戻れません" +msgid "E19: Mark has invalid line number" +msgstr "E19: マークに無効な行番号が指定されていました" -#~ msgid "Pathname:" -#~ msgstr "パス名:" +msgid "E20: Mark not set" +msgstr "E20: マークは設定されていません" -#~ msgid "E615: vim_SelFile: can't get current directory" -#~ msgstr "E615: vim_SelFile: 現在のディレクトリを取得できません" +msgid "E21: Cannot make changes, 'modifiable' is off" +msgstr "E21: 'modifiable' がオフなので, 変更できません" -#~ msgid "OK" -#~ msgstr "OK" +msgid "E22: Scripts nested too deep" +msgstr "E22: スクリプトの入れ子が深過ぎます" -#~ msgid "Cancel" -#~ msgstr "キャンセル" +msgid "E23: No alternate file" +msgstr "E23: 副ファイルはありません" -#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." -#~ msgstr "スクロールバー: 画像を取得できませんでした." +msgid "E24: No such abbreviation" +msgstr "E24: そのような短縮入力はありません" -#~ msgid "Vim dialog" -#~ msgstr "Vim ダイアログ" +msgid "E477: No ! allowed" +msgstr "E477: ! は許可されていません" -#~ msgid "E232: Cannot create BalloonEval with both message and callback" -#~ msgstr "E232: メッセージとコールバックのある BalloonEval を作成できません" +msgid "E25: GUI cannot be used: Not enabled at compile time" +msgstr "E25: GUIは使用不可能です: コンパイル時に無効にされています" -#~ msgid "Input _Methods" -#~ msgstr "インプットメソッド" +msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" +msgstr "E26: ヘブライ語は使用不可能です: コンパイル時に無効にされています\n" -#~ msgid "VIM - Search and Replace..." -#~ msgstr "VIM - 検索と置換..." +msgid "E27: Farsi cannot be used: Not enabled at compile time\n" +msgstr "E27: ペルシア語は使用不可能です: コンパイル時に無効にされています\n" -#~ msgid "VIM - Search..." -#~ msgstr "VIM - 検索..." +msgid "E800: Arabic cannot be used: Not enabled at compile time\n" +msgstr "E800: アラビア語は使用不可能です: コンパイル時に無効にされています\n" -#~ msgid "Find what:" -#~ msgstr "検索文字列:" +#, c-format +msgid "E28: No such highlight group name: %s" +msgstr "E28: そのような名のハイライトグループはありません: %s" -#~ msgid "Replace with:" -#~ msgstr "置換文字列:" +msgid "E29: No inserted text yet" +msgstr "E29: まだテキストが挿入されていません" -#~ msgid "Match whole word only" -#~ msgstr "正確に該当するものだけ" +msgid "E30: No previous command line" +msgstr "E30: 以前にコマンド行がありません" -#~ msgid "Match case" -#~ msgstr "大文字/小文字を区別する" +msgid "E31: No such mapping" +msgstr "E31: そのようなマッピングはありません" -#~ msgid "Direction" -#~ msgstr "方向" +msgid "E479: No match" +msgstr "E479: 該当はありません" -#~ msgid "Up" -#~ msgstr "上" +#, c-format +msgid "E480: No match: %s" +msgstr "E480: 該当はありません: %s" -#~ msgid "Down" -#~ msgstr "下" +msgid "E32: No file name" +msgstr "E32: ファイル名がありません" -#~ msgid "Find Next" -#~ msgstr "次を検索" +msgid "E33: No previous substitute regular expression" +msgstr "E33: 正規表現置換がまだ実行されていません" -#~ msgid "Replace" -#~ msgstr "置換" +msgid "E34: No previous command" +msgstr "E34: コマンドがまだ実行されていません" -#~ msgid "Replace All" -#~ msgstr "全て置換" +msgid "E35: No previous regular expression" +msgstr "E35: 正規表現がまだ実行されていません" -#~ msgid "Vim: Received \"die\" request from session manager\n" -#~ msgstr "Vim: セッションマネージャから \"die\" 要求を受け取りました\n" +msgid "E481: No range allowed" +msgstr "E481: 範囲指定は許可されていません" -#~ msgid "Close" -#~ msgstr "閉じる" +msgid "E36: Not enough room" +msgstr "E36: ウィンドウに十分な高さもしくは幅がありません" -#~ msgid "New tab" -#~ msgstr "新規タブページ" +#, c-format +msgid "E247: no registered server named \"%s\"" +msgstr "E247: %s という名前の登録されたサーバーはありません" -#~ msgid "Open Tab..." -#~ msgstr "タブページを開く..." +#, c-format +msgid "E482: Can't create file %s" +msgstr "E482: ファイル %s を作成できません" -#~ msgid "Vim: Main window unexpectedly destroyed\n" -#~ msgstr "Vim: メインウィンドウが不意に破壊されました\n" +msgid "E483: Can't get temp file name" +msgstr "E483: 一時ファイルの名前を取得できません" -#~ msgid "&Filter" -#~ msgstr "フィルタ(&F)" +#, c-format +msgid "E484: Can't open file %s" +msgstr "E484: ファイル \"%s\" を開けません" -#~ msgid "&Cancel" -#~ msgstr "キャンセル(&C)" +#, c-format +msgid "E485: Can't read file %s" +msgstr "E485: ファイル %s を読込めません" -#~ msgid "Directories" -#~ msgstr "ディレクトリ" +msgid "E37: No write since last change (add ! to override)" +msgstr "E37: 最後の変更が保存されていません (! を追加で変更を破棄)" -#~ msgid "Filter" -#~ msgstr "フィルタ" +msgid "E37: No write since last change" +msgstr "E37: 最後の変更が保存されていません" -#~ msgid "&Help" -#~ msgstr "ヘルプ(&H)" +msgid "E38: Null argument" +msgstr "E38: 引数が空です" -#~ msgid "Files" -#~ msgstr "ファイル" +msgid "E39: Number expected" +msgstr "E39: 数値が要求されています" -#~ msgid "&OK" -#~ msgstr "&OK" +#, c-format +msgid "E40: Can't open errorfile %s" +msgstr "E40: エラーファイル %s を開けません" -#~ msgid "Selection" -#~ msgstr "選択" +msgid "E233: cannot open display" +msgstr "E233: ディスプレイを開けません" -#~ msgid "Find &Next" -#~ msgstr "次を検索(&N)" +msgid "E41: Out of memory!" +msgstr "E41: メモリが尽き果てました!" -#~ msgid "&Replace" -#~ msgstr "置換(&R)" +msgid "Pattern not found" +msgstr "パターンは見つかりませんでした" -#~ msgid "Replace &All" -#~ msgstr "全て置換(&A)" +#, c-format +msgid "E486: Pattern not found: %s" +msgstr "E486: パターンは見つかりませんでした: %s" -#~ msgid "&Undo" -#~ msgstr "アンドゥ(&U)" +msgid "E487: Argument must be positive" +msgstr "E487: 引数は正の値でなければなりません" -#~ msgid "E671: Cannot find window title \"%s\"" -#~ msgstr "E671: タイトルが \"%s\" のウィンドウは見つかりません" +msgid "E459: Cannot go back to previous directory" +msgstr "E459: 前のディレクトリに戻れません" -#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." -#~ msgstr "E243: 引数はサポートされません: \"-%s\"; OLE版を使用してください." +msgid "E42: No Errors" +msgstr "E42: エラーはありません" -#~ msgid "E672: Unable to open window inside MDI application" -#~ msgstr "E672: MDIアプリの中ではウィンドウを開けません" +msgid "E776: No location list" +msgstr "E776: ロケーションリストはありません" -#~ msgid "Close tab" -#~ msgstr "タブページを閉じる" +msgid "E43: Damaged match string" +msgstr "E43: 該当文字列が破損しています" -#~ msgid "Open tab..." -#~ msgstr "タブページを開く" +msgid "E44: Corrupted regexp program" +msgstr "E44: 不正な正規表現プログラムです" -#~ msgid "Find string (use '\\\\' to find a '\\')" -#~ msgstr "検索文字列 ('\\' を検索するには '\\\\')" +msgid "E45: 'readonly' option is set (add ! to override)" +msgstr "E45: 'readonly' オプションが設定されています (! を追加で上書き)" -#~ msgid "Find & Replace (use '\\\\' to find a '\\')" -#~ msgstr "検索・置換 ('\\' を検索するには '\\\\')" +#, c-format +msgid "E46: Cannot change read-only variable \"%s\"" +msgstr "E46: 読取専用変数 \"%s\" には値を設定できません" -#~ msgid "Not Used" -#~ msgstr "使われません" +#, c-format +msgid "E794: Cannot set variable in the sandbox: \"%s\"" +msgstr "E794: サンドボックスでは変数 \"%s\" に値を設定できません" -#~ msgid "Directory\t*.nothing\n" -#~ msgstr "ディレクトリ\t*.nothing\n" +msgid "E713: Cannot use empty key for Dictionary" +msgstr "E713: 辞書型に空のキーを使うことはできません" -#~ msgid "" -#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" -#~ msgstr "Vim E458: 色指定が正しくないのでエントリを割り当てられません" +msgid "E715: Dictionary required" +msgstr "E715: 辞書型が必要です" -#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:" -#~ msgstr "E250: 以下の文字セットのフォントがありません %s:" +#, c-format +msgid "E684: list index out of range: %ld" +msgstr "E684: リストのインデックスが範囲外です: %ld" -#~ msgid "E252: Fontset name: %s" -#~ msgstr "E252: フォントセット名: %s" +#, c-format +msgid "E118: Too many arguments for function: %s" +msgstr "E118: 関数の引数が多過ぎます: %s" -#~ msgid "Font '%s' is not fixed-width" -#~ msgstr "フォント '%s' は固定幅ではありません" +#, c-format +msgid "E716: Key not present in Dictionary: %s" +msgstr "E716: 辞書型にキーが存在しません: %s" -#~ msgid "E253: Fontset name: %s" -#~ msgstr "E253: フォントセット名: %s" +msgid "E714: List required" +msgstr "E714: リスト型が必要です" -#~ msgid "Font0: %s" -#~ msgstr "フォント0: %s" +#, c-format +msgid "E712: Argument of %s must be a List or Dictionary" +msgstr "E712: %s の引数はリスト型または辞書型でなければなりません" -#~ msgid "Font1: %s" -#~ msgstr "フォント1: %s" +msgid "E47: Error while reading errorfile" +msgstr "E47: エラーファイルの読込中にエラーが発生しました" -#~ msgid "Font% width is not twice that of font0" -#~ msgstr "フォント% の幅がフォント0の2倍ではありません" +msgid "E48: Not allowed in sandbox" +msgstr "E48: サンドボックスでは許されません" -#~ msgid "Font0 width: %" -#~ msgstr "フォント0の幅: %" +msgid "E523: Not allowed here" +msgstr "E523: ここでは許可されません" -#~ msgid "Font1 width: %" -#~ msgstr "フォント1の幅: %" +msgid "E359: Screen mode setting not supported" +msgstr "E359: スクリーンモードの設定には対応していません" -#~ msgid "Invalid font specification" -#~ msgstr "無効なフォント指定です" +msgid "E49: Invalid scroll size" +msgstr "E49: 無効なスクロール量です" -#~ msgid "&Dismiss" -#~ msgstr "却下する(&D)" +msgid "E91: 'shell' option is empty" +msgstr "E91: 'shell' オプションが空です" -#~ msgid "no specific match" -#~ msgstr "マッチするものがありません" +msgid "E255: Couldn't read in sign data!" +msgstr "E255: sign のデータを読込めませんでした" -#~ msgid "Vim - Font Selector" -#~ msgstr "Vim - フォント選択" +msgid "E72: Close error on swap file" +msgstr "E72: スワップファイルのクローズ時エラーです" -#~ msgid "Name:" -#~ msgstr "名前:" +msgid "E73: tag stack empty" +msgstr "E73: タグスタックが空です" -#~ msgid "Show size in Points" -#~ msgstr "サイズをポイントで表示する" +msgid "E74: Command too complex" +msgstr "E74: コマンドが複雑過ぎます" -#~ msgid "Encoding:" -#~ msgstr "エンコード:" +msgid "E75: Name too long" +msgstr "E75: 名前が長過ぎます" -#~ msgid "Font:" -#~ msgstr "フォント:" +msgid "E76: Too many [" +msgstr "E76: [ が多過ぎます" -#~ msgid "Style:" -#~ msgstr "スタイル:" +msgid "E77: Too many file names" +msgstr "E77: ファイル名が多過ぎます" -#~ 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 \t\tUse for I/O" -#~ msgstr "-dev \t\tI/Oに を使用する" - -#~ msgid "-U \t\tUse instead of any .gvimrc" -#~ msgstr "-U \t\t.gvimrcの代わりに を使う" - -#~ msgid "-x\t\t\tEdit encrypted files" -#~ msgstr "-x\t\t\t暗号化されたファイルを編集する" - -#~ msgid "-display \tConnect vim to this particular X-server" -#~ msgstr "-display \tvimを指定した X サーバに接続する" - -#~ msgid "-X\t\t\tDo not connect to X server" -#~ msgstr "-X\t\t\tXサーバに接続しない" - -#~ msgid "--remote \tEdit in a Vim server if possible" -#~ msgstr "--remote \t可能ならばVimサーバで を編集する" - -#~ msgid "--remote-silent Same, don't complain if there is no server" -#~ msgstr "--remote-silent 同上, サーバが無くても警告文を出力しない" - -#~ msgid "" -#~ "--remote-wait As --remote but wait for files to have been edited" -#~ msgstr "--remote-wait \t--remote後 ファイルの編集が終わるのを待つ" - -#~ msgid "" -#~ "--remote-wait-silent Same, don't complain if there is no server" -#~ msgstr "" -#~ "--remote-wait-silent 同上, サーバが無くても警告文を出力しない" - -#~ msgid "" -#~ "--remote-tab[-wait][-silent] As --remote but use tab page per " -#~ "file" -#~ msgstr "" -#~ "--remote-tab[-wait][-silent] --remoteでファイル1つにつき1つのタブ" -#~ "ページを開く" - -#~ msgid "--remote-send \tSend to a Vim server and exit" -#~ msgstr "--remote-send \tVimサーバに を送信して終了する" - -#~ msgid "" -#~ "--remote-expr \tEvaluate in a Vim server and print result" -#~ msgstr "--remote-expr \tサーバで を実行して結果を表示する" - -#~ msgid "--serverlist\t\tList available Vim server names and exit" -#~ msgstr "--serverlist\t\tVimサーバ名の一覧を表示して終了する" - -#~ msgid "--servername \tSend to/become the Vim server " -#~ msgstr "--servername \tVimサーバ に送信/名前設定する" - -#~ 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 \tRun vim on " -#~ msgstr "-display \t でvimを実行する" - -#~ msgid "-iconic\t\tStart vim iconified" -#~ msgstr "-iconic\t\t最小化した状態でvimを起動する" - -#~ msgid "-background \tUse for the background (also: -bg)" -#~ msgstr "-background \t背景色に を使う(同義: -bg)" - -#~ msgid "-foreground \tUse for normal text (also: -fg)" -#~ msgstr "-foreground \t前景色に を使う(同義: -fg)" - -#~ msgid "-font \t\tUse for normal text (also: -fn)" -#~ msgstr "-font \t\tテキスト表示に を使う(同義: -fn)" - -#~ msgid "-boldfont \tUse for bold text" -#~ msgstr "-boldfont \t太字に を使う" - -#~ msgid "-italicfont \tUse for italic text" -#~ msgstr "-italicfont \t斜体字に を使う" - -#~ msgid "-geometry \tUse for initial geometry (also: -geom)" -#~ msgstr "-geometry \t初期配置に を使う(同義: -geom)" - -#~ msgid "-borderwidth \tUse a border width of (also: -bw)" -#~ msgstr "-borderwidth \t境界の幅を にする(同義: -bw)" - -#~ msgid "" -#~ "-scrollbarwidth Use a scrollbar width of (also: -sw)" -#~ msgstr "" -#~ "-scrollbarwidth スクロールバーの幅を にする(同義: -sw)" - -#~ msgid "-menuheight \tUse a menu bar height of (also: -mh)" -#~ msgstr "" -#~ "-menuheight \tメニューバーの高さを にする(同義: -mh)" - -#~ msgid "-reverse\t\tUse reverse video (also: -rv)" -#~ msgstr "-reverse\t\t反転映像を使用する(同義: -rv)" - -#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)" -#~ msgstr "+reverse\t\t反転映像を使用しない(同義: +rv)" - -#~ msgid "-xrm \tSet the specified resource" -#~ msgstr "-xrm \t特定のリソースを使用する" - -#~ msgid "" -#~ "\n" -#~ "Arguments recognised by gvim (GTK+ version):\n" -#~ msgstr "" -#~ "\n" -#~ "gvimによって解釈される引数(GTK+バージョン):\n" - -#~ msgid "-display \tRun vim on (also: --display)" -#~ msgstr "-display \t でvimを実行する(同義: --display)" - -#~ msgid "--role \tSet a unique role to identify the main window" -#~ msgstr "--role \tメインウィンドウを識別する一意な役割(role)を設定する" - -#~ msgid "--socketid \tOpen Vim inside another GTK widget" -#~ msgstr "--socketid \t異なるGTK widgetでVimを開く" - -#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout" -#~ msgstr "--echo-wid\t\tウィンドウIDを標準出力に出力する" - -#~ msgid "-P \tOpen Vim inside parent application" -#~ msgstr "-P <親のタイトル>\tVimを親アプリケーションの中で起動する" - -#~ msgid "--windowid \tOpen Vim inside another win32 widget" -#~ msgstr "--windowid \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 をサポートしません" - -#~ msgid "E843: Error while updating swap file crypt" -#~ msgstr "E843: スワップファイルの暗号を更新中にエラーが発生しました" - -#~ msgid "" -#~ "E833: %s is encrypted and this version of Vim does not support encryption" -#~ msgstr "" -#~ "E833: %s はこのバージョンのVimでサポートしていない形式で暗号化されています" - -#~ msgid "Swap file is encrypted: \"%s\"" -#~ msgstr "スワップファイルは暗号化されています: \"%s\"" - -#~ msgid "" -#~ "\n" -#~ "If you entered a new crypt key but did not write the text file," -#~ msgstr "" -#~ "\n" -#~ "新しい暗号キーを入力したあとにテキストファイルを保存していない場合は," - -#~ msgid "" -#~ "\n" -#~ "enter the new crypt key." -#~ msgstr "" -#~ "\n" -#~ "新しい暗号キーを入力してください." - -#~ msgid "" -#~ "\n" -#~ "If you wrote the text file after changing the crypt key press enter" -#~ msgstr "" -#~ "\n" -#~ "暗号キーを変えたあとにテキストファイルを保存した場合は, テキストファイルと" - -#~ msgid "" -#~ "\n" -#~ "to use the same key for text file and swap file" -#~ msgstr "" -#~ "\n" -#~ "スワップファイルに同じ暗号キーを使うためにenterだけを押してください." - -#~ msgid "Using crypt key from swap file for the text file.\n" -#~ msgstr "スワップファイルから取得した暗号キーをテキストファイルに使います.\n" - -#~ msgid "" -#~ "\n" -#~ " [not usable with this version of Vim]" -#~ msgstr "" -#~ "\n" -#~ " [このVimバージョンでは使用できません]" - -#~ msgid "Tear off this menu" -#~ msgstr "このメニューを切り取る" - -#~ msgid "Select Directory dialog" -#~ msgstr "ディレクトリ選択ダイアログ" - -#~ msgid "Save File dialog" -#~ msgstr "ファイル保存ダイアログ" - -#~ msgid "Open File dialog" -#~ msgstr "ファイル読込ダイアログ" - -#~ msgid "E338: Sorry, no file browser in console mode" -#~ msgstr "" -#~ "E338: コンソールモードではファイルブラウザを使えません, ごめんなさい" - -#~ msgid "Vim: preserving files...\n" -#~ msgstr "Vim: ファイルを保存中...\n" - -#~ msgid "Vim: Finished.\n" -#~ msgstr "Vim: 終了しました.\n" - -#~ msgid "ERROR: " -#~ msgstr "エラー: " - -#~ msgid "" -#~ "\n" -#~ "[bytes] total alloc-freed %-%, in use %, peak use " -#~ "%\n" -#~ msgstr "" -#~ "\n" -#~ "[メモリ(バイト)] 総割当-解放量 %-%, 使用量 %, ピー" -#~ "ク時 %\n" - -#~ msgid "" -#~ "[calls] total re/malloc()'s %, total free()'s %\n" -#~ "\n" -#~ msgstr "" -#~ "[呼出] 総 re/malloc() 回数 %, 総 free() 回数 %\n" -#~ "\n" - -#~ msgid "E340: Line is becoming too long" -#~ msgstr "E340: 行が長くなり過ぎました" - -#~ msgid "E341: Internal error: lalloc(%, )" -#~ msgstr "E341: 内部エラー: lalloc(%,)" - -#~ msgid "E547: Illegal mouseshape" -#~ msgstr "E547: 不正な 'mouseshape' です" - -#~ msgid "Enter encryption key: " -#~ msgstr "暗号化用のキーを入力してください: " - -#~ msgid "Enter same key again: " -#~ msgstr "もう一度同じキーを入力してください: " - -#~ msgid "Keys don't match!" -#~ msgstr "キーが一致しません" - -#~ msgid "Cannot connect to Netbeans #2" -#~ msgstr "Netbeans #2 に接続できません" - -#~ msgid "Cannot connect to Netbeans" -#~ msgstr "Netbeans に接続できません" - -#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\"" -#~ msgstr "" -#~ "E668: NetBeansの接続情報ファイルのアクセスモードに問題があります: \"%s\"" - -#~ msgid "read from Netbeans socket" -#~ msgstr "Netbeans のソケットを読込み" - -#~ msgid "E658: NetBeans connection lost for buffer %" -#~ msgstr "E658: バッファ % の NetBeans 接続が失われました" - -#~ msgid "E838: netbeans is not supported with this GUI" -#~ msgstr "E838: NetBeansはこのGUIには対応していません" - -#~ msgid "E511: netbeans already connected" -#~ msgstr "E511: NetBeansは既に接続しています" - -#~ msgid "E505: %s is read-only (add ! to override)" -#~ msgstr "E505: %s は読込専用です (強制書込には ! を追加)" - -#~ msgid "E775: Eval feature not available" -#~ msgstr "E775: 式評価機能が無効になっています" - -#~ msgid "freeing % lines" -#~ msgstr "% 行を解放中" - -#~ msgid "E530: Cannot change term in GUI" -#~ msgstr "E530: GUIでは 'term' を変更できません" - -#~ msgid "E531: Use \":gui\" to start the GUI" -#~ msgstr "E531: GUIをスタートするには \":gui\" を使用してください" - -#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI" -#~ msgstr "E617: GTK+2 GUIでは変更できません" - -#~ msgid "E596: Invalid font(s)" -#~ msgstr "E596: 無効なフォントです" - -#~ msgid "E597: can't select fontset" -#~ msgstr "E597: フォントセットを選択できません" - -#~ msgid "E598: Invalid fontset" -#~ msgstr "E598: 無効なフォントセットです" - -#~ msgid "E533: can't select wide font" -#~ msgstr "E533: ワイドフォントを選択できません" - -#~ msgid "E534: Invalid wide font" -#~ msgstr "E534: 無効なワイドフォントです" - -#~ msgid "E538: No mouse support" -#~ msgstr "E538: マウスはサポートされません" - -#~ msgid "cannot open " -#~ msgstr "開けません " - -#~ msgid "VIM: Can't open window!\n" -#~ msgstr "VIM: ウィンドウを開けません!\n" - -#~ msgid "Need Amigados version 2.04 or later\n" -#~ msgstr "Amigadosのバージョン 2.04かそれ以降が必要です\n" - -#~ msgid "Need %s version %\n" -#~ msgstr "%s のバージョン % が必要です\n" - -#~ msgid "Cannot open NIL:\n" -#~ msgstr "NILを開けません:\n" - -#~ msgid "Cannot create " -#~ msgstr "作成できません " - -#~ msgid "Vim exiting with %d\n" -#~ msgstr "Vimは %d で終了します\n" - -#~ msgid "cannot change console mode ?!\n" -#~ msgstr "コンソールモードを変更できません?!\n" - -#~ msgid "mch_get_shellsize: not a console??\n" -#~ msgstr "mch_get_shellsize: コンソールではない??\n" - -#~ msgid "E360: Cannot execute shell with -f option" -#~ msgstr "E360: -f オプションでシェルを実行できません" - -#~ msgid "Cannot execute " -#~ msgstr "実行できません " - -#~ msgid "shell " -#~ msgstr "シェル " - -#~ msgid " returned\n" -#~ msgstr " 戻りました\n" - -#~ msgid "ANCHOR_BUF_SIZE too small." -#~ msgstr "ANCHOR_BUF_SIZE が小さ過ぎます." - -#~ msgid "I/O ERROR" -#~ msgstr "入出力エラー" - -#~ msgid "Message" -#~ msgstr "メッセージ" - -#~ msgid "'columns' is not 80, cannot execute external commands" -#~ msgstr "'columns' が80ではないため, 外部コマンドを実行できません" - -#~ msgid "E237: Printer selection failed" -#~ msgstr "E237: プリンタの選択に失敗しました" - -#~ msgid "to %s on %s" -#~ msgstr "%s へ (%s 上の)" - -#~ msgid "E613: Unknown printer font: %s" -#~ msgstr "E613: 未知のプリンタオプションです: %s" - -#~ msgid "E238: Print error: %s" -#~ msgstr "E238: 印刷エラー: %s" - -#~ msgid "Printing '%s'" -#~ msgstr "印刷しています: '%s'" - -#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\"" -#~ msgstr "E244: 文字セット名 \"%s\" は不正です (フォント名 \"%s\")" - -#~ msgid "E245: Illegal char '%c' in font name \"%s\"" -#~ msgstr "E245: '%c' は不正な文字です (フォント名 \"%s\")" - -#~ msgid "Vim: Double signal, exiting\n" -#~ msgstr "Vim: 2重のシグナルのため, 終了します\n" - -#~ msgid "Vim: Caught deadly signal %s\n" -#~ msgstr "Vim: 致命的シグナル %s を検知しました\n" - -#~ msgid "Vim: Caught deadly signal\n" -#~ msgstr "Vim: 致命的シグナルを検知しました\n" - -#~ msgid "Opening the X display took % msec" -#~ msgstr "Xサーバへの接続に % ミリ秒かかりました" - -#~ msgid "" -#~ "\n" -#~ "Vim: Got X error\n" -#~ msgstr "" -#~ "\n" -#~ "Vim: X のエラーを検出しましたr\n" - -#~ msgid "Testing the X display failed" -#~ msgstr "X display のチェックに失敗しました" - -#~ msgid "Opening the X display timed out" -#~ msgstr "X display の open がタイムアウトしました" - -#~ msgid "" -#~ "\n" -#~ "Cannot execute shell sh\n" -#~ msgstr "" -#~ "\n" -#~ "sh シェルを実行できません\n" - -#~ msgid "" -#~ "\n" -#~ "Cannot create pipes\n" -#~ msgstr "" -#~ "\n" -#~ "パイプを作成できません\n" - -#~ msgid "" -#~ "\n" -#~ "Cannot fork\n" -#~ msgstr "" -#~ "\n" -#~ "fork できません\n" - -#~ msgid "" -#~ "\n" -#~ "Command terminated\n" -#~ msgstr "" -#~ "\n" -#~ "コマンドを中断しました\n" - -#~ msgid "XSMP lost ICE connection" -#~ msgstr "XSMP がICE接続を失いました" - -#~ msgid "Opening the X display failed" -#~ msgstr "X 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接続が失敗したようです" - -#~ msgid "XSMP SmcOpenConnection failed: %s" -#~ msgstr "XSMP SmcOpenConnectionが失敗しました: %s" - -#~ msgid "At line" -#~ msgstr "行" - -#~ msgid "Could not load vim32.dll!" -#~ msgstr "vim32.dll をロードできませんでした" - -#~ msgid "VIM Error" -#~ msgstr "VIMエラー" - -#~ msgid "Could not fix up function pointers to the DLL!" -#~ msgstr "DLLから関数ポインタを取得できませんでした" - -#~ msgid "shell returned %d" -#~ msgstr "シェルがコード %d で終了しました" - -#~ msgid "Vim: Caught %s event\n" -#~ msgstr "Vim: イベント %s を検知\n" - -#~ msgid "close" -#~ msgstr "閉じる" - -#~ msgid "logoff" -#~ msgstr "ログオフ" - -#~ msgid "shutdown" -#~ msgstr "シャットダウン" - -#~ msgid "E371: Command not found" -#~ msgstr "E371: コマンドがありません" - -#~ msgid "" -#~ "VIMRUN.EXE not found in your $PATH.\n" -#~ "External commands will not pause after completion.\n" -#~ "See :help win32-vimrun for more information." -#~ msgstr "" -#~ "VIMRUN.EXEが $PATH の中に見つかりません.\n" -#~ "外部コマンドの終了後に一時停止をしません.\n" -#~ "詳細は :help win32-vimrun を参照してください." - -#~ msgid "Vim Warning" -#~ msgstr "Vimの警告" - -#~ msgid "Error file" -#~ msgstr "エラーファイル" - -#~ msgid "E868: Error building NFA with equivalence class!" -#~ msgstr "E868: 等価クラスを含むNFA構築に失敗しました!" - -#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!" -#~ msgstr "E878: (NFA) 現在横断中のブランチに十分なメモリを割り当てられません!" - -#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\"" -#~ msgstr "" -#~ "警告: 単語リスト \"%s_%s.spl\" および \"%s_ascii.spl\" は見つかりません" - -#~ msgid "Conversion in %s not supported" -#~ msgstr "%s 内の変換はサポートされていません" - -#~ msgid "E845: Insufficient memory, word list will be incomplete" -#~ msgstr "E845: メモリが足りないので、単語リストは不完全です" - -#~ msgid "E430: Tag file path truncated for %s\n" -#~ msgstr "E430: タグファイルのパスが %s に切り捨てられました\n" - -#~ msgid "new shell started\n" -#~ msgstr "新しいシェルを起動します\n" - -#~ msgid "Used CUT_BUFFER0 instead of empty selection" -#~ msgstr "空の選択領域のかわりにCUT_BUFFER0が使用されました" - -#~ msgid "No undo possible; continue anyway" -#~ msgstr "可能なアンドゥはありません: とりあえず続けます" - -#~ msgid "E832: Non-encrypted file has encrypted undo file: %s" -#~ msgstr "" -#~ "E832: 非暗号化ファイルが暗号化されたアンドゥファイルを使ってます: %s" - -#~ msgid "E826: Undo file decryption failed: %s" -#~ msgstr "E826: 暗号化されたアンドゥファイルの解読に失敗しました: %s" - -#~ msgid "E827: Undo file is encrypted: %s" -#~ msgstr "E827: アンドゥファイルが暗号化されています: %s" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 16/32-bit GUI version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 16/32 ビット GUI 版" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 64-bit GUI version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 64 ビット GUI 版" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 32-bit GUI version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 32 ビット GUI 版" - -#~ msgid " in Win32s mode" -#~ msgstr " in Win32s モード" - -#~ msgid " with OLE support" -#~ msgstr " with OLE サポート" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 64-bit console version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 64 ビット コンソール 版" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 32-bit console version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 32 ビット コンソール 版" - -#~ msgid "" -#~ "\n" -#~ "MS-Windows 16-bit version" -#~ msgstr "" -#~ "\n" -#~ "MS-Windows 16 ビット 版" - -#~ msgid "" -#~ "\n" -#~ "32-bit MS-DOS version" -#~ msgstr "" -#~ "\n" -#~ "32 ビット MS-DOS 版" - -#~ msgid "" -#~ "\n" -#~ "16-bit MS-DOS version" -#~ msgstr "" -#~ "\n" -#~ "16 ビット MS-DOS 版" - -#~ msgid "" -#~ "\n" -#~ "MacOS X (unix) version" -#~ msgstr "" -#~ "\n" -#~ "MacOS X (unix) 版" - -#~ msgid "" -#~ "\n" -#~ "MacOS X version" -#~ msgstr "" -#~ "\n" -#~ "MacOS X 版" - -#~ msgid "" -#~ "\n" -#~ "MacOS version" -#~ msgstr "" -#~ "\n" -#~ "MacOS 版" - -#~ msgid "" -#~ "\n" -#~ "OpenVMS version" -#~ msgstr "" -#~ "\n" -#~ "OpenVMS 版" - -#~ msgid "" -#~ "\n" -#~ "Big version " -#~ msgstr "" -#~ "\n" -#~ "Big 版 " - -#~ msgid "" -#~ "\n" -#~ "Normal version " -#~ msgstr "" -#~ "\n" -#~ "通常 版 " - -#~ msgid "" -#~ "\n" -#~ "Small version " -#~ msgstr "" -#~ "\n" -#~ "Small 版 " - -#~ msgid "" -#~ "\n" -#~ "Tiny version " -#~ msgstr "" -#~ "\n" -#~ "Tiny 版 " - -#~ msgid "with GTK2-GNOME GUI." -#~ msgstr "with GTK2-GNOME GUI." - -#~ msgid "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 " system gvimrc file: \"" -#~ msgstr " システム gvimrc: \"" - -#~ msgid " user gvimrc file: \"" -#~ msgstr " ユーザ gvimrc: \"" - -#~ msgid "2nd user gvimrc file: \"" -#~ msgstr " 第2ユーザ gvimrc: \"" - -#~ msgid "3rd user gvimrc file: \"" -#~ msgstr " 第3ユーザ gvimrc: \"" - -#~ msgid " system menu file: \"" -#~ msgstr " システムメニュー: \"" - -#~ msgid "Compiler: " -#~ msgstr "コンパイラ: " - -#~ msgid "menu Help->Orphans for information " -#~ msgstr "詳細はメニューの ヘルプ→孤児 を参照して下さい " - -#~ 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 for info on this" -#~ msgstr " 詳細な情報は :help windows95 " +msgid "Zero count" +msgstr "ゼロカウント" -#~ msgid "Edit with &multiple Vims" -#~ msgstr "複数のVimで編集する (&M)" +msgid "E81: Using not in a script context" +msgstr "E81: スクリプト以外でが使われました" -#~ 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 に追加してください" -- cgit From 1e7806bd410f8ff0fcf5aec81370e57f1a57938e Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 29 Apr 2017 01:47:52 +0200 Subject: vim-patch:6d5ad4c4118c Updated runtime files. https://github.com/vim/vim/commit/6d5ad4c4118cab5fd96db157621c3aa9af368edb --- src/nvim/po/ga.po | 6393 ++++++++++++++++++++++++----------------------------- 1 file changed, 2854 insertions(+), 3539 deletions(-) (limited to 'src') 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 \n" "Language-Team: Irish \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 "Dramhal i ndiaidh arginte 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: sid mhcheart Blowfish mrcheannach/caolcheannach" + +msgid "E818: sha256 test failed" +msgstr "E818: Theip ar thstil sha256" + +msgid "E819: Blowfish test failed" +msgstr "E819: Theip ar thstil Blowfish" -#: ../buffer.c:92 msgid "[Location List]" msgstr "[Liosta Suomh]" -#: ../buffer.c:93 msgid "[Quickfix List]" -msgstr "[Liosta Ceartchn Tapa]" +msgstr "[Liosta Mearcheartchn]" -#: ../buffer.c:94 -#, fuzzy msgid "E855: Autocommands caused command to abort" -msgstr "E812: Bh maoln n ainm maolin athraithe ag orduithe uathoibrocha" +msgstr "E855: Tobscoireadh an t-ord mar gheall ar uathorduithe" -#: ../buffer.c:135 msgid "E82: Cannot allocate any buffer, exiting..." msgstr "E82: N fidir maoln a dhileadh, ag scor..." -#: ../buffer.c:138 msgid "E83: Cannot allocate buffer, using other one..." msgstr "E83: N fidir maoln a dhileadh, ag sid cinn eile..." -#: ../buffer.c:763 +msgid "E931: Buffer cannot be registered" +msgstr "E931: N fidir an maoln a chlr" + +msgid "E937: Attempt to delete a buffer that is in use" +msgstr "E937: Iarracht ar mhaoln in sid a scriosadh" + msgid "E515: No buffers were unloaded" msgstr "E515: N raibh aon mhaoln dluchtaithe" -#: ../buffer.c:765 msgid "E516: No buffers were deleted" msgstr "E516: N raibh aon mhaoln scriosta" -#: ../buffer.c:767 msgid "E517: No buffers were wiped out" msgstr "E517: N raibh aon mhaoln bnaithe" -#: ../buffer.c:772 msgid "1 buffer unloaded" msgstr "Bh maoln amhin dluchtaithe" -#: ../buffer.c:774 #, c-format msgid "%d buffers unloaded" msgstr "%d maoln folmhaithe" -#: ../buffer.c:777 msgid "1 buffer deleted" msgstr "Bh maoln amhin scriosta" -#: ../buffer.c:779 #, c-format msgid "%d buffers deleted" msgstr "%d maoln scriosta" -#: ../buffer.c:782 msgid "1 buffer wiped out" msgstr "Bh maoln amhin bnaithe" -#: ../buffer.c:784 #, c-format msgid "%d buffers wiped out" msgstr "%d maoln bnaithe" -#: ../buffer.c:806 msgid "E90: Cannot unload last buffer" msgstr "E90: N fidir an maoln deireanach a dhlucht" -#: ../buffer.c:874 msgid "E84: No modified buffer found" msgstr "E84: Nor aimsodh maoln mionathraithe" #. back where we started, didn't find anything. -#: ../buffer.c:903 msgid "E85: There is no listed buffer" msgstr "E85: Nl aon mhaoln liostaithe ann" -#: ../buffer.c:913 -#, c-format -msgid "E86: Buffer % does not exist" -msgstr "E86: Nl a leithid de mhaoln %" - -#: ../buffer.c:915 msgid "E87: Cannot go beyond last buffer" msgstr "E87: N fidir a dhul thar an maoln deireanach" -#: ../buffer.c:917 msgid "E88: Cannot go before first buffer" msgstr "E88: N fidir a dhul roimh an chad mhaoln" -#: ../buffer.c:945 #, c-format -msgid "" -"E89: No write since last change for buffer % (add ! to override)" +msgid "E89: No write since last change for buffer %ld (add ! to override)" msgstr "" -"E89: Athraodh maoln % ach nach bhfuil s sbhilte shin (cuir ! " -"leis an ord chun sr)" +"E89: Athraodh maoln %ld ach nach bhfuil s sbhilte shin (cuir ! leis " +"an ord chun sr)" -#. 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 % not found" -msgstr "E92: Maoln % gan aimsi" +msgid "E92: Buffer %ld not found" +msgstr "E92: Maoln %ld gan aimsi" -#: ../buffer.c:1798 #, c-format msgid "E93: More than one match for %s" msgstr "E93: Nos m n teaghrn amhin comhoirinaithe le %s" -#: ../buffer.c:1800 #, c-format msgid "E94: No matching buffer for %s" msgstr "E94: Nl aon mhaoln comhoirinaithe le %s" -#: ../buffer.c:2161 #, c-format -msgid "line %" -msgstr "lne %:" +msgid "line %ld" +msgstr "lne %ld:" -#: ../buffer.c:2233 msgid "E95: Buffer with this name already exists" msgstr "E95: T maoln 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 "[Earrid limh]" -#: ../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 "[inlite amhin]" -#: ../buffer.c:2524 #, c-format msgid "1 line --%d%%--" msgstr "1 lne --%d%%--" -#: ../buffer.c:2526 #, c-format -msgid "% lines --%d%%--" -msgstr "% lne --%d%%--" +msgid "%ld lines --%d%%--" +msgstr "%ld lne --%d%%--" -#: ../buffer.c:2530 #, c-format -msgid "line % of % --%d%%-- col " -msgstr "lne % de % --%d%%-- col " +msgid "line %ld of %ld --%d%%-- col " +msgstr "lne %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 "[Ramhamharc]" -#: ../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 maolin:\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=% id=%d name=%s" -msgstr " lne=% id=%d ainm=%s" +msgid " line=%ld id=%d name=%s" +msgstr " lne=%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 fidir ceangal leis an bport" -#: ../cursor_shape.c:70 ../cursor_shape.c:94 -msgid "E546: Illegal mode" -msgstr "E546: Md neamhcheadaithe" +msgid "E901: gethostbyname() in channel_open()" +msgstr "E901: gethostbyname() in channel_open()" -#: ../cursor_shape.c:134 -msgid "E548: digit expected" -msgstr "E548: ag sil le digit" +msgid "E898: socket() in channel_open()" +msgstr "E898: socket() in channel_open()" -#: ../cursor_shape.c:138 -msgid "E549: Illegal percentage" -msgstr "E549: Catadn neamhcheadaithe" +msgid "E903: received command with non-string argument" +msgstr "E903: fuarthas ord le hargint nach bhfuil ina theaghrn" + +msgid "E904: last argument for expr/call must be a number" +msgstr "E904: n mr don argint dheireanach ar expr/call a bheith ina huimhir" + +msgid "E904: third argument for call must be a list" +msgstr "E904: Caithfidh an tr argint 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(): scrobh gan ceangal a bheith ann" + +#, c-format +msgid "E631: %s(): write failed" +msgstr "E631: %s(): theip ar scrobh" + +#, c-format +msgid "E917: Cannot use a callback with %s()" +msgstr "E917: N fidir aisghlaoch a sid le %s()" + +msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" +msgstr "E912: n fidir ch_evalexpr()/ch_sendexpr() a sid le cainal raw n nl" + +msgid "E906: not an open channel" +msgstr "E906: n cainal oscailte " + +msgid "E920: _io file requires _name to be set" +msgstr "E920: caithfear _name a shocr chun comhad _io a sid" + +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 maoln in_io a sid" + +#, c-format +msgid "E918: buffer must be loaded: %s" +msgstr "E918: n mr an maoln 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: Criptichn lag; fach :help 'cm'" + +msgid "Enter encryption key: " +msgstr "Iontril eochair chriptichin: " + +msgid "Enter same key again: " +msgstr "Iontril an eochair ars: " + +msgid "Keys don't match!" +msgstr "Nl na heochracha comhoirinach le chile!" + +msgid "[crypted]" +msgstr "[criptithe]" + +#, c-format +msgid "E720: Missing colon in Dictionary: %s" +msgstr "E720: Idirstad ar iarraidh i bhFoclir: %s" + +#, c-format +msgid "E721: Duplicate key in Dictionary: \"%s\"" +msgstr "E721: Eochair dhblach i bhFoclir: \"%s\"" + +#, c-format +msgid "E722: Missing comma in Dictionary: %s" +msgstr "E722: Camg ar iarraidh i bhFoclir: %s" + +#, c-format +msgid "E723: Missing end of Dictionary '}': %s" +msgstr "E723: '}' ar iarraidh ag deireadh foclra: %s" + +msgid "extend() argument" +msgstr "argint extend()" + +#, c-format +msgid "E737: Key already exists: %s" +msgstr "E737: T eochair ann cheana: %s" -#: ../diff.c:146 #, c-format -msgid "E96: Can not diff more than % buffers" -msgstr "E96: N fidir diff a dhanamh ar nos m n % maoln" +msgid "E96: Cannot diff more than %ld buffers" +msgstr "E96: N fidir diff a dhanamh ar nos m n %ld maoln" -#: ../diff.c:753 msgid "E810: Cannot read or write temp files" msgstr "E810: N fidir comhaid shealadacha a lamh n a scrobh" -#: ../diff.c:755 msgid "E97: Cannot create diffs" msgstr "E97: N fidir diffeanna a chruth" -#: ../diff.c:966 +msgid "Patch file" +msgstr "Comhad paiste" + msgid "E816: Cannot read patch output" msgstr "E816: N fidir aschur 'patch' a lamh" -#: ../diff.c:1220 msgid "E98: Cannot read diff output" msgstr "E98: N fidir aschur 'diff' a lamh" -#: ../diff.c:2081 msgid "E99: Current buffer is not in diff mode" msgstr "E99: Nl an maoln reatha sa mhd diff" -#: ../diff.c:2100 msgid "E793: No other buffer in diff mode is modifiable" msgstr "E793: N fidir aon mhaoln eile a athr sa mhd diff" -#: ../diff.c:2102 msgid "E100: No other buffer in diff mode" msgstr "E100: Nl aon mhaoln eile sa mhd diff" -#: ../diff.c:2112 msgid "E101: More than two buffers in diff mode, don't know which one to use" msgstr "" "E101: T nos m n dh mhaoln sa mhd diff, nl fhios agam c acu ba chir " "a sid" -#: ../diff.c:2141 #, c-format msgid "E102: Can't find buffer \"%s\"" msgstr "E102: T maoln \"%s\" gan aimsi" -#: ../diff.c:2152 #, c-format msgid "E103: Buffer \"%s\" is not in diff mode" msgstr "E103: Nl maoln \"%s\" i md diff" -#: ../diff.c:2193 msgid "E787: Buffer changed unexpectedly" msgstr "E787: Athraodh an maoln gan choinne" -#: ../digraph.c:1598 msgid "E104: Escape not allowed in digraph" msgstr "E104: N cheadatear carachtair alchin i ndghraf" -#: ../digraph.c:1760 msgid "E544: Keymap file not found" msgstr "E544: Comhad eochairmhapla gan aimsi" -#: ../digraph.c:1785 msgid "E105: Using :loadkeymap not in a sourced file" msgstr "E105: Ag sid :loadkeymap ach n comhad foinsithe seo" -#: ../digraph.c:1821 msgid "E791: Empty keymap entry" msgstr "E791: Iontril fholamh eochairmhapla" -#: ../edit.c:82 msgid " Keyword completion (^N^P)" msgstr " Comhln 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 " md ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" -#: ../edit.c:85 msgid " Whole line completion (^L^N^P)" msgstr " Comhln Lnte Ina Iomln (^L^N^P)" -#: ../edit.c:86 msgid " File name completion (^F^N^P)" msgstr " Comhln de na hainmneacha comhaid (^F^N^P)" -#: ../edit.c:87 msgid " Tag completion (^]^N^P)" msgstr " Comhln clibeanna (^]/^N/^P)" -#: ../edit.c:88 msgid " Path pattern completion (^N^P)" msgstr " Comhln Conaire (^N^P)" -#: ../edit.c:89 msgid " Definition completion (^D^N^P)" msgstr " Comhln de na sainmhnithe (^D^N^P)" -#: ../edit.c:91 msgid " Dictionary completion (^K^N^P)" msgstr " Comhln foclra (^K^N^P)" -#: ../edit.c:92 msgid " Thesaurus completion (^T^N^P)" msgstr " Comhln teasrais (^T^N^P)" -#: ../edit.c:93 msgid " Command-line completion (^V^N^P)" msgstr " Comhln den lne ordaithe (^V^N^P)" -#: ../edit.c:94 msgid " User defined completion (^U^N^P)" msgstr " Comhln saincheaptha (^U^N^P)" -#: ../edit.c:95 msgid " Omni completion (^O^N^P)" msgstr " Comhln 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 " Comhln lognta lorgfhocal (^N^P)" -#: ../edit.c:100 msgid "Hit end of paragraph" msgstr "Sroicheadh croch an pharagraif" -#: ../edit.c:101 -#, fuzzy msgid "E839: Completion function changed window" -msgstr "E813: N fidir fuinneog autocmd a dhnadh" +msgstr "E839: D'athraigh an fheidhm chomhlnaithe an fhuinneog" -#: ../edit.c:102 msgid "E840: Completion function deleted text" -msgstr "" +msgstr "E840: Scrios an fheidhm chomhlnaithe roinnt tacs" -#: ../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 "Foclir scanadh: %s" -#: ../edit.c:3079 msgid " (insert) Scroll (^E/^Y)" msgstr " (ionsigh) 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 " Mad" @@ -438,702 +433,451 @@ msgstr " M #. * 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 mbunit" -#: ../edit.c:4621 msgid "Word from other line" msgstr "Focal as lne eile" -#: ../edit.c:4624 msgid "The only match" msgstr "An t-aon teaghrn amhin comhoirinaithe" -#: ../edit.c:4680 #, c-format msgid "match %d of %d" msgstr "comhoirin %d as %d" -#: ../edit.c:4684 #, c-format msgid "match %d" msgstr "comhoirin %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: %" -msgstr "E684: innacs liosta as raon: %" - -#: ../eval.c:139 #, c-format msgid "E121: Undefined variable: %s" msgstr "E121: Athrg gan sainmhni: %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 argint 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 argint de %s a bheith ina Liosta n Foclir" - -#: ../eval.c:144 -msgid "E713: Cannot use empty key for Dictionary" -msgstr "E713: N fidir eochair fholamh a sid le Foclir" - -#: ../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 foclir" - -#: ../eval.c:147 -#, c-format -msgid "E118: Too many arguments for function: %s" -msgstr "E118: An iomarca argint d'fheidhm: %s" - -#: ../eval.c:148 -#, c-format -msgid "E716: Key not present in Dictionary: %s" -msgstr "E716: Nl an eochair seo san Fhoclir: %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 asiti" - -#: ../eval.c:151 -msgid "E717: Dictionary entry already exists" -msgstr "E717: T an iontril foclra 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 fidir [:] a sid le foclir" -#: ../eval.c:154 #, c-format msgid "E734: Wrong variable type for %s=" msgstr "E734: Cinel mcheart athrige 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 athrige neamhcheadaithe: %s" -#: ../eval.c:157 msgid "E806: using Float as a String" msgstr "E806: Snmhphointe sid mar Theaghrn" -#: ../eval.c:1830 msgid "E687: Less targets than List items" msgstr "E687: Nos l spriocanna n mreanna Liosta" -#: ../eval.c:1834 msgid "E688: More targets than List items" msgstr "E688: Nos m spriocanna n mreanna Liosta" -#: ../eval.c:1906 msgid "Double ; in list of variables" msgstr "; dblach i liosta na n-athrg" -#: ../eval.c:2078 #, c-format msgid "E738: Can't list variables for %s" msgstr "E738: N fidir athrga do %s a thaispeint" -#: ../eval.c:2391 msgid "E689: Can only index a List or Dictionary" msgstr "E689: Is fidir Liosta n Foclir amhin a innacs" -#: ../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 folir Liosta a thabhairt le [:]" -#: ../eval.c:2674 msgid "E710: List value has more items than target" msgstr "E710: T nos m mreanna ag an Liosta n an sprioc" -#: ../eval.c:2678 msgid "E711: List value has not enough items" msgstr "E711: Nl go leor mreanna 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: Libn ar iarraidh: %s" - -#: ../eval.c:3263 #, c-format msgid "E108: No such variable: \"%s\"" msgstr "E108: Nl a leithid d'athrg: \"%s\"" -#: ../eval.c:3333 msgid "E743: variable nested too deep for (un)lock" msgstr "E743: athrg neadaithe rdhomhain chun a (d)ghlasil" -#: ../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 fidir Liosta a chur i gcomparid le Liosta eile amhin" -#: ../eval.c:3895 -msgid "E692: Invalid operation for Lists" +msgid "E692: Invalid operation for List" msgstr "E692: Oibrocht neamhbhail ar Liosta" -#: ../eval.c:3915 msgid "E735: Can only compare Dictionary with Dictionary" msgstr "E735: Is fidir Foclir a chur i gcomparid le Foclir eile amhin" -#: ../eval.c:3917 msgid "E736: Invalid operation for Dictionary" msgstr "E736: Oibrocht neamhbhail ar Fhoclir" -#: ../eval.c:3932 -msgid "E693: Can only compare Funcref with Funcref" -msgstr "E693: Is fidir Funcref a chur i gcomparid le Funcref eile amhin" - -#: ../eval.c:3934 msgid "E694: Invalid operation for Funcrefs" msgstr "E694: Oibrocht neamhbhail ar Funcref" -#: ../eval.c:4277 msgid "E804: Cannot use '%' with Float" msgstr "E804: N fidir '%' a sid le Snmhphointe" -#: ../eval.c:4478 msgid "E110: Missing ')'" msgstr "E110: ')' ar iarraidh" -#: ../eval.c:4609 msgid "E695: Cannot index a Funcref" msgstr "E695: N fidir Funcref a innacs" -#: ../eval.c:4839 +msgid "E909: Cannot index a special variable" +msgstr "E909: N fidir athrg speisialta a innacs" + #, 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: Camg ar iarraidh i Liosta: %s" +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "" +"Nl go leor cuimhne ann le tagairt a shocr; baili dramhaola thobscor!" -#: ../eval.c:5091 -#, c-format -msgid "E697: Missing end of List ']': %s" -msgstr "E697: ']' ar iarraidh ag deireadh liosta: %s" +msgid "E724: variable nested too deep for displaying" +msgstr "E724: athrg neadaithe rdhomhain chun a thaispeint" -#: ../eval.c:6475 -#, c-format -msgid "E720: Missing colon in Dictionary: %s" -msgstr "E720: Idirstad ar iarraidh i bhFoclir: %s" +msgid "E805: Using a Float as a Number" +msgstr "E805: Snmhphointe sid mar Uimhir" -#: ../eval.c:6499 -#, c-format -msgid "E721: Duplicate key in Dictionary: \"%s\"" -msgstr "E721: Eochair dhblach i bhFoclir: \"%s\"" +msgid "E703: Using a Funcref as a Number" +msgstr "E703: Funcref sid mar Uimhir" -#: ../eval.c:6517 -#, c-format -msgid "E722: Missing comma in Dictionary: %s" -msgstr "E722: Camg ar iarraidh i bhFoclir: %s" +msgid "E745: Using a List as a Number" +msgstr "E745: Liosta sid mar Uimhir" -#: ../eval.c:6524 -#, c-format -msgid "E723: Missing end of Dictionary '}': %s" -msgstr "E723: '}' ar iarraidh ag deireadh foclra: %s" +msgid "E728: Using a Dictionary as a Number" +msgstr "E728: Foclir sid mar Uimhir" -#: ../eval.c:6555 -msgid "E724: variable nested too deep for displaying" -msgstr "E724: athrg neadaithe rdhomhain chun a thaispeint" +msgid "E910: Using a Job as a Number" +msgstr "E910: Jab sid mar Uimhir" + +msgid "E913: Using a Channel as a Number" +msgstr "E913: Cainal sid mar Uimhir" + +msgid "E891: Using a Funcref as a Float" +msgstr "E891: Funcref sid mar Shnmhphointe" + +msgid "E892: Using a String as a Float" +msgstr "E892: Teaghrn sid mar Shnmhphointe" + +msgid "E893: Using a List as a Float" +msgstr "E893: Liosta sid mar Shnmhphointe" + +msgid "E894: Using a Dictionary as a Float" +msgstr "E894: Foclir sid mar Shnmhphointe" + +msgid "E907: Using a special value as a Float" +msgstr "E907: Luach speisialta sid mar Shnmhphointe" + +msgid "E911: Using a Job as a Float" +msgstr "E911: Jab sid mar Shnmhphointe" + +msgid "E914: Using a Channel as a Float" +msgstr "E914: Cainal sid mar Shnmhphointe" + +msgid "E729: using Funcref as a String" +msgstr "E729: Funcref sid mar Theaghrn" + +msgid "E730: using List as a String" +msgstr "E730: Liosta sid mar Theaghrn" + +msgid "E731: using Dictionary as a String" +msgstr "E731: Foclir sid mar Theaghrn" + +msgid "E908: using an invalid value as a String" +msgstr "E908: luach neamhbhail sid mar Theaghrn" -#: ../eval.c:7188 #, c-format -msgid "E740: Too many arguments for function %s" -msgstr "E740: An iomarca argint d'fheidhm %s" +msgid "E795: Cannot delete variable %s" +msgstr "E795: N fidir athrg %s a scriosadh" -#: ../eval.c:7190 #, c-format -msgid "E116: Invalid arguments for function %s" -msgstr "E116: Argint neamhbhail d'fheidhm %s" +msgid "E704: Funcref variable name must start with a capital: %s" +msgstr "E704: Caithfidh ceannlitir a bheith ar dts ainm Funcref: %s" -#: ../eval.c:7377 #, c-format -msgid "E117: Unknown function: %s" -msgstr "E117: Feidhm anaithnid: %s" +msgid "E705: Variable name conflicts with existing function: %s" +msgstr "E705: Tagann ainm athrige salach ar fheidhm at ann cheana: %s" -#: ../eval.c:7383 #, c-format -msgid "E119: Not enough arguments for function: %s" -msgstr "E119: Nl go leor feidhmeanna d'fheidhm: %s" +msgid "E741: Value is locked: %s" +msgstr "E741: T an luach faoi ghlas: %s" + +msgid "Unknown" +msgstr "Anaithnid" -#: ../eval.c:7387 #, c-format -msgid "E120: Using not in a script context: %s" -msgstr "E120: sid ach gan a bheith i gcomhthacs scripte: %s" +msgid "E742: Cannot change value of %s" +msgstr "E742: N fidir an luach de %s a athr" + +msgid "E698: variable nested too deep for making a copy" +msgstr "E698: athrg neadaithe rdhomhain chun a chipeil" + +msgid "" +"\n" +"# global variables:\n" +msgstr "" +"\n" +"# athrga comhchoiteanna:\n" + +msgid "" +"\n" +"\tLast set from " +msgstr "" +"\n" +"\tSocraithe is dana " + +msgid "map() argument" +msgstr "argint map()" + +msgid "filter() argument" +msgstr "argint filter()" -#: ../eval.c:7391 #, c-format -msgid "E725: Calling dict function without Dictionary: %s" -msgstr "E725: Feidhm 'dict' ghlao gan Foclir: %s" +msgid "E686: Argument of %s must be a List" +msgstr "E686: Caithfidh argint de %s a bheith ina Liosta" + +msgid "E928: String required" +msgstr "E928: Teaghrn de dhth" -#: ../eval.c:7453 msgid "E808: Number or Float required" msgstr "E808: Uimhir n Snmhphointe de dhth" -#: ../eval.c:7503 -#, fuzzy msgid "add() argument" -msgstr "argint -c" - -#: ../eval.c:7907 -msgid "E699: Too many arguments" -msgstr "E699: An iomarca argint" +msgstr "argint add()" -#: ../eval.c:8073 msgid "E785: complete() can only be used in Insert mode" msgstr "E785: is fidir complete() a sid sa mhd Ionsite amhin" -#: ../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:8676 -#, c-format -msgid "E737: Key already exists: %s" -msgstr "E737: T eochair ann cheana: %s" - -#: ../eval.c:8692 -#, fuzzy -msgid "extend() argument" -msgstr "argint --cmd" - -#: ../eval.c:8915 -#, fuzzy -msgid "map() argument" -msgstr "argint -c" - -#: ../eval.c:8916 -#, fuzzy -msgid "filter() argument" -msgstr "argint -c" - -#: ../eval.c:9229 #, c-format -msgid "+-%s%3ld lines: " -msgstr "+-%s%3ld lne: " +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld lne: " +msgstr[1] "+-%s%3ld lne: " +msgstr[2] "+-%s%3ld lne: " +msgstr[3] "+-%s%3ld lne: " +msgstr[4] "+-%s%3ld lne: " -#: ../eval.c:9291 #, c-format msgid "E700: Unknown function: %s" msgstr "E700: Feidhm anaithnid: %s" -#: ../eval.c:10729 +msgid "E922: expected a dict" +msgstr "E922: bhothas ag sil le foclir" + +msgid "E923: Second argument of function() must be a list or a dict" +msgstr "E923: Caithfidh an dara hargint de function() a bheith ina liosta n ina foclir" + +msgid "" +"&OK\n" +"&Cancel" +msgstr "" +"&OK\n" +"&Cealaigh" + msgid "called inputrestore() more often than inputsave()" msgstr "Glaodh inputrestore() nos minice n inputsave()" -#: ../eval.c:10771 -#, fuzzy msgid "insert() argument" -msgstr "argint -c" +msgstr "argint insert()" -#: ../eval.c:10841 msgid "E786: Range not allowed" msgstr "E786: N cheadatear an raon" -#: ../eval.c:11140 +msgid "E916: not a valid job" +msgstr "E916: n jab bail " + msgid "E701: Invalid type for len()" msgstr "E701: Cinel neamhbhail le haghaidh len()" -#: ../eval.c:11980 +#, c-format +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 chim" -#: ../eval.c:11982 msgid "E727: Start past end" msgstr "E727: Tosach thar dheireadh" -#: ../eval.c:12024 ../eval.c:15297 msgid "" msgstr "" -#: ../eval.c:12282 -#, fuzzy +msgid "E240: No connection to Vim server" +msgstr "E240: Nl aon nasc le freastala Vim" + +#, c-format +msgid "E241: Unable to send to %s" +msgstr "E241: N fidir aon rud a sheoladh chuig %s" + +msgid "E277: Unable to read a server reply" +msgstr "E277: N fidir freagra n fhreastala a lamh" + msgid "remove() argument" -msgstr "argint --cmd" +msgstr "argint remove()" -#: ../eval.c:12466 msgid "E655: Too many symbolic links (cycle?)" msgstr "E655: An iomarca naisc shiombalacha (ciogal?)" -#: ../eval.c:12593 -#, fuzzy msgid "reverse() argument" -msgstr "argint -c" +msgstr "argint reverse()" + +msgid "E258: Unable to send to client" +msgstr "E258: N fidir aon rud a sheoladh chuig an chliant" + +#, c-format +msgid "E927: Invalid action: '%s'" +msgstr "E927: Gnomh neamhbhail: '%s'" -#: ../eval.c:13721 -#, fuzzy msgid "sort() argument" -msgstr "argint -c" +msgstr "argint sort()" -#: ../eval.c:13721 -#, fuzzy msgid "uniq() argument" -msgstr "argint -c" +msgstr "argint uniq()" -#: ../eval.c:13776 msgid "E702: Sort compare function failed" msgstr "E702: Theip ar fheidhm chomparide le linn srtla" -#: ../eval.c:13806 -#, fuzzy msgid "E882: Uniq compare function failed" -msgstr "E702: Theip ar fheidhm chomparide le linn srtla" +msgstr "E882: Theip ar fheidhm chomparide Uniq" -#: ../eval.c:14085 msgid "(Invalid)" msgstr "(Neamhbhail)" -#: ../eval.c:14590 -msgid "E677: Error writing temp file" -msgstr "E677: Earrid agus comhad sealadach scrobh" - -#: ../eval.c:16159 -msgid "E805: Using a Float as a Number" -msgstr "E805: Snmhphointe sid mar Uimhir" - -#: ../eval.c:16162 -msgid "E703: Using a Funcref as a Number" -msgstr "E703: Funcref sid mar Uimhir" - -#: ../eval.c:16170 -msgid "E745: Using a List as a Number" -msgstr "E745: Liosta sid mar Uimhir" - -#: ../eval.c:16173 -msgid "E728: Using a Dictionary as a Number" -msgstr "E728: Foclir sid mar Uimhir" - -#: ../eval.c:16259 -msgid "E729: using Funcref as a String" -msgstr "E729: Funcref sid mar Theaghrn" - -#: ../eval.c:16262 -msgid "E730: using List as a String" -msgstr "E730: Liosta sid mar Theaghrn" - -#: ../eval.c:16265 -msgid "E731: using Dictionary as a String" -msgstr "E731: Foclir sid mar Theaghrn" - -#: ../eval.c:16619 -#, c-format -msgid "E706: Variable type mismatch for: %s" -msgstr "E706: Mmheaitseil idir cinelacha athrige: %s" - -#: ../eval.c:16705 -#, c-format -msgid "E795: Cannot delete variable %s" -msgstr "E795: N fidir athrg %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 dts ainm Funcref: %s" - -#: ../eval.c:16732 -#, c-format -msgid "E705: Variable name conflicts with existing function: %s" -msgstr "E705: Tagann ainm athrige 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 fidir an luach de %s a athr" - -#: ../eval.c:16838 -msgid "E698: variable nested too deep for making a copy" -msgstr "E698: athrg neadaithe rdhomhain chun a chipeil" - -#: ../eval.c:17249 -#, c-format -msgid "E123: Undefined function: %s" -msgstr "E123: Feidhm gan sainmhni: %s" - -#: ../eval.c:17260 -#, c-format -msgid "E124: Missing '(': %s" -msgstr "E124: '(' ar iarraidh: %s" - -#: ../eval.c:17293 -#, fuzzy -msgid "E862: Cannot use g: here" -msgstr "E284: N fidir luachanna IC a shocr" - -#: ../eval.c:17312 #, c-format -msgid "E125: Illegal argument: %s" -msgstr "E125: Argint neamhcheadaithe: %s" - -#: ../eval.c:17323 -#, fuzzy, c-format -msgid "E853: Duplicate argument name: %s" -msgstr "E125: Argint neamhcheadaithe: %s" - -#: ../eval.c:17416 -msgid "E126: Missing :endfunction" -msgstr "E126: :endfunction ar iarraidh" - -#: ../eval.c:17537 -#, c-format -msgid "E707: Function name conflicts with variable: %s" -msgstr "E707: Tagann ainm na feidhme salach ar athrg: %s" - -#: ../eval.c:17549 -#, c-format -msgid "E127: Cannot redefine function %s: It is in use" -msgstr "" -"E127: N fidir sainmhni nua a dhanamh ar fheidhm %s: In sid cheana" - -#: ../eval.c:17604 -#, c-format -msgid "E746: Function name does not match script file name: %s" -msgstr "" -"E746: Nl ainm na feidhme comhoirinach le hainm comhaid na scripte: %s" - -#: ../eval.c:17716 -msgid "E129: Function name required" -msgstr "E129: T g le hainm feidhme" - -#: ../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 dts ainm feidhme, n idirstad a " -"bheith ann: %s" - -#: ../eval.c:17833 -#, fuzzy, c-format -msgid "E884: Function name cannot contain a colon: %s" -msgstr "" -"E128: Caithfidh ceannlitir a bheith ar dts ainm feidhme, n idirstad a " -"bheith ann: %s" - -#: ../eval.c:18336 -#, c-format -msgid "E131: Cannot delete function %s: It is in use" -msgstr "E131: N fidir feidhm %s a scriosadh: T s in sid faoi lthair" - -#: ../eval.c:18441 -msgid "E132: Function call depth is higher than 'maxfuncdepth'" -msgstr "E132: Doimhneacht na nglaonna nos m n 'maxfuncdepth'" - -#: ../eval.c:18568 -#, c-format -msgid "calling %s" -msgstr "%s glao" - -#: ../eval.c:18651 -#, c-format -msgid "%s aborted" -msgstr "%s tobscortha" - -#: ../eval.c:18653 -#, c-format -msgid "%s returning #%" -msgstr "%s ag aisfhilleadh #%" - -#: ../eval.c:18670 -#, c-format -msgid "%s returning %s" -msgstr "%s ag aisfhilleadh %s" - -#: ../eval.c:18691 ../ex_cmds2.c:2695 -#, c-format -msgid "continuing in %s" -msgstr "ag leanint i %s" - -#: ../eval.c:18795 -msgid "E133: :return not inside a function" -msgstr "E133: Caithfidh :return a bheith isteach i bhfeidhm" - -#: ../eval.c:19159 -msgid "" -"\n" -"# global variables:\n" -msgstr "" -"\n" -"# athrga comhchoiteanna:\n" +msgid "E935: invalid submatch number: %d" +msgstr "E935: uimhir fho-mheaitsela neamhbhail: %d" -#: ../eval.c:19254 -msgid "" -"\n" -"\tLast set from " -msgstr "" -"\n" -"\tSocraithe is dana " +msgid "E677: Error writing temp file" +msgstr "E677: Earrid agus comhad sealadach scrobh" -#: ../eval.c:19272 -msgid "No old files" -msgstr "Gan seanchomhaid" +msgid "E921: Invalid callback argument" +msgstr "E921: Argint 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 lnte isteach iontu fin" -#: ../ex_cmds.c:747 msgid "1 line moved" msgstr "Bogadh lne amhin" -#: ../ex_cmds.c:749 #, c-format -msgid "% lines moved" -msgstr "Bogadh % lne" +msgid "%ld lines moved" +msgstr "Bogadh %ld lne" -#: ../ex_cmds.c:1175 #, c-format -msgid "% lines filtered" -msgstr "Scagadh % lne" +msgid "%ld lines filtered" +msgstr "Scagadh %ld lne" -#: ../ex_cmds.c:1194 msgid "E135: *Filter* Autocommands must not change current buffer" msgstr "" "E135: N cheadatear d'uathorduithe *scagaire* an maoln reatha a athr" -#: ../ex_cmds.c:1244 msgid "[No write since last change]\n" msgstr "[Athraithe agus nach sbhilte shin]\n" -#: ../ex_cmds.c:1424 #, c-format msgid "%sviminfo: %s in line: " msgstr "%sviminfo: %s i lne: " -#: ../ex_cmds.c:1431 msgid "E136: viminfo: Too many errors, skipping rest of file" msgstr "" "E136: viminfo: An iomarca earrid, ag scipeil 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 lamh" -#: ../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: Nl an comhad Viminfo inscrofa: %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 fidir comhad viminfo %s a scrobh!" -#: ../ex_cmds.c:1635 #, c-format msgid "Writing viminfo file \"%s\"" msgstr "Comhad viminfo \"%s\" scrobh" +#, c-format +msgid "E886: Can't rename viminfo file to %s!" +msgstr "E886: N fidir 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 fidir leat an comhad seo a chur in eagar ach b cramach!\n" "\n" -#: ../ex_cmds.c:1723 msgid "# Value of 'encoding' when this file was written\n" msgstr "# Luach 'encoding' agus an comhad seo scrobh\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" +"# Barralnte, cipeilte focal ar fhocal:\n" + +msgid "Save As" +msgstr "Sbhil Mar" + msgid "Write partial file?" msgstr "Scrobh comhad neamhiomln?" -#: ../ex_cmds.c:2166 msgid "E140: Use ! to write partial buffer" msgstr "E140: Bain sid as ! chun maoln neamhiomln a scrobh" -#: ../ex_cmds.c:2281 #, c-format msgid "Overwrite existing file \"%s\"?" msgstr "Forscrobh comhad \"%s\" at ann cheana?" -#: ../ex_cmds.c:2317 #, c-format msgid "Swap file \"%s\" exists, overwrite anyway?" msgstr "T comhad babhtla \"%s\" ann cheana; forscrobh mar sin fin?" -#: ../ex_cmds.c:2326 #, c-format msgid "E768: Swap file exists: %s (:silent! overrides)" msgstr "E768: T comhad babhtla ann cheana: %s (sid :silent! chun sr)" -#: ../ex_cmds.c:2381 #, c-format -msgid "E141: No file name for buffer %" -msgstr "E141: Nl aon ainm ar mhaoln %" +msgid "E141: No file name for buffer %ld" +msgstr "E141: Nl aon ainm ar mhaoln %ld" -#: ../ex_cmds.c:2412 msgid "E142: File not written: Writing is disabled by 'write' option" msgstr "E142: Nor scrobhadh an comhad: dchumasaithe 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 scrobh mar sin fin?" -#: ../ex_cmds.c:2439 #, c-format msgid "" "File permissions of \"%s\" are read-only.\n" @@ -1201,85 +944,70 @@ msgstr "" "Seans gurbh fhidir scrobh ann mar sin fin.\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 inlite amhin \"%s\" (cuir ! leis an ord chun sr)" -#: ../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 maoln nua %s go tobann" -#: ../ex_cmds.c:3313 msgid "E144: non-numeric argument to :z" msgstr "E144: argint neamhuimhriil chun :z" -#: ../ex_cmds.c:3404 msgid "E145: Shell commands not allowed in rvim" msgstr "E145: N cheadatear orduithe blaoisce i rvim" -#: ../ex_cmds.c:3498 msgid "E146: Regular expressions can't be delimited by letters" msgstr "" "E146: N cheadatear litreacha mar theormharcir ar shloinn ionadaochta" -#: ../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 comhoirinach" -#: ../ex_cmds.c:4384 msgid "1 substitution" msgstr "1 ionadaocht" -#: ../ex_cmds.c:4387 #, c-format -msgid "% matches" -msgstr "% rud comhoirinach" +msgid "%ld matches" +msgstr "%ld rud comhoirinach" -#: ../ex_cmds.c:4388 #, c-format -msgid "% substitutions" -msgstr "% ionadaocht" +msgid "%ld substitutions" +msgstr "%ld ionadaocht" -#: ../ex_cmds.c:4392 msgid " on 1 line" msgstr " ar lne amhin" -#: ../ex_cmds.c:4395 #, c-format -msgid " on % lines" -msgstr " ar % lne" +msgid " on %ld lines" +msgstr " ar %ld lne" -#: ../ex_cmds.c:4438 msgid "E147: Cannot do :global recursive" msgstr "E147: N cheadatear :global go hathchrsach" # should have ":" -#: ../ex_cmds.c:4467 msgid "E148: Regular expression missing from global" msgstr "E148: Slonn ionadaochta ar iarraidh :global" -#: ../ex_cmds.c:4508 #, c-format msgid "Pattern found in every line: %s" msgstr "Aimsodh an patrn i ngach lne: %s" -#: ../ex_cmds.c:4510 -#, fuzzy, c-format +#, c-format msgid "Pattern not found: %s" -msgstr "Patrn gan aimsi" +msgstr "Patrn gan aimsi: %s" -#: ../ex_cmds.c:4587 msgid "" "\n" "# Last Substitute String:\n" @@ -1289,682 +1017,599 @@ msgstr "" "# Teaghrn Ionadach Is Dana:\n" "$" -#: ../ex_cmds.c:4679 msgid "E478: Don't panic!" msgstr "E478: N tigh i scaoll!" -#: ../ex_cmds.c:4717 #, c-format msgid "E661: Sorry, no '%s' help for %s" msgstr "E661: T brn orm, n aon chabhair '%s' do %s" -#: ../ex_cmds.c:4719 #, c-format msgid "E149: Sorry, no help for %s" msgstr "E149: T brn orm, nl aon chabhair do %s" -#: ../ex_cmds.c:4751 #, c-format msgid "Sorry, help file \"%s\" not found" msgstr "T brn 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 meaitseil: %s" -#: ../ex_cmds.c:5446 #, c-format msgid "E152: Cannot open %s for writing" msgstr "E152: N fidir %s a oscailt chun scrobh ann" -#: ../ex_cmds.c:5471 #, c-format msgid "E153: Unable to open %s for reading" msgstr "E153: N fidir %s a oscailt chun a lamh" -#: ../ex_cmds.c:5500 #, c-format msgid "E670: Mix of help file encodings within a language: %s" msgstr "E670: Ionchduithe agsla 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 dhblach \"%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 sainmhnithe" -#: ../ex_cmds.c:5813 #, c-format msgid "E239: Invalid sign text: %s" msgstr "E239: Tacs 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 maolin neamhbhail: %s" -#: ../ex_cmds.c:6008 +msgid "E934: Cannot jump to a buffer that does not have a name" +msgstr "E934: N fidir lim go maoln gan ainm" + #, c-format -msgid "E157: Invalid sign ID: %" -msgstr "E157: ID neamhbhail comhartha: %" +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 fidir an comhartha a athr: %s" + +msgid " (NOT FOUND)" +msgstr " (AR IARRAIDH)" -#: ../ex_cmds.c:6066 msgid " (not supported)" msgstr " (nl an rogha seo ar fil)" -#: ../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 "Md dfhabhtaithe thos. Clscrobh \"cont\" chun leanint." -#: ../ex_cmds2.c:143 ../ex_docmd.c:759 #, c-format -msgid "line %: %s" -msgstr "lne %: %s" +msgid "line %ld: %s" +msgstr "lne %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 frma" + +#, c-format +msgid "frame at highest level: %d" +msgstr "frma ag an leibhal is airde: %d" + #, c-format -msgid "Breakpoint in \"%s%s\" line %" -msgstr "Brisphointe i \"%s%s\" lne %" +msgid "Breakpoint in \"%s%s\" line %ld" +msgstr "Brisphointe i \"%s%s\" lne %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 "Nl aon bhrisphointe socraithe" -#: ../ex_cmds2.c:617 #, c-format -msgid "%3d %s %s line %" -msgstr "%3d %s %s lne %" +msgid "%3d %s %s line %ld" +msgstr "%3d %s %s lne %ld" -#: ../ex_cmds2.c:942 msgid "E750: First use \":profile start {fname}\"" msgstr "E750: sid \":profile start {ainm}\" ar dts" -#: ../ex_cmds2.c:1269 #, c-format msgid "Save changes to \"%s\"?" msgstr "Sbhil 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: Athraodh maoln \"%s\" ach nach bhfuil s sbhilte shin" -#: ../ex_cmds2.c:1480 msgid "Warning: Entered other buffer unexpectedly (check autocommands)" msgstr "Rabhadh: Chuathas i maoln eile go tobann (seiceil na huathorduithe)" -#: ../ex_cmds2.c:1826 msgid "E163: There is only one file to edit" msgstr "E163: Nl ach aon chomhad amhin le cur in eagar" -#: ../ex_cmds2.c:1828 msgid "E164: Cannot go before first file" msgstr "E164: N fidir a dhul roimh an chad chomhad" -#: ../ex_cmds2.c:1830 msgid "E165: Cannot go beyond last file" msgstr "E165: N fidir 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 danamh cuardach ar \"%s\" i \"%s\"" -#: ../ex_cmds2.c:2284 #, c-format msgid "Searching for \"%s\"" msgstr "Ag danamh 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 fidir comhadlann a lamh: \"%s\"" -#: ../ex_cmds2.c:2518 #, c-format msgid "could not source \"%s\"" msgstr "norbh fhidir \"%s\" a lamh" -#: ../ex_cmds2.c:2520 #, c-format -msgid "line %: could not source \"%s\"" -msgstr "lne %: norbh fhidir \"%s\" a fhoinsi" +msgid "line %ld: could not source \"%s\"" +msgstr "lne %ld: norbh fhidir \"%s\" a fhoinsi" -#: ../ex_cmds2.c:2535 #, c-format msgid "sourcing \"%s\"" msgstr "\"%s\" fhoinsi" -#: ../ex_cmds2.c:2537 #, c-format -msgid "line %: sourcing \"%s\"" -msgstr "lne %: \"%s\" fhoinsi" +msgid "line %ld: sourcing \"%s\"" +msgstr "lne %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 leanint i %s" + msgid "modeline" msgstr "mdlne" -#: ../ex_cmds2.c:2767 msgid "--cmd argument" msgstr "argint --cmd" -#: ../ex_cmds2.c:2769 msgid "-c argument" msgstr "argint -c" -#: ../ex_cmds2.c:2771 msgid "environment variable" msgstr "athrg thimpeallachta" -#: ../ex_cmds2.c:2773 msgid "error handler" msgstr "limhsela earrid" -#: ../ex_cmds2.c:3020 msgid "W15: Warning: Wrong line separator, ^M may be missing" msgstr "" "W15: Rabhadh: Deighilteoir lnte mcheart, is fidir go bhfuil ^M ar iarraidh" -#: ../ex_cmds2.c:3139 msgid "E167: :scriptencoding used outside of a sourced file" msgstr "E167: n sidtear :scriptencoding ach i gcomhad foinsithe" -#: ../ex_cmds2.c:3166 msgid "E168: :finish used outside of a sourced file" msgstr "E168: n sidtear :finish ach i gcomhaid foinsithe" -#: ../ex_cmds2.c:3389 #, c-format msgid "Current %slanguage: \"%s\"" msgstr "%sTeanga faoi lthair: \"%s\"" -#: ../ex_cmds2.c:3404 #, c-format msgid "E197: Cannot set language to \"%s\"" msgstr "E197: N fidir 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 "Md Ex thos. Clscrobh \"visual\" le haghaidh an ghnthmhd." # in FARF -KPS -#: ../ex_docmd.c:428 msgid "E501: At end-of-file" msgstr "E501: Ag an chomhadchroch" -#: ../ex_docmd.c:513 msgid "E169: Command too recursive" msgstr "E169: Ord r-athchrsach" -#: ../ex_docmd.c:1006 #, c-format msgid "E605: Exception not caught: %s" msgstr "E605: Eisceacht gan limhseil: %s" -#: ../ex_docmd.c:1085 msgid "End of sourced file" msgstr "Croch chomhaid foinsithe" -#: ../ex_docmd.c:1086 msgid "End of function" msgstr "Croch fheidhme" -#: ../ex_docmd.c:1628 msgid "E464: Ambiguous use of user-defined command" msgstr "E464: sid athbhroch d'ord saincheaptha" -#: ../ex_docmd.c:1638 msgid "E492: Not an editor command" msgstr "E492: Nl ina ord eagarthra" -#: ../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, babhtil" -#. append -#. typed wrong -#: ../ex_docmd.c:1787 msgid "E494: Use w or w>>" msgstr "E494: Bain sid 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 brn orm, nl an t-ord ar fil sa leagan seo" -#: ../ex_docmd.c:3752 msgid "E172: Only one file name allowed" msgstr "E172: N cheadatear ach aon ainm comhaid amhin" -#: ../ex_docmd.c:4238 msgid "1 more file to edit. Quit anyway?" msgstr "1 comhad le cur in eagar fs. Scoir mar sin fin?" -#: ../ex_docmd.c:4242 #, c-format msgid "%d more files to edit. Quit anyway?" msgstr "%d comhad le cur in eagar fs. Scoir mar sin fin?" -#: ../ex_docmd.c:4248 msgid "E173: 1 more file to edit" msgstr "E173: 1 chomhad le heagr fs" -#: ../ex_docmd.c:4250 #, c-format -msgid "E173: % more files to edit" -msgstr "E173: % 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 sr" -#: ../ex_docmd.c:4432 msgid "" "\n" -" Name Args Range Complete Definition" +" Name Args Address Complete Definition" msgstr "" "\n" -" Ainm Arg Raon Iomln Sainmhni" +" Ainm Arg Seoladh Iomln Sainmhni" -#: ../ex_docmd.c:4516 msgid "No user-defined commands found" msgstr "Nl aon ord aimsithe at sainithe ag an sideoir" -#: ../ex_docmd.c:4538 msgid "E175: No attribute specified" msgstr "E175: Nl aon aitreabid sainithe" -#: ../ex_docmd.c:4583 msgid "E176: Invalid number of arguments" msgstr "E176: T lon na n-argint mcheart" -#: ../ex_docmd.c:4594 msgid "E177: Count cannot be specified twice" msgstr "E177: N cheadatear an t-ireamh a bheith tugtha faoi dh" -#: ../ex_docmd.c:4603 msgid "E178: Invalid default value for count" msgstr "E178: Luach ramhshocraithe neamhbhail ar ireamh" -#: ../ex_docmd.c:4625 msgid "E179: argument required for -complete" msgstr "E179: t g le hargint i ndiaidh -complete" -#: ../ex_docmd.c:4635 +msgid "E179: argument required for -addr" +msgstr "E179: t g le hargint i ndiaidh -addr" + #, c-format msgid "E181: Invalid attribute: %s" msgstr "E181: Aitreabid 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 dts orduithe at sainithe ag an " "sideoir" -#: ../ex_docmd.c:4696 -#, fuzzy msgid "E841: Reserved name, cannot be used for user defined command" -msgstr "E464: sid athbhroch d'ord saincheaptha" +msgstr "" +"E841: Ainm in irithe, n fidir a chur ar ord sainithe ag an sideoir" -#: ../ex_docmd.c:4751 #, c-format msgid "E184: No such user-defined command: %s" msgstr "E184: Nl a leithid d'ord saincheaptha: %s" -#: ../ex_docmd.c:5219 +#, c-format +msgid "E180: Invalid address type value: %s" +msgstr "E180: Cinel neamhbhail seolta: %s" + #, c-format msgid "E180: Invalid complete value: %s" msgstr "E180: Luach iomln neamhbhail: %s" -#: ../ex_docmd.c:5225 msgid "E468: Completion argument only allowed for custom completion" msgstr "" "E468: N cheadatear argint chomhlnaithe ach le comhln saincheaptha" -#: ../ex_docmd.c:5231 msgid "E467: Custom completion requires a function argument" msgstr "E467: T g le hargint fheidhme le comhln saincheaptha" -#: ../ex_docmd.c:5257 -#, fuzzy, c-format +msgid "unknown" +msgstr "anaithnid" + +#, c-format msgid "E185: Cannot find color scheme '%s'" -msgstr "E185: Scim dathanna %s gan aimsi" +msgstr "E185: Scim dathanna '%s' gan aimsi" -#: ../ex_docmd.c:5263 msgid "Greetings, Vim user!" msgstr "Dia duit, a sideoir Vim!" -#: ../ex_docmd.c:5431 msgid "E784: Cannot close last tab page" -msgstr "E784: N fidir an leathanach cluaisn deiridh a dhnadh" +msgstr "E784: N fidir an leathanach cluaisn deiridh a dhnadh" -#: ../ex_docmd.c:5462 msgid "Already only one tab page" -msgstr "Nl ach leathanach cluaisn amhin cheana fin" +msgstr "Nl ach leathanach cluaisn amhin cheana fin" + +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 cluaisn %d" -#: ../ex_docmd.c:6295 msgid "No swap file" msgstr "Nl aon chomhad babhtla 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 fidir an chomhadlann a athr, mionathraodh an maoln (cuir ! leis " "an ord chun sr)" -#: ../ex_docmd.c:6485 msgid "E186: No previous directory" msgstr "E186: Nl 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 folir dh argint uimhrila 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 fidir ionad na fuinneoige a fhil amach ar an chras seo" -#: ../ex_docmd.c:6662 msgid "E466: :winpos requires two number arguments" msgstr "E466: n folir dh argint uimhrila le :winpos" -#: ../ex_docmd.c:7241 +msgid "E930: Cannot use :redir inside execute()" +msgstr "E930: N fidir :redir a sid laistigh de execute()" + +msgid "Save Redirection" +msgstr "Sbhil Atreor" + +msgid "Save View" +msgstr "Sbhil an tAmharc" + +msgid "Save Session" +msgstr "Sbhil an Seisin" + +msgid "Save Setup" +msgstr "Sbhil an Socr" + #, c-format msgid "E739: Cannot create directory: %s" msgstr "E739: N fidir 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 sr)" -#: ../ex_docmd.c:7273 #, c-format msgid "E190: Cannot open \"%s\" for writing" msgstr "E190: N fidir \"%s\" a oscailt chun lamh" #. set mark -#: ../ex_docmd.c:7294 msgid "E191: Argument must be a letter or forward/backward quote" msgstr "E191: Caithfidh an argint a bheith litir n comhartha athfhriotal" -#: ../ex_docmd.c:7333 msgid "E192: Recursive use of :normal too deep" msgstr "E192: athchrsil :normal rdhomhain" -#: ../ex_docmd.c:7807 +msgid "E809: #< is not available without the +eval feature" +msgstr "E809: nl #< ar fil gan ghn +eval" + msgid "E194: No alternate file name to substitute for '#'" msgstr "E194: Nl aon ainm comhaid a chur in ionad '#'" -#: ../ex_docmd.c:7841 msgid "E495: no autocommand file name to substitute for \"\"" msgstr "E495: nl aon ainm comhaid uathordaithe le cur in ionad \"\"" -#: ../ex_docmd.c:7850 msgid "E496: no autocommand buffer number to substitute for \"\"" msgstr "E496: nl aon uimhir mhaoln uathordaithe le cur in ionad \"\"" -#: ../ex_docmd.c:7861 msgid "E497: no autocommand match name to substitute for \"\"" msgstr "" "E497: nl aon ainm meaitsela uathordaithe le cur in ionad \"\"" -#: ../ex_docmd.c:7870 msgid "E498: no :source file name to substitute for \"\"" msgstr "E498: nl aon ainm comhaid :source le cur in ionad \"\"" -#: ../ex_docmd.c:7876 -#, fuzzy msgid "E842: no line number to use for \"\"" -msgstr "E498: nl aon ainm comhaid :source le cur in ionad \"\"" +msgstr "E842: nl aon lne-uimhir ar fil le haghaidh \"\"" -#: ../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\" " "amhin" -#: ../ex_docmd.c:7905 msgid "E500: Evaluates to an empty string" msgstr "E500: Luachiltear seo mar theaghrn folamh" -#: ../ex_docmd.c:8838 msgid "E195: Cannot open viminfo file for reading" msgstr "E195: N fidir an comhad viminfo a oscailt chun lamh" -#: ../ex_eval.c:464 +msgid "E196: No digraphs in this version" +msgstr "E196: N cheadatear dghraif sa leagan seo" + msgid "E608: Cannot :throw exceptions with 'Vim' prefix" msgstr "E608: N fidir eisceachta a :throw le rimr '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 gcrch: %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 %" -msgstr "%s, lne %" +msgid "%s, line %ld" +msgstr "%s, lne %ld" #. always scroll up, don't overwrite -#: ../ex_eval.c:608 #, c-format msgid "Exception caught: %s" msgstr "Limhseladh 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 "atosaodh %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 "Earrid agus idirbhriseadh" -#: ../ex_eval.c:715 msgid "Error" msgstr "Earrid" #. 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 rdhomhain" -#: ../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 iomadla" -#: ../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 rdhomhain" -#: ../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 sid le :while" -#: ../ex_eval.c:1104 msgid "E733: Using :endwhile with :for" msgstr "E733: :endwhile sid le :for" -#: ../ex_eval.c:1247 msgid "E601: :try nesting too deep" msgstr "E601: :try neadaithe rdhomhain" -#: ../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 iomadla" -#: ../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: Nl cead agat maoln eile a chur in eagar anois" -#: ../ex_getln.c:1656 msgid "E811: Not allowed to change buffer information now" msgstr "E811: Nl cead agat faisnis an mhaolin a athr anois" -#: ../ex_getln.c:3178 msgid "tagname" msgstr "clibainm" -#: ../ex_getln.c:3181 msgid " kind file\n" msgstr " cinel 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 "Lne na nOrduithe:" -#: ../ex_getln.c:5048 msgid "Search String" msgstr "Teaghrn Cuardaigh" -#: ../ex_getln.c:5049 msgid "Expression" msgstr "Sloinn:" -#: ../ex_getln.c:5050 msgid "Input Line" msgstr "Lne an Ionchuir:" -#: ../ex_getln.c:5117 +msgid "Debug Line" +msgstr "Lne Dhfhabhtaithe" + 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 maoln 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 mr '**[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 fidir comhadlann \"%s\" a aimsi sa cdpath" - -#: ../file_search.c:1508 -#, c-format -msgid "E345: Can't find file \"%s\" in path" -msgstr "E345: N fidir comhad \"%s\" a aimsi sa chonair" - -#: ../file_search.c:1512 -#, c-format -msgid "E346: No more directory \"%s\" found in cdpath" -msgstr "E346: Nl comhadlann \"%s\" sa cdpath a thuilleadh" - -#: ../file_search.c:1515 -#, c-format -msgid "E347: No more file \"%s\" found in path" -msgstr "E347: Nl comhad \"%s\" sa chonair a thuilleadh" - -#: ../fileio.c:137 msgid "E812: Autocommands changed buffer or buffer name" msgstr "E812: Bh maoln n ainm maolin athraithe ag orduithe uathoibrocha" -#: ../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 glas seo (dchumasaithe 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 rmhr]" -#: ../fileio.c:534 msgid "[Permission Denied]" msgstr "[Cead Diltaithe]" -#: ../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 cheadatear d'uathorduithe *ReadPre an maoln reatha a athr" -#: ../fileio.c:672 -msgid "Nvim: Reading from stdin...\n" +msgid "Vim: Reading from stdin...\n" msgstr "Vim: Ag lamh n ionchur caighdenach...\n" +msgid "Reading from stdin..." +msgstr "Ag lamh n ionchur caighdenach..." + #. Re-opening the original file failed! -#: ../fileio.c:909 msgid "E202: Conversion made file unreadable!" msgstr "E202: Comhad dolite i ndiaidh an tiontaithe!" -#. fifo or socket -#: ../fileio.c:1782 msgid "[fifo/socket]" msgstr "[fifo/soicad]" # `TITA' ?! -KPS -#. fifo -#: ../fileio.c:1788 msgid "[fifo]" msgstr "[fifo]" -#. or socket -#: ../fileio.c:1794 msgid "[socket]" msgstr "[soicad]" -#. or character special -#: ../fileio.c:1801 msgid "[character special]" msgstr "[comhad speisialta den chinel carachtar]" -#: ../fileio.c:1815 msgid "[CR missing]" msgstr "[CR ar iarraidh]" -#: ../fileio.c:1819 msgid "[long lines split]" msgstr "[lnte 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 %]" -msgstr "[EARRID TIONTAITHE i lne %]" +msgid "[CONVERSION ERROR in line %ld]" +msgstr "[EARRID TIONTAITHE i lne %ld]" -#: ../fileio.c:1835 #, c-format -msgid "[ILLEGAL BYTE in line %]" -msgstr "[BEART NEAMHCHEADAITHE i lne %]" +msgid "[ILLEGAL BYTE in line %ld]" +msgstr "[BEART NEAMHCHEADAITHE i lne %ld]" -#: ../fileio.c:1838 msgid "[READ ERRORS]" msgstr "[EARRID LIMH]" -#: ../fileio.c:2104 msgid "Can't find temp file for conversion" msgstr "N fidir 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 fidir an t-aschur 'charconvert' a lamh" -#: ../fileio.c:2437 msgid "E676: No matching autocommands for acwrite buffer" msgstr "E676: Nl aon uathord comhoirinaithe le haghaidh maolin acwrite" -#: ../fileio.c:2466 msgid "E203: Autocommands deleted or unloaded buffer to be written" msgstr "E203: Scrios n dhluchtaigh uathorduithe an maoln le scrobh" -#: ../fileio.c:2486 msgid "E204: Autocommand changed number of lines in unexpected way" msgstr "E204: D'athraigh uathord lon na lnte gan choinne" -#: ../fileio.c:2548 ../fileio.c:2565 +msgid "NetBeans disallows writes of unmodified buffers" +msgstr "N cheadaonn NetBeans maolin gan athr a bheith scrofa" + +msgid "Partial writes disallowed for NetBeans buffers" +msgstr "N cheadatear maolin NetBeans a bheith scrofa go neamhiomln" + msgid "is not a file or writable device" msgstr "n comhad n glas inscrofa " -#: ../fileio.c:2601 +msgid "writing to device disabled with 'opendevice' option" +msgstr "dchumasaodh scrobh chuig glas le rogha 'opendevice'" + msgid "is read-only (add ! to override)" msgstr "is inlite amhin (cuir ! leis an ord chun sr)" -#: ../fileio.c:2886 msgid "E506: Can't write to backup file (add ! to override)" msgstr "" "E506: N fidir scrobh a dhanamh sa chomhad cltaca (sid ! chun sr)" -#: ../fileio.c:2898 msgid "E507: Close error for backup file (add ! to override)" msgstr "" "E507: Earrid agus comhad cltaca dhnadh (cuir ! leis an ord chun sr)" -#: ../fileio.c:2901 msgid "E508: Can't read file for backup (add ! to override)" msgstr "" "E508: N fidir an comhad cltaca a lamh (cuir ! leis an ord chun sr)" -#: ../fileio.c:2923 msgid "E509: Cannot create backup file (add ! to override)" msgstr "" "E509: N fidir comhad cltaca a chruth (cuir ! leis an ord chun sr)" -#: ../fileio.c:3008 msgid "E510: Can't make backup file (add ! to override)" msgstr "" "E510: N fidir comhad cltaca a chruth (cuir ! leis an ord chun sr)" -#. 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 sr)" + msgid "E214: Can't find temp file for writing" msgstr "E214: N fidir comhad sealadach a aimsi chun scrobh ann" -#: ../fileio.c:3134 msgid "E213: Cannot convert (add ! to write without conversion)" msgstr "E213: N fidir tiont (cuir ! leis an ord chun scrobh gan tiont)" -#: ../fileio.c:3169 msgid "E166: Can't open linked file for writing" msgstr "E166: N fidir comhad nasctha a oscailt chun scrobh ann" -#: ../fileio.c:3173 msgid "E212: Can't open file for writing" msgstr "E212: N fidir comhad a oscailt chun scrobh ann" -#: ../fileio.c:3363 msgid "E667: Fsync failed" msgstr "E667: Theip ar fsync" -#: ../fileio.c:3398 msgid "E512: Close failed" msgstr "E512: Theip ar dnadh" -#: ../fileio.c:3436 msgid "E513: write error, conversion failed (make 'fenc' empty to override)" msgstr "" "E513: earrid le linn scrobh, theip ar thiont (sid 'fenc' folamh chun " "sr)" -#: ../fileio.c:3441 #, c-format msgid "" -"E513: write error, conversion failed in line % (make 'fenc' empty to " +"E513: write error, conversion failed in line %ld (make 'fenc' empty to " "override)" msgstr "" -"E513: earrid le linn scrofa, theip ar thiont ar lne % (sid " -"'fenc' folamh le sr)" +"E513: earrid le linn scrofa, theip ar thiont ar lne %ld (sid 'fenc' " +"folamh le sr)" -#: ../fileio.c:3448 msgid "E514: write error (file system full?)" msgstr "E514: earrid le linn scrofa (an bhfuil an cras comhaid ln?)" -#: ../fileio.c:3506 msgid " CONVERSION ERROR" msgstr " EARRID TIONTAITHE" -#: ../fileio.c:3509 #, c-format -msgid " in line %;" -msgstr " ar lne %;" +msgid " in line %ld;" +msgstr " ar lne %ld;" -#: ../fileio.c:3519 msgid "[Device]" msgstr "[Glas]" -#: ../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 " scrofa" -#: ../fileio.c:3579 msgid "E205: Patchmode: can't save original file" msgstr "E205: Patchmode: n fidir an comhad bunsach a shbhil" -#: ../fileio.c:3602 msgid "E206: patchmode: can't touch empty original file" msgstr "E206: patchmode: n fidir an comhad bunsach folamh a theagmhil" -#: ../fileio.c:3616 msgid "E207: Can't delete backup file" msgstr "E207: N fidir an comhad cltaca a scriosadh" -#: ../fileio.c:3672 msgid "" "\n" "WARNING: Original file may be lost or damaged\n" @@ -2286,96 +1851,75 @@ msgstr "" "\n" "RABHADH: Is fidir gur caillte n loite an comhad bunsach\n" -#: ../fileio.c:3675 msgid "don't quit the editor until the file is successfully written!" msgstr "n scoir go dt go scrobhfa an comhad!" -#: ../fileio.c:3795 msgid "[dos]" msgstr "[dos]" -#: ../fileio.c:3795 msgid "[dos format]" msgstr "[formid dos]" -#: ../fileio.c:3801 msgid "[mac]" msgstr "[mac]" -#: ../fileio.c:3801 msgid "[mac format]" msgstr "[formid mac]" -#: ../fileio.c:3807 msgid "[unix]" msgstr "[unix]" -#: ../fileio.c:3807 msgid "[unix format]" msgstr "[formid unix]" -#: ../fileio.c:3831 msgid "1 line, " msgstr "1 lne, " -#: ../fileio.c:3833 #, c-format -msgid "% lines, " -msgstr "% lne, " +msgid "%ld lines, " +msgstr "%ld lne, " -#: ../fileio.c:3836 msgid "1 character" msgstr "1 carachtar" -#: ../fileio.c:3838 #, c-format -msgid "% characters" -msgstr "% carachtar" +msgid "%lld characters" +msgstr "%lld carachtar" -#: ../fileio.c:3849 msgid "[noeol]" msgstr "[ganEOL]" -#: ../fileio.c:3849 msgid "[Incomplete last line]" msgstr "[Is neamhiomln an lne 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: Athraodh an comhad ladh !!!" -#: ../fileio.c:3867 msgid "Do you really want to write to it" msgstr "An bhfuil t cinnte gur mhaith leat a scrobh" -#: ../fileio.c:4648 #, c-format msgid "E208: Error writing to \"%s\"" msgstr "E208: Earrid agus \"%s\" scrobh" -#: ../fileio.c:4655 #, c-format msgid "E209: Error closing \"%s\"" msgstr "E209: Earrid agus \"%s\" dhnadh" -#: ../fileio.c:4657 #, c-format msgid "E210: Error reading \"%s\"" msgstr "E210: Earrid agus \"%s\" lamh" -#: ../fileio.c:4883 msgid "E246: FileChangedShell autocommand deleted buffer" msgstr "E246: Scrios uathord FileChangedShell an maoln" -#: ../fileio.c:4894 #, c-format msgid "E211: File \"%s\" no longer available" msgstr "E211: Nl comhad \"%s\" ar fil 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: Athraodh comhad \"%s\" agus athraodh an maoln i Vim fosta" -#: ../fileio.c:4907 msgid "See \":help W12\" for more info." msgstr "Bain triail as \":help W12\" chun tuilleadh eolais a fhil." -#: ../fileio.c:4910 #, c-format msgid "W11: Warning: File \"%s\" has changed since editing started" msgstr "W11: Rabhadh: Athraodh comhad \"%s\" tosaodh a chur in eagar" -#: ../fileio.c:4911 msgid "See \":help W11\" for more info." msgstr "Bain triail as \":help W11\" chun tuilleadh eolais a fhil." -#: ../fileio.c:4914 #, c-format msgid "W16: Warning: Mode of file \"%s\" has changed since editing started" msgstr "" "W16: Rabhadh: Athraodh md an chomhaid \"%s\" tosaodh a chur in eagar" -#: ../fileio.c:4915 msgid "See \":help W16\" for more info." msgstr "Bain triail as \":help W16\" chun tuilleadh eolais a fhil." -#: ../fileio.c:4927 #, c-format msgid "W13: Warning: File \"%s\" has been created after editing started" msgstr "W13: Rabhadh: Cruthaodh comhad \"%s\" tosaodh 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 fidir \"%s\" a ullmh le haghaidh athluchtaithe" -#: ../fileio.c:5078 #, c-format msgid "E321: Could not reload \"%s\"" msgstr "E321: N fidir \"%s\" a athlucht" -#: ../fileio.c:5601 msgid "--Deleted--" msgstr "--Scriosta--" -#: ../fileio.c:5732 #, c-format msgid "auto-removing autocommand: %s " msgstr "uathord bhaint go huathoibroch: %s " #. the group doesn't exist -#: ../fileio.c:5772 #, c-format msgid "E367: No such group: \"%s\"" msgstr "E367: Nl a leithid de ghrpa: \"%s\"" -#: ../fileio.c:5897 +msgid "E936: Cannot delete the current group" +msgstr "E936: N fidir an grpa reatha a scriosadh" + +msgid "W19: Deleting augroup that is still in use" +msgstr "W19: Iarracht ar augroup at fs in sid 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: Nl a leithid de theagmhas: %s" -#: ../fileio.c:5907 #, c-format msgid "E216: No such group or event: %s" msgstr "E216: Nl a leithid de ghrpa 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: : invalid buffer number " msgstr "E680: : uimhir neamhbhail mhaolin " -#: ../fileio.c:6370 msgid "E217: Can't execute autocommands for ALL events" msgstr "E217: N fidir uathorduithe a rith i gcomhair teagmhas UILE" -#: ../fileio.c:6393 msgid "No matching autocommands" msgstr "Nl aon uathord comhoirinaithe" -#: ../fileio.c:6831 msgid "E218: autocommand nesting too deep" msgstr "E218: uathord neadaithe rdhomhain" -#: ../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: Nor aimsodh aon fhilleadh" -#: ../fold.c:544 msgid "E350: Cannot create fold with current 'foldmethod'" msgstr "E350: N fidir filleadh a chruth leis an 'foldmethod' reatha" -#: ../fold.c:546 msgid "E351: Cannot delete fold with current 'foldmethod'" msgstr "E351: N fidir filleadh a scriosadh leis an 'foldmethod' reatha" -#: ../fold.c:1784 #, c-format -msgid "+--%3ld lines folded " -msgstr "+--%3ld lne fillte " +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld lne fillte " +msgstr[1] "+--%3ld lne fillte " +msgstr[2] "+--%3ld lne fillte " +msgstr[3] "+--%3ld lne fillte " +msgstr[4] "+--%3ld lne fillte " -#. buffer has already been read -#: ../getchar.c:273 msgid "E222: Add to read buffer" msgstr "E222: Cuir leis an maoln lite" -#: ../getchar.c:2040 msgid "E223: recursive mapping" msgstr "E223: mapil athchrsach" -#: ../getchar.c:2849 #, c-format msgid "E224: global abbreviation already exists for %s" msgstr "E224: t giorrchn comhchoiteann ann cheana le haghaidh %s" -#: ../getchar.c:2852 #, c-format msgid "E225: global mapping already exists for %s" msgstr "E225: t mapil chomhchoiteann ann cheana le haghaidh %s" -#: ../getchar.c:2952 #, c-format msgid "E226: abbreviation already exists for %s" msgstr "E226: t giorrchn ann cheana le haghaidh %s" -#: ../getchar.c:2955 #, c-format msgid "E227: mapping already exists for %s" msgstr "E227: t mapil ann cheana le haghaidh %s" -#: ../getchar.c:3008 msgid "No abbreviation found" msgstr "Nor aimsodh aon ghiorrchn" -#: ../getchar.c:3010 msgid "No mapping found" msgstr "Nor aimsodh aon mhapil" -#: ../getchar.c:3974 msgid "E228: makemap: Illegal mode" msgstr "E228: makemap: Md 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 maoln folamh--" +msgid "E851: Failed to create a new process for the GUI" +msgstr "E851: Norbh fhidir priseas nua a chruth don GUI" -#. -#. * The error messages that can be shared are included here. -#. * Excluded are errors that are only used once and debugging messages. -#. -#: ../globals.h:996 -msgid "E470: Command aborted" -msgstr "E470: Ord tobscortha" +msgid "E852: The child process failed to start the GUI" +msgstr "E852: Theip ar an macphriseas an GUI a thos" -#: ../globals.h:997 -msgid "E471: Argument required" -msgstr "E471: T g le hargint" +msgid "E229: Cannot start the GUI" +msgstr "E229: N fidir an GUI a chur ag obair" -#: ../globals.h:998 -msgid "E10: \\ should be followed by /, ? or &" -msgstr "E10: Ba chir /, ? n & a chur i ndiaidh \\" +#, c-format +msgid "E230: Cannot read from \"%s\"" +msgstr "E230: N fidir lamh \"%s\"" -#: ../globals.h:1000 -msgid "E11: Invalid in command-line window; executes, CTRL-C quits" +msgid "E665: Cannot start GUI, no valid font found" msgstr "" -"E11: Neamhbhail i bhfuinneog lne na n-orduithe; =rith, CTRL-C=scoir" +"E665: N fidir an GUI a chur ag obair, nl aon chlfhoireann bhail ann" -#: ../globals.h:1002 -msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search" -msgstr "" -"E12: N cheadatear ord exrc/vimrc sa chomhadlann reatha n chuardach " -"clibe" +msgid "E231: 'guifontwide' invalid" +msgstr "E231: 'guifontwide' neamhbhail" -#: ../globals.h:1003 -msgid "E171: Missing :endif" -msgstr "E171: :endif ar iarraidh" +msgid "E599: Value of 'imactivatekey' is invalid" +msgstr "E599: Luach neamhbhail ar 'imactivatekey'" -#: ../globals.h:1004 -msgid "E600: Missing :endtry" -msgstr "E600: :endtry ar iarraidh" +#, c-format +msgid "E254: Cannot allocate color %s" +msgstr "E254: N fidir dath %s a dhileadh" -#: ../globals.h:1005 -msgid "E170: Missing :endwhile" -msgstr "E170: :endwhile ar iarraidh" +msgid "No match at cursor, finding next" +msgstr "Nl a leithid ag an chrsir, ag cuardach ar an chad cheann eile" -#: ../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" - -#: ../globals.h:1009 -msgid "E13: File exists (add ! to override)" -msgstr "E13: T comhad ann cheana (cuir ! leis an ord chun forscrobh)" - -#: ../globals.h:1010 -msgid "E472: Command failed" -msgstr "E472: Theip ar ord" - -#: ../globals.h:1011 -msgid "E473: Internal error" -msgstr "E473: Earrid inmhenach" +msgid " " +msgstr " " -#: ../globals.h:1012 -msgid "Interrupted" -msgstr "Idirbhriste" - -#: ../globals.h:1013 -msgid "E14: Invalid address" -msgstr "E14: Drochsheoladh" - -#: ../globals.h:1014 -msgid "E474: Invalid argument" -msgstr "E474: Argint neamhbhail" - -#: ../globals.h:1015 #, c-format -msgid "E475: Invalid argument: %s" -msgstr "E475: Argint neamhbhail: %s" +msgid "E616: vim_SelFile: can't get font %s" +msgstr "E616: vim_SelFile: nl aon fhil ar an chlfhoireann %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 fidir 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: nl an chomhadlann reatha ar fil" -#: ../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: Mid 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 "" +"Giuirlid Scrollbharra: N fidir cimseata an mhapa picteiln a fhil." -#: ../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 lne-uimhir neamhbhail ag an mharc" - -#: ../globals.h:1027 -msgid "E20: Mark not set" -msgstr "E20: Marc gan socr" +msgid "Vim dialog" +msgstr "Dialg Vim" -#: ../globals.h:1029 -msgid "E21: Cannot make changes, 'modifiable' is off" +msgid "E232: Cannot create BalloonEval with both message and callback" msgstr "" -"E21: N fidir athruithe a chur i bhfeidhm, nl an bhratach 'modifiable' " -"socraithe" - -#: ../globals.h:1030 -msgid "E22: Scripts nested too deep" -msgstr "E22: scripteanna neadaithe rdhomhain" +"E232: N fidir BalloonEval a chruth le teachtaireacht agus aisghlaoch araon" -#: ../globals.h:1031 -msgid "E23: No alternate file" -msgstr "E23: Nl aon chomhad malartach" +msgid "_Cancel" +msgstr "_Cealaigh" -#: ../globals.h:1032 -msgid "E24: No such abbreviation" -msgstr "E24: Nl a leithid de ghiorrchn ann" +msgid "_Save" +msgstr "_Sbhil" -#: ../globals.h:1033 -msgid "E477: No ! allowed" -msgstr "E477: N cheadatear !" +msgid "_Open" +msgstr "_Oscail" -#: ../globals.h:1035 -msgid "E25: Nvim does not have a built-in GUI" -msgstr "E25: N fidir an GUI a sid: Nor cumasaodh ag am tiomsaithe" +msgid "_OK" +msgstr "_OK" -#: ../globals.h:1036 -#, c-format -msgid "E28: No such highlight group name: %s" -msgstr "E28: Nl a leithid d'ainm grpa aibhsithe: %s" +msgid "" +"&Yes\n" +"&No\n" +"&Cancel" +msgstr "" +"&T\n" +"&Nl\n" +"&Cealaigh" -#: ../globals.h:1037 -msgid "E29: No inserted text yet" -msgstr "E29: Nl aon tacs ionsite go dt seo" +msgid "Yes" +msgstr "T" -#: ../globals.h:1038 -msgid "E30: No previous command line" -msgstr "E30: Nl aon lne na n-orduithe roimhe seo" +msgid "No" +msgstr "Nl" -#: ../globals.h:1039 -msgid "E31: No such mapping" -msgstr "E31: Nl a leithid de mhapil" +msgid "Input _Methods" +msgstr "_Modhanna ionchuir" -#: ../globals.h:1040 -msgid "E479: No match" -msgstr "E479: Nl aon rud comhoirinach ann" +# in OLT --KPS +msgid "VIM - Search and Replace..." +msgstr "VIM - Cuardaigh agus Athchuir..." -#: ../globals.h:1041 -#, c-format -msgid "E480: No match: %s" -msgstr "E480: Nl aon rud comhoirinach ann: %s" +msgid "VIM - Search..." +msgstr "VIM - Cuardaigh..." -#: ../globals.h:1042 -msgid "E32: No file name" -msgstr "E32: Nl aon ainm comhaid" +msgid "Find what:" +msgstr "Aimsigh:" -#: ../globals.h:1044 -msgid "E33: No previous substitute regular expression" -msgstr "E33: Nl aon slonn ionadaochta roimhe seo" +msgid "Replace with:" +msgstr "Le cur in ionad:" -#: ../globals.h:1045 -msgid "E34: No previous command" -msgstr "E34: Nl aon ord roimhe seo" +#. whole word only button +msgid "Match whole word only" +msgstr "Focal iomln amhin" -#: ../globals.h:1046 -msgid "E35: No previous regular expression" -msgstr "E35: Nl aon slonn ionadaochta roimhe seo" +#. match case button +msgid "Match case" +msgstr "Meaitseil an cs" -#: ../globals.h:1047 -msgid "E481: No range allowed" -msgstr "E481: N cheadatear raon" +msgid "Direction" +msgstr "Treo" -#: ../globals.h:1048 -msgid "E36: Not enough room" -msgstr "E36: Nl sl a dhthain ann" +#. 'Up' and 'Down' buttons +msgid "Up" +msgstr "Suas" -#: ../globals.h:1049 -#, c-format -msgid "E482: Can't create file %s" -msgstr "E482: N fidir comhad %s a chruth" +msgid "Down" +msgstr "Sos" -#: ../globals.h:1050 -msgid "E483: Can't get temp file name" -msgstr "E483: Nl aon fhil ar ainm comhaid sealadach" +msgid "Find Next" +msgstr "An Chad Cheann Eile" -#: ../globals.h:1051 -#, c-format -msgid "E484: Can't open file %s" -msgstr "E484: N fidir comhad %s a oscailt" +msgid "Replace" +msgstr "Ionadaigh" -#: ../globals.h:1052 -#, c-format -msgid "E485: Can't read file %s" -msgstr "E485: N fidir comhad %s a lamh" +msgid "Replace All" +msgstr "Ionadaigh Uile" -#: ../globals.h:1054 -msgid "E37: No write since last change (add ! to override)" -msgstr "E37: T athruithe ann gan sbhil (cuir ! leis an ord chun sr)" +msgid "_Close" +msgstr "_Dn" -#: ../globals.h:1055 -#, fuzzy -msgid "E37: No write since last change" -msgstr "[Athraithe agus nach sbhilte shin]\n" +msgid "Vim: Received \"die\" request from session manager\n" +msgstr "Vim: Fuarthas iarratas \"die\" bhainisteoir an tseisiin\n" -#: ../globals.h:1056 -msgid "E38: Null argument" -msgstr "E38: Argint nialasach" +msgid "Close tab" +msgstr "Dn cluaisn" -#: ../globals.h:1057 -msgid "E39: Number expected" -msgstr "E39: Ag sil le huimhir" +msgid "New tab" +msgstr "Cluaisn nua" -#: ../globals.h:1058 -#, c-format -msgid "E40: Can't open errorfile %s" -msgstr "E40: N fidir an comhad earride %s a oscailt" +msgid "Open Tab..." +msgstr "Oscail Cluaisn..." -#: ../globals.h:1059 -msgid "E41: Out of memory!" -msgstr "E41: Cuimhne dithe!" +msgid "Vim: Main window unexpectedly destroyed\n" +msgstr "Vim: Milleadh an promhfhuinneog gan choinne\n" -#: ../globals.h:1060 -msgid "Pattern not found" -msgstr "Patrn gan aimsi" +msgid "&Filter" +msgstr "&Scagaire" -#: ../globals.h:1061 -#, c-format -msgid "E486: Pattern not found: %s" -msgstr "E486: Patrn gan aimsi: %s" +msgid "&Cancel" +msgstr "&Cealaigh" -#: ../globals.h:1062 -msgid "E487: Argument must be positive" -msgstr "E487: N folir argint dheimhneach" +msgid "Directories" +msgstr "Comhadlanna" -#: ../globals.h:1064 -msgid "E459: Cannot go back to previous directory" -msgstr "E459: N fidir a fhilleadh ar an chomhadlann roimhe seo" +msgid "Filter" +msgstr "Scagaire" -#: ../globals.h:1066 -msgid "E42: No Errors" -msgstr "E42: Nl Aon Earrid Ann" +msgid "&Help" +msgstr "&Cabhair" -#: ../globals.h:1067 -msgid "E776: No location list" -msgstr "E776: Gan liosta suomh" +msgid "Files" +msgstr "Comhaid" -#: ../globals.h:1068 -msgid "E43: Damaged match string" -msgstr "E43: Teaghrn cuardaigh loite" +msgid "&OK" +msgstr "&OK" -#: ../globals.h:1069 -msgid "E44: Corrupted regexp program" -msgstr "E44: Clr na sloinn ionadaochta 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 sr)" +msgid "Find &Next" +msgstr "An Chad Chea&nn Eile" -#: ../globals.h:1073 -#, c-format -msgid "E46: Cannot change read-only variable \"%s\"" -msgstr "E46: N fidir athrg inlite amhin \"%s\" a athr" +msgid "&Replace" +msgstr "&Ionadaigh" -#: ../globals.h:1075 -#, c-format -msgid "E794: Cannot set variable in the sandbox: \"%s\"" -msgstr "E794: N fidir athrg a shocr sa bhosca gainimh: \"%s\"" +msgid "Replace &All" +msgstr "Ionadaigh &Uile" -#: ../globals.h:1076 -msgid "E47: Error while reading errorfile" -msgstr "E47: Earrid agus comhad earride lamh" +msgid "&Undo" +msgstr "&Cealaigh" -#: ../globals.h:1078 -msgid "E48: Not allowed in sandbox" -msgstr "E48: N cheadatear seo i mbosca gainimh" +msgid "Open tab..." +msgstr "Oscail cluaisn..." -#: ../globals.h:1080 -msgid "E523: Not allowed here" -msgstr "E523: N cheadatear anseo" +msgid "Find string (use '\\\\' to find a '\\')" +msgstr "Aimsigh teaghrn (bain sid as '\\\\' chun '\\' a aimsi)" -#: ../globals.h:1082 -msgid "E359: Screen mode setting not supported" -msgstr "E359: N fidir an md scilein a shocr" +msgid "Find & Replace (use '\\\\' to find a '\\')" +msgstr "Aimsigh & Athchuir (sid '\\\\' chun '\\' a aimsi)" -#: ../globals.h:1083 -msgid "E49: Invalid scroll size" -msgstr "E49: Mid 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 sid" -#: ../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: Norbh fhidir na sonra comhartha a lamh!" +#, c-format +msgid "E671: Cannot find window title \"%s\"" +msgstr "E671: N fidir teideal na fuinneoige \"%s\" a aimsi" -#: ../globals.h:1086 -msgid "E72: Close error on swap file" -msgstr "E72: Earrid agus comhad babhtla dhnadh" +#, c-format +msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." +msgstr "E243: Argint gan tacaocht: \"-%s\"; Bain sid 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 fidir fuinneog a oscailt isteach i bhfeidhmchlr MDI" -#: ../globals.h:1088 -msgid "E74: Command too complex" -msgstr "E74: Ord rchasta" +msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" +msgstr "" +"Vim E458: N fidir iontril dathmhapla a dhileadh, is fidir go mbeidh " +"dathanna mchearta ann" -#: ../globals.h:1089 -msgid "E75: Name too long" -msgstr "E75: Ainm rfhada" +#, c-format +msgid "E250: Fonts for the following charsets are missing in fontset %s:" +msgstr "" +"E250: Clnna 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 "Cl0: %s" -#: ../globals.h:1094 -msgid "E79: Cannot expand wildcards" -msgstr "E79: N fidir saorga a leathn" +#, c-format +msgid "Font1: %s" +msgstr "Cl1: %s" -#: ../globals.h:1096 -msgid "E591: 'winheight' cannot be smaller than 'winminheight'" -msgstr "E591: n cheadatear 'winheight' a bheith nos l n 'winminheight'" +#, c-format +msgid "Font%ld width is not twice that of font0" +msgstr "Nl Cl%ld nos leithne faoi dh n cl0" -#: ../globals.h:1098 -msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'" -msgstr "E592: n cheadatear 'winwidth' a bheith nos l n 'winminwidth'" +#, c-format +msgid "Font0 width: %ld" +msgstr "Leithead Cl0: %ld" -#: ../globals.h:1099 -msgid "E80: Error while writing" -msgstr "E80: Earrid agus scrobh" +#, c-format +msgid "Font1 width: %ld" +msgstr "Leithead cl1: %ld" -#: ../globals.h:1100 -msgid "Zero count" -msgstr "Nialas" +msgid "Invalid font specification" +msgstr "Sonr neamhbhail cl" -#: ../globals.h:1101 -msgid "E81: Using not in a script context" -msgstr "E81: sid nach i gcomhthacs scripte" +msgid "&Dismiss" +msgstr "&Ruaig" -#: ../globals.h:1102 -#, c-format -msgid "E685: Internal error: %s" -msgstr "E685: Earrid inmhenach: %s" +msgid "no specific match" +msgstr "nl a leithid ann" -#: ../globals.h:1104 -msgid "E363: pattern uses more memory than 'maxmempattern'" -msgstr "E363: sideann an patrn nos m cuimhne n 'maxmempattern'" +msgid "Vim - Font Selector" +msgstr "Vim - Roghn Cl" -#: ../globals.h:1105 -msgid "E749: empty buffer" -msgstr "E749: maoln folamh" +msgid "Name:" +msgstr "Ainm:" -#: ../globals.h:1108 -msgid "E682: Invalid search pattern or delimiter" -msgstr "E682: Patrn n teormharcir neamhbhail cuardaigh" +#. create toggle button +msgid "Show size in Points" +msgstr "Taispein mid (Point)" -#: ../globals.h:1109 -msgid "E139: File is loaded in another buffer" -msgstr "E139: T an comhad luchtaithe i maoln eile" +msgid "Encoding:" +msgstr "Ionchd:" -#: ../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 "Stl:" -#: ../globals.h:1114 -msgid "search hit TOP, continuing at BOTTOM" -msgstr "Buaileadh an BARR le linn an chuardaigh, ag leanint ag an CHROCH" +msgid "Size:" +msgstr "Mid:" -#: ../globals.h:1115 -msgid "search hit BOTTOM, continuing at TOP" -msgstr "Buaileadh an BUN le linn an chuardaigh, ag leanint ag an BHARR" +msgid "E256: Hangul automata ERROR" +msgstr "E256: EARRID leis na huathoibrein Hangul" -#: ../hardcopy.c:240 msgid "E550: Missing colon" msgstr "E550: Idirstad ar iarraidh" -#: ../hardcopy.c:252 msgid "E551: Illegal component" msgstr "E551: Comhphirt neamhcheadaithe" -#: ../hardcopy.c:259 msgid "E552: digit expected" msgstr "E552: ag sil le digit" -#: ../hardcopy.c:473 #, c-format msgid "Page %d" msgstr "Leathanach %d" -#: ../hardcopy.c:597 msgid "No text to be printed" msgstr "Nl aon tacs le priontil" -#: ../hardcopy.c:668 #, c-format msgid "Printing page %d (%d%%)" msgstr "Leathanach %d (%d%%) phriontil" -#: ../hardcopy.c:680 #, c-format msgid " Copy %d of %d" msgstr " Cip %d de %d" -#: ../hardcopy.c:733 #, c-format msgid "Printed: %s" msgstr "Priontilte: %s" -#: ../hardcopy.c:740 msgid "Printing aborted" msgstr "Priontil tobscortha" -#: ../hardcopy.c:1365 msgid "E455: Error writing to PostScript output file" msgstr "E455: Earrid le linn scrobh chuig aschomhad PostScript" -#: ../hardcopy.c:1747 #, c-format msgid "E624: Can't open file \"%s\"" msgstr "E624: N fidir 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 fidir comhad acmhainne PostScript \"%s\" a lamh" -#: ../hardcopy.c:1772 #, c-format msgid "E618: file \"%s\" is not a PostScript resource file" msgstr "E618: Nl 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 mcheart ar an gcomhad acmhainne \"%s\"" -#: ../hardcopy.c:2225 msgid "E673: Incompatible multi-byte encoding and character set." msgstr "E673: Ionchd agus tacar carachtar ilbhirt neamh-chomhoirinach." -#: ../hardcopy.c:2238 msgid "E674: printmbcharset cannot be empty with multi-byte encoding." msgstr "" "E674: n cheadatear printmbcharset a bheith folamh le hionchd ilbhirt." -#: ../hardcopy.c:2254 msgid "E675: No default font specified for multi-byte printing." msgstr "E675: Nor ramhshocraodh cl le haghaidh priontla ilbhirt." -#: ../hardcopy.c:2426 msgid "E324: Can't open PostScript output file" msgstr "E324: N fidir aschomhad PostScript a oscailt" -#: ../hardcopy.c:2458 #, c-format msgid "E456: Can't open file \"%s\"" msgstr "E456: N fidir 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 fidir an t-ionchd priontla \"%s\" a thiont" -#: ../hardcopy.c:2877 msgid "Sending to printer..." msgstr " sheoladh chuig an phrintir..." -#: ../hardcopy.c:2881 msgid "E365: Failed to print PostScript file" msgstr "E365: Theip ar phriontil comhaid PostScript" -#: ../hardcopy.c:2883 msgid "Print job sent." msgstr "Seoladh jab priontla." -#: ../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 phatrn" -#: ../if_cscope.c:89 msgid "Show this message" msgstr "Taispein an teachtaireacht seo" -#: ../if_cscope.c:91 msgid "Kill a connection" msgstr "Maraigh nasc" -#: ../if_cscope.c:93 msgid "Reinit all connections" msgstr "Atsaigh gach nasc" -#: ../if_cscope.c:95 msgid "Show connections" msgstr "Taispein naisc" -#: ../if_cscope.c:101 #, c-format msgid "E560: Usage: cs[cope] %s" msgstr "E560: sid: cs[cope] %s" -#: ../if_cscope.c:225 msgid "This cscope command does not support splitting the window.\n" msgstr "N fidir fuinneoga a scoilteadh leis an ord seo `cscope'.\n" -#: ../if_cscope.c:266 msgid "E562: Usage: cstag " msgstr "E562: sid: cstag " -#: ../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: earrid stat(%s): %d" -#: ../if_cscope.c:551 +msgid "E563: stat error" +msgstr "E563: earrid stat" + #, c-format msgid "E564: %s is not a directory or a valid cscope database" msgstr "E564: Nl %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 %" -msgstr "E262: earrid agus an nasc cscope % lamh" +msgid "E262: error reading cscope connection %ld" +msgstr "E262: earrid agus an nasc cscope %ld lamh" -#: ../if_cscope.c:711 msgid "E561: unknown cscope search type" msgstr "E561: cinel anaithnid cuardaigh cscope" -#: ../if_cscope.c:752 ../if_cscope.c:789 msgid "E566: Could not create cscope pipes" msgstr "E566: Norbh fhidir popa cscope a chruth" -#: ../if_cscope.c:767 msgid "E622: Could not fork for cscope" msgstr "E622: Norbh fhidir forc a dhanamh 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: Norbh fhidir priseas cscope a sceitheadh" -#: ../if_cscope.c:932 msgid "E567: no cscope connections" msgstr "E567: nl 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: nor aimsodh aon rud comhoirinach 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 (sid: %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 ritis sannachin 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 patrn egrep seo\n" @@ -3248,33 +2584,34 @@ msgstr "" " g: Aimsigh an sainmhni 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 teaghrn tacs seo\n" + +#, c-format +msgid "E625: cannot open cscope database: %s" +msgstr "E625: n fidir bunachar sonra cscope a oscailt: %s" + +msgid "E626: cannot get cscope database information" +msgstr "E626: n fidir eolas a fhil faoin bhunachar sonra cscope" -#: ../if_cscope.c:1226 msgid "E568: duplicate cscope database not added" msgstr "E568: nor cuireadh bunachar sonra dblach 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 "Dnadh nasc cscope %s" #. should not reach here -#: ../if_cscope.c:1486 msgid "E570: fatal error in cs_manage_matches" msgstr "E570: earrid 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" " # lne" -#: ../if_cscope.c:1713 msgid "filename / context / line\n" msgstr "ainm comhaid / comhthacs / lne\n" -#: ../if_cscope.c:1809 #, c-format msgid "E609: Cscope error: %s" msgstr "E609: Earrid cscope: %s" -#: ../if_cscope.c:2053 msgid "All cscope databases reset" msgstr "Athshocraodh gach bunachar sonra cscope" -#: ../if_cscope.c:2123 msgid "no cscope connections\n" msgstr "nl 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 "Unknown option argument" -msgstr "Argint anaithnid rogha" - -#: ../main.c:146 -msgid "Too many edit arguments" -msgstr "An iomarca argint eagarthireachta" +msgid "Lua library cannot be loaded." +msgstr "N fidir an leabharlann Lua a lucht." -#: ../main.c:148 -msgid "Argument missing after" -msgstr "Argint ar iarraidh i ndiaidh" +msgid "cannot save undo information" +msgstr "n fidir eolas cealaithe a shbhil" -#: ../main.c:150 -msgid "Garbage after option argument" -msgstr "Dramhal i ndiaidh arginte rogha" +msgid "" +"E815: Sorry, this command is disabled, the MzScheme libraries could not be " +"loaded." +msgstr "" +"E815: T brn orm, bh an t-ord seo dchumasaithe, norbh fhidir " +"leabharlanna MzScheme a lucht." -#: ../main.c:152 -msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" +msgid "" +"E895: Sorry, this command is disabled, the MzScheme's racket/base module " +"could not be loaded." msgstr "" -"An iomarca argint den chinel \"+ord\", \"-c ord\" n \"--cmd ord\"" +"E895: r leithscal, t an t-ord seo dchumasaithe; norbh fhidir " +"modl racket/base MzScheme a lucht." -#: ../main.c:154 -msgid "Invalid argument for" -msgstr "Argint neamhbhail do" +msgid "invalid expression" +msgstr "slonn neamhbhail" -#: ../main.c:294 -#, c-format -msgid "%d files to edit\n" -msgstr "%d comhad le heagr\n" +msgid "expressions disabled at compile time" +msgstr "dchumasaodh sloinn ag am an tiomsaithe" -#: ../main.c:1342 -msgid "Attempt to open script file again: \"" -msgstr "Dan iarracht ar oscailt na scripte ars: \"" +msgid "hidden option" +msgstr "rogha fholaithe" -#: ../main.c:1350 -msgid "Cannot open for reading: \"" -msgstr "N fidir a oscailt chun lamh: \"" +msgid "unknown option" +msgstr "rogha anaithnid" -#: ../main.c:1393 -msgid "Cannot open for script output: \"" -msgstr "N fidir a oscailt le haghaidh an aschuir scripte: \"" +msgid "window index is out of range" +msgstr "innacs fuinneoige as raon" -#: ../main.c:1622 -msgid "Vim: Warning: Output is not to a terminal\n" -msgstr "Vim: Rabhadh: Nl an t-aschur ag dul chuig teirminal\n" +msgid "couldn't open buffer" +msgstr "n fidir maoln a oscailt" -#: ../main.c:1624 -msgid "Vim: Warning: Input is not from a terminal\n" -msgstr "Vim: Rabhadh: Nl an t-ionchur ag teacht theirminal\n" +msgid "cannot delete line" +msgstr "n fidir an lne a scriosadh" -#. just in case.. -#: ../main.c:1891 -msgid "pre-vimrc command line" -msgstr "lne na n-orduithe pre-vimrc" +msgid "cannot replace line" +msgstr "n fidir an lne a athchur" + +msgid "cannot insert line" +msgstr "n fidir lne a ions" + +msgid "string cannot contain newlines" +msgstr "n cheadatear carachtair lne nua sa teaghrn" + +msgid "error converting Scheme values to Vim" +msgstr "earrid agus luach Scheme thiont go Vim" + +msgid "Vim error: ~a" +msgstr "earrid Vim: ~a" + +msgid "Vim error" +msgstr "earrid Vim" + +msgid "buffer is invalid" +msgstr "maoln neamhbhail" + +msgid "window is invalid" +msgstr "fuinneog neamhbhail" + +msgid "linenr out of range" +msgstr "lne-uimhir as raon" + +msgid "not allowed in the Vim sandbox" +msgstr "n cheadatear seo i mbosca gainimh Vim" + +msgid "E836: This Vim cannot execute :python after using :py3" +msgstr "" +"E836: N fidir leis an leagan seo de Vim :python a rith tar is :py3 a sid" + +msgid "" +"E263: Sorry, this command is disabled, the Python library could not be " +"loaded." +msgstr "" +"E263: T brn orm, nl an t-ord seo le fil, norbh fhidir an leabharlann " +"Python a lucht." + +msgid "" +"E887: Sorry, this command is disabled, the Python's site module could not be " +"loaded." +msgstr "" +"E887: r leithscal, nl an t-ord seo le fil, norbh fhidir an modl " +"Python a lucht." + +msgid "E659: Cannot invoke Python recursively" +msgstr "E659: N fidir Python a rith go hathchrsach" + +msgid "E837: This Vim cannot execute :py3 after using :python" +msgstr "" +"E837: N fidir leis an leagan seo de Vim :py3 a rith tar is :python a sid" + +msgid "E265: $_ must be an instance of String" +msgstr "E265: caithfidh $_ a bheith cinel Teaghrin" + +msgid "" +"E266: Sorry, this command is disabled, the Ruby library could not be loaded." +msgstr "" +"E266: T brn orm, nl an t-ord seo le fil, norbh fhidir 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 chlsal tarrthla" + +msgid "E272: unhandled exception" +msgstr "E272: eisceacht gan limhseil" + +#, c-format +msgid "E273: unknown longjmp status %d" +msgstr "E273: stdas anaithnid longjmp %d" + +msgid "invalid buffer number" +msgstr "uimhir neamhbhail mhaolin" + +msgid "not implemented yet" +msgstr "nl ar fil" + +#. ??? +msgid "cannot set line(s)" +msgstr "n fidir ln(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 "lne %d coln %d" + +msgid "cannot insert/append line" +msgstr "n fidir lne a ions/iarcheangal" + +msgid "line number out of range" +msgstr "lne-uimhir as raon" + +msgid "unknown flag: " +msgstr "bratach anaithnid: " + +msgid "unknown vimOption" +msgstr "vimOption anaithnid" + +msgid "keyboard interrupt" +msgstr "idirbhriseadh marchlir" + +msgid "vim error" +msgstr "earrid vim" + +msgid "cannot create buffer/window command: object is being deleted" +msgstr "n fidir ord maolin/fuinneoige a chruth: rad scriosadh" + +msgid "" +"cannot register callback command: buffer/window is already being deleted" +msgstr "n fidir ord aisghlaoch a chlr: maoln/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: EARRID MHARFACH TCL: liosta truaillithe tagartha!? Seol tuairisc " +"fhabht chuig le do thoil" + +msgid "cannot register callback command: buffer/window reference not found" +msgstr "" +"n fidir ord aisghlaoch a chlr: tagairt mhaoln/fhuinneoige gan aimsi" + +msgid "" +"E571: Sorry, this command is disabled: the Tcl library could not be loaded." +msgstr "" +"E571: T brn orm, nl an t-ord seo le fil: norbh fhidir an leabharlann " +"Tcl a lucht." + +#, c-format +msgid "E572: exit code %d" +msgstr "E572: cd scortha %d" + +msgid "cannot get line" +msgstr "n fidir an lne a fhil" + +msgid "Unable to register a command server name" +msgstr "N fidir ainm fhreastala ordaithe a chlr" + +msgid "E248: Failed to send command to the destination program" +msgstr "E248: Theip ar sheoladh ord chuig an sprioc-chlr" + +#, c-format +msgid "E573: Invalid server id used: %s" +msgstr "E573: Aitheantas neamhbhail freastala in sid: %s" + +msgid "E251: VIM instance registry property is badly formed. Deleted!" +msgstr "E251: Air mchumtha sa chlrlann isc VIM. Scriosta!" + +#, c-format +msgid "E696: Missing comma in List: %s" +msgstr "E696: Camg 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 "Argint anaithnid rogha" + +msgid "Too many edit arguments" +msgstr "An iomarca argint eagarthireachta" + +msgid "Argument missing after" +msgstr "Argint ar iarraidh i ndiaidh" + +msgid "Garbage after option argument" +msgstr "Dramhal i ndiaidh arginte rogha" + +msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" +msgstr "" +"An iomarca argint den chinel \"+ord\", \"-c ord\" n \"--cmd ord\"" + +msgid "Invalid argument for" +msgstr "Argint neamhbhail do" + +#, c-format +msgid "%d files to edit\n" +msgstr "%d comhad le heagr\n" + +msgid "netbeans is not supported with this GUI\n" +msgstr "N thacatear le netbeans sa GUI seo\n" + +msgid "'-nb' cannot be used: not enabled at compile time\n" +msgstr "N fidir '-nb' a sid: nor cumasaodh ag am tiomsaithe\n" + +msgid "This Vim was not compiled with the diff feature." +msgstr "Nor tiomsaodh an leagan Vim seo le `diff' ar fil." + +msgid "Attempt to open script file again: \"" +msgstr "Dan iarracht ar oscailt na scripte ars: \"" + +msgid "Cannot open for reading: \"" +msgstr "N fidir a oscailt chun lamh: \"" + +msgid "Cannot open for script output: \"" +msgstr "N fidir a oscailt le haghaidh an aschuir scripte: \"" + +msgid "Vim: Error: Failure to start gvim from NetBeans\n" +msgstr "Vim: Earrid: Theip ar thos gvim NetBeans\n" + +msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n" +msgstr "Vim: Earrid: N fidir an leagan seo de Vim a rith i dteirminal Cygwin\n" + +msgid "Vim: Warning: Output is not to a terminal\n" +msgstr "Vim: Rabhadh: Nl an t-aschur ag dul chuig teirminal\n" + +msgid "Vim: Warning: Input is not from a terminal\n" +msgstr "Vim: Rabhadh: Nl an t-ionchur ag teacht theirminal\n" + +#. just in case.. +msgid "pre-vimrc command line" +msgstr "lne na n-orduithe pre-vimrc" -#: ../main.c:1964 #, c-format msgid "E282: Cannot read from \"%s\"" msgstr "E282: N fidir lamh \"%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 "- scrobh tacs 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 chad earrid in eagar" -#: ../main.c:2187 msgid "" "\n" "\n" @@ -3397,11 +2942,9 @@ msgstr "" "\n" "sid:" -#: ../main.c:2189 msgid " vim [arguments] " msgstr " vim [argint] " -#: ../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 csogair , cuir '/' ag tosach na brata chun a chur sa chs " +"uachtair" + msgid "" "\n" "\n" @@ -3419,194 +2969,338 @@ msgstr "" "\n" "Argint:\n" -#: ../main.c:2197 msgid "--\t\t\tOnly file names after this" msgstr "--\t\t\tN cheadatear ach ainmneacha comhaid i ndiaidh seo" -#: ../main.c:2199 msgid "--literal\t\tDon't expand wildcards" msgstr "--literal\t\tN leathnaigh saorga" -#: ../main.c:2201 +msgid "-register\t\tRegister this gvim for OLE" +msgstr "-register\t\tClraigh an gvim seo le haghaidh OLE" + +msgid "-unregister\t\tUnregister gvim for OLE" +msgstr "-unregister\t\tDchlraigh an gvim seo le haghaidh OLE" + +msgid "-g\t\t\tRun using GUI (like \"gvim\")" +msgstr "-g\t\t\tRith agus sid an GUI (mar \"gvim\")" + +msgid "-f or --nofork\tForeground: Don't fork when starting GUI" +msgstr "-f n --nofork\tTulra: N dan forc agus an GUI thos" + msgid "-v\t\t\tVi mode (like \"vi\")" msgstr "-v\t\t\tMd Vi (mar \"vi\")" -#: ../main.c:2202 msgid "-e\t\t\tEx mode (like \"ex\")" msgstr "-e\t\t\tMd Ex (mar \"ex\")" -#: ../main.c:2203 msgid "-E\t\t\tImproved Ex mode" -msgstr "" +msgstr "-E\t\t\tMd Ex feabhsaithe" -#: ../main.c:2204 msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")" msgstr "-s\t\t\tMd ciin (baiscphrisela) (do \"ex\" amhin)" -#: ../main.c:2205 msgid "-d\t\t\tDiff mode (like \"vimdiff\")" msgstr "-d\t\t\tMd diff (mar \"vimdiff\")" -#: ../main.c:2206 msgid "-y\t\t\tEasy mode (like \"evim\", modeless)" msgstr "-y\t\t\tMd asca (mar \"evim\", gan mhid)" -#: ../main.c:2207 msgid "-R\t\t\tReadonly mode (like \"view\")" msgstr "-R\t\t\tMd inlite amhin (mar \"view\")" -#: ../main.c:2208 msgid "-Z\t\t\tRestricted mode (like \"rvim\")" msgstr "-Z\t\t\tMd srianta (mar \"rvim\")" -#: ../main.c:2209 msgid "-m\t\t\tModifications (writing files) not allowed" msgstr "-m\t\t\tN cheadatear athruithe (.i. scrobh na gcomhad)" -#: ../main.c:2210 msgid "-M\t\t\tModifications in text not allowed" msgstr "-M\t\t\tN cheadatear athruithe sa tacs" -#: ../main.c:2211 msgid "-b\t\t\tBinary mode" msgstr "-b\t\t\tMd dnrtha" -#: ../main.c:2212 msgid "-l\t\t\tLisp mode" msgstr "-l\t\t\tMd Lisp" -#: ../main.c:2213 msgid "-C\t\t\tCompatible with Vi: 'compatible'" msgstr "-C\t\t\tComhoirinach le Vi: 'compatible'" -#: ../main.c:2214 msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'" msgstr "-N\t\t\tN comhoirinaithe le Vi go hiomln: 'nocompatible'" -#: ../main.c:2215 msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]" msgstr "" "-V[N][fname]\t\tB foclach [leibhal N] [logil teachtaireachta i fname]" -#: ../main.c:2216 msgid "-D\t\t\tDebugging mode" msgstr "-D\t\t\tMd dfhabhtaithe" -#: ../main.c:2217 msgid "-n\t\t\tNo swap file, use memory only" msgstr "-n\t\t\tN hsid comhad babhtla .i. n hsid ach an chuimhne" -#: ../main.c:2218 msgid "-r\t\t\tList swap files and exit" msgstr "-r\t\t\tTaispein comhaid bhabhtla agus scoir" -#: ../main.c:2219 msgid "-r (with file name)\tRecover crashed session" msgstr "-r (le hainm comhaid)\tAthshlnaigh 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 hsid newcli chun fuinneog a oscailt" + +msgid "-dev \t\tUse for I/O" +msgstr "-dev \t\tBain sid as do I/A" + msgid "-A\t\t\tstart in Arabic mode" msgstr "-A\t\t\ttosaigh sa mhd Araibise" -#: ../main.c:2222 msgid "-H\t\t\tStart in Hebrew mode" msgstr "-H\t\t\tTosaigh sa mhd Eabhraise" -#: ../main.c:2223 msgid "-F\t\t\tStart in Farsi mode" msgstr "-F\t\t\tTosaigh sa mhd Pheirsise" -#: ../main.c:2224 msgid "-T \tSet terminal type to " msgstr "-T \tSocraigh cinel teirminal" -#: ../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 teirminal" + msgid "-u \t\tUse instead of any .vimrc" msgstr "-u \t\tsid in ionad aon .vimrc" -#: ../main.c:2226 +msgid "-U \t\tUse instead of any .gvimrc" +msgstr "-U \t\tBain sid as in ionad aon .gvimrc" + msgid "--noplugin\t\tDon't load plugin scripts" msgstr "--noplugin\t\tN luchtaigh breisein" -#: ../main.c:2227 msgid "-p[N]\t\tOpen N tab pages (default: one for each file)" -msgstr "-p[N]\t\tOscail N leathanach cluaisn (default: ceann do gach comhad)" +msgstr "-p[N]\t\tOscail N leathanach cluaisn (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 (ramhshocr: 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 chomhadchroch" -#: ../main.c:2231 msgid "+\t\tStart at line " msgstr "+\t\tTosaigh ar lne " -#: ../main.c:2232 msgid "--cmd \tExecute before loading any vimrc file" msgstr "--cmd \tRith roimh aon chomhad vimrc a lucht" -#: ../main.c:2233 msgid "-c \t\tExecute after loading the first file" msgstr "-c \t\tRith i ndiaidh lucht an chad chomhad" -#: ../main.c:2235 msgid "-S \t\tSource file after loading the first file" msgstr "" "-S \t\tLigh comhad i ndiaidh an chad chomhad lamh" -#: ../main.c:2236 msgid "-s \tRead Normal mode commands from file " msgstr "-s