aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2014-12-08 20:42:25 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2014-12-08 20:42:25 +0100
commit43777708af20f53abbe268cc908854071d971d36 (patch)
treebc8e80a08f029f0a809f955d6389b3beea536c15
parent6e5a6113af29dcc2380e6884fb49ed0e4fcbe16d (diff)
downloadsciteco-43777708af20f53abbe268cc908854071d971d36.tar.gz
do not show possible completions for hidden files and directories
* added platform-dependant file_is_visible() function
-rw-r--r--doc/sciteco.7.template13
-rw-r--r--src/cmdline.cpp29
-rw-r--r--src/ioview.cpp27
-rw-r--r--src/ioview.h7
4 files changed, 64 insertions, 12 deletions
diff --git a/doc/sciteco.7.template b/doc/sciteco.7.template
index ef994e8..bad98cc 100644
--- a/doc/sciteco.7.template
+++ b/doc/sciteco.7.template
@@ -357,7 +357,9 @@ If \*(ST is not busy,
is self-inserting and might be used as a regular command.
T}
.TE
-.LP
+.
+.SS Auto Completion
+.
The immediate editing commands that perform auto-completions, do
so in a manner similar to Posix shells.
Upon first invocation they try to fully or partially complete the file
@@ -365,6 +367,15 @@ name (or token).
If no completion can be performed, the invocation will display a
list of file names (or tokens) beginning with the token to complete
in \*(ST's popup area.
+.LP
+When completing file names, hidden files are not considered for
+completion unless a prefix of the hidden file's name has already
+been typed.
+On Unix, \*(ST considers files and directories beginning with \(lq.\(rq
+as hidden.
+On Windows, the \fIhidden\fP file attribute is evaluated.
+On other platforms, \*(ST might not identify hidden files correctly.
+.LP
Note that no additional expansions are performed before attempting
a completion, so for instance \(lq~/foo\(rq will not complete a file
in the user's home directory (tilde is not part of the file name but
diff --git a/src/cmdline.cpp b/src/cmdline.cpp
index 78c0bdb..0907106 100644
--- a/src/cmdline.cpp
+++ b/src/cmdline.cpp
@@ -32,6 +32,7 @@
#include "parser.h"
#include "qregisters.h"
#include "ring.h"
+#include "ioview.h"
#include "goto.h"
#include "undo.h"
#include "symbols.h"
@@ -360,7 +361,8 @@ macro_echo(const gchar *macro)
static gchar *
filename_complete(const gchar *filename, gchar completed)
{
- gchar *dirname, *basename;
+ gchar *dirname;
+ const gchar *basename, *cur_basename;
GDir *dir;
GList *files = NULL;
guint files_len = 0;
@@ -384,27 +386,34 @@ filename_complete(const gchar *filename, gchar completed)
if (*dirname != *filename)
*dirname = '\0';
- while ((basename = (gchar *)g_dir_read_name(dir))) {
- gchar *cur_file = g_build_filename(dirname, basename, NIL);
+ basename = strrchr(filename, G_DIR_SEPARATOR);
+ if (basename)
+ basename++;
+ else
+ basename = filename;
- if (g_file_test(cur_file, G_FILE_TEST_IS_DIR))
- String::append(cur_file, G_DIR_SEPARATOR_S);
+ while ((cur_basename = g_dir_read_name(dir))) {
+ gchar *cur_filename = g_build_filename(dirname, cur_basename, NIL);
- if (!g_str_has_prefix(cur_file, filename)) {
- g_free(cur_file);
+ if (!g_str_has_prefix(cur_basename, basename) ||
+ (!*basename && !file_is_visible(cur_filename))) {
+ g_free(cur_filename);
continue;
}
- files = g_list_prepend(files, cur_file);
+ if (g_file_test(cur_filename, G_FILE_TEST_IS_DIR))
+ String::append(cur_filename, G_DIR_SEPARATOR_S);
+
+ files = g_list_prepend(files, cur_filename);
if (g_list_next(files)) {
const gchar *other_file = (gchar *)g_list_next(files)->data;
gsize len = String::diff(other_file + filename_len,
- cur_file + filename_len);
+ cur_filename + filename_len);
if (len < prefix_len)
prefix_len = len;
} else {
- prefix_len = strlen(cur_file + filename_len);
+ prefix_len = strlen(cur_filename + filename_len);
}
files_len++;
diff --git a/src/ioview.cpp b/src/ioview.cpp
index b0a2d40..c052454 100644
--- a/src/ioview.cpp
+++ b/src/ioview.cpp
@@ -328,6 +328,16 @@ get_absolute_path(const gchar *path)
return resolved;
}
+bool
+file_is_visible(const gchar *path)
+{
+ gchar *basename = g_path_get_basename(path);
+ bool ret = *basename != '.';
+
+ g_free(basename);
+ return ret;
+}
+
#elif defined(G_OS_WIN32)
gchar *
@@ -342,6 +352,12 @@ get_absolute_path(const gchar *path)
return resolved;
}
+bool
+file_is_visible(const gchar *path)
+{
+ return !(get_file_attributes(path) & FILE_ATTRIBUTE_HIDDEN);
+}
+
#else
/*
@@ -353,6 +369,17 @@ get_absolute_path(const gchar *path)
return path ? g_file_read_link(path, NULL) : NULL;
}
+/*
+ * There's no platform-independant way to determine if a file
+ * is visible/hidden, so we just assume that all files are
+ * visible.
+ */
+bool
+file_is_visible(const gchar *path)
+{
+ return true;
+}
+
#endif /* !G_OS_UNIX && !G_OS_WIN32 */
} /* namespace SciTECO */
diff --git a/src/ioview.h b/src/ioview.h
index 0c1e653..7f26222 100644
--- a/src/ioview.h
+++ b/src/ioview.h
@@ -31,13 +31,18 @@ namespace SciTECO {
* Auxiliary functions
*/
-/*
+/**
* Get absolute/full version of a possibly relative path.
* Works with existing and non-existing paths (in the latter case,
* heuristics may be applied.)
+ *
+ * @param path Possibly relative path name.
+ * @return Newly-allocated absolute path name.
*/
gchar *get_absolute_path(const gchar *path);
+bool file_is_visible(const gchar *path);
+
class IOView : public ViewCurrent {
class UndoTokenRemoveFile : public UndoToken {
gchar *filename;