changeset 98:f20831f7d349

[/trunk] Changeset 112 by mikael * Completion system enabled for commands. It almost works! ;-)
author mikael
date Wed, 20 Apr 2005 20:35:48 +0000
parents 191f4d00d19b
children 7fffb8a6b229
files mcabber/src/TODO mcabber/src/commands.c mcabber/src/compl.c mcabber/src/compl.h mcabber/src/screen.c
diffstat 5 files changed, 128 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/TODO	Wed Apr 20 20:30:09 2005 +0000
+++ b/mcabber/src/TODO	Wed Apr 20 20:35:48 2005 +0000
@@ -4,6 +4,7 @@
 * Should not stay on buddy buffer when one moves to a group
 * Pending message not displayed if buddy outside Contact window
 * Command not recognised if there is a trailing space! ("/quit ")
+* Completion is buggy when we're not at the EOL...
 
 
 TODO:
--- a/mcabber/src/commands.c	Wed Apr 20 20:30:09 2005 +0000
+++ b/mcabber/src/commands.c	Wed Apr 20 20:35:48 2005 +0000
@@ -121,7 +121,7 @@
 int process_line(char *line)
 {
   if (*line != '/') {
-    send_message(line);
+    send_message(line); // FIXME: are we talking to a _buddy_?
     return 0;
   }
   if (!strcasecmp(line, "/quit")) {
--- a/mcabber/src/compl.c	Wed Apr 20 20:30:09 2005 +0000
+++ b/mcabber/src/compl.c	Wed Apr 20 20:35:48 2005 +0000
@@ -79,7 +79,8 @@
   for (sl_cat=compl_cat; sl_cat; sl_cat = g_slist_next(sl_cat)) {
     char *word = sl_cat->data;
     if (!strncmp(prefix, word, len)) {
-      c->list = g_slist_append(c->list, g_strdup(word+len)); // TODO sort
+      if (strlen(word) != len)
+        c->list = g_slist_append(c->list, g_strdup(word+len)); // TODO sort
     }
   }
   c->next = c->list;
@@ -89,6 +90,8 @@
 //  done_completion();
 void done_completion(void)
 {
+  if (!InputCompl)  return;
+
   // TODO free everything
   g_slist_free(InputCompl->list);
   g_free(InputCompl);
@@ -100,6 +103,7 @@
 //guint cancel_completion(compl *c)
 guint cancel_completion(void)
 {
+  if (!InputCompl)  return 0;
   return InputCompl->len_compl;
 }
 
@@ -108,6 +112,9 @@
 {
   compl* c = InputCompl;
   char *r;
+
+  if (!InputCompl)  return NULL;
+
   if (!c->next) {
     c->next = c->list;  // back to the beginning
     c->len_compl = 0;
--- a/mcabber/src/compl.h	Wed Apr 20 20:30:09 2005 +0000
+++ b/mcabber/src/compl.h	Wed Apr 20 20:35:48 2005 +0000
@@ -10,11 +10,12 @@
 #define COMPL_STATUS    16      // Not implemented yet
 #define COMPL_FILENAME  32      // Not implemented yet
 
-void compl_add_category_word(guint, const char *command);
+void    compl_add_category_word(guint, const char *command);
+GSList *compl_get_category_list(guint cat_flags);
 
-void new_completion(char *prefix, GSList *compl_cat);
-void done_completion(void);
-guint cancel_completion(void);
+void    new_completion(char *prefix, GSList *compl_cat);
+void    done_completion(void);
+guint   cancel_completion(void);
 const char *complete(void);
 
 #endif /* __COMPL_H__ */
--- a/mcabber/src/screen.c	Wed Apr 20 20:30:09 2005 +0000
+++ b/mcabber/src/screen.c	Wed Apr 20 20:35:48 2005 +0000
@@ -45,6 +45,7 @@
 static char inputLine[INPUTLINE_LENGTH+1];
 static char *ptr_inputline;
 static short int inputline_offset;
+static int  completion_started;
 
 
 /* Funciones */
@@ -582,6 +583,109 @@
   doupdate();
 }
 
+//  which_row()
+// Tells which row our cursor is in, in the command line.
+// -1 -> normal text
+//  0 -> command
+//  1 -> parameter 1 (etc.)
+int which_row(void)
+{
+  int row = -1;
+  char *p;
+  int quote = FALSE;
+
+  // Not a command?
+  if ((ptr_inputline == inputLine) || (inputLine[0] != '/'))
+    return -1;
+
+  // This is a command
+  row = 0;
+  for (p = inputLine ; p < ptr_inputline ; p++) {
+    if (quote) {
+      if (*p == '"' && *(p-1) != '\\')
+        quote = FALSE;
+      continue;
+    }
+    if (*p == '"' && *(p-1) != '\\') {
+      quote = TRUE;
+    } else if (*p == ' ' && *(p-1) != ' ')
+      row++;
+  }
+  return row;
+}
+
+void scr_insert_text(const char *text)
+{
+  char tmpLine[INPUTLINE_LENGTH+1];
+  int len = strlen(text);
+  // Check the line isn't too long
+  if (strlen(inputLine) + len >= INPUTLINE_LENGTH) {
+    scr_LogPrint("Cannot insert text, line too long.");
+    return;
+  }
+
+  strcpy(tmpLine, ptr_inputline);
+  strcpy(ptr_inputline, text);    ptr_inputline += len;
+  strcpy(ptr_inputline, tmpLine);
+}
+
+void scr_handle_tab(void)
+{
+  int row;
+  row = which_row();
+
+  if (row == -1) return;    // No completion if no leading slash
+
+  if (row == 0) {   // Command completion
+    if (!completion_started) {
+      GSList *list = compl_get_category_list(COMPL_CMD);
+      if (list) {
+        const char *cchar;
+        char *prefix = g_strndup(&inputLine[1], ptr_inputline-inputLine);
+        new_completion(prefix, list);
+        cchar = complete();
+        if (cchar)
+          scr_insert_text(cchar);
+        g_free(prefix);
+        completion_started = TRUE;
+      }
+    } else {
+      char *c;
+      const char *cchar;
+      guint back = cancel_completion();
+      // Remove $back chars
+      ptr_inputline -= back;
+      c = ptr_inputline;
+      for ( ; *c ; c++)
+        *c = *(c+back);
+      // Now complete again
+      cchar = complete();
+      if (cchar)
+        scr_insert_text(cchar);
+    }
+    return;
+  }
+  scr_LogPrint("I'm unable to complete that yet");
+}
+
+void scr_cancel_current_completion(void)
+{
+  char *c;
+  guint back = cancel_completion();
+  // Remove $back chars
+  ptr_inputline -= back;
+  c = ptr_inputline;
+  for ( ; *c ; c++)
+    *c = *(c+back);
+}
+
+void scr_end_current_completion(void)
+{
+  done_completion();
+  completion_started = FALSE;
+  scr_LogPrint("Freeing completion data");
+}
+
 //  check_offset(int direction)
 // Check inputline_offset value, and make sure the cursor is inside the
 // screen.
@@ -645,8 +749,14 @@
             ptr_inputline++;
             check_offset(1);
           break;
+      case 7:     // Ctrl-g
+          scr_cancel_current_completion();
+          scr_end_current_completion();
+          check_offset(-1);
+          break;
       case 9:     // Tab
-          scr_LogPrint("I'm unable to complete yet");
+          scr_handle_tab();
+          check_offset(0);
           break;
       case '\n':  // Enter
           chatmode = TRUE;
@@ -711,6 +821,8 @@
           scr_LogPrint("Unkown key=%d", key);
     }
   }
+  if (completion_started && key != 9)
+    scr_end_current_completion();
   mvwprintw(inputWnd, 0,0, "%s", inputLine + inputline_offset);
   wclrtoeol(inputWnd);
   if (*ptr_inputline) {