diff mcabber/mcabber/compl.c @ 2143:2f294c2b6778

Add a backward completion (Oleg) When we skip some needed item with tab, we can back with shift+tab.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 06 Jul 2014 14:51:17 +0200
parents fc7a758ebbde
children f5402d705f67
line wrap: on
line diff
--- a/mcabber/mcabber/compl.c	Sun Jul 06 14:51:14 2014 +0200
+++ b/mcabber/mcabber/compl.c	Sun Jul 06 14:51:17 2014 +0200
@@ -41,10 +41,10 @@
 
 // Completion structure
 typedef struct {
-  GSList *list;         // list of matches
+  GList *list;          // list of matches
   guint len_prefix;     // length of text already typed by the user
   guint len_compl;      // length of the last completion
-  GSList *next;         // pointer to next completion to try
+  GList *next;          // pointer to next completion to try
 } compl;
 
 typedef GSList *(*compl_handler_t) (void); // XXX userdata? *dynlist?
@@ -233,12 +233,13 @@
         else
           compval = g_strdup(word+len);
         // for a bit of efficiency, will reverse order afterwards
-        c->list = g_slist_prepend(c->list, compval);
+        c->list = g_list_prepend(c->list, compval);
         ret_len ++;
       }
     }
   }
-  c->next = c->list = g_slist_reverse (c->list);
+  c->list = g_list_reverse(c->list);
+  c->next = NULL;
   InputCompl = c;
   return ret_len;
 }
@@ -246,14 +247,14 @@
 //  done_completion();
 void done_completion(void)
 {
-  GSList *clp;
+  GList *clp;
 
   if (!InputCompl)  return;
 
   // Free the current completion list
-  for (clp = InputCompl->list; clp; clp = g_slist_next(clp))
+  for (clp = InputCompl->list; clp; clp = g_list_next(clp))
     g_free(clp->data);
-  g_slist_free(InputCompl->list);
+  g_list_free(InputCompl->list);
   g_free(InputCompl);
   InputCompl = NULL;
 }
@@ -267,7 +268,7 @@
 }
 
 // Returns pointer to text to insert, NULL if no completion.
-const char *complete()
+const char *complete(gboolean fwd)
 {
   compl* c = InputCompl;
   char *r;
@@ -275,12 +276,25 @@
   if (!InputCompl)  return NULL;
 
   if (!c->next) {
-    c->next = c->list;  // back to the beginning
+    if (fwd)
+      c->next = c->list;  // back to the beginning
+    else
+      c->next = g_list_last(c->list); // back to the ending
+  } else {
+    if (fwd)
+      c->next = g_list_next(c->next);
+    else
+      c->next = g_list_previous(c->next);
+  }
+
+  if (!c->next) {
+    c->next = NULL;
     c->len_compl = 0;
     return NULL;
   }
+
   r = (char*)c->next->data;
-  c->next = g_slist_next(c->next);
+
   if (!utf8_mode) {
     c->len_compl = strlen(r);
   } else {