diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index af7d233619..0ded6a9060 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -90,6 +90,7 @@ argument. --clean Equivalent to "-u NONE -i NONE": - Skips initializations from files and environment variables. - No 'shada' file is read or written. + - Excludes user directories from 'runtimepath' *--noplugin* --noplugin Skip loading plugins. Resets the 'loadplugins' option. diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 383a45b9d3..12a5ca729d 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -458,7 +458,7 @@ au BufNewFile,BufRead *.desc setf desc au BufNewFile,BufRead *.d call dist#ft#DtraceCheck() " Desktop files -au BufNewFile,BufRead *.desktop,.directory setf desktop +au BufNewFile,BufRead *.desktop,*.directory setf desktop " Dict config au BufNewFile,BufRead dict.conf,.dictrc setf dictconf @@ -1162,6 +1162,7 @@ else endif au BufNewFile,BufRead *.plx,*.al,*.psgi setf perl au BufNewFile,BufRead *.p6,*.pm6,*.pl6 setf perl6 +au BufNewFile,BufRead *.raku,*.rakumod setf perl6 " Perl, XPM or XPM2 au BufNewFile,BufRead *.pm @@ -1291,7 +1292,8 @@ au BufNewFile,BufRead *.pyx,*.pxd setf pyrex " Python, Python Shell Startup and Python Stub Files " Quixote (Python-based web framework) -au BufNewFile,BufRead *.py,*.pyw,.pythonstartup,.pythonrc,*.ptl,*.pyi setf python +au BufNewFile,BufRead *.py,*.pyw,.pythonstartup,.pythonrc setf python +au BufNewFile,BufRead *.ptl,*.pyi,SConstruct setf python " Radiance au BufNewFile,BufRead *.rad,*.mat setf radiance @@ -1613,10 +1615,12 @@ au BufNewFile,BufRead *.sqlj setf sqlj au BufNewFile,BufRead *.sqr,*.sqi setf sqr " OpenSSH configuration -au BufNewFile,BufRead ssh_config,*/.ssh/config setf sshconfig +au BufNewFile,BufRead ssh_config,*/.ssh/config setf sshconfig +au BufNewFile,BufRead */etc/ssh/ssh_config.d/*.conf setf sshconfig " OpenSSH server configuration -au BufNewFile,BufRead sshd_config setf sshdconfig +au BufNewFile,BufRead sshd_config setf sshdconfig +au BufNewFile,BufRead */etc/ssh/sshd_config.d/*.conf setf sshdconfig " Stata au BufNewFile,BufRead *.ado,*.do,*.imata,*.mata setf stata diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index 28dc3256c7..2898bd991b 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -247,10 +247,12 @@ func s:StartDebug_term(dict) endif let response = '' - for lnum in range(1,200) - if len(getbufline(s:gdbbuf, lnum)) > 0 && getbufline(s:gdbbuf, lnum)[0] =~ 'new-ui mi ' + for lnum in range(1, 200) + let line1 = get(getbufline(s:gdbbuf, lnum), 0, '') + let line2 = get(getbufline(s:gdbbuf, lnum + 1), 0, '') + if line1 =~ 'new-ui mi ' " response can be in the same line or the next line - let response = getbufline(s:gdbbuf, lnum)[0] . getbufline(s:gdbbuf, lnum + 1)[0] + let response = line1 . line2 if response =~ 'Undefined command' echoerr 'Sorry, your gdb is too old, gdb 7.12 is required' call s:CloseBuffers() @@ -260,10 +262,9 @@ func s:StartDebug_term(dict) " Success! break endif - if response =~ 'Reading symbols from' && response !~ 'new-ui' - " Reading symbols might take a while - let try_count -= 1 - endif + elseif line1 =~ 'Reading symbols from' && line2 !~ 'new-ui mi ' + " Reading symbols might take a while, try more times + let try_count -= 1 endif endfor if response =~ 'New UI allocated' diff --git a/runtime/scripts.vim b/runtime/scripts.vim index c552f0202f..6aae2b1ec3 100644 --- a/runtime/scripts.vim +++ b/runtime/scripts.vim @@ -1,7 +1,7 @@ " Vim support file to detect file types in scripts " " Maintainer: Bram Moolenaar -" Last change: 2019 Jun 25 +" Last change: 2020 Jun 07 " This file is called by an autocommand for every file that has just been " loaded into a buffer. It checks if the type of file can be recognized by @@ -35,10 +35,12 @@ let s:line1 = getline(1) if s:line1 =~# "^#!" " A script that starts with "#!". - " Check for a line like "#!/usr/bin/env VAR=val bash". Turn it into + " Check for a line like "#!/usr/bin/env {options} bash". Turn it into " "#!/usr/bin/bash" to make matching easier. + " Recognize only a few {options} that are commonly used. if s:line1 =~# '^#!\s*\S*\b_flags & BF_NOTEDITED) - && !bt_dontwrite(curbuf) - ? _("[Not edited]") : "", - (curbuf->b_flags & BF_NEW) - && !bt_dontwrite(curbuf) - ? _("[New file]") : "", - (curbuf->b_flags & BF_READERR) ? _("[Read errors]") : "", - curbuf->b_p_ro ? (shortmess(SHM_RO) ? _("[RO]") - : _("[readonly]")) : "", - (curbufIsChanged() || (curbuf->b_flags & BF_WRITE_MASK) - || curbuf->b_p_ro) ? - " " : ""); - /* With 32 bit longs and more than 21,474,836 lines multiplying by 100 - * causes an overflow, thus for large numbers divide instead. */ - if (curwin->w_cursor.lnum > 1000000L) + curbufIsChanged() + ? (shortmess(SHM_MOD) ? " [+]" : _(" [Modified]")) : " ", + (curbuf->b_flags & BF_NOTEDITED) && !bt_dontwrite(curbuf) + ? _("[Not edited]") : "", + (curbuf->b_flags & BF_NEW) && !bt_dontwrite(curbuf) + ? new_file_message() : "", + (curbuf->b_flags & BF_READERR) + ? _("[Read errors]") : "", + curbuf->b_p_ro + ? (shortmess(SHM_RO) ? _("[RO]") : _("[readonly]")) : "", + (curbufIsChanged() + || (curbuf->b_flags & BF_WRITE_MASK) + || curbuf->b_p_ro) + ? " " : ""); + // With 32 bit longs and more than 21,474,836 lines multiplying by 100 + // causes an overflow, thus for large numbers divide instead. + if (curwin->w_cursor.lnum > 1000000L) { n = (int)(((long)curwin->w_cursor.lnum) / ((long)curbuf->b_ml.ml_line_count / 100L)); - else + } else { n = (int)(((long)curwin->w_cursor.lnum * 100L) / (long)curbuf->b_ml.ml_line_count); + } if (curbuf->b_ml.ml_flags & ML_EMPTY) { vim_snprintf_add((char *)buffer, IOSIZE, "%s", _(no_lines_msg)); } else if (p_ru) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 66cd0e09c6..b7e827e86b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8137,9 +8137,6 @@ void set_argv_var(char **argv, int argc) list_T *l = tv_list_alloc(argc); int i; - if (l == NULL) { - getout(1); - } tv_list_set_lock(l, VAR_FIXED); for (i = 0; i < argc; i++) { tv_list_append_string(l, (const char *const)argv[i], -1); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index f29304867a..20f0cdccc3 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -569,20 +569,21 @@ readfile( return FAIL; } } - if (dir_of_file_exists(fname)) - filemess(curbuf, sfname, (char_u *)_("[New File]"), 0); - else - filemess(curbuf, sfname, - (char_u *)_("[New DIRECTORY]"), 0); - /* Even though this is a new file, it might have been - * edited before and deleted. Get the old marks. */ + if (dir_of_file_exists(fname)) { + filemess(curbuf, sfname, (char_u *)new_file_message(), 0); + } else { + filemess(curbuf, sfname, (char_u *)_("[New DIRECTORY]"), 0); + } + // Even though this is a new file, it might have been + // edited before and deleted. Get the old marks. check_marks_read(); - /* Set forced 'fileencoding'. */ - if (eap != NULL) + // Set forced 'fileencoding'. + if (eap != NULL) { set_forced_fenc(eap); + } apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname, - FALSE, curbuf, eap); - /* remember the current fileformat */ + false, curbuf, eap); + // remember the current fileformat save_file_ff(curbuf); if (aborting()) /* autocmds may abort script processing */ @@ -2203,6 +2204,11 @@ static void check_marks_read(void) curbuf->b_marks_read = true; } +char *new_file_message(void) +{ + return shortmess(SHM_NEW) ? _("[New]") : _("[New File]"); +} + /* * buf_write() - write to file "fname" lines "start" through "end" * @@ -3513,8 +3519,8 @@ restore_backup: STRCAT(IObuff, _("[Device]")); c = TRUE; } else if (newfile) { - STRCAT(IObuff, shortmess(SHM_NEW) ? _("[New]") : _("[New File]")); - c = TRUE; + STRCAT(IObuff, new_file_message()); + c = true; } if (no_eol) { msg_add_eol(); diff --git a/src/nvim/main.c b/src/nvim/main.c index b3a903cbe3..8d5b91ec91 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -84,44 +84,11 @@ #endif #include "nvim/api/vim.h" -// Maximum number of commands from + or -c arguments. -#define MAX_ARG_CMDS 10 - // values for "window_layout" #define WIN_HOR 1 // "-o" horizontally split windows #define WIN_VER 2 // "-O" vertically split windows #define WIN_TABS 3 // "-p" windows on tab pages -// Struct for various parameters passed between main() and other functions. -typedef struct { - int argc; - char **argv; - - char *use_vimrc; // vimrc from -u argument - - int n_commands; // no. of commands from + or -c - char *commands[MAX_ARG_CMDS]; // commands from + or -c arg - char_u cmds_tofree[MAX_ARG_CMDS]; // commands that need free() - int n_pre_commands; // no. of commands from --cmd - char *pre_commands[MAX_ARG_CMDS]; // commands from --cmd argument - - int edit_type; // type of editing to do - char_u *tagname; // tag from -t argument - char_u *use_ef; // 'errorfile' from -q argument - - bool input_isatty; // stdin is a terminal - bool output_isatty; // stdout is a terminal - bool err_isatty; // stderr is a terminal - int no_swap_file; // "-n" argument used - int use_debug_break_level; - int window_count; // number of windows to use - int window_layout; // 0, WIN_HOR, WIN_VER or WIN_TABS - - int diff_mode; // start with 'diff' set - - char *listen_addr; // --listen {address} -} mparm_T; - // Values for edit_type. #define EDIT_NONE 0 // no edit type yet #define EDIT_FILE 1 // file name argument[s] given, use argument list @@ -188,7 +155,7 @@ bool event_teardown(void) /// Performs early initialization. /// /// Needed for unit tests. Must be called after `time_init()`. -void early_init(void) +void early_init(mparm_T *paramp) { env_init(); fs_init(); @@ -222,7 +189,7 @@ void early_init(void) // msg_outtrans_len_attr(). // First find out the home directory, needed to expand "~" in options. init_homedir(); // find real value of $HOME - set_init_1(); + set_init_1(paramp != NULL ? paramp->clean : false); log_init(); TIME_MSG("inits 1"); @@ -265,9 +232,17 @@ int main(int argc, char **argv) init_startuptime(¶ms); + // Need to find "--clean" before actually parsing arguments. + for (int i = 1; i < params.argc; i++) { + if (STRICMP(params.argv[i], "--clean") == 0) { + params.clean = true; + break; + } + } + event_init(); - early_init(); + early_init(¶ms); set_argv_var(argv, argc); // set v:argv @@ -862,6 +837,7 @@ static void command_line_scan(mparm_T *parmp) argv_idx += 11; } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) { parmp->use_vimrc = "NONE"; + parmp->clean = true; set_option_value("shadafile", 0L, "NONE", 0); } else { if (argv[0][argv_idx]) @@ -1277,9 +1253,8 @@ static void init_params(mparm_T *paramp, int argc, char **argv) /// Initialize global startuptime file if "--startuptime" passed as an argument. static void init_startuptime(mparm_T *paramp) { - for (int i = 1; i < paramp->argc; i++) { - if (STRICMP(paramp->argv[i], "--startuptime") == 0 - && i + 1 < paramp->argc) { + for (int i = 1; i < paramp->argc - 1; i++) { + if (STRICMP(paramp->argv[i], "--startuptime") == 0) { time_fd = os_fopen(paramp->argv[i + 1], "a"); time_start("--- NVIM STARTING ---"); break; diff --git a/src/nvim/main.h b/src/nvim/main.h index 86d25fe657..61252f2bce 100644 --- a/src/nvim/main.h +++ b/src/nvim/main.h @@ -4,8 +4,42 @@ #include "nvim/normal.h" #include "nvim/event/loop.h" +// Maximum number of commands from + or -c arguments. +#define MAX_ARG_CMDS 10 + extern Loop main_loop; +// Struct for various parameters passed between main() and other functions. +typedef struct { + int argc; + char **argv; + + char *use_vimrc; // vimrc from -u argument + bool clean; // --clean argument + + int n_commands; // no. of commands from + or -c + char *commands[MAX_ARG_CMDS]; // commands from + or -c arg + char_u cmds_tofree[MAX_ARG_CMDS]; // commands that need free() + int n_pre_commands; // no. of commands from --cmd + char *pre_commands[MAX_ARG_CMDS]; // commands from --cmd argument + + int edit_type; // type of editing to do + char_u *tagname; // tag from -t argument + char_u *use_ef; // 'errorfile' from -q argument + + bool input_isatty; // stdin is a terminal + bool output_isatty; // stdout is a terminal + bool err_isatty; // stderr is a terminal + int no_swap_file; // "-n" argument used + int use_debug_break_level; + int window_count; // number of windows to use + int window_layout; // 0, WIN_HOR, WIN_VER or WIN_TABS + + int diff_mode; // start with 'diff' set + + char *listen_addr; // --listen {address} +} mparm_T; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "main.h.generated.h" #endif diff --git a/src/nvim/ops.c b/src/nvim/ops.c index eb32a1dd9b..e905029dae 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4671,17 +4671,23 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) int maxlen = 0; pos_T startpos; pos_T endpos; + colnr_T save_coladd = 0; dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX" dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal" dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin" doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha" + if (virtual_active()) { + save_coladd = pos->coladd; + pos->coladd = 0; + } + curwin->w_cursor = *pos; ptr = ml_get(pos->lnum); col = pos->col; - if (*ptr == NUL) { + if (*ptr == NUL || col + !!save_coladd >= (int)STRLEN(ptr)) { goto theend; } @@ -4976,6 +4982,8 @@ theend: curwin->w_cursor = save_cursor; } else if (did_change) { curwin->w_set_curswant = true; + } else if (virtual_active()) { + curwin->w_cursor.coladd = save_coladd; } return did_change; diff --git a/src/nvim/option.c b/src/nvim/option.c index 96f8e1529a..d789ad3587 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -524,11 +524,17 @@ char *get_lib_dir(void) /// /// Windows: Uses "…/nvim-data" for kXDGDataHome to avoid storing /// configuration and data files in the same path. #4403 -static void set_runtimepath_default(void) +/// +/// If "clean_arg" is true, Nvim was started with --clean. +static void set_runtimepath_default(bool clean_arg) { size_t rtp_size = 0; - char *const data_home = stdpaths_get_xdg_var(kXDGDataHome); - char *const config_home = stdpaths_get_xdg_var(kXDGConfigHome); + char *const data_home = clean_arg + ? NULL + : stdpaths_get_xdg_var(kXDGDataHome); + char *const config_home = clean_arg + ? NULL + : stdpaths_get_xdg_var(kXDGConfigHome); char *const vimruntime = vim_getenv("VIMRUNTIME"); char *const libdir = get_lib_dir(); char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs); @@ -622,7 +628,8 @@ static void set_runtimepath_default(void) /// Initialize the options, first part. /// /// Called only once from main(), just after creating the first buffer. -void set_init_1(void) +/// If "clean_arg" is true, Nvim was started with --clean. +void set_init_1(bool clean_arg) { int opt_idx; @@ -765,7 +772,7 @@ void set_init_1(void) true); // Set default for &runtimepath. All necessary expansions are performed in // this function. - set_runtimepath_default(); + set_runtimepath_default(clean_arg); /* * Set all the options (except the terminal options) to their default @@ -2538,8 +2545,8 @@ static bool valid_filetype(const char_u *val) return valid_name(val, ".-_"); } -/// Return true if "val" is a valid 'spellang' value. -bool valid_spellang(const char_u *val) +/// Return true if "val" is a valid 'spelllang' value. +bool valid_spelllang(const char_u *val) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return valid_name(val, ".-_,@"); @@ -3071,7 +3078,7 @@ ambw_end: const bool is_spellfile = varp == &(curwin->w_s->b_p_spf); if ((is_spellfile && !valid_spellfile(*varp)) - || (!is_spellfile && !valid_spellang(*varp))) { + || (!is_spellfile && !valid_spelllang(*varp))) { errmsg = e_invarg; } else { errmsg = did_set_spell_option(is_spellfile); @@ -5469,9 +5476,6 @@ static int put_setstring(FILE *fd, char *cmd, char *name, // replace home directory in the whole option value into "buf" buf = xmalloc(size); - if (buf == NULL) { - goto fail; - } home_replace(NULL, *valuep, buf, size, false); // If the option value is longer than MAXPATHL, we need to append @@ -5479,10 +5483,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, // can be expanded when read back. if (size >= MAXPATHL && (flags & P_COMMA) != 0 && vim_strchr(*valuep, ',') != NULL) { - part = xmalloc(size); - if (part == NULL) { - goto fail; - } + part = xmalloc(size); // write line break to clear the option, e.g. ':set rtp=' if (put_eol(fd) == FAIL) { diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 2ca5f42e51..387732fdee 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4960,7 +4960,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 && (!rex.reg_ic || mb_tolower(c1) != mb_tolower(c2))) + if ((c1 != c2 && (!rex.reg_ic || utf_fold(c1) != utf_fold(c2))) || c1_len != c2_len) { match = false; break; @@ -5682,11 +5682,11 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, break; } if (rex.reg_ic) { - int curc_low = mb_tolower(curc); + int curc_low = utf_fold(curc); int done = false; for (; c1 <= c2; c1++) { - if (mb_tolower(c1) == curc_low) { + if (utf_fold(c1) == curc_low) { result = result_if_matched; done = TRUE; break; @@ -5698,8 +5698,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 - || (rex.reg_ic && mb_tolower(curc) - == mb_tolower(state->c)))) { + || (rex.reg_ic + && utf_fold(curc) == utf_fold(state->c)))) { result = result_if_matched; break; } @@ -6106,7 +6106,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, result = (c == curc); if (!result && rex.reg_ic) { - result = mb_tolower(c) == mb_tolower(curc); + result = utf_fold(c) == utf_fold(curc); } // If rex.reg_icombine is not set only skip over the character @@ -6260,8 +6260,9 @@ 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 && (!rex.reg_ic || mb_tolower(c) - != mb_tolower(prog->regstart))) { + if (c != prog->regstart + && (!rex.reg_ic + || utf_fold(c) != utf_fold(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 23086c629b..b105d99d7c 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2326,9 +2326,9 @@ int findsent(Direction dir, long count) func = decl; while (count--) { - /* - * if on an empty line, skip up to a non-empty line - */ + const pos_T prev_pos = pos; + + // if on an empty line, skip up to a non-empty line if (gchar_pos(&pos) == NUL) { do { if ((*func)(&pos) == -1) { @@ -2411,6 +2411,17 @@ found: while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) if (incl(&pos) == -1) break; + + if (equalpos(prev_pos, pos)) { + // didn't actually move, advance one character and try again + if ((*func)(&pos) == -1) { + if (count) { + return FAIL; + } + break; + } + count++; + } } setpcmark(); diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 180073ade1..4d8da1ba14 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2007,7 +2007,7 @@ char_u *did_set_spelllang(win_T *wp) region = NULL; len = (int)STRLEN(lang); - if (!valid_spellang(lang)) { + if (!valid_spelllang(lang)) { continue; } diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 5217aa7339..d116246ef3 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1252,6 +1252,10 @@ func Test_TextYankPost() call assert_equal( \{'regcontents': ['foo'], 'inclusive': v:false, 'regname': '', 'operator': 'y', 'visual': v:false, 'regtype': 'V'}, \g:event) + norm Vy + call assert_equal( + \{'regcontents': ['foo'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'visual': v:true, 'regtype': 'V'}, + \g:event) call feedkeys("\y", 'x') call assert_equal( \{'regcontents': ['f'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'visual': v:true, 'regtype': "\x161"}, diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index ffd2cee80f..5d75d1aa57 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -131,7 +131,7 @@ let s:filename_checks = { \ 'def': ['file.def'], \ 'denyhosts': ['denyhosts.conf'], \ 'desc': ['file.desc'], - \ 'desktop': ['file.desktop', '.directory'], + \ 'desktop': ['file.desktop', '.directory', 'file.directory'], \ 'dictconf': ['dict.conf', '.dictrc'], \ 'dictdconf': ['dictd.conf'], \ 'diff': ['file.diff', 'file.rej'], @@ -329,7 +329,7 @@ let s:filename_checks = { \ 'pccts': ['file.g'], \ 'pdf': ['file.pdf'], \ 'perl': ['file.plx', 'file.al', 'file.psgi', 'gitolite.rc', '.gitolite.rc', 'example.gitolite.rc'], - \ 'perl6': ['file.p6', 'file.pm6', 'file.pl6'], + \ 'perl6': ['file.p6', 'file.pm6', 'file.pl6', 'file.raku', 'file.rakumod'], \ 'pf': ['pf.conf'], \ 'pfmain': ['main.cf'], \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp'], @@ -360,7 +360,7 @@ let s:filename_checks = { \ 'protocols': ['/etc/protocols'], \ 'psf': ['file.psf'], \ 'pyrex': ['file.pyx', 'file.pxd'], - \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi'], + \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi', 'SConstruct'], \ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg'], \ 'radiance': ['file.rad', 'file.mat'], \ 'ratpoison': ['.ratpoisonrc', 'ratpoisonrc'], @@ -427,8 +427,8 @@ let s:filename_checks = { \ 'sqr': ['file.sqr', 'file.sqi'], \ 'squid': ['squid.conf'], \ 'srec': ['file.s19', 'file.s28', 'file.s37', 'file.mot', 'file.srec'], - \ 'sshconfig': ['ssh_config', '/.ssh/config'], - \ 'sshdconfig': ['sshd_config'], + \ 'sshconfig': ['ssh_config', '/.ssh/config', '/etc/ssh/ssh_config.d/file.conf', 'any/etc/ssh/ssh_config.d/file.conf'], + \ 'sshdconfig': ['sshd_config', '/etc/ssh/sshd_config.d/file.conf', 'any/etc/ssh/sshd_config.d/file.conf'], \ 'st': ['file.st'], \ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'], \ 'stp': ['file.stp'], @@ -606,9 +606,19 @@ let s:script_checks = { \ 'yaml': [['%YAML 1.2']], \ } -func Test_script_detection() +" Various forms of "env" optional arguments. +let s:script_env_checks = { + \ 'perl': [['#!/usr/bin/env VAR=val perl']], + \ 'scala': [['#!/usr/bin/env VAR=val VVAR=vval scala']], + \ 'awk': [['#!/usr/bin/env VAR=val -i awk']], + \ 'scheme': [['#!/usr/bin/env VAR=val --ignore-environment scheme']], + \ 'python': [['#!/usr/bin/env VAR=val -S python -w -T']], + \ 'wml': [['#!/usr/bin/env VAR=val --split-string wml']], + \ } + +func Run_script_detection(test_dict) filetype on - for [ft, files] in items(s:script_checks) + for [ft, files] in items(a:test_dict) for file in files call writefile(file, 'Xtest') split Xtest @@ -620,6 +630,11 @@ func Test_script_detection() filetype off endfunc +func Test_script_detection() + call Run_script_detection(s:script_checks) + call Run_script_detection(s:script_env_checks) +endfunc + func Test_setfiletype_completion() call feedkeys(":setfiletype java\\\"\", 'tx') call assert_equal('"setfiletype java javacc javascript javascriptreact', @:) diff --git a/src/nvim/testdir/test_increment.vim b/src/nvim/testdir/test_increment.vim index ab11d943d9..f81f8edbde 100644 --- a/src/nvim/testdir/test_increment.vim +++ b/src/nvim/testdir/test_increment.vim @@ -779,4 +779,40 @@ func Test_increment_empty_line() bwipe! endfunc +func Test_normal_increment_with_virtualedit() + set virtualedit=all + + call setline(1, ["\1"]) + exec "norm! 0\" + call assert_equal("\2", getline(1)) + call assert_equal([0, 1, 2, 0], getpos('.')) + + call setline(1, ["\1"]) + exec "norm! 0l\" + call assert_equal("\2", getline(1)) + call assert_equal([0, 1, 2, 0], getpos('.')) + + call setline(1, ["\1"]) + exec "norm! 07l\" + call assert_equal("\2", getline(1)) + call assert_equal([0, 1, 2, 0], getpos('.')) + + call setline(1, ["\1"]) + exec "norm! 0w\" + call assert_equal("\2", getline(1)) + call assert_equal([0, 1, 2, 0], getpos('.')) + + call setline(1, ["\1"]) + exec "norm! 0wl\" + call assert_equal("\1", getline(1)) + call assert_equal([0, 1, 3, 0], getpos('.')) + + call setline(1, ["\1"]) + exec "norm! 0w30l\" + call assert_equal("\1", getline(1)) + call assert_equal([0, 1, 3, 29], getpos('.')) + + set virtualedit& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim index ecd0e8d56b..f48458566b 100644 --- a/src/nvim/testdir/test_regexp_utf8.vim +++ b/src/nvim/testdir/test_regexp_utf8.vim @@ -332,4 +332,23 @@ func Test_ambiwidth() set regexpengine& ambiwidth& endfunc +func Run_regexp_ignore_case() + call assert_equal('iIİ', substitute('iIİ', '\([iIİ]\)', '\1', 'g')) + + call assert_equal('iIx', substitute('iIİ', '\c\([İ]\)', 'x', 'g')) + call assert_equal('xxİ', substitute('iIİ', '\(i\c\)', 'x', 'g')) + call assert_equal('iIx', substitute('iIİ', '\(İ\c\)', 'x', 'g')) + call assert_equal('iIx', substitute('iIİ', '\c\(\%u0130\)', 'x', 'g')) + call assert_equal('iIx', substitute('iIİ', '\c\([\u0130]\)', 'x', 'g')) + call assert_equal('iIx', substitute('iIİ', '\c\([\u012f-\u0131]\)', 'x', 'g')) +endfunc + +func Test_regexp_ignore_case() + set regexpengine=1 + call Run_regexp_ignore_case() + set regexpengine=2 + call Run_regexp_ignore_case() + set regexpengine& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 5fd71d8bfc..6abe5b7c89 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -255,8 +255,52 @@ func Test_tagjump_etags() ta foo call assert_equal('void foo() {}', getline('.')) + " Test for including another tags file + call writefile([ + \ "\x0c", + \ "Xmain.c,64", + \ "void foo() {}\x7ffoo\x011,0", + \ "\x0c", + \ "Xnonexisting,include", + \ "\x0c", + \ "Xtags2,include" + \ ], 'Xtags') + call writefile([ + \ "\x0c", + \ "Xmain.c,64", + \ "int main(int argc, char **argv)\x7fmain\x012,14", + \ ], 'Xtags2') + tag main + call assert_equal(2, line('.')) + + " corrupted tag line + call writefile([ + \ "\x0c", + \ "Xmain.c,8", + \ "int main" + \ ], 'Xtags', 'b') + call assert_fails('tag foo', 'E426:') + + " invalid line number + call writefile([ + \ "\x0c", + \ "Xmain.c,64", + \ "void foo() {}\x7ffoo\x0abc,0", + \ ], 'Xtags') + call assert_fails('tag foo', 'E426:') + + " invalid tag name + call writefile([ + \ "\x0c", + \ "Xmain.c,64", + \ ";;;;\x7f1,0", + \ ], 'Xtags') + call assert_fails('tag foo', 'E426:') + call delete('Xtags') + call delete('Xtags2') call delete('Xmain.c') + set tags& bwipe! endfunc @@ -531,4 +575,29 @@ func Test_tagline() set tags& endfunc +" Test for the 'taglength' option +func Test_tag_length() + set tags=Xtags + call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", + \ "tame\tXfile1\t1;", + \ "tape\tXfile2\t1;"], 'Xtags') + call writefile(['tame'], 'Xfile1') + call writefile(['tape'], 'Xfile2') + + " Jumping to the tag 'tape', should instead jump to 'tame' + new + set taglength=2 + tag tape + call assert_equal('Xfile1', @%) + " Tag search should jump to the right tag + enew + tag /^tape$ + call assert_equal('Xfile2', @%) + + call delete('Xtags') + call delete('Xfile1') + call delete('Xfile2') + set tags& taglength& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim index b20c4df311..7863317eb0 100644 --- a/src/nvim/testdir/test_textobjects.vim +++ b/src/nvim/testdir/test_textobjects.vim @@ -290,5 +290,16 @@ func! Test_sentence_with_cursor_on_delimiter() normal! 17|yas call assert_equal("A '([sentence.])' ", @") + " don't get stuck on a quote at the start of a sentence + %delete _ + call setline(1, ['A sentence.', '"A sentence"?', 'A sentence!']) + normal gg)) + call assert_equal(3, getcurpos()[1]) + + %delete _ + call setline(1, ['A sentence.', "'A sentence'?", 'A sentence!']) + normal gg)) + call assert_equal(3, getcurpos()[1]) + %delete _ endfunc diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 3269fbc68d..394eb73187 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command +local ok = helpers.ok local eq = helpers.eq local matches = helpers.matches local eval = helpers.eval @@ -17,6 +18,7 @@ local rmdir = helpers.rmdir local sleep = helpers.sleep local iswin = helpers.iswin local write_file = helpers.write_file +local meths = helpers.meths describe('startup', function() before_each(function() @@ -357,3 +359,10 @@ describe('sysinit', function() eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')) end) end) + +describe('clean', function() + clear() + ok(string.match(meths.get_option('runtimepath'), funcs.stdpath('config')) ~= nil) + clear('--clean') + ok(string.match(meths.get_option('runtimepath'), funcs.stdpath('config')) == nil) +end) diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua index e774b939f7..14c02f9eb2 100644 --- a/test/functional/eval/input_spec.lua +++ b/test/functional/eval/input_spec.lua @@ -462,7 +462,7 @@ describe('confirm()', function() -- With shortmess-=F command('set shortmess-=F') feed(':edit foo') - check_and_clear('"foo" [New File] |\n') + check_and_clear('"foo" [New] |\n') -- With shortmess+=F command('set shortmess+=F') diff --git a/test/functional/ex_cmds/drop_spec.lua b/test/functional/ex_cmds/drop_spec.lua index 762ea3d166..ef53fe75e3 100644 --- a/test/functional/ex_cmds/drop_spec.lua +++ b/test/functional/ex_cmds/drop_spec.lua @@ -31,7 +31,7 @@ describe(":drop", function() {0:~ }| {0:~ }| {1:tmp1.vim }| - "tmp1.vim" [New File] | + "tmp1.vim" [New] | ]]) end) @@ -70,7 +70,7 @@ describe(":drop", function() {0:~ }{2:│}{0:~ }| {0:~ }{2:│}{0:~ }| {2:tmp2 [+] tmp1 }| - "tmp3" [New File] | + "tmp3" [New] | ]]) end) diff --git a/test/functional/options/shortmess_spec.lua b/test/functional/options/shortmess_spec.lua index 8ea9a19464..a56e9c09b4 100644 --- a/test/functional/options/shortmess_spec.lua +++ b/test/functional/options/shortmess_spec.lua @@ -25,7 +25,7 @@ describe("'shortmess'", function() ~ | ~ | ~ | - "foo" [New File] | + "foo" [New] | ]]) eq(1, eval('bufnr("%")')) @@ -50,7 +50,7 @@ describe("'shortmess'", function() ~ | ~ | ~ | - "foo" [New File] | + "foo" [New] | ]]) eq(1, eval('bufnr("%")')) feed(':edit bar') @@ -59,7 +59,7 @@ describe("'shortmess'", function() ~ | ~ | ~ | - "bar" [New File] | + "bar" [New] | ]]) eq(2, eval('bufnr("%")')) feed(':bprevious') @@ -68,7 +68,7 @@ describe("'shortmess'", function() ~ | ~ | ~ | - "foo" [New file] --No lines in buffer-- | + "foo" [New] --No lines in buffer-- | ]]) eq(1, eval('bufnr("%")')) diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua index a77a089763..465b553693 100644 --- a/test/unit/helpers.lua +++ b/test/unit/helpers.lua @@ -96,8 +96,8 @@ local init = only_separate(function() c.func(unpack(c.args)) end libnvim.time_init() - libnvim.early_init() libnvim.event_init() + libnvim.early_init(nil) if child_calls_mod then for _, c in ipairs(child_calls_mod) do c.func(unpack(c.args))