Re: gio, gvfs and nautilus fixes



On Mon, 2008-02-25 at 12:54 -0500, David Zeuthen wrote:
> > I cleaned up the completion code a bit to do less magic string uri
> > handling and instead use GFile apis.
> 
> It's a lot more simple now.. but you broke this important use-case
> 
>  $ gvfs-ls <tab>
>  file:///            sftp://hook.local/
>  $ gvfs-ls s<tab>
> 
> and it should complete to sftp://hook.local/
> 
> Also, there's no completion on ./ or ~/. Typically ./ is used to
> complete on files in $CWD as completion on the empty string will give
> you the user visible mounts (which is a design choice). So some of the
> magic handling needs to be added back...

Attached is a patch that adds back the old completion code (but with
some coding style fixes; hopefully I got it right). So I really don't
think it can be much simpler than this... one thing the code needs to
do. and that the generic GFile handling can't / shouldn't do, is to
print the names in the same form as the user enters it... so e.g. the
input

 ~/Ha

would complete to

 ~/Hacking/
 ~/HappyStuff

assuming $HOME contains the directory Hacking and the file HappyStuff.

      David

Index: programs/gvfs-ls.c
===================================================================
--- programs/gvfs-ls.c	(revision 1379)
+++ programs/gvfs-ls.c	(working copy)
@@ -207,62 +207,68 @@
 }
 
 static void
-show_completed_file (GFile *hit,
-                     gboolean is_dir,
-                     const char *arg)
+print_completions (const char *given_uri)
 {
-  char *display, *cwd;
-  GFile *cwd_f;
-  
-  if (g_file_is_native (hit))
+  char *uri;
+  GFile *f;
+  GFile *parent;
+  char *uri_skip;
+  char *uri_prepend;
+
+  uri_skip = NULL;
+
+  /* TODO: implement completion on '..', '../..' and so on... Is going to be a bit
+   *       difficult; need a better g_file_get_relative_path() 
+   */
+  if (g_str_has_prefix (given_uri, "/"))
     {
+      uri = g_strdup_printf ("file://%s", given_uri);
+      uri_skip = g_strdup ("file://");
+    }
+  else if (strcmp (given_uri, ".") == 0)
+    {
+      char *cwd;
       cwd = g_get_current_dir ();
-      cwd_f = g_file_new_for_path (cwd);
+      uri = g_strdup_printf ("file://%s/.", cwd);
+      uri_skip = g_strdup_printf ("file://%s/", cwd);
+      uri_prepend = g_strdup ("./");
       g_free (cwd);
-
-      if (g_file_has_prefix (hit, cwd_f) &&
-          !g_path_is_absolute (arg))
-        display = g_file_get_relative_path (cwd_f, hit);
-      else
-        display = g_file_get_path (hit);
-      g_object_unref (cwd_f);
     }
-  else
-    display = g_file_get_uri (hit);
-  
-  g_print ("%s%s\n", display, (is_dir)?"/":"");
-  g_free (display);
-}
-  
-static void
-print_completions (const char *arg)
-{
-  GFile *f;
-  GFile *parent;
-  char *basename;
-
-  f = g_file_new_for_commandline_arg (arg);
-  
-  if (g_str_has_suffix (arg, "/") ||
-      *arg == 0)
+  else if (g_str_has_prefix (given_uri, "./"))
     {
-      parent = g_object_ref (f);
-      basename = g_strdup ("");
+      char *cwd;
+      cwd = g_get_current_dir ();
+      uri = g_strdup_printf ("file://%s/%s", cwd, given_uri + 2);
+      uri_skip = g_strdup_printf ("file://%s/", cwd);
+      uri_prepend = g_strdup ("./");
+      g_free (cwd);
     }
+  else if (g_str_has_prefix (given_uri, "~/"))
+    {
+      const char *home;
+      home = g_get_home_dir ();
+      uri = g_strdup_printf ("file://%s/%s", home, given_uri + 2);
+      uri_skip = g_strdup_printf ("file://%s/", home);
+      uri_prepend = g_strdup ("\\~/");
+    }
   else
     {
-      parent = g_file_get_parent (f);
-      basename = g_file_get_basename (f);
+      uri = g_strdup (given_uri);
     }
 
-  if (parent == NULL ||
-      !g_file_query_exists (parent, NULL))
+  f = g_file_new_for_uri (uri);
+  if (g_str_has_suffix (uri, "/") || g_str_has_suffix (uri, "."))
+    parent = g_object_ref (f);
+  else
+    parent = g_file_get_parent (f);
+  
+  if (!(parent != NULL && g_file_query_exists (parent, NULL)))
     {
       GMount *mount;
       mount = g_file_find_enclosing_mount (f, NULL, NULL);
       if (mount == NULL)
         {
-          print_mounts (arg);
+          print_mounts (uri);
           goto out;
         }
       g_object_unref (mount);
@@ -280,7 +286,6 @@
       if (enumerator != NULL)
         {
           GFileInfo *info;
-          
           while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL)
             {
               const char *name;
@@ -288,14 +293,36 @@
               
               name = g_file_info_get_name (info);
               type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
-              if (name != NULL && g_str_has_prefix (name, basename))
+              if (name != NULL)
                 {
                   GFile *entry;
                   char *entry_uri;
-                  
+
                   entry = g_file_get_child (parent, name);
-                  show_completed_file (entry, type == G_FILE_TYPE_DIRECTORY, arg);
+                  entry_uri = g_file_get_uri (entry);
                   g_object_unref (entry);
+
+                  if (g_str_has_prefix (entry_uri, uri))
+                    {
+                      int skip_chars;
+
+                      skip_chars = 0;
+
+                      if (uri_skip != NULL && g_str_has_prefix (entry_uri, uri_skip))
+                        skip_chars = strlen (uri_skip);
+
+                      if (uri_prepend != NULL)
+                        g_print ("%s", uri_prepend);
+
+                      g_print ("%s", entry_uri + skip_chars);
+
+                      if (type & G_FILE_TYPE_DIRECTORY)
+                        g_print ("/");
+
+                      g_print ("\n");
+                    }
+
+                  g_free (entry_uri);
                 }
               g_object_unref (info);
             }
@@ -306,7 +333,9 @@
 
  out:
   g_object_unref (f);
-  g_free (basename);
+  g_free (uri);
+  g_free (uri_skip);
+  g_free (uri_prepend);
 }
 
 int


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]