qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs bufed.c charset.c extras.c input.c qe.c ...


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs bufed.c charset.c extras.c input.c qe.c ...
Date: Sat, 17 Oct 2020 11:41:32 -0400 (EDT)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        20/10/17 11:41:32

Modified files:
        .              : bufed.c charset.c extras.c input.c qe.c 
                         qscript.c util.c variables.h buffer.c dired.c 
                         image.c latex-mode.c qe.h tty.c variables.c 

Log message:
        Improve completion system
        
        - rename and extend CompletionEntry as CompletionDef
        - create xxx_completion CompletionDef structures
        - rename xxx_completion() functions to xxx_complete()
        - register CompletionDef structs with qe_register_completion()
        - add (start, end) range in CompleteState
        - use eb_puts() and eb_putc() instead of eb_printf()
        - simplify eb_delete_chars()
        - ignore left pane in compare-windows()
        - simplify qe_list_bindings()
        - improve command and variable completion popup

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/bufed.c?cvsroot=qemacs&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/qemacs/charset.c?cvsroot=qemacs&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.75&r2=1.76
http://cvs.savannah.gnu.org/viewcvs/qemacs/input.c?cvsroot=qemacs&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.296&r2=1.297
http://cvs.savannah.gnu.org/viewcvs/qemacs/qscript.c?cvsroot=qemacs&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/qemacs/util.c?cvsroot=qemacs&r1=1.87&r2=1.88
http://cvs.savannah.gnu.org/viewcvs/qemacs/variables.h?cvsroot=qemacs&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.116&r2=1.117
http://cvs.savannah.gnu.org/viewcvs/qemacs/dired.c?cvsroot=qemacs&r1=1.83&r2=1.84
http://cvs.savannah.gnu.org/viewcvs/qemacs/image.c?cvsroot=qemacs&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/qemacs/latex-mode.c?cvsroot=qemacs&r1=1.58&r2=1.59
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.277&r2=1.278
http://cvs.savannah.gnu.org/viewcvs/qemacs/tty.c?cvsroot=qemacs&r1=1.88&r2=1.89
http://cvs.savannah.gnu.org/viewcvs/qemacs/variables.c?cvsroot=qemacs&r1=1.25&r2=1.26

Patches:
Index: bufed.c
===================================================================
RCS file: /sources/qemacs/qemacs/bufed.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- bufed.c     19 Dec 2018 11:45:39 -0000      1.47
+++ bufed.c     17 Oct 2020 15:41:31 -0000      1.48
@@ -152,11 +152,10 @@
                 b->cur_style = BUFED_STYLE_DIRECTORY;
             else
                 b->cur_style = BUFED_STYLE_FILENAME;
-            eb_printf(b, "%s",
-                      make_user_path(path, sizeof(path), b1->filename));
+            eb_puts(b, make_user_path(path, sizeof(path), b1->filename));
             b->cur_style = style0;
         }
-        eb_printf(b, "\n");
+        eb_putc(b, '\n');
     }
     b->modified = 0;
     b->flags |= BF_READONLY;

Index: charset.c
===================================================================
RCS file: /sources/qemacs/qemacs/charset.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- charset.c   25 Apr 2017 16:56:26 -0000      1.52
+++ charset.c   17 Oct 2020 15:41:32 -0000      1.53
@@ -1130,7 +1130,7 @@
     *pp = charset;
 }
 
-void charset_completion(CompleteState *cp)
+void charset_complete(CompleteState *cp)
 {
     QECharset *charset;
     char name[32];

Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -b -r1.75 -r1.76
--- extras.c    2 Oct 2020 20:26:21 -0000       1.75
+++ extras.c    17 Oct 2020 15:41:32 -0000      1.76
@@ -123,21 +123,24 @@
 
     s1 = s;
     /* Should use same internal function as for next_window */
-    if (s1->next_window)
-        s2 = s1->next_window;
-    else
+    for (s2 = s1;;) {
+        s2 = s2->next_window;
+        if (s2 == NULL)
         s2 = qs->first_window;
-
+        if (s2 == s1) {
+            /* single window: bail out */
+            return;
+        }
+        if (s2->b->flags & BF_DIRED)
+            continue;
+        break;
+    }
     if (argval != NO_ARG) {
         if (argval & 4)
             qs->ignore_spaces ^= 1;
         if (argval & 16)
             qs->ignore_comments ^= 1;
     }
-    if (s1 == s2) {
-        /* single window: bail out */
-        return;
-    }
 
     size1 = s1->b->total_size;
     size2 = s2->b->total_size;
@@ -867,8 +870,7 @@
 
 /*---------------- help ----------------*/
 
-static int qe_list_bindings(char *buf, int size, CmdDef *d,
-                            ModeDef *mode, int inherit)
+int qe_list_bindings(CmdDef *d, ModeDef *mode, int inherit, char *buf, int 
size)
 {
     int pos;
     buf_t outbuf, *out;
@@ -904,7 +906,7 @@
         put_status(s, "No command %s", cmd_name);
         return;
     }
-    if (qe_list_bindings(buf, sizeof(buf), d, s->mode, 1)) {
+    if (qe_list_bindings(d, s->mode, 1, buf, sizeof(buf))) {
         put_status(s, "%s is bound to %s", cmd_name, buf);
     } else {
         put_status(s, "%s is not bound to any key", cmd_name);
@@ -916,18 +918,21 @@
     char buf[256];
     CmdDef *d;
     int gfound;
+    //int start = b->total_size;
 
+    /* XXX: should sort matches */
     gfound = 0;
     d = qe_state.first_cmd;
     while (d != NULL) {
         while (d->name != NULL) {
-            if (qe_list_bindings(buf, sizeof(buf), d, mode, 0)) {
+            if (qe_list_bindings(d, mode, 0, buf, sizeof(buf))) {
                 if (!gfound) {
                     if (mode) {
                         eb_printf(b, "\n%s mode bindings:\n\n", mode->name);
                     } else {
                         eb_printf(b, "\nGlobal bindings:\n\n");
                     }
+                    //start = b->total_size;
                     gfound = 1;
                 }
                 eb_printf(b, "%24s : %s\n", d->name, buf);
@@ -936,6 +941,7 @@
         }
         d = d->action.next;
     }
+    //do_sort_span(b, start, b->total_size, 0, NO_ARG);
 }
 
 void do_describe_bindings(EditState *s)
@@ -966,7 +972,10 @@
     if (!b)
         return;
 
-    eb_printf(b, "\n");
+    eb_putc(b, '\n');
+
+    /* XXX: should sort matches */
+    /* XXX: should print description */
 
     found = 0;
     d = qs->first_cmd;
@@ -975,12 +984,12 @@
             if (strstr(d->name, str)) {
                 /* print name and prototype */
                 qe_get_prototype(d, buf, sizeof(buf));
-                eb_printf(b, "command: %s(%s)", d->name, buf);
-                if (qe_list_bindings(buf, sizeof(buf), d, s->mode, 1))
+                eb_printf(b, "command: %s%s", d->name, buf);
+                if (qe_list_bindings(d, s->mode, 1, buf, sizeof(buf)))
                     eb_printf(b, " bound to %s", buf);
-                eb_printf(b, "\n");
+                eb_putc(b, '\n');
                 /* TODO: print short description */
-                eb_printf(b, "\n");
+                eb_putc(b, '\n');
                 found = 1;
             }
             d++;
@@ -994,7 +1003,7 @@
             eb_printf(b, "%s variable: %s -> %s\n",
                       var_domain[vp->domain], vp->name, buf);
             /* TODO: print short description */
-            eb_printf(b, "\n");
+            eb_putc(b, '\n');
             found = 1;
         }
     }
@@ -1023,7 +1032,7 @@
     b = eb_scratch("*About QEmacs*", BF_UTF8);
     eb_printf(b, "\n  %s\n\n%s\n", str_version, str_credits);
 
-    /* list commands */
+    /* list current bindings */
     print_bindings(b, s->mode);
     print_bindings(b, NULL);
 
@@ -1035,11 +1044,13 @@
 
     /* list commands */
     eb_printf(b, "\nCommands:\n\n");
+
+    /* XXX: should sort commands */
     d = qs->first_cmd;
     while (d != NULL) {
         while (d->name != NULL) {
             qe_get_prototype(d, buf, sizeof(buf));
-            eb_printf(b, "    %s(%s);\n", d->name, buf);
+            eb_printf(b, "    %s%s\n", d->name, buf);
             d++;
         }
         d = d->action.next;
@@ -1052,6 +1063,7 @@
         char **envp;
 
         eb_printf(b, "\nEnvironment:\n\n");
+        /* XXX: should sort environment variables */
         for (envp = environ; *envp; envp++) {
             eb_printf(b, "    %s\n", *envp);
         }
@@ -1226,7 +1238,7 @@
     if (!b1)
         return;
 
-    eb_printf(b1, "\n");
+    eb_putc(b1, '\n');
 
     eb_printf(b1, "        name: %s\n", b->name);
     eb_printf(b1, "    filename: %s\n", b->filename);
@@ -1370,12 +1382,12 @@
                 col += eb_printf(b1, "  0x%02x", i);
 
             if (col >= 60) {
-                eb_printf(b1, "\n");
+                eb_putc(b1, '\n');
                 col = 0;
             }
         }
         if (col) {
-            eb_printf(b1, "\n");
+            eb_putc(b1, '\n');
         }
     }
 
@@ -1402,14 +1414,14 @@
                     if (c < 32 || c >= 127)
                         eb_printf(b1, "\\%03o", c);
                     else
-                        eb_printf(b1, "%c", c);
+                        eb_putc(b1, c);
                     continue;
                 }
                 eb_printf(b1, "\\%c", c);
             }
             eb_printf(b1, "|%s\n", p->size > 16 ? "..." : "");
         }
-        eb_printf(b1, "\n");
+        eb_putc(b1, '\n');
     }
 
     b1->flags |= BF_READONLY;
@@ -1425,7 +1437,7 @@
     if (!b1)
         return;
 
-    eb_printf(b1, "\n");
+    eb_putc(b1, '\n');
 
     w = 28;
     eb_printf(b1, "%*s: %d, %d\n", w, "xleft, ytop", s->xleft, s->ytop);
@@ -1479,7 +1491,7 @@
     eb_printf(b1, "%*s: %d\n", w, "show_selection", s->show_selection);
     eb_printf(b1, "%*s: %d\n", w, "region_style", s->region_style);
     eb_printf(b1, "%*s: %d\n", w, "curline_style", s->curline_style);
-    eb_printf(b1, "\n");
+    eb_putc(b1, '\n');
 
     b1->flags |= BF_READONLY;
     show_popup(s, b1, "Window Description");
@@ -1495,7 +1507,7 @@
     if (!b1)
         return;
 
-    eb_printf(b1, "\n");
+    eb_putc(b1, '\n');
 
     w = 16;
     eb_printf(b1, "%*s: %s\n", w, "dpy.name", s->dpy.name);
@@ -1627,6 +1639,8 @@
     struct chunk *chunk_array;
 
     s->region_style = 0;
+    if (argval != NO_ARG)
+        flags |= argval;
 
     if (p1 > p2) {
         int tmp = p1;
@@ -1634,8 +1648,6 @@
         p2 = tmp;
     }
     ctx.b = s->b;
-    if (argval != NO_ARG)
-        flags |= argval;
     ctx.flags = flags;
     ctx.col = 0;
     eb_get_pos(s->b, &line1, &col1, p1); /* line1 is included */
@@ -1703,7 +1715,7 @@
     }
 }
 
-static void tag_completion(CompleteState *cp) {
+static void tag_complete(CompleteState *cp) {
     /* XXX: only support current buffer */
     QEProperty *p;
 
@@ -1876,6 +1888,10 @@
     CMD_DEF_END,
 };
 
+static CompletionDef tag_completion = {
+    "tag", tag_complete,
+};
+
 static int extras_init(void)
 {
     int key;
@@ -1884,7 +1900,7 @@
     for (key = KEY_META('0'); key <= KEY_META('9'); key++) {
         qe_register_binding(key, "numeric-argument", NULL);
     }
-    register_completion("tag", tag_completion);
+    qe_register_completion(&tag_completion);
 
     return 0;
 }

Index: input.c
===================================================================
RCS file: /sources/qemacs/qemacs/input.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- input.c     27 Mar 2019 07:43:56 -0000      1.24
+++ input.c     17 Oct 2020 15:41:32 -0000      1.25
@@ -80,7 +80,7 @@
     *p = m;
 }
 
-static void input_completion(CompleteState *cp)
+static void input_complete(CompleteState *cp)
 {
     QEmacsState *qs = cp->s->qe_state;
     InputMethod *m;
@@ -122,9 +122,13 @@
         s->input_method = s->selected_input_method;
 }
 
+static CompletionDef input_completion = {
+    "input", input_complete,
+};
+
 void init_input_methods(void)
 {
     register_input_method(&default_input_method);
     register_input_method(&unicode_input_method);
-    register_completion("input", input_completion);
+    qe_register_completion(&input_completion);
 }

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.296
retrieving revision 1.297
diff -u -b -r1.296 -r1.297
--- qe.c        13 Oct 2020 07:14:18 -0000      1.296
+++ qe.c        17 Oct 2020 15:41:32 -0000      1.297
@@ -62,7 +62,6 @@
 #ifndef CONFIG_TINY
 static void save_selection(void);
 #endif
-static CompletionFunc find_completion(const char *name);
 
 QEmacsState qe_state;
 /* should handle multiple screens, and multiple sessions */
@@ -206,7 +205,7 @@
     }
 }
 
-void mode_completion(CompleteState *cp)
+void mode_complete(CompleteState *cp)
 {
     QEmacsState *qs = cp->s->qe_state;
     ModeDef *m;
@@ -218,6 +217,10 @@
     }
 }
 
+static CompletionDef mode_completion = {
+    "mode", mode_complete
+};
+
 /* commands handling */
 
 CmdDef *qe_find_cmd(const char *cmd_name)
@@ -237,7 +240,7 @@
     return NULL;
 }
 
-void command_completion(CompleteState *cp)
+void command_complete(CompleteState *cp)
 {
     QEmacsState *qs = cp->s->qe_state;
     CmdDef *d;
@@ -252,6 +255,51 @@
     }
 }
 
+int command_print_entry(EditState *s, const char *name)
+{
+    EditBuffer *b = s->b;
+    CmdDef *d = qe_find_cmd(name);
+    if (d) {
+        char buf[256];
+        int len;
+
+        b->cur_style = QE_STYLE_FUNCTION;
+        len = eb_puts(b, d->name);
+        b->cur_style = QE_STYLE_DEFAULT;
+        qe_get_prototype(d, buf, sizeof buf);
+        len += eb_puts(b, buf);
+#ifndef CONFIG_TINY
+        if (qe_list_bindings(d, s->mode, 1, buf, sizeof buf)) {
+            b->cur_style = QE_STYLE_COMMENT;
+            if (2 + len < 40) {
+                b->tab_width = max(2 + len, b->tab_width);
+                len += eb_putc(b, '\t');
+            } else {
+                b->tab_width = 40;
+            }
+            len += eb_printf(b, "  bound to %s", buf);
+            b->cur_style = QE_STYLE_DEFAULT;
+        }
+#endif
+        return len;
+    } else {
+        return eb_puts(b, name);
+    }
+}
+
+int command_get_entry(EditState *s, char *dest, int size, int offset)
+{
+    int len;
+    eb_fgets(s->b, dest, size, offset, &offset);
+    len = strcspn(dest, " \t\n(");
+    dest[len] = '\0';   /* strip the TAB or trailing newline if any */
+    return len;
+}
+
+static CompletionDef command_completion = {
+    "command", command_complete, command_print_entry, command_get_entry
+};
+
 static int qe_register_binding1(unsigned int *keys, int nb_keys,
                                 CmdDef *d, ModeDef *m)
 {
@@ -2958,7 +3006,7 @@
         apply_style(stp, style);
 }
 
-void style_completion(CompleteState *cp)
+void style_complete(CompleteState *cp)
 {
     int i;
     QEStyleDef *stp;
@@ -2997,6 +3045,10 @@
         return NULL;
 }
 
+static CompletionDef style_completion = {
+    "style", style_complete
+};
+
 static const char * const qe_style_properties[] = {
 #define CSS_PROP_COLOR  0
     "color",            /* color */
@@ -3015,7 +3067,7 @@
     "text-decoration",  /* text_decoration: none / underline */
 };
 
-void style_property_completion(CompleteState *cp)
+void style_property_complete(CompleteState *cp)
 {
     int i;
 
@@ -3024,6 +3076,10 @@
     }
 }
 
+static CompletionDef style_property_completion = {
+    "style-property", style_property_complete
+};
+
 int find_style_property(const char *name)
 {
     int i;
@@ -4721,6 +4777,8 @@
 
     out = buf_init(&outbuf, buf, size);
 
+    buf_put_byte(out, '(');
+
     /* construct argument type list */
     r = d->name + strlen(d->name) + 1;
     if (*r == '*') {
@@ -4763,6 +4821,7 @@
             buf_puts(out, *history ? history : completion);
         }
     }
+    buf_put_byte(out, ')');
     return out->len;
 }
 
@@ -4874,6 +4933,7 @@
             char def_input[1024];
 
             /* XXX: currently, default input is handled non generically */
+            /* XXX: should use completion function for default input? */
             def_input[0] = '\0';
             es->default_input[0] = '\0';
             if (strequal(completion_name, "file")) {
@@ -5010,6 +5070,7 @@
 {
     CmdDef *d;
 
+    /* XXX: should test for '(' and '=' and evaluate script instead */
     d = qe_find_cmd(cmd);
     if (d) {
         exec_command(s, d, argval, 0);
@@ -5917,7 +5978,7 @@
     "|"
 };
 
-void file_completion(CompleteState *cp)
+void file_complete(CompleteState *cp)
 {
     char path[MAX_FILENAME_SIZE];
     char file[MAX_FILENAME_SIZE];
@@ -5969,7 +6030,11 @@
     find_file_close(&ffst);
 }
 
-void buffer_completion(CompleteState *cp)
+static CompletionDef file_completion = {
+    "file", file_complete
+};
+
+void buffer_complete(CompleteState *cp)
 {
     QEmacsState *qs = cp->s->qe_state;
     EditBuffer *b;
@@ -5980,45 +6045,69 @@
     }
 }
 
+static CompletionDef buffer_completion = {
+    "buffer", buffer_complete
+};
+
+static int default_completion_window_print_entry(EditState *s, const char 
*name) {
+    return eb_puts(s->b, name);
+}
+
+static int default_completion_window_get_entry(EditState *s, char *dest, int 
size, int offset) {
+    int len = eb_fgets(s->b, dest, size, offset, &offset);
+    char *p = strchr(dest, '\t');
+    if (p != NULL)
+        len = p - dest;
+    dest[len] = '\0';   /* strip the TAB or trailing newline if any */
+    return len;
+}
+
 /* register a new completion method */
-void register_completion(const char *name, CompletionFunc completion_func)
+void qe_register_completion(CompletionDef *cp)
 {
     QEmacsState *qs = &qe_state;
-    CompletionEntry **lp, *p;
+    CompletionDef **p;
 
-    p = qe_mallocz(CompletionEntry);
-    if (!p)
+    for (p = &qs->first_completion;; p = &(*p)->next) {
+        if (*p == cp) {
+            /* completion is already registered, do nothing */
         return;
-
-    p->name = name;
-    p->completion_func = completion_func;
-    p->next = NULL;
-
-    lp = &qs->first_completion;
-    while (*lp != NULL)
-        lp = &(*lp)->next;
-    *lp = p;
+        }
+        if (*p == NULL) {
+            cp->next = NULL;
+            *p = cp;
+            break;
+        }
+    }
+    if (!cp->print_entry)
+        cp->print_entry = default_completion_window_print_entry;
+    if (!cp->get_entry)
+        cp->get_entry = default_completion_window_get_entry;
 }
 
-static CompletionFunc find_completion(const char *name)
+static CompletionDef *find_completion(const char *name)
 {
-    CompletionEntry *p;
+    CompletionDef *p;
 
     if (name[0] != '\0') {
         for (p = qe_state.first_completion; p != NULL; p = p->next) {
             if (strequal(p->name, name))
-                return p->completion_func;
+                return p;
         }
     }
     return NULL;
 }
 
-static void complete_start(CompleteState *cp, EditState *s, EditState *target)
+static void complete_start(CompleteState *cp, EditState *s, int start, int end,
+                           EditState *target)
 {
     memset(cp, 0, sizeof(*cp));
     cp->s = s;
     cp->target = target;
-    cp->len = eb_get_contents(s->b, cp->current, sizeof(cp->current));
+    cp->start = start;
+    cp->end = end;
+    cp->len = eb_get_region_contents(s->b, cp->start, cp->end,
+                                     cp->current, sizeof(cp->current));
 }
 
 /* XXX: should have a globbing option */
@@ -6065,8 +6154,10 @@
     void *opaque;
 
     EditState *completion_popup_window;  /* XXX: should have a popup_window 
member */
-    OWNED char *completion_name;
-    CompletionFunc completion_function;
+    int completion_flags;
+    int completion_start;
+    int completion_end;
+    CompletionDef *completion;
 
     StringArray *history;
     int history_index;
@@ -6082,7 +6173,7 @@
 void do_minibuffer_complete(EditState *s, int type)
 {
     QEmacsState *qs = s->qe_state;
-    int count, i, match_len, c;
+    int count, i, match_len, c, start, end;
     CompleteState cs;
     StringItem **outputs;
     EditState *e;
@@ -6093,7 +6184,7 @@
     if ((mb = minibuffer_get_state(s, 1)) == NULL)
         return;
 
-    if (!mb->completion_function)
+    if (!mb->completion)
         return;
 
     /* Remove highlighted selection. */
@@ -6117,8 +6208,21 @@
         return;
     }
 
-    complete_start(&cs, s, s->target_window);
-    (*mb->completion_function)(&cs);
+    start = 0;
+    end = s->offset;
+    if (mb->completion_flags) {
+        /* XXX: completion select? */
+        int offset = end;
+        while ((start = offset) > 0) {
+            int c = eb_prevc(s->b, offset, &offset);
+            if (!qe_isalnum_(c) && c != '-')
+                break;
+        }
+    }
+    mb->completion_start = start;
+    mb->completion_end = end;
+    complete_start(&cs, s, start, end, s->target_window);
+    (*mb->completion->enumerate)(&cs);
     count = cs.cs.nb_items;
     outputs = cs.cs.items;
 #if 0
@@ -6150,10 +6254,12 @@
     if (match_len > cs.len) {
         /* add the possible chars */
         // XXX: potential utf-8 issue?
-        eb_write(s->b, 0, outputs[0]->str, match_len);
-        s->offset = match_len;
+        // XXX: replace the completed part, not necessarily at the start (use 
mark?)
+        // XXX: should delete region and insert as utf-8
+        eb_replace(s->b, cs.start, cs.end - cs.start, outputs[0]->str, 
match_len);
+        s->offset = cs.start + match_len;
         if (type == COMPLETION_OTHER) {
-            do_mark_region(s, match_len, cs.len);
+            do_mark_region(s, cs.start + match_len, cs.start + cs.len);  // 
XXX: ???
         }
     } else {
         if (count > 1) {
@@ -6170,7 +6276,7 @@
                 w = (w1 * 3) / 4;
                 h = (h1 * 3) / 4;
                 e = edit_new(b, (w1 - w) / 2, (h1 - h) / 2, w, h, WF_POPUP);
-                snprintf(buf, sizeof buf, "Select a %s:", mb->completion_name);
+                snprintf(buf, sizeof buf, "Select a %s:", 
mb->completion->name);
                 e->caption = qe_strdup(buf);
                 e->target_window = s;
                 mb->completion_popup_window = e;
@@ -6190,10 +6296,12 @@
         qsort(outputs, count, sizeof(StringItem *), completion_sort_func);
         b->flags &= ~BF_READONLY;
         eb_delete(b, 0, b->total_size);
+        b->tab_width = 4;
         for (i = 0; i < count; i++) {
-            eb_printf(b, " %s", outputs[i]->str);
+            eb_putc(b, ' ');    /* XXX: should use window margins */
+            mb->completion->print_entry(e, outputs[i]->str);
             if (i != count - 1)
-                eb_printf(b, "\n");
+                eb_putc(b, '\n');
         }
         b->flags |= BF_READONLY;
         e->mouse_force_highlight = 1;
@@ -6221,7 +6329,7 @@
     int c, offset, stop;
     MinibufState *mb = minibuffer_get_state(s, 0);
 
-    if (mb && mb->completion_function == file_completion) {
+    if (mb && mb->completion == &file_completion) {
         stop = s->offset;
         c = eb_prevc(s->b, s->offset, &offset);
         if (c == '/') {
@@ -6242,7 +6350,7 @@
     QEmacsState *qs = s->qe_state;
     MinibufState *mb = minibuffer_get_state(s, 0);
 
-    if (!mb || !mb->completion_function) {
+    if (!mb || !mb->completion) {
         do_char(s, ' ', 1);
     } else
     if (check_window(&mb->completion_popup_window)
@@ -6278,15 +6386,15 @@
     }
 }
 
-static void minibuf_set_str(EditState *s, const char *str)
+static void minibuf_set_str(EditState *s, int start, int end, const char *str)
 {
     int len;
 
-    eb_delete(s->b, 0, s->b->total_size);
+    /* Replace the completion trigger zone */
     /* XXX: should insert utf-8? */
     len = strlen(str);
-    eb_write(s->b, 0, str, len);
-    s->offset = len;
+    eb_replace(s->b, start, end - start, str, len);
+    s->offset = start + len;
 }
 
 /* CG: should use buffer of responses */
@@ -6347,7 +6455,7 @@
     /* insert history text */
     mb->history_index = index;
     str = hist->items[index]->str;
-    minibuf_set_str(s, str);
+    minibuf_set_str(s, 0, s->b->total_size, str);
     if (index == hist->nb_items - 1) {
         s->offset = mb->history_saved_offset;
     }
@@ -6383,12 +6491,11 @@
         /* if completion is activated, then select current file only if
            the selection is highlighted */
         if (cw && cw->force_highlight) {
-            int offset, len;
-
-            len = eb_fgets(cw->b, buf, sizeof(buf), list_get_offset(cw), 
&offset);
-            buf[len] = '\0';   /* strip the trailing newline if any */
+            int len;
+            len = mb->completion->get_entry(cw, buf, sizeof(buf), 
list_get_offset(cw) + 1);
             if (len > 0) {
-                minibuf_set_str(s, buf + 1);
+                eb_delete_range(s->b, s->b->mark, s->offset);     // delete 
highlighted completion
+                minibuf_set_str(s, mb->completion_start, mb->completion_end, 
buf);
             }
         }
 
@@ -6417,7 +6524,6 @@
     target = s->target_window;
     mb->cb = NULL;
     mb->opaque = NULL;
-    qe_free(&mb->completion_name);
 
     /* Close the minibuffer window */
     s->b->flags |= BF_TRANSIENT;
@@ -6477,11 +6583,13 @@
     mb = minibuffer_get_state(s, 0);
     if (mb) {
         mb->completion_popup_window = NULL;
-        mb->completion_name = NULL;
-        mb->completion_function = NULL;
+        mb->completion = NULL;
         if (completion_name) {
-            mb->completion_name = qe_strdup(completion_name);
-            mb->completion_function = find_completion(completion_name);
+            if (*completion_name == '.') {
+                mb->completion_flags = 1;
+                completion_name++;
+            }
+            mb->completion = find_completion(completion_name);
         }
         mb->history = hist;
         mb->history_saved_offset = 0;
@@ -8039,7 +8147,7 @@
     if (!b)
         return;
 
-    eb_printf(b,
+    eb_puts(b,
               "QEmacs help for help - Press q to quit:\n"
               "\n"
               "C-h C-h   Show this help\n"
@@ -8952,6 +9060,14 @@
     char **argv;
 } QEArgs;
 
+static CompletionDef charset_completion = {
+    "charset", charset_complete
+};
+
+static CompletionDef color_completion = {
+    "color", color_complete
+};
+
 /* init function */
 static void qe_init(void *opaque)
 {
@@ -8998,14 +9114,14 @@
     qe_register_cmd_table(basic_commands, NULL);
     qe_register_cmd_line_options(cmd_options);
 
-    register_completion("command", command_completion);
-    register_completion("charset", charset_completion);
-    register_completion("mode", mode_completion);
-    register_completion("style", style_completion);
-    register_completion("style-property", style_property_completion);
-    register_completion("file", file_completion);
-    register_completion("buffer", buffer_completion);
-    register_completion("color", color_completion);
+    qe_register_completion(&command_completion);
+    qe_register_completion(&charset_completion);
+    qe_register_completion(&mode_completion);
+    qe_register_completion(&style_completion);
+    qe_register_completion(&style_property_completion);
+    qe_register_completion(&file_completion);
+    qe_register_completion(&buffer_completion);
+    qe_register_completion(&color_completion);
 
     minibuffer_init();
     popup_init();
@@ -9216,7 +9332,7 @@
             }
         }
         while (qs->first_completion) {
-            CompletionEntry *cp = qs->first_completion;
+            CompletionDef *cp = qs->first_completion;
             qs->first_completion = cp->next;
             qe_free(&cp);
         }

Index: qscript.c
===================================================================
RCS file: /sources/qemacs/qemacs/qscript.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- qscript.c   14 Oct 2020 23:32:03 -0000      1.1
+++ qscript.c   17 Oct 2020 15:41:32 -0000      1.2
@@ -112,6 +112,7 @@
     sp->u.str = qe_malloc_array(char, len + 1);
     memcpy(sp->u.str, str, len);
     sp->u.str[len] = '\0';
+    sp->len = len;
     sp->type = TOK_STRING;
 }
 
@@ -1163,11 +1164,29 @@
 }
 #endif
 
+void script_complete(CompleteState *cp) {
+    command_complete(cp);
+    variable_complete(cp);
+}
+
+int script_print_entry(EditState *s, const char *name) {
+    CmdDef *d = qe_find_cmd(name);
+    if (d) {
+        return command_print_entry(s, name);
+    } else {
+        return variable_print_entry(s, name);
+    }        
+}
+
+static CompletionDef script_completion = {
+    "script", script_complete, script_print_entry, command_get_entry
+};
+
 static CmdDef parser_commands[] = {
 
     CMD2( KEY_META(':'), KEY_NONE,
           "eval-expression", do_eval_expression, ESsi,
-          "s{Eval: }|expression|ui")
+          "s{Eval: }[.script]|expression|ui")
     CMD0( KEY_NONE, KEY_NONE,
           "eval-region", do_eval_region)
     CMD0( KEY_NONE, KEY_NONE,
@@ -1182,6 +1201,7 @@
 static int parser_init(void)
 {
     qe_register_cmd_table(parser_commands, NULL);
+    qe_register_completion(&script_completion);
     return 0;
 }
 

Index: util.c
===================================================================
RCS file: /sources/qemacs/qemacs/util.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -b -r1.87 -r1.88
--- util.c      9 Oct 2020 00:00:55 -0000       1.87
+++ util.c      17 Oct 2020 15:41:32 -0000      1.88
@@ -1811,7 +1811,7 @@
     return color & 0xFFFFFF;
 }
 
-void color_completion(CompleteState *cp)
+void color_complete(CompleteState *cp)
 {
     ColorDef const *def;
     int count;

Index: variables.h
===================================================================
RCS file: /sources/qemacs/qemacs/variables.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- variables.h 25 Mar 2017 18:15:01 -0000      1.10
+++ variables.h 17 Oct 2020 15:41:32 -0000      1.11
@@ -95,7 +95,8 @@
 
 void qe_register_variables(VarDef *vars, int count);
 VarDef *qe_find_variable(const char *name);
-void qe_complete_variable(CompleteState *cp);
+void variable_complete(CompleteState *cp);
+int variable_print_entry(EditState *s, const char *name);
 
 QVarType qe_get_variable(EditState *s, const char *name,
                          char *buf, int size, int *pnum, int as_source);

Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -b -r1.116 -r1.117
--- buffer.c    7 May 2017 06:08:57 -0000       1.116
+++ buffer.c    17 Oct 2020 15:41:32 -0000      1.117
@@ -1531,16 +1531,7 @@
  */
 int eb_delete_chars(EditBuffer *b, int offset, int n)
 {
-    int offset1 = eb_skip_chars(b, offset, n);
-    int size = offset1 - offset;
-
-    if (size < 0) {
-        offset += size;
-        offset1 -= size;
-        size = -size;
-    }
-
-    return eb_delete(b, offset, size);
+    return eb_delete_range(b, offset, eb_skip_chars(b, offset, n));
 }
 
 /* XXX: only stateless charsets are supported */

Index: dired.c
===================================================================
RCS file: /sources/qemacs/qemacs/dired.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -b -r1.83 -r1.84
--- dired.c     2 Oct 2020 20:18:26 -0000       1.83
+++ dired.c     17 Oct 2020 15:41:32 -0000      1.84
@@ -683,11 +683,11 @@
     if (DIRED_HEADER) {
         int seq = ' ';
         b->cur_style = DIRED_STYLE_HEADER;
-        eb_printf(b, "  Directory of ");
+        eb_puts(b, "  Directory of ");
         b->cur_style = DIRED_STYLE_DIRECTORY;
-        eb_printf(b, "%s", ds->path);
+        eb_puts(b, ds->path);
         b->cur_style = DIRED_STYLE_HEADER;
-        eb_printf(b, "\n  ");
+        eb_puts(b, "\n  ");
         if (ds->ndirs) {
             eb_printf(b, "%c %d %s", seq, ds->ndirs,
                       inflect(ds->ndirs, "directory", "directories"));
@@ -717,7 +717,7 @@
         if (ds->ndirs + ds->ndirs_hidden + ds->nfiles + ds->nfiles_hidden == 
0) {
             eb_printf(b, "%c empty", seq);
         }
-        eb_printf(b, "\n");
+        eb_putc(b, '\n');
     }
     b->cur_style = DIRED_STYLE_NORMAL;
 
@@ -767,12 +767,12 @@
         else
             b->cur_style = DIRED_STYLE_FILENAME;
 
-        eb_printf(b, "%s", dip->name);
+        eb_puts(b, dip->name);
 
         if (1) {
             int trailchar = get_trailchar(dip->mode);
             if (trailchar) {
-                eb_printf(b, "%c", trailchar);
+                eb_putc(b, trailchar);
             }
         }
         if (S_ISLNK(dip->mode)
@@ -780,7 +780,7 @@
             eb_printf(b, " -> %s", buf);
         }
         b->cur_style = DIRED_STYLE_NORMAL;
-        eb_printf(b, "\n");
+        eb_putc(b, '\n');
     }
     b->modified = 0;
     b->flags |= BF_READONLY;

Index: image.c
===================================================================
RCS file: /sources/qemacs/qemacs/image.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- image.c     5 May 2017 19:59:49 -0000       1.35
+++ image.c     17 Oct 2020 15:41:32 -0000      1.36
@@ -846,7 +846,7 @@
                ib->interleaved ? 'I' : ' ');
 }
 
-static void pixel_format_completion(CompleteState *cp)
+static void pixel_format_complete(CompleteState *cp)
 {
     int i;
     const char *name;
@@ -863,7 +863,7 @@
           "image-rotate", image_rotate)
     CMD2( 'c', KEY_NONE,
           "image-convert", image_convert, ESs,
-          "s{New pixel format: }[pixel_format]|pixel_format|")
+          "s{New pixel format: }[pixel-format]|pixel-format|")
     CMD2( 'b', KEY_NONE,
           "image-set-background-color", image_set_background_color, ESs,
           "s{Background color (use 'transparent' for tiling): }")
@@ -909,13 +909,17 @@
     .get_mode_line = image_mode_line,
 };
 
+static CompletionDef pixel_format_completion = {
+    "pixel-format", pixel_format_complete
+};
+
 static int image_init(void)
 {
     av_register_all();
     eb_register_data_type(&image_data_type);
     qe_register_mode(&image_mode, MODEF_DATATYPE | MODEF_VIEW);
     qe_register_cmd_table(image_commands, &image_mode);
-    register_completion("pixel_format", pixel_format_completion);
+    qe_register_completion(&pixel_format_completion);
     /* additional mode specific keys */
     qe_register_binding('f', "toggle-full-screen", &image_mode);
     return 0;

Index: latex-mode.c
===================================================================
RCS file: /sources/qemacs/qemacs/latex-mode.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- latex-mode.c        20 May 2017 20:43:14 -0000      1.58
+++ latex-mode.c        17 Oct 2020 15:41:32 -0000      1.59
@@ -211,7 +211,7 @@
 #undef INIT_TAIL
 };
 
-static void latex_completion(CompleteState *cp)
+static void latex_complete(CompleteState *cp)
 {
     struct latex_function *func;
 
@@ -344,12 +344,16 @@
     .colorize_flags = TEX_TEXINFO,
 };
 
+static CompletionDef latex_completion = {
+    "latex", latex_complete,
+};
+
 static int latex_init(void)
 {
     qe_register_mode(&latex_mode, MODEF_SYNTAX);
     qe_register_mode(&texinfo_mode, MODEF_SYNTAX);
     qe_register_cmd_table(latex_commands, &latex_mode);
-    register_completion("latex", latex_completion);
+    qe_register_completion(&latex_completion);
 
     return 0;
 }

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.277
retrieving revision 1.278
diff -u -b -r1.277 -r1.278
--- qe.h        13 Oct 2020 07:14:18 -0000      1.277
+++ qe.h        17 Oct 2020 15:41:32 -0000      1.278
@@ -194,7 +194,7 @@
     StringArray cs;
     struct EditState *s;
     struct EditState *target;
-    int len;
+    int start, end, len;
     char current[MAX_FILENAME_SIZE];
 } CompleteState;
 
@@ -502,7 +502,7 @@
 /* Convert a composite color to an RGB triplet */
 QEColor qe_unmap_color(int color, int count);
 
-void color_completion(CompleteState *cp);
+void color_complete(CompleteState *cp);
 int css_define_color(const char *name, const char *value);
 int css_get_color(QEColor *color_ptr, const char *p);
 void css_free_colors(void);
@@ -810,7 +810,7 @@
 char *utf8_char_to_string(char *buf, int c);
 int utf8_to_unicode(unsigned int *dest, int dest_length, const char *str);
 
-void charset_completion(CompleteState *cp);
+void charset_complete(CompleteState *cp);
 QECharset *find_charset(const char *str);
 void charset_decode_init(CharsetDecodeState *s, QECharset *charset,
                          EOLType eol_type);
@@ -1637,7 +1637,7 @@
     struct ModeDef *first_mode;
     struct KeyDef *first_key;
     struct CmdDef *first_cmd;
-    struct CompletionEntry *first_completion;
+    struct CompletionDef *first_completion;
     struct HistoryEntry *first_history;
     //struct QECharset *first_charset;
     //struct QETimer *first_timer;
@@ -1819,11 +1819,12 @@
 ModeDef *qe_find_mode(const char *name, int flags);
 ModeDef *qe_find_mode_filename(const char *filename, int flags);
 void qe_register_mode(ModeDef *m, int flags);
-void mode_completion(CompleteState *cp);
+void mode_complete(CompleteState *cp);
 void qe_register_cmd_table(CmdDef *cmds, ModeDef *m);
 int qe_register_binding(int key, const char *cmd_name, ModeDef *m);
 CmdDef *qe_find_cmd(const char *cmd_name);
 int qe_get_prototype(CmdDef *d, char *buf, int size);
+int qe_list_bindings(CmdDef *d, ModeDef *mode, int inherit, char *buf, int 
size);
 
 /* text display system */
 
@@ -1998,25 +1999,29 @@
 extern CmdDef minibuffer_commands[];
 extern CmdDef popup_commands[];
 
-typedef void (*CompletionFunc)(CompleteState *cp);
-
-typedef struct CompletionEntry {
+typedef struct CompletionDef {
     const char *name;
-    CompletionFunc completion_func;
-    struct CompletionEntry *next;
-} CompletionEntry;
+    void (*enumerate)(CompleteState *cp);
+    int (*print_entry)(EditState *s, const char *name);
+    int (*get_entry)(EditState *s, char *dest, int size, int offset);
+    int flags;
+    struct CompletionDef *next;
+} CompletionDef;
+
+void qe_register_completion(CompletionDef *cp);
 
 void complete_test(CompleteState *cp, const char *str);
 
-void register_completion(const char *name, CompletionFunc completion_func);
 void put_status(EditState *s, const char *fmt, ...) qe__attr_printf(2,3);
 void put_error(EditState *s, const char *fmt, ...) qe__attr_printf(2,3);
 void minibuffer_edit(EditState *e, const char *input, const char *prompt,
                      StringArray *hist, const char *completion_name,
                      void (*cb)(void *opaque, char *buf), void *opaque);
-void command_completion(CompleteState *cp);
-void file_completion(CompleteState *cp);
-void buffer_completion(CompleteState *cp);
+void command_complete(CompleteState *cp);
+int command_print_entry(EditState *s, const char *name);
+int command_get_entry(EditState *s, char *dest, int size, int offset);
+void file_complete(CompleteState *cp);
+void buffer_complete(CompleteState *cp);
 
 #ifdef CONFIG_WIN32
 static inline int is_user_input_pending(void) {
@@ -2223,9 +2228,9 @@
 void display_window_borders(EditState *e);
 int find_style_index(const char *name);
 QEStyleDef *find_style(const char *name);
-void style_completion(CompleteState *cp);
+void style_complete(CompleteState *cp);
 void get_style(EditState *e, QEStyleDef *stp, QETermStyle style);
-void style_property_completion(CompleteState *cp);
+void style_property_complete(CompleteState *cp);
 int find_style_property(const char *name);
 void do_define_color(EditState *e, const char *name, const char *value);
 void do_set_style(EditState *e, const char *stylestr,

Index: tty.c
===================================================================
RCS file: /sources/qemacs/qemacs/tty.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -b -r1.88 -r1.89
--- tty.c       18 May 2017 14:14:28 -0000      1.88
+++ tty.c       17 Oct 2020 15:41:32 -0000      1.89
@@ -906,7 +906,7 @@
     eb_printf(b, "%*s: fg:%d, bg:%d\n", w, "virtual tty colors",
               ts->tty_fg_colors_count, ts->tty_bg_colors_count);
     
-    eb_printf(b, "\n");
+    eb_putc(b, '\n');
     eb_printf(b, "Unicode combination cache:\n\n");
     
     for (ip = ts->comb_cache; *ip != 0; ip += *ip & 0xFFFF) {
@@ -919,7 +919,7 @@
             for (i = 1; i < (*ip & 0xFFFF); i++) {
                 eb_printf(b, " %04X", ip[i]);
             }
-            eb_printf(b, "\n");
+            eb_putc(b, '\n');
         }
     }
 }

Index: variables.c
===================================================================
RCS file: /sources/qemacs/qemacs/variables.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- variables.c 28 May 2019 04:30:56 -0000      1.25
+++ variables.c 17 Oct 2020 15:41:32 -0000      1.26
@@ -115,7 +115,7 @@
     return NULL;
 }
 
-void qe_complete_variable(CompleteState *cp)
+void variable_complete(CompleteState *cp)
 {
     QEmacsState *qs = cp->s->qe_state;
     const VarDef *vp;
@@ -369,6 +369,7 @@
 
     eb_puts(b, "\n  variables:\n\n");
     for (vp = qs->first_variable; vp; vp = vp->next) {
+        /* XXX: merge with variable_print_entry() */
         switch (vp->type) {
         case VAR_NUMBER:
             type = "int";
@@ -415,15 +416,67 @@
     eb_putc(b, '\n');
 }
 
+int variable_print_entry(EditState *s, const char *name)
+{
+    char buf[256];
+    char typebuf[32];
+    const char *type = typebuf;
+    int len;
+    VarDef *vp = qe_find_variable(name);
+    EditBuffer *b = s->b;
+
+    len = eb_puts(b, name);
+    if (!vp)
+        return len;
+
+    switch (vp->type) {
+    case VAR_NUMBER:
+        type = "int";
+        break;
+    case VAR_STRING:
+        type = "string";
+        break;
+    case VAR_CHARS:
+        snprintf(typebuf, sizeof(typebuf), "char[%d]", vp->size);
+        break;
+    default:
+        type = "var";
+        break;
+    }
+    len += eb_printf(b, " = ");
+    qe_get_variable(s, vp->name, buf, sizeof(buf), NULL, 1);
+    if (*buf == '\"')
+        b->cur_style = QE_STYLE_STRING;
+    else
+        b->cur_style = QE_STYLE_NUMBER;
+    len += eb_puts(b, buf);
+    b->cur_style = QE_STYLE_COMMENT;
+    if (2 + len < 40) {
+        b->tab_width = max(2 + len, b->tab_width);
+        len += eb_putc(b, '\t');
+    } else {
+        b->tab_width = 40;
+    }
+    len += eb_printf(b, "  %s%s %s",
+                     vp->rw ? "" : "read-only ",
+                     var_domain[vp->domain], type);
+    b->cur_style = QE_STYLE_DEFAULT;
+    return len;
+}
+
+static CompletionDef variable_completion = {
+    "variable", variable_complete, variable_print_entry, command_get_entry
+};
+
 /*---------------- commands ----------------*/
 
 static CmdDef var_commands[] = {
     CMD2( KEY_NONE, KEY_NONE,
           "show-variable", do_show_variable, ESs,
-          "s{Show variable: }[var]|var|")
+          "s{Show variable: }[variable]|variable|")
     CMD2( KEY_F8, KEY_NONE,
           "set-variable", do_set_variable, ESss,
-          "s{Set variable: }[var]|var|s{to value: }|value|")
+          "s{Set variable: }[variable]|variable|s{to value: }|value|")
 
     CMD_DEF_END,
 };
@@ -432,7 +485,7 @@
 {
     qe_register_variables(var_table, countof(var_table));
     qe_register_cmd_table(var_commands, NULL);
-    register_completion("var", qe_complete_variable);
+    qe_register_completion(&variable_completion);
     return 0;
 }
 



reply via email to

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