[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);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemacs-commit] qemacs TODO.org buffer.c clang.c extras.c qe.c ...,
Charlie Gordon <=