Commit e2556274 authored by Benno Schulenberg's avatar Benno Schulenberg
Browse files

browser: provide tab completion also outside of the working directory

Add a global variable, 'present_path', so that 'cwd_tab_completion()'
knows where the user is in the browser, so that it can try completions
against names in that directory instead of always against names in the
current working directory (where nano was invoked).

This fixes https://savannah.gnu.org/bugs/?47234

.
Signed-off-by: default avatarRishabh Dave <rishabhddave@gmail.com>
Signed-off-by: default avatarBenno Schulenberg <bensberg@justemail.net>
No related merge requests found
Showing with 27 additions and 8 deletions
+27 -8
...@@ -41,8 +41,6 @@ static int longest = 0; ...@@ -41,8 +41,6 @@ static int longest = 0;
/* The number of columns in the longest filename in the list. */ /* The number of columns in the longest filename in the list. */
static size_t selected = 0; static size_t selected = 0;
/* The currently selected filename in the list; zero-based. */ /* The currently selected filename in the list; zero-based. */
static char *path_save = NULL;
/* A copy of the current path. */
/* Our main file browser function. path is the tilde-expanded path we /* Our main file browser function. path is the tilde-expanded path we
* start browsing from. */ * start browsing from. */
...@@ -75,7 +73,7 @@ char *do_browser(char *path, DIR *dir) ...@@ -75,7 +73,7 @@ char *do_browser(char *path, DIR *dir)
path = mallocstrassn(path, get_full_path(path)); path = mallocstrassn(path, get_full_path(path));
/* Save the current path in order to be used later. */ /* Save the current path in order to be used later. */
path_save = path; present_path = mallocstrcpy(present_path, path);
assert(path != NULL && path[strlen(path) - 1] == '/'); assert(path != NULL && path[strlen(path) - 1] == '/');
...@@ -117,7 +115,7 @@ char *do_browser(char *path, DIR *dir) ...@@ -117,7 +115,7 @@ char *do_browser(char *path, DIR *dir)
#ifndef NANO_TINY #ifndef NANO_TINY
if (kbinput == KEY_WINCH) { if (kbinput == KEY_WINCH) {
/* Rebuild the file list and sort it. */ /* Rebuild the file list and sort it. */
browser_init(path_save, opendir(path_save)); browser_init(present_path, opendir(present_path));
qsort(filelist, filelist_len, sizeof(char *), diralphasort); qsort(filelist, filelist_len, sizeof(char *), diralphasort);
/* Make sure the selected file is within range. */ /* Make sure the selected file is within range. */
...@@ -545,7 +543,7 @@ void browser_refresh(void) ...@@ -545,7 +543,7 @@ void browser_refresh(void)
char *info; char *info;
/* The additional information that we'll display about a file. */ /* The additional information that we'll display about a file. */
titlebar(path_save); titlebar(present_path);
blank_edit(); blank_edit();
wmove(edit, 0, 0); wmove(edit, 0, 0);
......
...@@ -1120,6 +1120,8 @@ void do_insertfile( ...@@ -1120,6 +1120,8 @@ void do_insertfile(
_("File to insert [from %s] "); _("File to insert [from %s] ");
} }
present_path = mallocstrcpy(present_path, "./");
i = do_prompt(TRUE, i = do_prompt(TRUE,
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
TRUE, TRUE,
...@@ -2280,6 +2282,8 @@ int do_writeout(bool exiting) ...@@ -2280,6 +2282,8 @@ int do_writeout(bool exiting)
(append == APPEND) ? _("File Name to Append to") : (append == APPEND) ? _("File Name to Append to") :
_("File Name to Write"); _("File Name to Write");
present_path = mallocstrcpy(present_path, "./");
/* If we're using restricted mode, and the filename isn't blank, /* If we're using restricted mode, and the filename isn't blank,
* disable tab completion. */ * disable tab completion. */
i = do_prompt(!ISSET(RESTRICTED) || i = do_prompt(!ISSET(RESTRICTED) ||
...@@ -2684,10 +2688,16 @@ char **cwd_tab_completion(const char *buf, bool allow_files, size_t ...@@ -2684,10 +2688,16 @@ char **cwd_tab_completion(const char *buf, bool allow_files, size_t
/* Cut off the filename part after the slash. */ /* Cut off the filename part after the slash. */
*slash = '\0'; *slash = '\0';
dirname = real_dir_from_tilde(dirname); dirname = real_dir_from_tilde(dirname);
/* A non-absolute path is relative to the current browser directory. */
if (dirname[0] != '/') {
dirname = charealloc(dirname, strlen(present_path) +
strlen(wasdirname) + 1);
sprintf(dirname, "%s%s", present_path, wasdirname);
}
free(wasdirname); free(wasdirname);
} else { } else {
filename = dirname; filename = dirname;
dirname = mallocstrcpy(NULL, "./"); dirname = mallocstrcpy(NULL, present_path);
} }
assert(dirname[strlen(dirname) - 1] == '/'); assert(dirname[strlen(dirname) - 1] == '/');
...@@ -2784,7 +2794,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place, ...@@ -2784,7 +2794,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
beep(); beep();
else { else {
size_t match, common_len = 0; size_t match, common_len = 0;
char *mzero; char *mzero, *glued;
const char *lastslash = revstrstr(buf, "/", buf + *place); const char *lastslash = revstrstr(buf, "/", buf + *place);
size_t lastslash_len = (lastslash == NULL) ? 0 : lastslash - buf + 1; size_t lastslash_len = (lastslash == NULL) ? 0 : lastslash - buf + 1;
char *match1 = charalloc(mb_cur_max()); char *match1 = charalloc(mb_cur_max());
...@@ -2820,9 +2830,13 @@ char *input_tab(char *buf, bool allow_files, size_t *place, ...@@ -2820,9 +2830,13 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
common_len += lastslash_len; common_len += lastslash_len;
mzero[common_len] = '\0'; mzero[common_len] = '\0';
/* Cover also the case of the user specifying a relative path. */
glued = charalloc(strlen(present_path) + strlen(mzero) + 1);
sprintf(glued, "%s%s", present_path, mzero);
assert(common_len >= *place); assert(common_len >= *place);
if (num_matches == 1 && is_dir(mzero)) { if (num_matches == 1 && (is_dir(mzero) || is_dir(glued))) {
mzero[common_len++] = '/'; mzero[common_len++] = '/';
assert(common_len > *place); assert(common_len > *place);
...@@ -2892,6 +2906,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place, ...@@ -2892,6 +2906,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
*listed = TRUE; *listed = TRUE;
} }
free(glued);
free(mzero); free(mzero);
} }
......
...@@ -57,6 +57,9 @@ ssize_t wrap_at = -CHARS_FROM_EOL; ...@@ -57,6 +57,9 @@ ssize_t wrap_at = -CHARS_FROM_EOL;
char *last_search = NULL; char *last_search = NULL;
/* The last string we searched for. */ /* The last string we searched for. */
char *present_path = NULL;
/* The current browser directory when trying to do tab completion. */
unsigned flags[4] = {0, 0, 0, 0}; unsigned flags[4] = {0, 0, 0, 0};
/* Our flag containing the states of all global options. */ /* Our flag containing the states of all global options. */
WINDOW *topwin; WINDOW *topwin;
...@@ -1647,6 +1650,7 @@ void thanks_for_all_the_fish(void) ...@@ -1647,6 +1650,7 @@ void thanks_for_all_the_fish(void)
#endif #endif
free(answer); free(answer);
free(last_search); free(last_search);
free(present_path);
#ifndef DISABLE_SPELLER #ifndef DISABLE_SPELLER
free(alt_speller); free(alt_speller);
#endif #endif
......
...@@ -46,6 +46,8 @@ extern ssize_t wrap_at; ...@@ -46,6 +46,8 @@ extern ssize_t wrap_at;
extern char *last_search; extern char *last_search;
extern char *present_path;
extern unsigned flags[4]; extern unsigned flags[4];
extern WINDOW *topwin; extern WINDOW *topwin;
extern WINDOW *edit; extern WINDOW *edit;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment