mirror of
https://github.com/neovim/neovim.git
synced 2025-01-01 17:23:36 -07:00
vim-patch:7.4.672
Problem: When completing a shell command, directories in the current
directory are not listed.
Solution: When "." is not in $PATH also look in the current directory for
directories.
b5971141df
Most of it applied manually.
This commit is contained in:
parent
d542de4a76
commit
00c35ab3b4
@ -8692,7 +8692,11 @@ static void f_eventhandler(typval_T *argvars, typval_T *rettv)
|
|||||||
*/
|
*/
|
||||||
static void f_executable(typval_T *argvars, typval_T *rettv)
|
static void f_executable(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = os_can_exe(get_tv_string(&argvars[0]), NULL);
|
char_u *name = get_tv_string(&argvars[0]);
|
||||||
|
|
||||||
|
// Check in $PATH and also check directly if there is a directory name
|
||||||
|
rettv->vval.v_number = os_can_exe(name, NULL, true)
|
||||||
|
|| (gettail_dir(name) != name && os_can_exe(name, NULL, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "exepath()" function
|
/// "exepath()" function
|
||||||
@ -8701,7 +8705,7 @@ static void f_exepath(typval_T *argvars, typval_T *rettv)
|
|||||||
char_u *arg = get_tv_string(&argvars[0]);
|
char_u *arg = get_tv_string(&argvars[0]);
|
||||||
char_u *path = NULL;
|
char_u *path = NULL;
|
||||||
|
|
||||||
(void)os_can_exe(arg, &path);
|
(void)os_can_exe(arg, &path, true);
|
||||||
|
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = path;
|
rettv->vval.v_string = path;
|
||||||
@ -11606,7 +11610,7 @@ static char **tv_to_argv(typval_T *cmd_tv, char **cmd)
|
|||||||
assert(argl->lv_first);
|
assert(argl->lv_first);
|
||||||
|
|
||||||
const char_u *exe = get_tv_string_chk(&argl->lv_first->li_tv);
|
const char_u *exe = get_tv_string_chk(&argl->lv_first->li_tv);
|
||||||
if (!exe || !os_can_exe(exe, NULL)) {
|
if (!exe || !os_can_exe(exe, NULL, true)) {
|
||||||
// String is not executable
|
// String is not executable
|
||||||
if (exe) {
|
if (exe) {
|
||||||
EMSG2(e_jobexe, exe);
|
EMSG2(e_jobexe, exe);
|
||||||
|
@ -3983,6 +3983,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
|
|||||||
char_u *s, *e;
|
char_u *s, *e;
|
||||||
int flags = flagsarg;
|
int flags = flagsarg;
|
||||||
int ret;
|
int ret;
|
||||||
|
bool did_curdir = false;
|
||||||
|
|
||||||
/* for ":set path=" and ":set tags=" halve backslashes for escaped
|
/* for ":set path=" and ":set tags=" halve backslashes for escaped
|
||||||
* space */
|
* space */
|
||||||
@ -3991,7 +3992,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
|
|||||||
if (pat[i] == '\\' && pat[i + 1] == ' ')
|
if (pat[i] == '\\' && pat[i + 1] == ' ')
|
||||||
STRMOVE(pat + i, pat + i + 1);
|
STRMOVE(pat + i, pat + i + 1);
|
||||||
|
|
||||||
flags |= EW_FILE | EW_EXEC;
|
flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
|
||||||
|
|
||||||
bool mustfree = false; // Track memory allocation for *path.
|
bool mustfree = false; // Track memory allocation for *path.
|
||||||
/* For an absolute name we don't use $PATH. */
|
/* For an absolute name we don't use $PATH. */
|
||||||
@ -4011,10 +4012,23 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Go over all directories in $PATH. Expand matches in that directory and
|
* Go over all directories in $PATH. Expand matches in that directory and
|
||||||
* collect them in "ga".
|
* collect them in "ga". When "." is not in $PATH also expaned for the
|
||||||
|
* current directory, to find "subdir/cmd".
|
||||||
*/
|
*/
|
||||||
ga_init(&ga, (int)sizeof(char *), 10);
|
ga_init(&ga, (int)sizeof(char *), 10);
|
||||||
for (s = path; *s != NUL; s = e) {
|
for (s = path; ; s = e) {
|
||||||
|
if (*s == NUL)
|
||||||
|
{
|
||||||
|
if (did_curdir) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Find directories in the current directory, path is empty.
|
||||||
|
did_curdir = true;
|
||||||
|
}
|
||||||
|
else if (*s == '.') {
|
||||||
|
did_curdir = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (*s == ' ')
|
if (*s == ' ')
|
||||||
++s; /* Skip space used for absolute path name. */
|
++s; /* Skip space used for absolute path name. */
|
||||||
|
|
||||||
|
@ -164,6 +164,7 @@ int os_nodetype(const char *name)
|
|||||||
///
|
///
|
||||||
/// @param[in] name Name of the executable.
|
/// @param[in] name Name of the executable.
|
||||||
/// @param[out] abspath Path of the executable, if found and not `NULL`.
|
/// @param[out] abspath Path of the executable, if found and not `NULL`.
|
||||||
|
/// @param[in] use_path If 'false', only check if "name" is executable
|
||||||
///
|
///
|
||||||
/// @return `true` if `name` is executable and
|
/// @return `true` if `name` is executable and
|
||||||
/// - can be found in $PATH,
|
/// - can be found in $PATH,
|
||||||
@ -171,15 +172,18 @@ int os_nodetype(const char *name)
|
|||||||
/// - is absolute.
|
/// - is absolute.
|
||||||
///
|
///
|
||||||
/// @return `false` otherwise.
|
/// @return `false` otherwise.
|
||||||
bool os_can_exe(const char_u *name, char_u **abspath)
|
bool os_can_exe(const char_u *name, char_u **abspath, bool use_path)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
// If it's an absolute or relative path don't need to use $PATH.
|
// when use_path is false or if it's an absolute or relative path don't
|
||||||
if (path_is_absolute_path(name)
|
// need to use $PATH.
|
||||||
|
if (!use_path || path_is_absolute_path(name)
|
||||||
|| (name[0] == '.'
|
|| (name[0] == '.'
|
||||||
&& (name[1] == '/'
|
&& (name[1] == '/'
|
||||||
|| (name[1] == '.' && name[2] == '/')))) {
|
|| (name[1] == '.' && name[2] == '/')))) {
|
||||||
if (is_executable(name)) {
|
// There must be a path separator, files in the current directory
|
||||||
|
// can't be executed
|
||||||
|
if (gettail_dir(name) != name && is_executable(name)) {
|
||||||
if (abspath != NULL) {
|
if (abspath != NULL) {
|
||||||
*abspath = save_absolute_path(name);
|
*abspath = save_absolute_path(name);
|
||||||
}
|
}
|
||||||
|
@ -577,7 +577,8 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Skip files that are not executable if we check for that. */
|
/* Skip files that are not executable if we check for that. */
|
||||||
if (!dir && (flags & EW_EXEC) && !os_can_exe((*file)[i], NULL))
|
if (!dir && (flags & EW_EXEC)
|
||||||
|
&& !os_can_exe((*file)[i], NULL, !(flags & EW_SHELLCMD)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p = xmalloc(STRLEN((*file)[i]) + 1 + dir);
|
p = xmalloc(STRLEN((*file)[i]) + 1 + dir);
|
||||||
|
@ -981,12 +981,12 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
|
|||||||
* "/path/file", "/path/dir/", "/path//dir", "/file"
|
* "/path/file", "/path/dir/", "/path//dir", "/file"
|
||||||
* ^ ^ ^ ^
|
* ^ ^ ^ ^
|
||||||
*/
|
*/
|
||||||
static char_u *gettail_dir(char_u *fname)
|
char_u *gettail_dir(const char_u *fname)
|
||||||
{
|
{
|
||||||
char_u *dir_end = fname;
|
const char_u *dir_end = fname;
|
||||||
char_u *next_dir_end = fname;
|
const char_u *next_dir_end = fname;
|
||||||
bool look_for_sep = true;
|
bool look_for_sep = true;
|
||||||
char_u *p;
|
const char_u *p;
|
||||||
|
|
||||||
for (p = fname; *p != NUL; ) {
|
for (p = fname; *p != NUL; ) {
|
||||||
if (vim_ispathsep(*p)) {
|
if (vim_ispathsep(*p)) {
|
||||||
@ -1001,7 +1001,7 @@ static char_u *gettail_dir(char_u *fname)
|
|||||||
}
|
}
|
||||||
mb_ptr_adv(p);
|
mb_ptr_adv(p);
|
||||||
}
|
}
|
||||||
return dir_end;
|
return (char_u *)dir_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1318,8 +1318,10 @@ void addfile(
|
|||||||
if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE)))
|
if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If the file isn't executable, may not add it. Do accept directories. */
|
// If the file isn't executable, may not add it. Do accept directories.
|
||||||
if (!isdir && (flags & EW_EXEC) && !os_can_exe(f, NULL))
|
// When invoked from expand_shellcmd() do not use $PATH.
|
||||||
|
if (!isdir && (flags & EW_EXEC)
|
||||||
|
&& !os_can_exe(f, NULL, !(flags & EW_SHELLCMD)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char_u *p = xmalloc(STRLEN(f) + 1 + isdir);
|
char_u *p = xmalloc(STRLEN(f) + 1 + isdir);
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
|
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
|
||||||
* is used when executing commands and EW_SILENT for interactive expanding. */
|
* is used when executing commands and EW_SILENT for interactive expanding. */
|
||||||
#define EW_ALLLINKS 0x1000 // also links not pointing to existing file
|
#define EW_ALLLINKS 0x1000 // also links not pointing to existing file
|
||||||
|
#define EW_SHELLCMD 0x2000 // called from expand_shellcmd(), don't check
|
||||||
|
// if executable is in $PATH
|
||||||
#define EW_DODOT 0x4000 // also files starting with a dot
|
#define EW_DODOT 0x4000 // also files starting with a dot
|
||||||
#define EW_EMPTYOK 0x8000 // no matches is not an error
|
#define EW_EMPTYOK 0x8000 // no matches is not an error
|
||||||
|
|
||||||
|
@ -1006,7 +1006,7 @@ static int included_patches[] = {
|
|||||||
675,
|
675,
|
||||||
// 674 NA
|
// 674 NA
|
||||||
673,
|
673,
|
||||||
// 672,
|
672,
|
||||||
671,
|
671,
|
||||||
670,
|
670,
|
||||||
// 669 NA
|
// 669 NA
|
||||||
|
@ -148,7 +148,7 @@ describe('fs function', function()
|
|||||||
local function os_can_exe(name)
|
local function os_can_exe(name)
|
||||||
local buf = ffi.new('char *[1]')
|
local buf = ffi.new('char *[1]')
|
||||||
buf[0] = NULL
|
buf[0] = NULL
|
||||||
local ok = fs.os_can_exe(to_cstr(name), buf)
|
local ok = fs.os_can_exe(to_cstr(name), buf, true)
|
||||||
|
|
||||||
-- When os_can_exe returns true, it must set the path.
|
-- When os_can_exe returns true, it must set the path.
|
||||||
-- When it returns false, the path must be NULL.
|
-- When it returns false, the path must be NULL.
|
||||||
|
Loading…
Reference in New Issue
Block a user