qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs TODO.org buffer.c clang.c extras.c qe.c ...


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs TODO.org buffer.c clang.c extras.c qe.c ...
Date: Fri, 31 Mar 2017 03:51:57 -0400 (EDT)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        17/03/31 03:51:57

Modified files:
        .              : TODO.org buffer.c clang.c extras.c qe.c qe.h 

Log message:
        clang: add primitive tag support
        - add buffer properties with offset tracking
        - use buffer properties for type, macro, function and object 
definitions.
        - display current function or type name on mode line
        - add list-tags command to show the tags detected for the current buffer
        - add goto-tag on C-X , and M-F1 to jump to the definition of the 
current word
        - add find-tag on C-X . to search for a given tag with completion

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/TODO.org?cvsroot=qemacs&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.107&r2=1.108
http://cvs.savannah.gnu.org/viewcvs/qemacs/clang.c?cvsroot=qemacs&r1=1.117&r2=1.118
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.61&r2=1.62
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.257&r2=1.258
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.242&r2=1.243

Patches:
Index: TODO.org
===================================================================
RCS file: /sources/qemacs/qemacs/TODO.org,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- TODO.org    25 Mar 2017 18:00:52 -0000      1.29
+++ TODO.org    31 Mar 2017 07:51:56 -0000      1.30
@@ -5,6 +5,7 @@
 
 * Needed for release version 5
 
+
 * Priority 0
 
 ** basic: fix current position when changing buffer attached to window
@@ -14,6 +15,7 @@
 ** basic: use visual movement for left, right, up, down and character based 
for C-b C-f C-n C-p
 ** basic: share mmapped pages correctly
 ** completion: fix electric behavior
+** completion: add completion function to get the default value
 ** files: check file date to detect asynchronous modifications on disk
 ** files: reload modified file upon change if untouched since load
 ** layout: kill buffer should delete popup and popleft window
@@ -316,10 +318,16 @@
 ** c-indent
 ** indent-with-tabs
 ** stats command for slcc
-** add TAGS support:
-*** recursive search of QTAGS file.
-*** C decl parser
-*** global QTAGS file indexed with global includes
+** improve tag support:
+*** tag multiple files and buffers
+*** tag project files recursively
+*** save tags to QTAGS or .qetags file
+*** handle multiple tag files
+*** update tag files automatically
+*** list-definitions with hot load function
+*** show-definition in popup
+*** handle standard libraries with tag system
+*** generate #include lines automatically
 ** see if java/javascript/c++ is OK.
 ** autocomplete keyword, function, variable, member names
 ** automatic indentation detection

Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -b -r1.107 -r1.108
--- buffer.c    26 Mar 2017 15:57:24 -0000      1.107
+++ buffer.c    31 Mar 2017 07:51:56 -0000      1.108
@@ -802,6 +802,7 @@
             qe_free(&cb);
         }
 
+        eb_delete_properties(b, 0, INT_MAX);
         eb_cache_remove(b);
         eb_clear(b);
 
@@ -1020,6 +1021,7 @@
 int eb_create_style_buffer(EditBuffer *b, int flags)
 {
     if (b->b_styles) {
+        /* XXX: should extend style width if needed */
         return 0;
     } else {
         char name[MAX_BUFFERNAME_SIZE];
@@ -2534,6 +2536,99 @@
     return offset;
 }
 
+/* buffer property handling */
+
+static void eb_plist_callback(EditBuffer *b, void *opaque, int edge,
+                              enum LogOperation op, int offset, int size)
+{
+    QEProperty **pp;
+    QEProperty *p;
+                                 
+    /* update properties */
+    if (op == LOGOP_INSERT) {
+        for (p = b->property_list; p; p = p->next) {
+            if (p->offset >= offset)
+                p->offset += size;
+        }
+    } else
+    if (op == LOGOP_DELETE) {
+        for (pp = &b->property_list; (p = *pp) != NULL;) {
+            if (p->offset >= offset) {
+                if (p->offset < offset + size) {
+                    /* property is anchored inside block: remove it */
+                    *pp = (*pp)->next;
+                    if (p->type & QE_PROP_FREE) {
+                        qe_free(&p->data);
+                    }
+                    qe_free(&p);
+                    continue;
+                }
+                p->offset -= size;
+            }
+            pp = &(*pp)->next;
+        }
+    }
+}
+
+void eb_add_property(EditBuffer *b, int offset, int type, void *data) {
+    QEProperty *p = qe_mallocz(QEProperty);
+    QEProperty **pp;
+
+    if (!b->property_list) {
+        eb_add_callback(b, eb_plist_callback, NULL, 0);
+    }
+
+    p->offset = offset;
+    p->type = type;
+    p->data = data;
+    for (pp = &b->property_list; *pp; pp = &(*pp)->next) {
+        if ((*pp)->offset >= offset) {
+            if ((*pp)->offset == offset && p->type == type && type == 
QE_PROP_TAG) {
+                /* prevent tag duplicates */
+                if (strequal(p->data, data))
+                    return;
+                continue;
+            }
+            break;
+        }
+    }
+    p->next = *pp;
+    *pp = p;
+}
+
+QEProperty *eb_find_property(EditBuffer *b, int offset, int offset2, int type) 
{
+    QEProperty *found = NULL;
+    QEProperty *p;
+    for (p = b->property_list; p && p->offset < offset2; p = p->next) {
+        if (p->offset >= offset) {
+            found = p;
+        }
+    }
+    return found;
+}
+
+void eb_delete_properties(EditBuffer *b, int offset, int offset2) {
+    QEProperty *p;
+    QEProperty **pp;
+
+    if (b->property_list) {
+        for (pp = &b->property_list; (p = *pp) != NULL;) {
+            if (p->offset >= offset && p->offset < offset2) {
+                *pp = (*pp)->next;
+                if (p->type & QE_PROP_FREE) {
+                    qe_free(&p->data);
+                }
+                qe_free(&p);
+            } else {
+                pp = &(*pp)->next;
+            }
+        }
+        if (!b->property_list) {
+            eb_free_callback(b, eb_plist_callback, NULL);
+        }
+    }
+}
+
 /* buffer data type handling */
 
 void eb_register_data_type(EditBufferDataType *bdt)

Index: clang.c
===================================================================
RCS file: /sources/qemacs/qemacs/clang.c,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -b -r1.117 -r1.118
--- clang.c     26 Mar 2017 15:57:24 -0000      1.117
+++ clang.c     31 Mar 2017 07:51:56 -0000      1.118
@@ -186,7 +186,7 @@
                             unsigned int *str, int n, ModeDef *syn)
 {
     int i = 0, start, i1, i2, indent, level;
-    int c, style, style0, style1, type_decl, klen, delim, prev;
+    int c, style, style0, style1, type_decl, klen, delim, prev, tag;
     char kbuf[32];
     int mode_flags = syn->colorize_flags;
     int flavor = (mode_flags & CLANG_FLAVOR);
@@ -195,6 +195,7 @@
     for (indent = 0; qe_isblank(str[indent]); indent++)
         continue;
 
+    tag = !indent && cp->s->mode == syn;
     start = i;
     type_decl = 0;
     c = 0;
@@ -542,6 +543,10 @@
                     goto parse_comment1;
             }
             break;
+        case '(':
+        case '{':
+            tag = 0;
+            break;
         default:
         normal:
             if (state & IN_C_PREPROCESS)
@@ -578,6 +583,10 @@
                 while (str[i2] == '*' || qe_isblank(str[i2]))
                     i2++;
 
+                if (tag && qe_findchar("({[,;=", str[i1])) {
+                    eb_add_property(cp->b, cp->offset, QE_PROP_TAG, 
qe_strdup(kbuf));
+                }
+
                 if ((start == 0 || str[start - 1] != '.')
                 &&  (!qe_findchar(".(:", str[i]) || flavor == CLANG_PIKE)
                 &&  (strfind(syn->types, kbuf)
@@ -1526,7 +1535,7 @@
                              unsigned int *str, int n, ModeDef *syn)
 {
     int i = 0, start, i1, indent;
-    int c, style, klen, delim, prev;
+    int c, style, klen, delim, prev, tag;
     char kbuf[32];
     int mode_flags = syn->colorize_flags;
     int flavor = (mode_flags & CLANG_FLAVOR);
@@ -1535,6 +1544,7 @@
 
     indent = 0;
     //for (; qe_isblank(str[indent]); indent++) continue;
+    tag = !qe_isblank(str[0]) && (cp->s->mode == syn || cp->s->mode == 
&htmlsrc_mode);
 
     start = i;
     //type_decl = 0;
@@ -1677,6 +1687,10 @@
                     goto parse_comment1;
             }
             continue;
+        case '(':
+        case '{':
+            tag = 0;
+            break;
         default:
             if (qe_isdigit(c)) {
                 /* XXX: should parse actual number syntax */
@@ -1692,7 +1706,7 @@
                 klen = get_js_identifier(kbuf, countof(kbuf), str + start);
                 i = start + klen;
 
-                if (cp->state_only)
+                if (cp->state_only && !tag)
                     continue;
 
                 if (strfind(syn->keywords, kbuf)) {
@@ -1705,10 +1719,20 @@
                     i1++;
 
                 if (str[i1] == '(') {
-                    /* function call */
+                    /* function call or definition */
                     style = C_STYLE_FUNCTION;
+                    if (tag) {
+                        /* tag function definition */
+                        eb_add_property(cp->b, cp->offset, QE_PROP_TAG, 
qe_strdup(kbuf));
+                        tag = 0;
+                    }
                     break;
+                } else
+                if (tag && qe_findchar("(,;=", str[i1])) {
+                    /* tag variable definition */
+                    eb_add_property(cp->b, cp->offset, QE_PROP_TAG, 
qe_strdup(kbuf));
                 }
+
                 if ((start == 0 || str[start - 1] != '.')
                 &&  !qe_findchar(".(:", str[i])
                 &&  strfind(syn->types, kbuf)) {

Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -b -r1.61 -r1.62
--- extras.c    28 Mar 2017 06:33:29 -0000      1.61
+++ extras.c    31 Mar 2017 07:51:56 -0000      1.62
@@ -1504,6 +1504,83 @@
     do_sort_span(s, 0, s->b->total_size, flags, argval);
 }
 
+static void tag_buffer(EditState *s) {
+    unsigned int buf[100];
+    int offset, line_num, col_num;
+
+    /* force complete buffer colorizarion */
+    eb_get_pos(s->b, &line_num, &col_num, s->b->total_size);
+    s->get_colorized_line(s, buf, countof(buf), s->b->total_size,
+                          &offset, line_num);
+}
+
+static void tag_completion(CompleteState *cp) {
+    /* XXX: only support current buffer */
+    QEProperty *p;
+
+    tag_buffer(cp->s);
+
+    for (p = cp->s->b->property_list; p; p = p->next) {
+        if (p->type == QE_PROP_TAG) {
+            complete_test(cp, p->data);
+        }
+    }
+}
+
+static void do_find_tag(EditState *s, const char *str) {
+    QEProperty *p;
+
+    tag_buffer(s);
+
+    for (p = s->b->property_list; p; p = p->next) {
+        if (p->type == QE_PROP_TAG && strequal(p->data, str)) {
+            s->offset = p->offset;
+            return;
+        }
+    }
+    put_status(s, "Tag not found: %s", str);
+}
+
+static void do_goto_tag(EditState *s) {
+    char buf[80];
+    size_t len;
+
+    len = qe_get_word(s, buf, sizeof buf, s->offset, NULL);
+    if (len >= sizeof(buf)) {
+        put_status(s, "Tag too large");
+        return;
+    } else
+    if (len == 0) {
+        put_status(s, "No tag");
+        return;
+    } else {
+        do_find_tag(s, buf);
+    }
+}
+
+/* XXX: should have next-tag and previous-tag */
+
+static void do_list_tags(EditState *s) {
+    EditBuffer *b;
+    QEProperty *p;
+
+    b = new_help_buffer();
+    if (!b)
+        return;
+
+    tag_buffer(s);
+
+    eb_printf(b, "\nTags in file %s:\n\n", s->b->filename);
+    for (p = s->b->property_list; p; p = p->next) {
+        if (p->type == QE_PROP_TAG) {
+            eb_printf(b, "%12d  %s\n", p->offset, (char*)p->data);
+        }
+    }
+
+    b->flags |= BF_READONLY;
+    show_popup(s, b);
+}
+
 static CmdDef extra_commands[] = {
     CMD2( KEY_META('='), KEY_NONE,
           "compare-windows", do_compare_windows, ESi, "ui" )
@@ -1596,6 +1673,14 @@
     CMD3( KEY_NONE, KEY_NONE,
           "reverse-sort-region", do_sort_region, ESii, SF_REVERSE, "*vui")
 
+    CMD0( KEY_NONE, KEY_NONE,
+          "list-tags", do_list_tags)
+    CMD0( KEY_CTRLX(','), KEY_META(KEY_F1),
+          "goto-tag", do_goto_tag)
+    CMD2( KEY_CTRLX('.'), KEY_NONE,
+          "find-tag", do_find_tag, ESs,
+          "s{Find tag: }[tag]|tag|")
+
     CMD_DEF_END,
 };
 
@@ -1607,6 +1692,8 @@
     for (key = KEY_META('0'); key <= KEY_META('9'); key++) {
         qe_register_binding(key, "numeric-argument", NULL);
     }
+    register_completion("tag", tag_completion);
+
     return 0;
 }
 

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.257
retrieving revision 1.258
diff -u -b -r1.257 -r1.258
--- qe.c        26 Mar 2017 15:57:24 -0000      1.257
+++ qe.c        31 Mar 2017 07:51:57 -0000      1.258
@@ -562,6 +562,39 @@
     }
 }
 
+int qe_get_word(EditState *s, char *buf, int buf_size,
+                int offset, int *offset_ptr)
+{
+    EditBuffer *b = s->b;
+    buf_t outbuf, *out;
+    int offset1;
+    int c;
+
+    out = buf_init(&outbuf, buf, buf_size);
+
+    /* XXX: the qe_isword pattern should depend on the current mode */
+    if (qe_isword(eb_nextc(b, offset, &offset1))) {
+        while (qe_isword(eb_prevc(b, offset, &offset1))) {
+            offset = offset1;
+        }
+    } else {
+        while ((offset = offset1) < b->total_size) {
+            if (!qe_isword(eb_nextc(b, offset, &offset1)))
+                break;
+        }
+    }
+    while (offset < b->total_size) {
+        if (!qe_isword(c = eb_nextc(b, offset, &offset1)))
+            break;
+        buf_putc_utf8(out, c);
+        offset = offset1;
+    }
+    if (offset_ptr) {
+        *offset_ptr = offset;
+    }
+    return out->len;
+}
+
 void do_mark_region(EditState *s, int mark, int offset)
 {
     /* CG: Should have local and global mark rings */
@@ -2619,6 +2652,7 @@
 void text_mode_line(EditState *s, buf_t *out)
 {
     int line_num, col_num, wrap_mode;
+    const QEProperty *tag;
 
     wrap_mode = '-';
     if (!s->hex_mode) {
@@ -2646,6 +2680,9 @@
         buf_printf(out, "--<%d", -s->x_disp[0]);
     if (s->x_disp[1])
         buf_printf(out, "-->%d", -s->x_disp[1]);
+    tag = eb_find_property(s->b, 0, s->offset + 1, QE_PROP_TAG);
+    if (tag)
+        buf_printf(out, "--%s", tag->data);
 #if 0
     buf_printf(out, "--[%d]", s->y_disp);
 #endif
@@ -3805,6 +3842,7 @@
         line++;
         if (line < s->colorize_nb_valid_lines)
             s->colorize_nb_valid_lines = line;
+        eb_delete_properties(b, s->colorize_max_valid_offset, INT_MAX);
         s->colorize_max_valid_offset = INT_MAX;
     }
 
@@ -3947,8 +3985,10 @@
 #ifndef CONFIG_TINY
     if (s->colorize_func) {
         len = syntax_get_colorized_line(s, buf, buf_size, offset, offsetp, 
line_num);
-        if (s->b->b_styles && s->colorize_func != shell_colorize_line)
+        if (s->b->b_styles && s->colorize_func != shell_colorize_line) {
+            /* XXX: shell mode should have its own get_colorized_line handler 
*/
             combine_static_colorized_line(s, buf, buf_size, len);
+        }
     } else
 #endif
     if (s->b->b_styles) {

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.242
retrieving revision 1.243
diff -u -b -r1.242 -r1.243
--- qe.h        26 Mar 2017 15:57:24 -0000      1.242
+++ qe.h        31 Mar 2017 07:51:57 -0000      1.243
@@ -128,6 +128,7 @@
 typedef struct KeyDef KeyDef;
 typedef struct InputMethod InputMethod;
 typedef struct ISearchState ISearchState;
+typedef struct QEProperty QEProperty;
 
 static inline char *s8(u8 *p) { return (char*)p; }
 static inline const char *cs8(const u8 *p) { return (const char*)p; }
@@ -932,6 +933,7 @@
 
     /* modification callbacks */
     OWNED EditBufferCallbackList *first_callback;
+    OWNED QEProperty *property_list;
 
 #if 0
     /* asynchronous loading/saving support */
@@ -1097,6 +1099,19 @@
 void eb_invalidate_raw_data(EditBuffer *b);
 extern EditBufferDataType raw_data_type;
 
+struct QEProperty {
+    int offset;
+#define QE_PROP_FREE  1
+#define QE_PROP_TAG   3
+    int type;
+    void *data;
+    QEProperty *next;
+};
+
+void eb_add_property(EditBuffer *b, int offset, int type, void *data);
+QEProperty *eb_find_property(EditBuffer *b, int offset, int offset2, int type);
+void eb_delete_properties(EditBuffer *b, int offset, int offset2);
+
 /* qe module handling */
 
 #ifdef QE_MODULE
@@ -1637,7 +1652,6 @@
 
 #define STYLE_BITS     12
 #define STYLE_SHIFT    (32 - STYLE_BITS)
-#define STYLE_MASK     (((1 << STYLE_BITS) - 1) << STYLE_SHIFT)
 #define CHAR_MASK      ((1 << STYLE_SHIFT) - 1)
 
 struct DisplayState {
@@ -1742,7 +1756,7 @@
     int i;
 
     for (i = 0; i < count; i++)
-        p[i] &= ~STYLE_MASK;
+        p[i] &= CHAR_MASK;
 }
 
 /* input.c */
@@ -1943,6 +1957,8 @@
 void text_move_eof(EditState *s);
 void word_right(EditState *s, int w);
 void word_left(EditState *s, int w);
+int qe_get_word(EditState *s, char *buf, int buf_size,
+                int offset, int *offset_ptr);
 void do_goto(EditState *s, const char *str, int unit);
 void do_goto_line(EditState *s, int line, int column);
 void do_up_down(EditState *s, int dir);



reply via email to

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