From 20f7a390b8f1523eef136695d95b88bbca5da7ac Mon Sep 17 00:00:00 2001 From: Rishabh Dave Date: Mon, 2 May 2016 07:37:59 +0530 Subject: [PATCH] Fix tab completion for path changes in browser Add a global variable, 'present_path' so that 'cwd_tab_completion()' has update of where user is in browser, resolve where path is relative to current directory in browser, not to where nano was invoked, and, where required, make arrangements for testing path's correctness. This fixes bug #47234. Signed-off-by: Rishabh Dave --- src/browser.c | 8 +++----- src/files.c | 20 +++++++++++++++++--- src/global.c | 4 ++++ src/proto.h | 2 ++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/browser.c b/src/browser.c index 974b643..bd2485b 100644 --- a/src/browser.c +++ b/src/browser.c @@ -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. */ @@ -544,7 +542,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); diff --git a/src/files.c b/src/files.c index 08c9fd6..1a69de6 100644 --- a/src/files.c +++ b/src/files.c @@ -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); + /* Take a relative path 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,12 @@ char *input_tab(char *buf, bool allow_files, size_t *place, common_len += lastslash_len; mzero[common_len] = '\0'; + 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 +2905,7 @@ char *input_tab(char *buf, bool allow_files, size_t *place, *listed = TRUE; } + free(glued); free(mzero); } diff --git a/src/global.c b/src/global.c index 37de038..999595e 100644 --- a/src/global.c +++ b/src/global.c @@ -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 diff --git a/src/proto.h b/src/proto.h index 418a9d0..02f5ef1 100644 --- a/src/proto.h +++ b/src/proto.h @@ -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; -- 2.8.1