diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.c | 1 | ||||
-rw-r--r-- | src/nvim/eval.h | 1 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 11 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 18 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 21 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 3 | ||||
-rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 15 | ||||
-rw-r--r-- | src/nvim/testdir/test_excmd.vim | 126 | ||||
-rw-r--r-- | src/nvim/testdir/test_fnameescape.vim | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_ga.vim | 9 | ||||
-rw-r--r-- | src/nvim/testdir/test_global.vim | 8 | ||||
-rw-r--r-- | src/nvim/testdir/test_move.vim | 5 | ||||
-rw-r--r-- | src/nvim/testdir/test_options.vim | 19 | ||||
-rw-r--r-- | src/nvim/testdir/test_sort.vim | 210 | ||||
-rw-r--r-- | src/nvim/testdir/test_substitute.vim | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_writefile.vim | 63 |
16 files changed, 501 insertions, 17 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 079c0dc3c0..d67db94339 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -228,6 +228,7 @@ static struct vimvar { VV(VV_EVENT, "event", VAR_DICT, VV_RO), VV(VV_ECHOSPACE, "echospace", VAR_NUMBER, VV_RO), VV(VV_ARGV, "argv", VAR_LIST, VV_RO), + VV(VV_COLLATE, "collate", VAR_STRING, VV_RO), VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO), // Neovim VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO), diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 8188502987..41120b3c78 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -157,6 +157,7 @@ typedef enum { VV_EVENT, VV_ECHOSPACE, VV_ARGV, + VV_COLLATE, VV_EXITING, // Neovim VV_STDERR, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 865abcc110..911b3c2c2f 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -9154,6 +9154,7 @@ static void f_sockconnect(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// struct storing information about current sort typedef struct { int item_compare_ic; + bool item_compare_lc; bool item_compare_numeric; bool item_compare_numbers; bool item_compare_float; @@ -9228,10 +9229,10 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero) p2 = ""; } if (!sortinfo->item_compare_numeric) { - if (sortinfo->item_compare_ic) { - res = STRICMP(p1, p2); + if (sortinfo->item_compare_lc) { + res = strcoll(p1, p2); } else { - res = STRCMP(p1, p2); + res = sortinfo->item_compare_ic ? STRICMP(p1, p2): STRCMP(p1, p2); } } else { double n1, n2; @@ -9366,6 +9367,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } info.item_compare_ic = false; + info.item_compare_lc = false; info.item_compare_numeric = false; info.item_compare_numbers = false; info.item_compare_float = false; @@ -9410,6 +9412,9 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) } else if (strcmp(info.item_compare_func, "i") == 0) { info.item_compare_func = NULL; info.item_compare_ic = true; + } else if (strcmp(info.item_compare_func, "l") == 0) { + info.item_compare_func = NULL; + info.item_compare_lc = true; } } } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 3e330b88a2..349c7d6280 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -358,6 +358,7 @@ static int linelen(int *has_tab) static char_u *sortbuf1; static char_u *sortbuf2; +static int sort_lc; ///< sort using locale static int sort_ic; ///< ignore case static int sort_nr; ///< sort on number static int sort_rx; ///< sort on regex instead of skipping it @@ -381,6 +382,13 @@ typedef struct { } st_u; } sorti_T; +static int string_compare(const void *s1, const void *s2) FUNC_ATTR_NONNULL_ALL +{ + if (sort_lc) { + return strcoll((char *)s1, (char *)s2); + } + return sort_ic ? STRICMP(s1, s2) : STRCMP(s1, s2); +} static int sort_compare(const void *s1, const void *s2) { @@ -424,8 +432,7 @@ static int sort_compare(const void *s1, const void *s2) l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1); sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = NUL; - result = sort_ic ? STRICMP(sortbuf1, sortbuf2) - : STRCMP(sortbuf1, sortbuf2); + result = string_compare(sortbuf1, sortbuf2); } /* If two lines have the same value, preserve the original line order. */ @@ -466,7 +473,7 @@ void ex_sort(exarg_T *eap) regmatch.regprog = NULL; sorti_T *nrs = xmalloc(count * sizeof(sorti_T)); - sort_abort = sort_ic = sort_rx = sort_nr = sort_flt = 0; + sort_abort = sort_ic = sort_lc = sort_rx = sort_nr = sort_flt = 0; size_t format_found = 0; bool change_occurred = false; // Buffer contents changed. @@ -474,6 +481,8 @@ void ex_sort(exarg_T *eap) if (ascii_iswhite(*p)) { } else if (*p == 'i') { sort_ic = true; + } else if (*p == 'l') { + sort_lc = true; } else if (*p == 'r') { sort_rx = true; } else if (*p == 'n') { @@ -645,8 +654,7 @@ void ex_sort(exarg_T *eap) s = ml_get(get_lnum); size_t bytelen = STRLEN(s) + 1; // include EOL in bytelen old_count += bytelen; - if (!unique || i == 0 - || (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0) { + if (!unique || i == 0 || string_compare(s, sortbuf1) != 0) { // Copy the line into a buffer, it may become invalid in // ml_append(). And it's needed for "unique". STRCPY(sortbuf1, s); diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 7f28c001f9..0a2802397d 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -3621,6 +3621,14 @@ void set_lang_var(void) loc = get_locale_val(LC_TIME); # endif set_vim_var_string(VV_LC_TIME, loc, -1); + +# ifdef HAVE_GET_LOCALE_VAL + loc = get_locale_val(LC_COLLATE); +# else + // setlocale() not supported: use the default value + loc = "C"; +# endif + set_vim_var_string(VV_COLLATE, loc, -1); } #ifdef HAVE_WORKING_LIBINTL @@ -3661,6 +3669,10 @@ void ex_language(exarg_T *eap) what = LC_TIME; name = skipwhite(p); whatstr = "time "; + } else if (STRNICMP(eap->arg, "collate", p - eap->arg) == 0) { + what = LC_COLLATE; + name = skipwhite(p); + whatstr = "collate "; } } @@ -3705,7 +3717,7 @@ void ex_language(exarg_T *eap) // Reset $LC_ALL, otherwise it would overrule everything. os_setenv("LC_ALL", "", 1); - if (what != LC_TIME) { + if (what != LC_TIME && what != LC_COLLATE) { // Tell gettext() what to translate to. It apparently doesn't // use the currently effective locale. if (what == LC_ALL) { @@ -3720,7 +3732,7 @@ void ex_language(exarg_T *eap) } } - // Set v:lang, v:lc_time and v:ctype to the final result. + // Set v:lang, v:lc_time, v:collate and v:ctype to the final result. set_lang_var(); maketitle(); } @@ -3805,12 +3817,15 @@ char_u *get_lang_arg(expand_T *xp, int idx) if (idx == 2) { return (char_u *)"time"; } + if (idx == 3) { + return (char_u *)"collate"; + } init_locales(); if (locales == NULL) { return NULL; } - return locales[idx - 3]; + return locales[idx - 4]; } /// Function given to ExpandGeneric() to obtain the available locales. diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index ae5c334592..555029c1fb 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -3642,7 +3642,8 @@ const char * set_one_cmd_context( } else { if (strncmp(arg, "messages", p - arg) == 0 || strncmp(arg, "ctype", p - arg) == 0 - || strncmp(arg, "time", p - arg) == 0) { + || strncmp(arg, "time", p - arg) == 0 + || strncmp(arg, "collate", p - arg) == 0) { xp->xp_context = EXPAND_LOCALES; xp->xp_pattern = skipwhite((const char_u *)p); } else { diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 489b2477e6..a1968807ac 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -615,10 +615,20 @@ func Test_cmdline_complete_bang() endfunc funct Test_cmdline_complete_languages() + let lang = substitute(execute('language time'), '.*"\(.*\)"$', '\1', '') + call assert_equal(lang, v:lc_time) + + let lang = substitute(execute('language ctype'), '.*"\(.*\)"$', '\1', '') + call assert_equal(lang, v:ctype) + + let lang = substitute(execute('language collate'), '.*"\(.*\)"$', '\1', '') + call assert_equal(lang, v:collate) + let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '') + call assert_equal(lang, v:lang) call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx') - call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:) + call assert_match('^"language .*\<collate\>.*\<ctype\>.*\<messages\>.*\<time\>', @:) if has('unix') " TODO: these tests don't work on Windows. lang appears to be 'C' @@ -633,6 +643,9 @@ funct Test_cmdline_complete_languages() call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx') call assert_match('^"language .*\<' . lang . '\>', @:) + + call feedkeys(":language collate \<c-a>\<c-b>\"\<cr>", 'tx') + call assert_match('^"language .*\<' . lang . '\>', @:) endif endfunc diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim index 4c7452fe69..ed2bb2c06b 100644 --- a/src/nvim/testdir/test_excmd.vim +++ b/src/nvim/testdir/test_excmd.vim @@ -54,6 +54,132 @@ func Test_buffers_lastused() bwipeout bufc endfunc +" Test for the :copy command +func Test_copy() + new + + call setline(1, ['L1', 'L2', 'L3', 'L4']) + " copy lines in a range to inside the range + 1,3copy 2 + call assert_equal(['L1', 'L2', 'L1', 'L2', 'L3', 'L3', 'L4'], getline(1, 7)) + + close! +endfunc + +" Test for the :file command +func Test_file_cmd() + call assert_fails('3file', 'E474:') + call assert_fails('0,0file', 'E474:') + call assert_fails('0file abc', 'E474:') +endfunc + +" Test for the :drop command +func Test_drop_cmd() + call writefile(['L1', 'L2'], 'Xfile') + enew | only + drop Xfile + call assert_equal('L2', getline(2)) + " Test for switching to an existing window + below new + drop Xfile + call assert_equal(1, winnr()) + " Test for splitting the current window + enew | only + set modified + drop Xfile + call assert_equal(2, winnr('$')) + " Check for setting the argument list + call assert_equal(['Xfile'], argv()) + enew | only! + call delete('Xfile') +endfunc + +" Test for the :append command +func Test_append_cmd() + new + call setline(1, [' L1']) + call feedkeys(":append\<CR> L2\<CR> L3\<CR>.\<CR>", 'xt') + call assert_equal([' L1', ' L2', ' L3'], getline(1, '$')) + %delete _ + " append after a specific line + call setline(1, [' L1', ' L2', ' L3']) + call feedkeys(":2append\<CR> L4\<CR> L5\<CR>.\<CR>", 'xt') + call assert_equal([' L1', ' L2', ' L4', ' L5', ' L3'], getline(1, '$')) + %delete _ + " append with toggling 'autoindent' + call setline(1, [' L1']) + call feedkeys(":append!\<CR> L2\<CR> L3\<CR>.\<CR>", 'xt') + call assert_equal([' L1', ' L2', ' L3'], getline(1, '$')) + call assert_false(&autoindent) + %delete _ + " append with 'autoindent' set and toggling 'autoindent' + set autoindent + call setline(1, [' L1']) + call feedkeys(":append!\<CR> L2\<CR> L3\<CR>.\<CR>", 'xt') + call assert_equal([' L1', ' L2', ' L3'], getline(1, '$')) + call assert_true(&autoindent) + set autoindent& + close! +endfunc + +" Test for the :insert command +func Test_insert_cmd() + set noautoindent " test assumes noautoindent, but it's on by default in Nvim + new + call setline(1, [' L1']) + call feedkeys(":insert\<CR> L2\<CR> L3\<CR>.\<CR>", 'xt') + call assert_equal([' L2', ' L3', ' L1'], getline(1, '$')) + %delete _ + " insert before a specific line + call setline(1, [' L1', ' L2', ' L3']) + call feedkeys(":2insert\<CR> L4\<CR> L5\<CR>.\<CR>", 'xt') + call assert_equal([' L1', ' L4', ' L5', ' L2', ' L3'], getline(1, '$')) + %delete _ + " insert with toggling 'autoindent' + call setline(1, [' L1']) + call feedkeys(":insert!\<CR> L2\<CR> L3\<CR>.\<CR>", 'xt') + call assert_equal([' L2', ' L3', ' L1'], getline(1, '$')) + call assert_false(&autoindent) + %delete _ + " insert with 'autoindent' set and toggling 'autoindent' + set autoindent + call setline(1, [' L1']) + call feedkeys(":insert!\<CR> L2\<CR> L3\<CR>.\<CR>", 'xt') + call assert_equal([' L2', ' L3', ' L1'], getline(1, '$')) + call assert_true(&autoindent) + set autoindent& + close! +endfunc + +" Test for the :change command +func Test_change_cmd() + set noautoindent " test assumes noautoindent, but it's on by default in Nvim + new + call setline(1, [' L1', 'L2', 'L3']) + call feedkeys(":change\<CR> L4\<CR> L5\<CR>.\<CR>", 'xt') + call assert_equal([' L4', ' L5', 'L2', 'L3'], getline(1, '$')) + %delete _ + " change a specific line + call setline(1, [' L1', ' L2', ' L3']) + call feedkeys(":2change\<CR> L4\<CR> L5\<CR>.\<CR>", 'xt') + call assert_equal([' L1', ' L4', ' L5', ' L3'], getline(1, '$')) + %delete _ + " change with toggling 'autoindent' + call setline(1, [' L1', 'L2', 'L3']) + call feedkeys(":change!\<CR> L4\<CR> L5\<CR>.\<CR>", 'xt') + call assert_equal([' L4', ' L5', 'L2', 'L3'], getline(1, '$')) + call assert_false(&autoindent) + %delete _ + " change with 'autoindent' set and toggling 'autoindent' + set autoindent + call setline(1, [' L1', 'L2', 'L3']) + call feedkeys(":change!\<CR> L4\<CR> L5\<CR>.\<CR>", 'xt') + call assert_equal([' L4', ' L5', 'L2', 'L3'], getline(1, '$')) + call assert_true(&autoindent) + set autoindent& + close! +endfunc + " Test for the :confirm command dialog func Test_confirm_cmd() CheckNotGui diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim index 5382b89aa6..0bafdc29fb 100644 --- a/src/nvim/testdir/test_fnameescape.vim +++ b/src/nvim/testdir/test_fnameescape.vim @@ -18,4 +18,10 @@ func Test_fnameescape() endtry call assert_true(status, "ExclamationMark") call delete(fname) + + call assert_equal('\-', fnameescape('-')) + call assert_equal('\+', fnameescape('+')) + call assert_equal('\>', fnameescape('>')) endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_ga.vim b/src/nvim/testdir/test_ga.vim index 87f1382342..ce31edfc7a 100644 --- a/src/nvim/testdir/test_ga.vim +++ b/src/nvim/testdir/test_ga.vim @@ -18,6 +18,7 @@ func Test_ga_command() call assert_equal("\nNUL", Do_ga('')) call assert_equal("\n<^A> 1, Hex 01, Oct 001, Digr SH", Do_ga("\x01")) call assert_equal("\n<^I> 9, Hex 09, Oct 011, Digr HT", Do_ga("\t")) + call assert_equal("\n<^@> 0, Hex 00, Octal 000", Do_ga("\n")) call assert_equal("\n<e> 101, Hex 65, Octal 145", Do_ga('e')) @@ -30,5 +31,13 @@ func Test_ga_command() call assert_equal("\n<e> 101, Hex 65, Octal 145 < ́> 769, Hex 0301, Octal 1401", Do_ga("e\u0301")) call assert_equal("\n<e> 101, Hex 65, Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461", Do_ga("e\u0301\u0331")) call assert_equal("\n<e> 101, Hex 65, Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461 < ̸> 824, Hex 0338, Octal 1470", Do_ga("e\u0301\u0331\u0338")) + + " When using Mac fileformat, CR instead of NL is used for line termination + enew! + set fileformat=mac + call assert_equal("\n<^J> 10, Hex 0a, Oct 012, Digr NU", Do_ga("\r")) + bwipe! endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_global.vim b/src/nvim/testdir/test_global.vim index 7ccf2812ff..2de2c412de 100644 --- a/src/nvim/testdir/test_global.vim +++ b/src/nvim/testdir/test_global.vim @@ -29,3 +29,11 @@ func Test_nested_global() call assert_equal(['nothing', '++found', 'found bad', 'bad'], getline(1, 4)) bwipe! endfunc + +func Test_global_error() + call assert_fails('g\\a', 'E10:') + call assert_fails('g', 'E148:') + call assert_fails('g/\(/y', 'E476:') +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_move.vim b/src/nvim/testdir/test_move.vim index d774c93dbd..f666a904b0 100644 --- a/src/nvim/testdir/test_move.vim +++ b/src/nvim/testdir/test_move.vim @@ -35,6 +35,11 @@ func Test_move() call assert_fails('1,2move 1', 'E134') call assert_fails('2,3move 2', 'E134') + call assert_fails("move -100", 'E16:') + call assert_fails("move +100", 'E16:') + call assert_fails('move', 'E16:') %bwipeout! endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index 5aef33cb09..8796af7a20 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -629,6 +629,25 @@ func Test_visualbell() set belloff=all endfunc +" Test for the 'write' option +func Test_write() + new + call setline(1, ['L1']) + set nowrite + call assert_fails('write Xfile', 'E142:') + set write + close! +endfunc + +" Test for 'buftype' option +func Test_buftype() + new + call setline(1, ['L1']) + set buftype=nowrite + call assert_fails('write', 'E382:') + close! +endfunc + " Test for setting option values using v:false and v:true func Test_opt_boolean() set number& diff --git a/src/nvim/testdir/test_sort.vim b/src/nvim/testdir/test_sort.vim index 7533eaf2e8..6d55889641 100644 --- a/src/nvim/testdir/test_sort.vim +++ b/src/nvim/testdir/test_sort.vim @@ -13,6 +13,37 @@ func Test_sort_strings() " numbers compared as strings call assert_equal([1, 2, 3], sort([3, 2, 1])) call assert_equal([13, 28, 3], sort([3, 28, 13])) + + call assert_equal(['A', 'O', 'P', 'a', 'o', 'p', 'Ä', 'Ô', 'ä', 'ô', 'Œ', 'œ'], + \ sort(['A', 'O', 'P', 'a', 'o', 'p', 'Ä', 'Ô', 'ä', 'ô', 'œ', 'Œ'])) + + call assert_equal(['A', 'a', 'o', 'O', 'p', 'P', 'Ä', 'Ô', 'ä', 'ô', 'Œ', 'œ'], + \ sort(['A', 'a', 'o', 'O', 'œ', 'Œ', 'p', 'P', 'Ä', 'ä', 'ô', 'Ô'], 'i')) + + " This does not appear to work correctly on Mac. + if !has('mac') + if v:collate =~? '^\(en\|fr\)_ca.utf-\?8$' + " with Canadian English capitals come before lower case. + " 'Œ' is omitted because it can sort before or after 'œ' + call assert_equal(['A', 'a', 'Ä', 'ä', 'O', 'o', 'Ô', 'ô', 'œ', 'P', 'p'], + \ sort(['A', 'a', 'o', 'O', 'œ', 'p', 'P', 'Ä', 'ä', 'ô', 'Ô'], 'l')) + elseif v:collate =~? '^\(en\|es\|de\|fr\|it\|nl\).*\.utf-\?8$' + " With the following locales, the accentuated letters are ordered + " similarly to the non-accentuated letters... + call assert_equal(['a', 'A', 'ä', 'Ä', 'o', 'O', 'ô', 'Ô', 'œ', 'Œ', 'p', 'P'], + \ sort(['A', 'a', 'o', 'O', 'œ', 'Œ', 'p', 'P', 'Ä', 'ä', 'ô', 'Ô'], 'l')) + elseif v:collate =~? '^sv.*utf-\?8$' + " ... whereas with a Swedish locale, the accentuated letters are ordered + " after Z. + call assert_equal(['a', 'A', 'o', 'O', 'p', 'P', 'ä', 'Ä', 'œ', 'œ', 'ô', 'Ô'], + \ sort(['A', 'a', 'o', 'O', 'œ', 'œ', 'p', 'P', 'Ä', 'ä', 'ô', 'Ô'], 'l')) + endif + endif +endfunc + +func Test_sort_null_string() + " null strings are sorted as empty strings. + call assert_equal(['', 'a', 'b'], sort(['b', v:_null_string, 'a'])) endfunc func Test_sort_numeric() @@ -1150,7 +1181,7 @@ func Test_sort_cmd() \ 'input' : [ \ '1.234', \ '0.88', - \ '123.456', + \ ' + 123.456', \ '1.15e-6', \ '-1.1e3', \ '-1.01e3', @@ -1165,7 +1196,7 @@ func Test_sort_cmd() \ '1.15e-6', \ '0.88', \ '1.234', - \ '123.456' + \ ' + 123.456' \ ] \ }, \ { @@ -1197,8 +1228,133 @@ func Test_sort_cmd() \ 'cc', \ ] \ }, + \ { + \ 'name' : 'sort one line buffer', + \ 'cmd' : 'sort', + \ 'input' : [ + \ 'single line' + \ ], + \ 'expected' : [ + \ 'single line' + \ ] + \ }, + \ { + \ 'name' : 'sort ignoring case', + \ 'cmd' : '%sort i', + \ 'input' : [ + \ 'BB', + \ 'Cc', + \ 'aa' + \ ], + \ 'expected' : [ + \ 'aa', + \ 'BB', + \ 'Cc' + \ ] + \ }, \ ] + " This does not appear to work correctly on Mac. + if !has('mac') + if v:collate =~? '^\(en\|fr\)_ca.utf-\?8$' + " en_CA.utf-8 sorts capitals before lower case + " 'Œ' is omitted because it can sort before or after 'œ' + let tests += [ + \ { + \ 'name' : 'sort with locale ' .. v:collate, + \ 'cmd' : '%sort l', + \ 'input' : [ + \ 'A', + \ 'E', + \ 'O', + \ 'À', + \ 'È', + \ 'É', + \ 'Ô', + \ 'Z', + \ 'a', + \ 'e', + \ 'o', + \ 'à', + \ 'è', + \ 'é', + \ 'ô', + \ 'œ', + \ 'z' + \ ], + \ 'expected' : [ + \ 'A', + \ 'a', + \ 'À', + \ 'à', + \ 'E', + \ 'e', + \ 'É', + \ 'é', + \ 'È', + \ 'è', + \ 'O', + \ 'o', + \ 'Ô', + \ 'ô', + \ 'œ', + \ 'Z', + \ 'z' + \ ] + \ }, + \ ] + elseif v:collate =~? '^\(en\|es\|de\|fr\|it\|nl\).*\.utf-\?8$' + " With these locales, the accentuated letters are ordered + " similarly to the non-accentuated letters. + let tests += [ + \ { + \ 'name' : 'sort with locale ' .. v:collate, + \ 'cmd' : '%sort l', + \ 'input' : [ + \ 'A', + \ 'E', + \ 'O', + \ 'À', + \ 'È', + \ 'É', + \ 'Ô', + \ 'Œ', + \ 'Z', + \ 'a', + \ 'e', + \ 'o', + \ 'à', + \ 'è', + \ 'é', + \ 'ô', + \ 'œ', + \ 'z' + \ ], + \ 'expected' : [ + \ 'a', + \ 'A', + \ 'à', + \ 'À', + \ 'e', + \ 'E', + \ 'é', + \ 'É', + \ 'è', + \ 'È', + \ 'o', + \ 'O', + \ 'ô', + \ 'Ô', + \ 'œ', + \ 'Œ', + \ 'z', + \ 'Z' + \ ] + \ }, + \ ] + endif + endif + for t in tests enew! call append(0, t.input) @@ -1217,7 +1373,11 @@ func Test_sort_cmd() endif endfor - call assert_fails('sort no', 'E474') + " Needs atleast two lines for this test + call setline(1, ['line1', 'line2']) + call assert_fails('sort no', 'E474:') + call assert_fails('sort c', 'E475:') + call assert_fails('sort #pat%', 'E682:') enew! endfunc @@ -1319,4 +1479,46 @@ func Test_sort_cmd_report() " the output comes from the :g command, not from the :sort call assert_match("6 fewer lines", res) enew! - endfunc +endfunc + +" Test for a :sort command followed by another command +func Test_sort_followed_by_cmd() + new + let var = '' + call setline(1, ['cc', 'aa', 'bb']) + %sort | let var = "sortcmdtest" + call assert_equal(var, "sortcmdtest") + call assert_equal(['aa', 'bb', 'cc'], getline(1, '$')) + " Test for :sort followed by a comment + call setline(1, ['3b', '1c', '2a']) + %sort /\d\+/ " sort alphabetically + call assert_equal(['2a', '3b', '1c'], getline(1, '$')) + close! +endfunc + +" Test for :sort using last search pattern +func Test_sort_last_search_pat() + new + let @/ = '\d\+' + call setline(1, ['3b', '1c', '2a']) + sort // + call assert_equal(['2a', '3b', '1c'], getline(1, '$')) + close! +endfunc + +" Test for retaining marks across a :sort +func Test_sort_with_marks() + new + call setline(1, ['cc', 'aa', 'bb']) + call setpos("'c", [0, 1, 0, 0]) + call setpos("'a", [0, 2, 0, 0]) + call setpos("'b", [0, 3, 0, 0]) + %sort + call assert_equal(['aa', 'bb', 'cc'], getline(1, '$')) + call assert_equal(2, line("'a")) + call assert_equal(3, line("'b")) + call assert_equal(1, line("'c")) + close! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim index 32167a45ba..e7f9bb76f2 100644 --- a/src/nvim/testdir/test_substitute.vim +++ b/src/nvim/testdir/test_substitute.vim @@ -426,6 +426,8 @@ func Test_substitute_errors() call assert_fails('s/FOO/bar/', 'E486:') call assert_fails('s/foo/bar/@', 'E488:') call assert_fails('s/\(/bar/', 'E476:') + call assert_fails('s afooabara', 'E146:') + call assert_fails('s\\a', 'E10:') setl nomodifiable call assert_fails('s/foo/bar/', 'E21:') diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim index c62c01d5f3..c7710ff198 100644 --- a/src/nvim/testdir/test_writefile.vim +++ b/src/nvim/testdir/test_writefile.vim @@ -164,6 +164,69 @@ func Test_writefile_autowrite_nowrite() set noautowrite endfunc +" Test for ':w !<cmd>' to pipe lines from the current buffer to an external +" command. +func Test_write_pipe_to_cmd() + if !has('unix') + return + endif + new + call setline(1, ['L1', 'L2', 'L3', 'L4']) + 2,3w !cat > Xfile + call assert_equal(['L2', 'L3'], readfile('Xfile')) + close! + call delete('Xfile') +endfunc + +" Test for :saveas +func Test_saveas() + call assert_fails('saveas', 'E471:') + call writefile(['L1'], 'Xfile') + new Xfile + new + call setline(1, ['L1']) + call assert_fails('saveas Xfile', 'E139:') + close! + enew | only + call delete('Xfile') +endfunc + +func Test_write_errors() + " Test for writing partial buffer + call writefile(['L1', 'L2', 'L3'], 'Xfile') + new Xfile + call assert_fails('1,2write', 'E140:') + close! + + " Try to overwrite a directory + if has('unix') + call mkdir('Xdir1') + call assert_fails('write Xdir1', 'E17:') + call delete('Xdir1', 'd') + endif + + " Test for :wall for a buffer with no name + enew | only + call setline(1, ['L1']) + call assert_fails('wall', 'E141:') + enew! + + " Test for writing a 'readonly' file + new Xfile + set readonly + call assert_fails('write', 'E45:') + close + + " Test for writing to a read-only file + new Xfile + call setfperm('Xfile', 'r--r--r--') + call assert_fails('write', 'E505:') + call setfperm('Xfile', 'rw-rw-rw-') + close + + call delete('Xfile') +endfunc + func Test_writefile_sync_dev_stdout() if !has('unix') return |