[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);
}