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: Rishabh Dave <rishabhddave@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@justemail.net>
This commit is contained in:
Benno Schulenberg 2016-04-30 21:22:16 +02:00
parent e0c4f9c5fe
commit e2556274f7
4 changed files with 27 additions and 8 deletions

View File

@ -41,8 +41,6 @@ static int longest = 0;
/* The number of columns in the longest filename in the list. */
static size_t selected = 0;
/* 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
* start browsing from. */
@ -75,7 +73,7 @@ char *do_browser(char *path, DIR *dir)
path = mallocstrassn(path, get_full_path(path));
/* 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] == '/');
@ -117,7 +115,7 @@ char *do_browser(char *path, DIR *dir)
#ifndef NANO_TINY
if (kbinput == KEY_WINCH) {
/* 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);
/* Make sure the selected file is within range. */
@ -545,7 +543,7 @@ void browser_refresh(void)
char *info;
/* The additional information that we'll display about a file. */
titlebar(path_save);
titlebar(present_path);
blank_edit();
wmove(edit, 0, 0);

View File

@ -1120,6 +1120,8 @@ void do_insertfile(
_("File to insert [from %s] ");
}
present_path = mallocstrcpy(present_path, "./");
i = do_prompt(TRUE,
#ifndef DISABLE_TABCOMP
TRUE,
@ -2280,6 +2282,8 @@ int do_writeout(bool exiting)
(append == APPEND) ? _("File Name to Append to") :
_("File Name to Write");
present_path = mallocstrcpy(present_path, "./");
/* If we're using restricted mode, and the filename isn't blank,
* disable tab completion. */
i = do_prompt(!ISSET(RESTRICTED) ||
@ -2684,10 +2688,16 @@ char **cwd_tab_completion(const char *buf, bool allow_files, size_t
/* Cut off the filename part after the slash. */
*slash = '\0';
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);
} else {
filename = dirname;
dirname = mallocstrcpy(NULL, "./");
dirname = mallocstrcpy(NULL, present_path);
}
assert(dirname[strlen(dirname) - 1] == '/');
@ -2784,7 +2794,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
beep();
else {
size_t match, common_len = 0;
char *mzero;
char *mzero, *glued;
const char *lastslash = revstrstr(buf, "/", buf + *place);
size_t lastslash_len = (lastslash == NULL) ? 0 : lastslash - buf + 1;
char *match1 = charalloc(mb_cur_max());
@ -2820,9 +2830,13 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
common_len += lastslash_len;
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);
if (num_matches == 1 && is_dir(mzero)) {
if (num_matches == 1 && (is_dir(mzero) || is_dir(glued))) {
mzero[common_len++] = '/';
assert(common_len > *place);
@ -2892,6 +2906,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place,
*listed = TRUE;
}
free(glued);
free(mzero);
}

View File

@ -57,6 +57,9 @@ ssize_t wrap_at = -CHARS_FROM_EOL;
char *last_search = NULL;
/* 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};
/* Our flag containing the states of all global options. */
WINDOW *topwin;
@ -1647,6 +1650,7 @@ void thanks_for_all_the_fish(void)
#endif
free(answer);
free(last_search);
free(present_path);
#ifndef DISABLE_SPELLER
free(alt_speller);
#endif

View File

@ -46,6 +46,8 @@ extern ssize_t wrap_at;
extern char *last_search;
extern char *present_path;
extern unsigned flags[4];
extern WINDOW *topwin;
extern WINDOW *edit;