From 9d8c2841352e2c946b9a42071e75bb8147786770 Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Tue, 7 Feb 2006 21:11:05 +0000 Subject: [PATCH] allow tab completion of directories at the "Go To Directory" prompt git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3280 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 5 +++++ src/browser.c | 6 +++++- src/files.c | 49 ++++++++++++++++++++++++++++++++----------------- src/prompt.c | 35 ++++++++++++++++++++++++----------- src/proto.h | 20 ++++++++++++++------ src/search.c | 19 +++++++++++++++---- src/text.c | 10 +++++++--- 7 files changed, 102 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 88e29de9..7cb57adf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,11 @@ CVS code - - Rework input parsing in the file browser to be more flexible. New function parse_browser_input(); changes to do_browser(). (DLR) + - Allow tab completion of directories at the "Go To Directory" + prompt. Changes to do_browser(), do_insertfile(), + do_writeout(), cwd_tab_completion(), input_tab(), + get_prompt_string(), do_prompt(), search_init(), do_replace(), + do_gotolinecolumn(), and do_int_spell_fix. (DLR) - browser.c: do_browser() - Properly set currshortcut back to the file browser shortcut diff --git a/src/browser.c b/src/browser.c index 9b6583e3..e919d913 100644 --- a/src/browser.c +++ b/src/browser.c @@ -237,7 +237,11 @@ char *do_browser(char *path, DIR *dir) case NANO_GOTOLINE_KEY: curs_set(1); - j = do_prompt(FALSE, gotodir_list, "", + j = do_prompt(TRUE, +#ifndef DISABLE_TABCOMP + FALSE, +#endif + gotodir_list, "", #ifndef NANO_TINY NULL, #endif diff --git a/src/files.c b/src/files.c index ee73afdf..5c78a732 100644 --- a/src/files.c +++ b/src/files.c @@ -713,6 +713,9 @@ void do_insertfile( #endif i = do_prompt(TRUE, +#ifndef DISABLE_TABCOMP + TRUE, +#endif #ifndef NANO_TINY execute ? extcmd_list : #endif @@ -1752,7 +1755,11 @@ int do_writeout(bool exiting) * and we're at the "Write File" prompt, disable tab * completion. */ i = do_prompt(!ISSET(RESTRICTED) || - openfile->filename[0] == '\0', writefile_list, ans, + openfile->filename[0] == '\0', +#ifndef DISABLE_TABCOMP + TRUE, +#endif + writefile_list, ans, #ifndef NANO_TINY NULL, "%s%s%s", _(msg), formatstr, backupstr #else @@ -2021,8 +2028,8 @@ char **username_tab_completion(const char *buf, size_t *num_matches, /* We consider the first buflen characters of buf for filename tab * completion. */ -char **cwd_tab_completion(const char *buf, size_t *num_matches, size_t - buflen) +char **cwd_tab_completion(const char *buf, bool allow_files, size_t + *num_matches, size_t buflen) { char *dirname = mallocstrcpy(NULL, buf), *filename; #ifndef DISABLE_OPERATINGDIR @@ -2072,6 +2079,8 @@ char **cwd_tab_completion(const char *buf, size_t *num_matches, size_t filenamelen = strlen(filename); while ((nextdir = readdir(dir)) != NULL) { + bool skip_match = FALSE; + #ifdef DEBUG fprintf(stderr, "Comparing \'%s\'\n", nextdir->d_name); #endif @@ -2082,22 +2091,26 @@ char **cwd_tab_completion(const char *buf, size_t *num_matches, size_t /* Cool, found a match. Add it to the list. This makes a * lot more sense to me (Chris) this way... */ + char *tmp = charalloc(strlen(dirname) + + strlen(nextdir->d_name) + 1); + sprintf(tmp, "%s%s", dirname, nextdir->d_name); + #ifndef DISABLE_OPERATINGDIR /* ...unless the match exists outside the operating - * directory, in which case just go to the next match. To - * properly do operating directory checking, we have to add - * the directory name to the beginning of the proposed match - * before we check it. */ - char *tmp2 = charalloc(strlen(dirname) + - strlen(nextdir->d_name) + 1); + * directory, in which case just go to the next match. */ + if (check_operating_dir(tmp, TRUE)) + skip_match = TRUE; +#endif + + /* ...or unless the match isn't a directory and allow_files + * isn't set, in which case just go to the next match. */ + if (!allow_files && !is_dir(tmp)) { + skip_match = TRUE; + + free(tmp); - sprintf(tmp2, "%s%s", dirname, nextdir->d_name); - if (check_operating_dir(tmp2, TRUE)) { - free(tmp2); + if (skip_match) continue; - } - free(tmp2); -#endif matches = (char **)nrealloc(matches, (*num_matches + 1) * sizeof(char *)); @@ -2115,7 +2128,8 @@ char **cwd_tab_completion(const char *buf, size_t *num_matches, size_t /* Do tab completion. place refers to how much the statusbar cursor * position should be advanced. */ -char *input_tab(char *buf, size_t *place, bool *lastwastab, bool *list) +char *input_tab(char *buf, bool allow_files, size_t *place, bool + *lastwastab, bool *list) { size_t num_matches = 0; char **matches = NULL; @@ -2136,7 +2150,8 @@ char *input_tab(char *buf, size_t *place, bool *lastwastab, bool *list) /* Match against files relative to the current working directory. */ if (matches == NULL) - matches = cwd_tab_completion(buf, &num_matches, *place); + matches = cwd_tab_completion(buf, allow_files, &num_matches, + *place); if (num_matches <= 0) beep(); diff --git a/src/prompt.c b/src/prompt.c index 072e6189..c745eb2b 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -897,7 +897,11 @@ bool need_statusbar_horizontal_update(size_t old_pww) /* Get a string of input at the statusbar prompt. This should only be * called from do_prompt(). */ -int get_prompt_string(bool allow_tabs, const char *curranswer, +int get_prompt_string(bool allow_tabs, +#ifndef DISABLE_TABCOMP + bool allow_files, +#endif + const char *curranswer, #ifndef NANO_TINY filestruct **history_list, #endif @@ -985,8 +989,8 @@ int get_prompt_string(bool allow_tabs, const char *curranswer, } else #endif /* !NANO_TINY */ if (allow_tabs) - answer = input_tab(answer, &statusbar_x, &tabbed, - list); + answer = input_tab(answer, allow_files, + &statusbar_x, &tabbed, list); update_statusbar_line(answer, statusbar_x); break; @@ -1090,9 +1094,14 @@ int get_prompt_string(bool allow_tabs, const char *curranswer, * curranswer is any editable text that we want to put up by default. * * The allow_tabs parameter indicates whether we should allow tabs to be - * interpreted. */ -int do_prompt(bool allow_tabs, const shortcut *s, const char - *curranswer, + * interpreted. The allow_files parameter indicates whether we should + * allow all files (as opposed to just directories) to be tab + * completed. */ +int do_prompt(bool allow_tabs, +#ifndef DISABLE_TABCOMP + bool allow_files, +#endif + const shortcut *s, const char *curranswer, #ifndef NANO_TINY filestruct **history_list, #endif @@ -1118,15 +1127,19 @@ int do_prompt(bool allow_tabs, const shortcut *s, const char va_end(ap); null_at(&prompt, actual_x(prompt, COLS - 4)); - retval = get_prompt_string(allow_tabs, curranswer, + retval = get_prompt_string(allow_tabs, +#ifndef DISABLE_TABCOMP + allow_files, +#endif + curranswer, #ifndef NANO_TINY - history_list, + history_list, #endif - s + s #ifndef DISABLE_TABCOMP - , &list + , &list #endif - ); + ); free(prompt); prompt = NULL; diff --git a/src/proto.h b/src/proto.h index 97aecc33..ea412173 100644 --- a/src/proto.h +++ b/src/proto.h @@ -297,9 +297,10 @@ void free_chararray(char **array, size_t len); #ifndef DISABLE_TABCOMP char **username_tab_completion(const char *buf, size_t *num_matches, size_t buflen); -char **cwd_tab_completion(const char *buf, size_t *num_matches, size_t - buflen); -char *input_tab(char *buf, size_t *place, bool *lastwastab, bool *list); +char **cwd_tab_completion(const char *buf, bool allow_files, size_t + *num_matches, size_t buflen); +char *input_tab(char *buf, bool allow_files, size_t *place, bool + *lastwastab, bool *list); #endif const char *tail(const char *foo); #if !defined(NANO_TINY) && defined(ENABLE_NANORC) @@ -463,7 +464,11 @@ size_t get_statusbar_page_start(size_t start_col, size_t column); void update_statusbar_line(const char *curranswer, size_t index); void reset_statusbar_cursor(void); bool need_statusbar_horizontal_update(size_t old_pww); -int get_prompt_string(bool allow_tabs, const char *curranswer, +int get_prompt_string(bool allow_tabs, +#ifndef DISABLE_TABCOMP + bool allow_files, +#endif + const char *curranswer, #ifndef NANO_TINY filestruct **history_list, #endif @@ -472,8 +477,11 @@ int get_prompt_string(bool allow_tabs, const char *curranswer, , bool *list #endif ); -int do_prompt(bool allow_tabs, const shortcut *s, const char - *curranswer, +int do_prompt(bool allow_tabs, +#ifndef DISABLE_TABCOMP + bool allow_files, +#endif + const shortcut *s, const char *curranswer, #ifndef NANO_TINY filestruct **history_list, #endif diff --git a/src/search.c b/src/search.c index 901b6cd8..17fd1be7 100644 --- a/src/search.c +++ b/src/search.c @@ -168,8 +168,11 @@ int search_init(bool replacing, bool use_answer) buf = mallocstrcpy(NULL, ""); /* This is now one simple call. It just does a lot. */ - i = do_prompt(FALSE, replacing ? replace_list : whereis_list, - backupstring, + i = do_prompt(FALSE, +#ifndef DISABLE_TABCOMP + TRUE, +#endif + replacing ? replace_list : whereis_list, backupstring, #ifndef NANO_TINY &search_history, #endif @@ -916,7 +919,11 @@ void do_replace(void) last_replace = mallocstrcpy(last_replace, ""); - i = do_prompt(FALSE, replace_list_2, last_replace, + i = do_prompt(FALSE, +#ifndef DISABLE_TABCOMP + TRUE, +#endif + replace_list_2, last_replace, #ifndef NANO_TINY &replace_history, #endif @@ -980,7 +987,11 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer, char *ans = mallocstrcpy(NULL, answer); /* Ask for it. */ - int i = do_prompt(FALSE, gotoline_list, use_answer ? ans : "", + int i = do_prompt(FALSE, +#ifndef DISABLE_TABCOMP + TRUE, +#endif + gotoline_list, use_answer ? ans : "", #ifndef NANO_TINY NULL, #endif diff --git a/src/text.c b/src/text.c index 738b40b7..7bfafec7 100644 --- a/src/text.c +++ b/src/text.c @@ -1668,11 +1668,15 @@ bool do_int_spell_fix(const char *word) do_replace_highlight(TRUE, exp_word); /* Allow all instances of the word to be corrected. */ - canceled = (do_prompt(FALSE, spell_list, word, + canceled = (do_prompt(FALSE, +#ifndef DISABLE_TABCOMP + TRUE, +#endif + spell_list, word, #ifndef NANO_TINY - NULL, + NULL, #endif - _("Edit a replacement")) == -1); + _("Edit a replacement")) == -1); do_replace_highlight(FALSE, exp_word); -- 2.39.5