aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/file_search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/file_search.c')
-rw-r--r--src/nvim/file_search.c110
1 files changed, 86 insertions, 24 deletions
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 2ac8e27047..8094a1b266 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// File searching functions for 'path', 'tags' and 'cdpath' options.
//
// External visible functions:
@@ -48,6 +51,7 @@
#include <limits.h>
#include "nvim/vim.h"
+#include "nvim/eval.h"
#include "nvim/ascii.h"
#include "nvim/file_search.h"
#include "nvim/charset.h"
@@ -192,7 +196,6 @@ typedef struct ff_search_ctx_T {
static char_u e_pathtoolong[] = N_("E854: path too long for completion");
-
/*
* Initialization routine for vim_findfile().
*
@@ -322,8 +325,11 @@ vim_findfile_init (
drive[0] = path[0];
drive[1] = ':';
drive[2] = NUL;
- if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+ if (vim_FullName((const char *)drive, (char *)ff_expand_buffer, MAXPATHL,
+ true)
+ == FAIL) {
goto error_return;
+ }
path += 2;
} else
#endif
@@ -636,9 +642,8 @@ char_u *vim_findfile(void *search_ctx_arg)
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("Already Searched: %s (%s)",
- stackp->ffs_fix_path, stackp->ffs_wc_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ stackp->ffs_fix_path, stackp->ffs_wc_path);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -650,8 +655,7 @@ char_u *vim_findfile(void *search_ctx_arg)
verbose_enter_scroll();
smsg("Searching: %s (%s)",
stackp->ffs_fix_path, stackp->ffs_wc_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -809,10 +813,8 @@ char_u *vim_findfile(void *search_ctx_arg)
) == FAIL) {
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("Already: %s",
- file_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ smsg("Already: %s", file_path);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
continue;
@@ -837,8 +839,7 @@ char_u *vim_findfile(void *search_ctx_arg)
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("HIT: %s", file_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -999,10 +1000,8 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("ff_get_visited_list: FOUND list for %s",
- filename);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ smsg("ff_get_visited_list: FOUND list for %s", filename);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -1016,8 +1015,7 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("ff_get_visited_list: new list for %s", filename);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -1062,7 +1060,7 @@ static bool ff_wc_equal(char_u *s1, char_u *s2)
c1 = PTR2CHAR(s1 + i);
c2 = PTR2CHAR(s2 + j);
- if ((p_fic ? vim_tolower(c1) != vim_tolower(c2) : c1 != c2)
+ if ((p_fic ? mb_tolower(c1) != mb_tolower(c2) : c1 != c2)
&& (prev1 != '*' || prev2 != '*')) {
return false;
}
@@ -1370,6 +1368,11 @@ find_file_in_path_option (
char_u *buf = NULL;
int rel_to_curdir;
+ if (rel_fname != NULL && path_with_url((const char *)rel_fname)) {
+ // Do not attempt to search "relative" to a URL. #6009
+ rel_fname = NULL;
+ }
+
if (first == TRUE) {
/* copy file name into NameBuff, expanding environment variables */
save_char = ptr[len];
@@ -1522,26 +1525,85 @@ theend:
return file_name;
}
+void do_autocmd_dirchanged(char *new_dir, CdScope scope)
+{
+ static bool recursive = false;
+
+ if (recursive || !has_event(EVENT_DIRCHANGED)) {
+ // No autocommand was defined or we changed
+ // the directory from this autocommand.
+ return;
+ }
+
+ recursive = true;
+
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+ char buf[8];
+
+ switch (scope) {
+ case kCdScopeGlobal:
+ snprintf(buf, sizeof(buf), "global");
+ break;
+ case kCdScopeTab:
+ snprintf(buf, sizeof(buf), "tab");
+ break;
+ case kCdScopeWindow:
+ snprintf(buf, sizeof(buf), "window");
+ break;
+ case kCdScopeInvalid:
+ // Should never happen.
+ assert(false);
+ }
+
+ tv_dict_add_str(dict, S_LEN("scope"), buf);
+ tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
+ tv_dict_set_keys_readonly(dict);
+
+ apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
+ NULL);
+
+ tv_dict_clear(dict);
+
+ recursive = false;
+}
+
/// Change to a file's directory.
/// Caller must call shorten_fnames()!
/// @return OK or FAIL
int vim_chdirfile(char_u *fname)
{
- char_u dir[MAXPATHL];
+ char dir[MAXPATHL];
STRLCPY(dir, fname, MAXPATHL);
- *path_tail_with_sep(dir) = NUL;
- return os_chdir((char *)dir) == 0 ? OK : FAIL;
+ *path_tail_with_sep((char_u *)dir) = NUL;
+
+ if (os_dirname(NameBuff, sizeof(NameBuff)) != OK) {
+ NameBuff[0] = NUL;
+ }
+
+ if (os_chdir(dir) != 0) {
+ return FAIL;
+ }
+
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(dir);
+#endif
+ if (!strequal(dir, (char *)NameBuff)) {
+ do_autocmd_dirchanged(dir, kCdScopeWindow);
+ }
+
+ return OK;
}
/// Change directory to "new_dir". Search 'cdpath' for relative directory names.
-int vim_chdir(char_u *new_dir)
+int vim_chdir(char_u *new_dir, CdScope scope)
{
char_u *dir_name = find_directory_in_path(new_dir, STRLEN(new_dir),
FNAME_MESS, curbuf->b_ffname);
if (dir_name == NULL) {
return -1;
}
+
int r = os_chdir((char *)dir_name);
xfree(dir_name);
return r;