diff options
-rw-r--r-- | src/cmdline.cpp | 85 |
1 files changed, 31 insertions, 54 deletions
diff --git a/src/cmdline.cpp b/src/cmdline.cpp index b4c7b18..84d09c3 100644 --- a/src/cmdline.cpp +++ b/src/cmdline.cpp @@ -55,7 +55,6 @@ static gchar *symbol_complete(SymbolList &list, const gchar *symbol, static const gchar *last_occurrence(const gchar *str, const gchar *chars = " \t\v\r\n\f<>,;@"); static inline gboolean filename_is_dir(const gchar *filename); -static inline gchar derive_dir_separator(const gchar *filename); /** Current command line. */ Cmdline cmdline; @@ -525,8 +524,10 @@ get_eol(void) static gchar * filename_complete(const gchar *filename, gchar completed) { - gchar *dirname; + gsize dirname_len; + gchar *dirname, dir_sep; const gchar *basename, *cur_basename; + GDir *dir; GSList *files = NULL; guint files_len = 0; @@ -534,8 +535,6 @@ filename_complete(const gchar *filename, gchar completed) gsize filename_len; gsize prefix_len = 0; - gchar dir_sep[2]; - if (!filename) filename = ""; filename_len = strlen(filename); @@ -544,43 +543,47 @@ filename_complete(const gchar *filename, gchar completed) return NULL; /* - * On Windows, both forward and backslash - * directory separators are allowed in directory - * names passed to glib. - * To imitate glib's behaviour, we use - * the last valid directory separator in `filename` - * to generate new separators. - * This also allows forward-slash auto-completion - * on Windows. - */ - dir_sep[0] = derive_dir_separator(filename); - dir_sep[1] = '\0'; - - /* * Derive base and directory names. * We do not use g_path_get_basename() or g_path_get_dirname() * since we need strict suffixes and prefixes of filename * in order to construct paths of entries in dirname * that are suitable for auto completion. */ - basename = strrchr(filename, *dir_sep); - if (basename) - basename++; - else - basename = filename; - dirname = g_strndup(filename, basename-filename); - - dir = g_dir_open(*dirname ? dirname : ".", 0, NULL); + dirname_len = file_get_dirname_len(filename); + dirname = g_strndup(filename, dirname_len); + basename = filename + dirname_len; + + dir = g_dir_open(dirname_len ? dirname : ".", 0, NULL); if (!dir) { g_free(dirname); return NULL; } + /* + * On Windows, both forward and backslash + * directory separators are allowed in directory + * names passed to glib. + * To imitate glib's behaviour, we use + * the last valid directory separator in `filename` + * to generate new separators. + * This also allows forward-slash auto-completion + * on Windows. + */ + dir_sep = dirname_len ? dirname[dirname_len-1] + : G_DIR_SEPARATOR; + while ((cur_basename = g_dir_read_name(dir))) { - gchar *cur_filename = g_build_path(dir_sep, dirname, cur_basename, NIL); + gchar *cur_filename; + + if (!g_str_has_prefix(cur_basename, basename)) + continue; - if (!g_str_has_prefix(cur_basename, basename) || - (!*basename && !file_is_visible(cur_filename))) { + /* + * dirname contains any directory separator, + * so g_strconcat() works here. + */ + cur_filename = g_strconcat(dirname, cur_basename, NIL); + if (!*basename && !file_is_visible(cur_filename)) { g_free(cur_filename); continue; } @@ -747,30 +750,4 @@ filename_is_dir(const gchar *filename) return G_IS_DIR_SEPARATOR(c); } -#ifdef G_OS_WIN32 - -static inline gchar -derive_dir_separator(const gchar *filename) -{ - gchar sep = G_DIR_SEPARATOR; - - while (*filename) { - if (G_IS_DIR_SEPARATOR(*filename)) - sep = *filename; - filename++; - } - - return sep; -} - -#else /* !G_OS_WIN32 */ - -static inline gchar -derive_dir_separator(const gchar *filename) -{ - return G_DIR_SEPARATOR; -} - -#endif - } /* namespace SciTECO */ |