diff --git a/src/browser.c b/src/browser.c index 31972be..6d10bd8 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..924d725 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] == '/'); @@ -2820,10 +2830,27 @@ char *input_tab(char *buf, bool allow_files, size_t *place, common_len += lastslash_len; mzero[common_len] = '\0'; + bool trim_again = FALSE; + /* If is_dir fails, prepending present_path to it. */ + if (num_matches == 1 && !is_dir(mzero)) { + trim_again = TRUE; + char *mzero_copy = strdup(mzero); + mzero = charealloc(mzero, strlen(present_path) + strlen(mzero_copy) + + 2); + sprintf(mzero, "%s%s", present_path, mzero_copy); + common_len += strlen(present_path); + free(mzero_copy); + } + assert(common_len >= *place); if (num_matches == 1 && is_dir(mzero)) { mzero[common_len++] = '/'; + if (trim_again) { + mzero = memmove(mzero, mzero + strlen(present_path), + strlen(mzero) - strlen(present_path)); + common_len -= strlen(present_path); + } assert(common_len > *place); } 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 6ad900b..380458c 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;