Merge pull request #12455 from janlazo/vim-8.0.1554

[RDY]vim-patch:8.0.1554,8.1.1977,8.2.{927,930,932,938,954,963,964,966,980,983,998,999}
This commit is contained in:
Matthieu Coudron 2020-06-22 22:40:33 +02:00 committed by GitHub
commit 8f30753aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 334 additions and 129 deletions

View File

@ -90,6 +90,7 @@ argument.
--clean Equivalent to "-u NONE -i NONE": --clean Equivalent to "-u NONE -i NONE":
- Skips initializations from files and environment variables. - Skips initializations from files and environment variables.
- No 'shada' file is read or written. - No 'shada' file is read or written.
- Excludes user directories from 'runtimepath'
*--noplugin* *--noplugin*
--noplugin Skip loading plugins. Resets the 'loadplugins' option. --noplugin Skip loading plugins. Resets the 'loadplugins' option.

View File

@ -458,7 +458,7 @@ au BufNewFile,BufRead *.desc setf desc
au BufNewFile,BufRead *.d call dist#ft#DtraceCheck() au BufNewFile,BufRead *.d call dist#ft#DtraceCheck()
" Desktop files " Desktop files
au BufNewFile,BufRead *.desktop,.directory setf desktop au BufNewFile,BufRead *.desktop,*.directory setf desktop
" Dict config " Dict config
au BufNewFile,BufRead dict.conf,.dictrc setf dictconf au BufNewFile,BufRead dict.conf,.dictrc setf dictconf
@ -1162,6 +1162,7 @@ else
endif endif
au BufNewFile,BufRead *.plx,*.al,*.psgi setf perl au BufNewFile,BufRead *.plx,*.al,*.psgi setf perl
au BufNewFile,BufRead *.p6,*.pm6,*.pl6 setf perl6 au BufNewFile,BufRead *.p6,*.pm6,*.pl6 setf perl6
au BufNewFile,BufRead *.raku,*.rakumod setf perl6
" Perl, XPM or XPM2 " Perl, XPM or XPM2
au BufNewFile,BufRead *.pm au BufNewFile,BufRead *.pm
@ -1291,7 +1292,8 @@ au BufNewFile,BufRead *.pyx,*.pxd setf pyrex
" Python, Python Shell Startup and Python Stub Files " Python, Python Shell Startup and Python Stub Files
" Quixote (Python-based web framework) " 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 " Radiance
au BufNewFile,BufRead *.rad,*.mat setf 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 au BufNewFile,BufRead *.sqr,*.sqi setf sqr
" OpenSSH configuration " 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 " 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 " Stata
au BufNewFile,BufRead *.ado,*.do,*.imata,*.mata setf stata au BufNewFile,BufRead *.ado,*.do,*.imata,*.mata setf stata

View File

@ -247,10 +247,12 @@ func s:StartDebug_term(dict)
endif endif
let response = '' let response = ''
for lnum in range(1,200) for lnum in range(1, 200)
if len(getbufline(s:gdbbuf, lnum)) > 0 && getbufline(s:gdbbuf, lnum)[0] =~ 'new-ui mi ' 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 " 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' if response =~ 'Undefined command'
echoerr 'Sorry, your gdb is too old, gdb 7.12 is required' echoerr 'Sorry, your gdb is too old, gdb 7.12 is required'
call s:CloseBuffers() call s:CloseBuffers()
@ -260,10 +262,9 @@ func s:StartDebug_term(dict)
" Success! " Success!
break break
endif endif
if response =~ 'Reading symbols from' && response !~ 'new-ui' elseif line1 =~ 'Reading symbols from' && line2 !~ 'new-ui mi '
" Reading symbols might take a while " Reading symbols might take a while, try more times
let try_count -= 1 let try_count -= 1
endif
endif endif
endfor endfor
if response =~ 'New UI allocated' if response =~ 'New UI allocated'

View File

@ -1,7 +1,7 @@
" Vim support file to detect file types in scripts " Vim support file to detect file types in scripts
" "
" Maintainer: Bram Moolenaar <Bram@vim.org> " Maintainer: Bram Moolenaar <Bram@vim.org>
" Last change: 2019 Jun 25 " Last change: 2020 Jun 07
" This file is called by an autocommand for every file that has just been " 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 " 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 =~# "^#!" if s:line1 =~# "^#!"
" A script that starts with "#!". " 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. " "#!/usr/bin/bash" to make matching easier.
" Recognize only a few {options} that are commonly used.
if s:line1 =~# '^#!\s*\S*\<env\s' if s:line1 =~# '^#!\s*\S*\<env\s'
let s:line1 = substitute(s:line1, '\S\+=\S\+', '', 'g') let s:line1 = substitute(s:line1, '\S\+=\S\+', '', 'g')
let s:line1 = substitute(s:line1, '\(-[iS]\|--ignore-environment\|--split-string\)', '', '')
let s:line1 = substitute(s:line1, '\<env\s\+', '', '') let s:line1 = substitute(s:line1, '\<env\s\+', '', '')
endif endif

View File

@ -3084,28 +3084,29 @@ fileinfo(
} }
vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s", vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s",
curbufIsChanged() ? (shortmess(SHM_MOD) curbufIsChanged()
? " [+]" : _(" [Modified]")) : " ", ? (shortmess(SHM_MOD) ? " [+]" : _(" [Modified]")) : " ",
(curbuf->b_flags & BF_NOTEDITED) (curbuf->b_flags & BF_NOTEDITED) && !bt_dontwrite(curbuf)
&& !bt_dontwrite(curbuf) ? _("[Not edited]") : "",
? _("[Not edited]") : "", (curbuf->b_flags & BF_NEW) && !bt_dontwrite(curbuf)
(curbuf->b_flags & BF_NEW) ? new_file_message() : "",
&& !bt_dontwrite(curbuf) (curbuf->b_flags & BF_READERR)
? _("[New file]") : "", ? _("[Read errors]") : "",
(curbuf->b_flags & BF_READERR) ? _("[Read errors]") : "", curbuf->b_p_ro
curbuf->b_p_ro ? (shortmess(SHM_RO) ? _("[RO]") ? (shortmess(SHM_RO) ? _("[RO]") : _("[readonly]")) : "",
: _("[readonly]")) : "", (curbufIsChanged()
(curbufIsChanged() || (curbuf->b_flags & BF_WRITE_MASK) || (curbuf->b_flags & BF_WRITE_MASK)
|| curbuf->b_p_ro) ? || curbuf->b_p_ro)
" " : ""); ? " " : "");
/* With 32 bit longs and more than 21,474,836 lines multiplying by 100 // With 32 bit longs and more than 21,474,836 lines multiplying by 100
* causes an overflow, thus for large numbers divide instead. */ // causes an overflow, thus for large numbers divide instead.
if (curwin->w_cursor.lnum > 1000000L) if (curwin->w_cursor.lnum > 1000000L) {
n = (int)(((long)curwin->w_cursor.lnum) / n = (int)(((long)curwin->w_cursor.lnum) /
((long)curbuf->b_ml.ml_line_count / 100L)); ((long)curbuf->b_ml.ml_line_count / 100L));
else } else {
n = (int)(((long)curwin->w_cursor.lnum * 100L) / n = (int)(((long)curwin->w_cursor.lnum * 100L) /
(long)curbuf->b_ml.ml_line_count); (long)curbuf->b_ml.ml_line_count);
}
if (curbuf->b_ml.ml_flags & ML_EMPTY) { if (curbuf->b_ml.ml_flags & ML_EMPTY) {
vim_snprintf_add((char *)buffer, IOSIZE, "%s", _(no_lines_msg)); vim_snprintf_add((char *)buffer, IOSIZE, "%s", _(no_lines_msg));
} else if (p_ru) { } else if (p_ru) {

View File

@ -8137,9 +8137,6 @@ void set_argv_var(char **argv, int argc)
list_T *l = tv_list_alloc(argc); list_T *l = tv_list_alloc(argc);
int i; int i;
if (l == NULL) {
getout(1);
}
tv_list_set_lock(l, VAR_FIXED); tv_list_set_lock(l, VAR_FIXED);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
tv_list_append_string(l, (const char *const)argv[i], -1); tv_list_append_string(l, (const char *const)argv[i], -1);

View File

@ -569,20 +569,21 @@ readfile(
return FAIL; return FAIL;
} }
} }
if (dir_of_file_exists(fname)) if (dir_of_file_exists(fname)) {
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0); filemess(curbuf, sfname, (char_u *)new_file_message(), 0);
else } else {
filemess(curbuf, sfname, filemess(curbuf, sfname, (char_u *)_("[New DIRECTORY]"), 0);
(char_u *)_("[New DIRECTORY]"), 0); }
/* Even though this is a new file, it might have been // Even though this is a new file, it might have been
* edited before and deleted. Get the old marks. */ // edited before and deleted. Get the old marks.
check_marks_read(); check_marks_read();
/* Set forced 'fileencoding'. */ // Set forced 'fileencoding'.
if (eap != NULL) if (eap != NULL) {
set_forced_fenc(eap); set_forced_fenc(eap);
}
apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname, apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname,
FALSE, curbuf, eap); false, curbuf, eap);
/* remember the current fileformat */ // remember the current fileformat
save_file_ff(curbuf); save_file_ff(curbuf);
if (aborting()) /* autocmds may abort script processing */ if (aborting()) /* autocmds may abort script processing */
@ -2203,6 +2204,11 @@ static void check_marks_read(void)
curbuf->b_marks_read = true; 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" * buf_write() - write to file "fname" lines "start" through "end"
* *
@ -3513,8 +3519,8 @@ restore_backup:
STRCAT(IObuff, _("[Device]")); STRCAT(IObuff, _("[Device]"));
c = TRUE; c = TRUE;
} else if (newfile) { } else if (newfile) {
STRCAT(IObuff, shortmess(SHM_NEW) ? _("[New]") : _("[New File]")); STRCAT(IObuff, new_file_message());
c = TRUE; c = true;
} }
if (no_eol) { if (no_eol) {
msg_add_eol(); msg_add_eol();

View File

@ -84,44 +84,11 @@
#endif #endif
#include "nvim/api/vim.h" #include "nvim/api/vim.h"
// Maximum number of commands from + or -c arguments.
#define MAX_ARG_CMDS 10
// values for "window_layout" // values for "window_layout"
#define WIN_HOR 1 // "-o" horizontally split windows #define WIN_HOR 1 // "-o" horizontally split windows
#define WIN_VER 2 // "-O" vertically split windows #define WIN_VER 2 // "-O" vertically split windows
#define WIN_TABS 3 // "-p" windows on tab pages #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. // Values for edit_type.
#define EDIT_NONE 0 // no edit type yet #define EDIT_NONE 0 // no edit type yet
#define EDIT_FILE 1 // file name argument[s] given, use argument list #define EDIT_FILE 1 // file name argument[s] given, use argument list
@ -188,7 +155,7 @@ bool event_teardown(void)
/// Performs early initialization. /// Performs early initialization.
/// ///
/// Needed for unit tests. Must be called after `time_init()`. /// Needed for unit tests. Must be called after `time_init()`.
void early_init(void) void early_init(mparm_T *paramp)
{ {
env_init(); env_init();
fs_init(); fs_init();
@ -222,7 +189,7 @@ void early_init(void)
// msg_outtrans_len_attr(). // msg_outtrans_len_attr().
// First find out the home directory, needed to expand "~" in options. // First find out the home directory, needed to expand "~" in options.
init_homedir(); // find real value of $HOME init_homedir(); // find real value of $HOME
set_init_1(); set_init_1(paramp != NULL ? paramp->clean : false);
log_init(); log_init();
TIME_MSG("inits 1"); TIME_MSG("inits 1");
@ -265,9 +232,17 @@ int main(int argc, char **argv)
init_startuptime(&params); init_startuptime(&params);
// 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(); event_init();
early_init(); early_init(&params);
set_argv_var(argv, argc); // set v:argv set_argv_var(argv, argc); // set v:argv
@ -862,6 +837,7 @@ static void command_line_scan(mparm_T *parmp)
argv_idx += 11; argv_idx += 11;
} else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) { } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) {
parmp->use_vimrc = "NONE"; parmp->use_vimrc = "NONE";
parmp->clean = true;
set_option_value("shadafile", 0L, "NONE", 0); set_option_value("shadafile", 0L, "NONE", 0);
} else { } else {
if (argv[0][argv_idx]) 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. /// Initialize global startuptime file if "--startuptime" passed as an argument.
static void init_startuptime(mparm_T *paramp) static void init_startuptime(mparm_T *paramp)
{ {
for (int i = 1; i < paramp->argc; i++) { for (int i = 1; i < paramp->argc - 1; i++) {
if (STRICMP(paramp->argv[i], "--startuptime") == 0 if (STRICMP(paramp->argv[i], "--startuptime") == 0) {
&& i + 1 < paramp->argc) {
time_fd = os_fopen(paramp->argv[i + 1], "a"); time_fd = os_fopen(paramp->argv[i + 1], "a");
time_start("--- NVIM STARTING ---"); time_start("--- NVIM STARTING ---");
break; break;

View File

@ -4,8 +4,42 @@
#include "nvim/normal.h" #include "nvim/normal.h"
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
// Maximum number of commands from + or -c arguments.
#define MAX_ARG_CMDS 10
extern Loop main_loop; 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 #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "main.h.generated.h" # include "main.h.generated.h"
#endif #endif

View File

@ -4671,17 +4671,23 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
int maxlen = 0; int maxlen = 0;
pos_T startpos; pos_T startpos;
pos_T endpos; pos_T endpos;
colnr_T save_coladd = 0;
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX" dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX"
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal" dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal"
dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin" dobin = (vim_strchr(curbuf->b_p_nf, 'b') != NULL); // "Bin"
doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha" doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); // "alPha"
if (virtual_active()) {
save_coladd = pos->coladd;
pos->coladd = 0;
}
curwin->w_cursor = *pos; curwin->w_cursor = *pos;
ptr = ml_get(pos->lnum); ptr = ml_get(pos->lnum);
col = pos->col; col = pos->col;
if (*ptr == NUL) { if (*ptr == NUL || col + !!save_coladd >= (int)STRLEN(ptr)) {
goto theend; goto theend;
} }
@ -4976,6 +4982,8 @@ theend:
curwin->w_cursor = save_cursor; curwin->w_cursor = save_cursor;
} else if (did_change) { } else if (did_change) {
curwin->w_set_curswant = true; curwin->w_set_curswant = true;
} else if (virtual_active()) {
curwin->w_cursor.coladd = save_coladd;
} }
return did_change; return did_change;

View File

@ -524,11 +524,17 @@ char *get_lib_dir(void)
/// ///
/// Windows: Uses "…/nvim-data" for kXDGDataHome to avoid storing /// Windows: Uses "…/nvim-data" for kXDGDataHome to avoid storing
/// configuration and data files in the same path. #4403 /// 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; size_t rtp_size = 0;
char *const data_home = stdpaths_get_xdg_var(kXDGDataHome); char *const data_home = clean_arg
char *const config_home = stdpaths_get_xdg_var(kXDGConfigHome); ? 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 vimruntime = vim_getenv("VIMRUNTIME");
char *const libdir = get_lib_dir(); char *const libdir = get_lib_dir();
char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs); char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs);
@ -622,7 +628,8 @@ static void set_runtimepath_default(void)
/// Initialize the options, first part. /// Initialize the options, first part.
/// ///
/// Called only once from main(), just after creating the first buffer. /// 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; int opt_idx;
@ -765,7 +772,7 @@ void set_init_1(void)
true); true);
// Set default for &runtimepath. All necessary expansions are performed in // Set default for &runtimepath. All necessary expansions are performed in
// this function. // this function.
set_runtimepath_default(); set_runtimepath_default(clean_arg);
/* /*
* Set all the options (except the terminal options) to their default * 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 valid_name(val, ".-_");
} }
/// Return true if "val" is a valid 'spellang' value. /// Return true if "val" is a valid 'spelllang' value.
bool valid_spellang(const char_u *val) bool valid_spelllang(const char_u *val)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{ {
return valid_name(val, ".-_,@"); return valid_name(val, ".-_,@");
@ -3071,7 +3078,7 @@ ambw_end:
const bool is_spellfile = varp == &(curwin->w_s->b_p_spf); const bool is_spellfile = varp == &(curwin->w_s->b_p_spf);
if ((is_spellfile && !valid_spellfile(*varp)) if ((is_spellfile && !valid_spellfile(*varp))
|| (!is_spellfile && !valid_spellang(*varp))) { || (!is_spellfile && !valid_spelllang(*varp))) {
errmsg = e_invarg; errmsg = e_invarg;
} else { } else {
errmsg = did_set_spell_option(is_spellfile); 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" // replace home directory in the whole option value into "buf"
buf = xmalloc(size); buf = xmalloc(size);
if (buf == NULL) {
goto fail;
}
home_replace(NULL, *valuep, buf, size, false); home_replace(NULL, *valuep, buf, size, false);
// If the option value is longer than MAXPATHL, we need to append // 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. // can be expanded when read back.
if (size >= MAXPATHL && (flags & P_COMMA) != 0 if (size >= MAXPATHL && (flags & P_COMMA) != 0
&& vim_strchr(*valuep, ',') != NULL) { && vim_strchr(*valuep, ',') != NULL) {
part = xmalloc(size); part = xmalloc(size);
if (part == NULL) {
goto fail;
}
// write line break to clear the option, e.g. ':set rtp=' // write line break to clear the option, e.g. ':set rtp='
if (put_eol(fd) == FAIL) { if (put_eol(fd) == FAIL) {

View File

@ -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_len = PTR2LEN(s2);
int c2 = PTR2CHAR(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) { || c1_len != c2_len) {
match = false; match = false;
break; break;
@ -5682,11 +5682,11 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
break; break;
} }
if (rex.reg_ic) { if (rex.reg_ic) {
int curc_low = mb_tolower(curc); int curc_low = utf_fold(curc);
int done = false; int done = false;
for (; c1 <= c2; c1++) { for (; c1 <= c2; c1++) {
if (mb_tolower(c1) == curc_low) { if (utf_fold(c1) == curc_low) {
result = result_if_matched; result = result_if_matched;
done = TRUE; done = TRUE;
break; 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) } else if (state->c < 0 ? check_char_class(state->c, curc)
: (curc == state->c : (curc == state->c
|| (rex.reg_ic && mb_tolower(curc) || (rex.reg_ic
== mb_tolower(state->c)))) { && utf_fold(curc) == utf_fold(state->c)))) {
result = result_if_matched; result = result_if_matched;
break; break;
} }
@ -6106,7 +6106,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
result = (c == curc); result = (c == curc);
if (!result && rex.reg_ic) { 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 // 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 // Checking if the required start character matches is
// cheaper than adding a state that won't match. // cheaper than adding a state that won't match.
c = PTR2CHAR(reginput + clen); c = PTR2CHAR(reginput + clen);
if (c != prog->regstart && (!rex.reg_ic || mb_tolower(c) if (c != prog->regstart
!= mb_tolower(prog->regstart))) { && (!rex.reg_ic
|| utf_fold(c) != utf_fold(prog->regstart))) {
#ifdef REGEXP_DEBUG #ifdef REGEXP_DEBUG
fprintf(log_fd, fprintf(log_fd,
" Skipping start state, regstart does not match\n"); " Skipping start state, regstart does not match\n");

View File

@ -2326,9 +2326,9 @@ int findsent(Direction dir, long count)
func = decl; func = decl;
while (count--) { while (count--) {
/* const pos_T prev_pos = pos;
* if on an empty line, skip up to a non-empty line
*/ // if on an empty line, skip up to a non-empty line
if (gchar_pos(&pos) == NUL) { if (gchar_pos(&pos) == NUL) {
do { do {
if ((*func)(&pos) == -1) { if ((*func)(&pos) == -1) {
@ -2411,6 +2411,17 @@ found:
while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t'))
if (incl(&pos) == -1) if (incl(&pos) == -1)
break; 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(); setpcmark();

View File

@ -2007,7 +2007,7 @@ char_u *did_set_spelllang(win_T *wp)
region = NULL; region = NULL;
len = (int)STRLEN(lang); len = (int)STRLEN(lang);
if (!valid_spellang(lang)) { if (!valid_spelllang(lang)) {
continue; continue;
} }

View File

@ -1252,6 +1252,10 @@ func Test_TextYankPost()
call assert_equal( call assert_equal(
\{'regcontents': ['foo'], 'inclusive': v:false, 'regname': '', 'operator': 'y', 'visual': v:false, 'regtype': 'V'}, \{'regcontents': ['foo'], 'inclusive': v:false, 'regname': '', 'operator': 'y', 'visual': v:false, 'regtype': 'V'},
\g:event) \g:event)
norm Vy
call assert_equal(
\{'regcontents': ['foo'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'visual': v:true, 'regtype': 'V'},
\g:event)
call feedkeys("\<C-V>y", 'x') call feedkeys("\<C-V>y", 'x')
call assert_equal( call assert_equal(
\{'regcontents': ['f'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'visual': v:true, 'regtype': "\x161"}, \{'regcontents': ['f'], 'inclusive': v:true, 'regname': '', 'operator': 'y', 'visual': v:true, 'regtype': "\x161"},

View File

@ -131,7 +131,7 @@ let s:filename_checks = {
\ 'def': ['file.def'], \ 'def': ['file.def'],
\ 'denyhosts': ['denyhosts.conf'], \ 'denyhosts': ['denyhosts.conf'],
\ 'desc': ['file.desc'], \ 'desc': ['file.desc'],
\ 'desktop': ['file.desktop', '.directory'], \ 'desktop': ['file.desktop', '.directory', 'file.directory'],
\ 'dictconf': ['dict.conf', '.dictrc'], \ 'dictconf': ['dict.conf', '.dictrc'],
\ 'dictdconf': ['dictd.conf'], \ 'dictdconf': ['dictd.conf'],
\ 'diff': ['file.diff', 'file.rej'], \ 'diff': ['file.diff', 'file.rej'],
@ -329,7 +329,7 @@ let s:filename_checks = {
\ 'pccts': ['file.g'], \ 'pccts': ['file.g'],
\ 'pdf': ['file.pdf'], \ 'pdf': ['file.pdf'],
\ 'perl': ['file.plx', 'file.al', 'file.psgi', 'gitolite.rc', '.gitolite.rc', 'example.gitolite.rc'], \ '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'], \ 'pf': ['pf.conf'],
\ 'pfmain': ['main.cf'], \ 'pfmain': ['main.cf'],
\ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp'], \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp'],
@ -360,7 +360,7 @@ let s:filename_checks = {
\ 'protocols': ['/etc/protocols'], \ 'protocols': ['/etc/protocols'],
\ 'psf': ['file.psf'], \ 'psf': ['file.psf'],
\ 'pyrex': ['file.pyx', 'file.pxd'], \ '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'], \ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg'],
\ 'radiance': ['file.rad', 'file.mat'], \ 'radiance': ['file.rad', 'file.mat'],
\ 'ratpoison': ['.ratpoisonrc', 'ratpoisonrc'], \ 'ratpoison': ['.ratpoisonrc', 'ratpoisonrc'],
@ -427,8 +427,8 @@ let s:filename_checks = {
\ 'sqr': ['file.sqr', 'file.sqi'], \ 'sqr': ['file.sqr', 'file.sqi'],
\ 'squid': ['squid.conf'], \ 'squid': ['squid.conf'],
\ 'srec': ['file.s19', 'file.s28', 'file.s37', 'file.mot', 'file.srec'], \ 'srec': ['file.s19', 'file.s28', 'file.s37', 'file.mot', 'file.srec'],
\ 'sshconfig': ['ssh_config', '/.ssh/config'], \ 'sshconfig': ['ssh_config', '/.ssh/config', '/etc/ssh/ssh_config.d/file.conf', 'any/etc/ssh/ssh_config.d/file.conf'],
\ 'sshdconfig': ['sshd_config'], \ 'sshdconfig': ['sshd_config', '/etc/ssh/sshd_config.d/file.conf', 'any/etc/ssh/sshd_config.d/file.conf'],
\ 'st': ['file.st'], \ 'st': ['file.st'],
\ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'], \ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'],
\ 'stp': ['file.stp'], \ 'stp': ['file.stp'],
@ -606,9 +606,19 @@ let s:script_checks = {
\ 'yaml': [['%YAML 1.2']], \ '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 filetype on
for [ft, files] in items(s:script_checks) for [ft, files] in items(a:test_dict)
for file in files for file in files
call writefile(file, 'Xtest') call writefile(file, 'Xtest')
split Xtest split Xtest
@ -620,6 +630,11 @@ func Test_script_detection()
filetype off filetype off
endfunc 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() func Test_setfiletype_completion()
call feedkeys(":setfiletype java\<C-A>\<C-B>\"\<CR>", 'tx') call feedkeys(":setfiletype java\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"setfiletype java javacc javascript javascriptreact', @:) call assert_equal('"setfiletype java javacc javascript javascriptreact', @:)

View File

@ -779,4 +779,40 @@ func Test_increment_empty_line()
bwipe! bwipe!
endfunc endfunc
func Test_normal_increment_with_virtualedit()
set virtualedit=all
call setline(1, ["\<TAB>1"])
exec "norm! 0\<C-A>"
call assert_equal("\<TAB>2", getline(1))
call assert_equal([0, 1, 2, 0], getpos('.'))
call setline(1, ["\<TAB>1"])
exec "norm! 0l\<C-A>"
call assert_equal("\<TAB>2", getline(1))
call assert_equal([0, 1, 2, 0], getpos('.'))
call setline(1, ["\<TAB>1"])
exec "norm! 07l\<C-A>"
call assert_equal("\<TAB>2", getline(1))
call assert_equal([0, 1, 2, 0], getpos('.'))
call setline(1, ["\<TAB>1"])
exec "norm! 0w\<C-A>"
call assert_equal("\<TAB>2", getline(1))
call assert_equal([0, 1, 2, 0], getpos('.'))
call setline(1, ["\<TAB>1"])
exec "norm! 0wl\<C-A>"
call assert_equal("\<TAB>1", getline(1))
call assert_equal([0, 1, 3, 0], getpos('.'))
call setline(1, ["\<TAB>1"])
exec "norm! 0w30l\<C-A>"
call assert_equal("\<TAB>1", getline(1))
call assert_equal([0, 1, 3, 29], getpos('.'))
set virtualedit&
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -332,4 +332,23 @@ func Test_ambiwidth()
set regexpengine& ambiwidth& set regexpengine& ambiwidth&
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -255,8 +255,52 @@ func Test_tagjump_etags()
ta foo ta foo
call assert_equal('void foo() {}', getline('.')) 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('Xtags')
call delete('Xtags2')
call delete('Xmain.c') call delete('Xmain.c')
set tags&
bwipe! bwipe!
endfunc endfunc
@ -531,4 +575,29 @@ func Test_tagline()
set tags& set tags&
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -290,5 +290,16 @@ func! Test_sentence_with_cursor_on_delimiter()
normal! 17|yas normal! 17|yas
call assert_equal("A '([sentence.])' ", @") 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 _ %delete _
endfunc endfunc

View File

@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear local clear = helpers.clear
local command = helpers.command local command = helpers.command
local ok = helpers.ok
local eq = helpers.eq local eq = helpers.eq
local matches = helpers.matches local matches = helpers.matches
local eval = helpers.eval local eval = helpers.eval
@ -17,6 +18,7 @@ local rmdir = helpers.rmdir
local sleep = helpers.sleep local sleep = helpers.sleep
local iswin = helpers.iswin local iswin = helpers.iswin
local write_file = helpers.write_file local write_file = helpers.write_file
local meths = helpers.meths
describe('startup', function() describe('startup', function()
before_each(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))')) eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
end) end)
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)

View File

@ -462,7 +462,7 @@ describe('confirm()', function()
-- With shortmess-=F -- With shortmess-=F
command('set shortmess-=F') command('set shortmess-=F')
feed(':edit foo<cr>') feed(':edit foo<cr>')
check_and_clear('"foo" [New File] |\n') check_and_clear('"foo" [New] |\n')
-- With shortmess+=F -- With shortmess+=F
command('set shortmess+=F') command('set shortmess+=F')

View File

@ -31,7 +31,7 @@ describe(":drop", function()
{0:~ }| {0:~ }|
{0:~ }| {0:~ }|
{1:tmp1.vim }| {1:tmp1.vim }|
"tmp1.vim" [New File] | "tmp1.vim" [New] |
]]) ]])
end) end)
@ -70,7 +70,7 @@ describe(":drop", function()
{0:~ }{2:}{0:~ }| {0:~ }{2:}{0:~ }|
{0:~ }{2:}{0:~ }| {0:~ }{2:}{0:~ }|
{2:tmp2 [+] tmp1 }| {2:tmp2 [+] tmp1 }|
"tmp3" [New File] | "tmp3" [New] |
]]) ]])
end) end)

View File

@ -25,7 +25,7 @@ describe("'shortmess'", function()
~ | ~ |
~ | ~ |
~ | ~ |
"foo" [New File] | "foo" [New] |
]]) ]])
eq(1, eval('bufnr("%")')) eq(1, eval('bufnr("%")'))
@ -50,7 +50,7 @@ describe("'shortmess'", function()
~ | ~ |
~ | ~ |
~ | ~ |
"foo" [New File] | "foo" [New] |
]]) ]])
eq(1, eval('bufnr("%")')) eq(1, eval('bufnr("%")'))
feed(':edit bar<CR>') feed(':edit bar<CR>')
@ -59,7 +59,7 @@ describe("'shortmess'", function()
~ | ~ |
~ | ~ |
~ | ~ |
"bar" [New File] | "bar" [New] |
]]) ]])
eq(2, eval('bufnr("%")')) eq(2, eval('bufnr("%")'))
feed(':bprevious<CR>') feed(':bprevious<CR>')
@ -68,7 +68,7 @@ describe("'shortmess'", function()
~ | ~ |
~ | ~ |
~ | ~ |
"foo" [New file] --No lines in buffer-- | "foo" [New] --No lines in buffer-- |
]]) ]])
eq(1, eval('bufnr("%")')) eq(1, eval('bufnr("%")'))

View File

@ -96,8 +96,8 @@ local init = only_separate(function()
c.func(unpack(c.args)) c.func(unpack(c.args))
end end
libnvim.time_init() libnvim.time_init()
libnvim.early_init()
libnvim.event_init() libnvim.event_init()
libnvim.early_init(nil)
if child_calls_mod then if child_calls_mod then
for _, c in ipairs(child_calls_mod) do for _, c in ipairs(child_calls_mod) do
c.func(unpack(c.args)) c.func(unpack(c.args))