qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs qe.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs qe.c
Date: Mon, 13 Jan 2014 11:53:19 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/01/13 11:53:19

Modified files:
        .              : qe.c 

Log message:
        improve minibuffer completion system
        
        * fix utf8 issues with completion, no longer match partial characters
        * fix missing focus on completion popup upon first display
        * close completion popup on space/tab

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.119&r2=1.120

Patches:
Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.119
retrieving revision 1.120
diff -u -b -r1.119 -r1.120
--- qe.c        13 Jan 2014 11:28:00 -0000      1.119
+++ qe.c        13 Jan 2014 11:53:19 -0000      1.120
@@ -4846,7 +4846,6 @@
 static int minibuffer_history_index;
 static int minibuffer_history_saved_offset;
 
-/* XXX: utf8 ? */
 void do_completion(EditState *s)
 {
     QEmacsState *qs = s->qe_state;
@@ -4854,11 +4853,23 @@
     CompleteState cs;
     StringItem **outputs;
     EditState *e;
+    EditBuffer *b;
     int w, h, h1, w1;
 
     if (!completion_function)
         return;
 
+    /* XXX: if completion_popup_window already displayed, should page
+     * through the window, if at end, should remove focus from
+     * completion_popup_window or close it.
+     */
+    if (completion_popup_window && qs->last_cmd_func == qs->this_cmd_func) {
+        edit_close(completion_popup_window);
+        completion_popup_window = NULL;
+        do_refresh(s);
+        return;
+    }
+
     complete_start(s, &cs);
     (*completion_function)(&cs);
     count = cs.cs.nb_items;
@@ -4868,22 +4879,27 @@
     for (i = 0; i < count; i++)
         printf("out[%d]=%s\n", i, outputs[i]->str);
 #endif
-    /* no completion ? */
-    if (count == 0)
-        goto the_end;
     /* compute the longest match len */
     match_len = cs.len;
-    for (;;) {
-        /* Potential UTF-8 issue: should use utility function */
-        c = outputs[0]->str[match_len];
-        if (c == '\0')
-            break;
-        for (i = 1; i < count; i++)
+
+    if (count > 0) {
+        for (; (c = outputs[0]->str[match_len]) != '\0'; match_len++) {
+            for (i = 1; i < count; i++) {
             if (outputs[i]->str[match_len] != c)
-                goto no_match;
-        match_len++;
+                    break;
+            }
+            if (i < count)
+                break;
+        }
+        /* Clip incomplete UTF-8 character before match_len */
+        for (i = cs.len; i < match_len; ) {
+            int clen = utf8_length[(unsigned char)outputs[0]->str[i]];
+            if (i + clen > match_len)
+                match_len = i;
+            else
+                i += clen;
+        }
     }
- no_match:
     if (match_len > cs.len) {
         /* add the possible chars */
         eb_write(s->b, 0, outputs[0]->str, match_len);
@@ -4893,7 +4909,6 @@
             /* if more than one match, then display them in a new popup
                buffer */
             if (!completion_popup_window) {
-                EditBuffer *b;
                 b = eb_new("*completion*", BF_SYSTEM | BF_UTF8 | BF_TRANSIENT);
                 w1 = qs->screen->width;
                 h1 = qs->screen->height - qs->status_height;
@@ -4905,10 +4920,17 @@
                 do_refresh(e);
                 completion_popup_window = e;
             }
+        } else {
+            if (completion_popup_window) {
+                edit_close(completion_popup_window);
+                completion_popup_window = NULL;
+                do_refresh(s);
+            }
         }
         if (completion_popup_window) {
-            EditBuffer *b = completion_popup_window->b;
             /* modify the list with the current matches */
+            e = completion_popup_window;
+            b = e->b;
             qsort(outputs, count, sizeof(StringItem *), completion_sort_func);
             b->flags &= ~BF_READONLY;
             eb_delete(b, 0, b->total_size);
@@ -4918,12 +4940,11 @@
                     eb_printf(b, "\n");
             }
             b->flags |= BF_READONLY;
-            completion_popup_window->mouse_force_highlight = 1;
-            completion_popup_window->force_highlight = 0;
-            completion_popup_window->offset = 0;
+            e->mouse_force_highlight = 1;
+            e->force_highlight = 1;
+            e->offset = 0;
         }
     }
- the_end:
     complete_end(&cs);
 }
 
@@ -5044,23 +5065,24 @@
     static void (*cb)(void *opaque, char *buf);
     static void *opaque;
     char buf[4096], *retstr;
+    EditState *cw = completion_popup_window;
 
     /* if completion is activated, then select current file only if
        the selection is highlighted */
-    if (completion_popup_window &&
-        completion_popup_window->force_highlight) {
+    if (cw && cw->force_highlight) {
         int offset;
 
-        offset = list_get_offset(completion_popup_window);
-        eb_get_strline(completion_popup_window->b, buf, sizeof(buf), &offset);
+        offset = list_get_offset(cw);
+        eb_get_strline(cw->b, buf, sizeof(buf), &offset);
         if (buf[0] != '\0')
             set_minibuffer_str(s, buf + 1);
     }
 
     /* remove completion popup if present */
     /* CG: assuming completion_popup_window != s */
-    if (completion_popup_window) {
-        edit_close(completion_popup_window);
+    if (cw) {
+        edit_close(cw);
+        completion_popup_window = cw = NULL;
         do_refresh(s);
     }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]