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.h ...


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs TODO.org buffer.c clang.c extras.c qe.h ...
Date: Sun, 23 Mar 2014 01:11:35 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/03/23 01:11:35

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

Log message:
        improve c-mode
        
        * add indent_func method in ModeDef
        * make c-indent-region more general as indent-region
        * add c-forward-conditional on M-]
        * add c-backward-conditional on M-[
        * add c-list-conditionals on M-i
        * use trick to disambiguate M-[ and CSI sequences
        * add eb_is_in_indentation(b, offset)
        * fix c-mode indentation of case and default lines

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/TODO.org?cvsroot=qemacs&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.78&r2=1.79
http://cvs.savannah.gnu.org/viewcvs/qemacs/clang.c?cvsroot=qemacs&r1=1.50&r2=1.51
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.155&r2=1.156
http://cvs.savannah.gnu.org/viewcvs/qemacs/tty.c?cvsroot=qemacs&r1=1.59&r2=1.60

Patches:
Index: TODO.org
===================================================================
RCS file: /sources/qemacs/qemacs/TODO.org,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- TODO.org    22 Mar 2014 13:42:29 -0000      1.1
+++ TODO.org    23 Mar 2014 01:11:34 -0000      1.2
@@ -5,7 +5,6 @@
 
 * Needed for release version 5
 
-** basic: indent-region
 ** basic: indent-rigidly
 ** basic: minibuffer completion -> bad return on C-x C-f . SPC qe SPC RET
 ** basic: scripting
@@ -35,6 +34,7 @@
 ** shell: yank at shell prompt
 ** undo: undo should handle sequence of undo records upto tagged start.
 ** x11: handle X11 window manager close window event and exit cleanly
+** DONE basic: indent-region
 ** DONE basic: untabify-region, untabify-buffer
 ** DONE basic: indent on TAB according to indent-width and indent-with-tabs
 ** DONE c-mode: fix c-mode tab on line with excess indentation
@@ -54,7 +54,6 @@
 ** add custom memory handling functions.
 ** use failsafe memory allocator and longjmp recover.
 ** redefine KEY_Fx to make them sequential
-** timers for esc key disambiguation
 ** move ungot_key to key_context
 ** use trick for entering spaces in filename prompts without completion
 ** static init_call stuff ?
@@ -81,6 +80,7 @@
 ** C-x x next-buffer ??? Move to the next buffer.
 ** abbreviation mode
 ** qe_realloc -> typed and clear reallocated area
+** DONE timers for esc key disambiguation
 ** DONE ftp: / http: support
 ** DONE set-auto-mode: reselect best mode
 ** DONE set-next-mode: select nth best mode

Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -b -r1.78 -r1.79
--- buffer.c    21 Mar 2014 20:49:30 -0000      1.78
+++ buffer.c    23 Mar 2014 01:11:34 -0000      1.79
@@ -2131,6 +2131,18 @@
     return 1;
 }
 
+/* check if <offset> is within indentation. */
+int eb_is_in_indentation(EditBuffer *b, int offset)
+{
+    int c;
+
+    while ((c = eb_prevc(b, offset, &offset)) != '\n') {
+        if (!qe_isblank(c))
+            return 0;
+    }
+    return 1;
+}
+
 /* return offset of the end of the line containing offset */
 int eb_goto_eol(EditBuffer *b, int offset)
 {

Index: clang.c
===================================================================
RCS file: /sources/qemacs/qemacs/clang.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- clang.c     18 Mar 2014 08:20:04 -0000      1.50
+++ clang.c     23 Mar 2014 01:11:34 -0000      1.51
@@ -564,7 +564,7 @@
             j = get_c_identifier(buf1, countof(buf1), buf + i);
 
             if (style == QE_STYLE_KEYWORD) {
-                if (strfind(buf1, "case|default"))
+                if (strfind("case|default", buf1))
                     goto unindent;
             }
             for (j += i; qe_isblank(buf[j] & CHAR_MASK); j++)
@@ -610,36 +610,11 @@
 
 static void do_c_indent(EditState *s)
 {
-    if (s->qe_state->last_cmd_func == (CmdFunc)do_c_indent) {
-        do_tab(s, 1);
-    } else {
+    if (eb_is_in_indentation(s->b, s->offset)
+    &&  s->qe_state->last_cmd_func != (CmdFunc)do_c_indent) {
         c_indent_line(s, s->offset);
-    }
-}
-
-static void do_c_indent_region(EditState *s)
-{
-    int col_num, line1, line2;
-
-    /* deactivate region hilite */
-    s->region_style = 0;
-
-    /* Swap point and mark so mark <= point */
-    if (s->offset < s->b->mark) {
-        int tmp = s->b->mark;
-        s->b->mark = s->offset;
-        s->offset = tmp;
-    }
-    /* We do it with lines to avoid offset variations during indenting */
-    eb_get_pos(s->b, &line1, &col_num, s->b->mark);
-    eb_get_pos(s->b, &line2, &col_num, s->offset);
-
-    if (col_num == 0)
-        line2--;
-
-    /* Iterate over all lines inside block */
-    for (; line1 <= line2; line1++) {
-        c_indent_line(s, eb_goto_pos(s->b, line1, 0));
+    } else {
+        do_tab(s, 1);
     }
 }
 
@@ -658,11 +633,132 @@
     do_return(s, 1);
     /* reindent line to remove indent on blank line */
     c_indent_line(s, offset);
+    /* XXX: should indent line if auto-indent is active */
+}
+
+static int ustr_match_mask(const unsigned int *buf, const char *str)
+{
+    while (*str) {
+        if ((*buf++ & CHAR_MASK) != *str++)
+            return 0;
+    }
+    return 1;
 }
 
 /* forward / backward preprocessor */
-static void do_c_forward_preprocessor(EditState *s, int dir)
+static void do_c_forward_conditional(EditState *s, int dir)
 {
+    unsigned int buf[COLORED_MAX_LINE_SIZE], *p;
+    int line_num, col_num, len, sharp, level;
+    int offset, offset0, offset1;
+
+    offset = offset0 = eb_goto_bol(s->b, s->offset);
+    eb_get_pos(s->b, &line_num, &col_num, offset);
+    level = 0;
+    for (;;) {
+        offset1 = offset;
+        len = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num);
+        sharp = 0;
+        for (p = buf; *p; p++) {
+            int c = (*p & CHAR_MASK);
+            int style = (*p >> STYLE_SHIFT);
+            if (qe_isblank(c))
+                continue;
+            if (c == '#' && style == QE_STYLE_PREPROCESS)
+                sharp++;
+            else
+                break;
+        }
+        if (sharp == 1) {
+            if (ustr_match_mask(p, dir < 0 ? "endif" : "if")) {
+                if (level || offset == offset0)
+                    level++;
+                else
+                    break;
+            } else
+            if (ustr_match_mask(p, "el")) {
+                if (offset == offset0)
+                    level++;
+                else
+                if (level <= 1)
+                    break;
+            } else
+            if (ustr_match_mask(p, dir > 0 ? "endif" : "if")) {
+                if (level)
+                    level--;
+                if (!level && offset != offset0)
+                    break;
+            }
+        }
+        if (dir > 0) {
+            line_num++;
+            offset = offset1;
+            if (offset >= s->b->total_size)
+                break;
+        } else {
+            if (offset <= 0)
+                break;
+            line_num--;
+            offset = eb_prev_line(s->b, offset);
+        }
+    }
+    s->offset = offset;
+}
+
+static void do_c_list_conditionals(EditState *s)
+{
+    unsigned int buf[COLORED_MAX_LINE_SIZE], *p;
+    int line_num, col_num, len, sharp, level;
+    int offset, offset1;
+    EditBuffer *b;
+
+    b = eb_scratch("Preprocessor conditionals", BF_UTF8);
+    if (!b)
+        return;
+
+    offset = eb_goto_bol(s->b, s->offset);
+    eb_get_pos(s->b, &line_num, &col_num, offset);
+    level = 0;
+    while (offset > 0) {
+        line_num--;
+        offset = eb_prev_line(s->b, offset);
+        offset1 = offset;
+        len = s->get_colorized_line(s, buf, countof(buf), &offset1, line_num);
+        sharp = 0;
+        for (p = buf; *p; p++) {
+            int c = (*p & CHAR_MASK);
+            int style = (*p >> STYLE_SHIFT);
+            if (qe_isblank(c))
+                continue;
+            if (c == '#' && style == QE_STYLE_PREPROCESS)
+                sharp++;
+            else
+                break;
+        }
+        if (sharp == 1) {
+            if (ustr_match_mask(p, "endif")) {
+                level++;
+            } else
+            if (ustr_match_mask(p, "el")) {
+                if (level == 0) {
+                    eb_insert_buffer_convert(b, 0, s->b, offset, offset1 - 
offset);
+                }
+            } else
+            if (ustr_match_mask(p, "if")) {
+                if (level) {
+                    level--;
+                } else {
+                    eb_insert_buffer_convert(b, 0, s->b, offset, offset1 - 
offset);
+                }
+            }
+        }
+    }
+    if (b->total_size > 0) {
+        show_popup(b);
+    } else {
+        eb_free(&b);
+        put_status(s, "Not in a #if conditional");
+    }
 }
 
 static int c_mode_probe(ModeDef *mode, ModeProbeData *p)
@@ -701,13 +797,13 @@
 static CmdDef c_commands[] = {
     CMD2( KEY_CTRL('i'), KEY_NONE,
           "c-indent-command", do_c_indent, ES, "*")
-    CMD2( KEY_META(KEY_CTRL('\\')), KEY_NONE,
-          "c-indent-region", do_c_indent_region, ES, "*")
             /* should map to KEY_META + KEY_CTRL_LEFT ? */
     CMD3( KEY_META('['), KEY_NONE,
-          "c-backward-preprocessor", do_c_forward_preprocessor, ESi, -1, "*v")
+          "c-backward-conditional", do_c_forward_conditional, ESi, -1, "*v")
     CMD3( KEY_META(']'), KEY_NONE,
-          "c-forward-preprocessor", do_c_forward_preprocessor, ESi, 1, "*v")
+          "c-forward-conditional", do_c_forward_conditional, ESi, 1, "*v")
+    CMD2( KEY_META('i'), KEY_NONE,
+          "c-list-conditionals", do_c_list_conditionals, ES, "")
     CMD2( '{', '}',
           "c-electric-key", do_c_electric, ESi, "*ki")
     CMD2( KEY_RET, KEY_NONE,
@@ -727,6 +823,7 @@
     c_mode.extensions = c_mode_extensions;
     c_mode.mode_probe = c_mode_probe;
     c_mode.colorize_func = c_colorize_line;
+    c_mode.indent_func = c_indent_line;
 
     qe_register_mode(&c_mode);
     qe_register_cmd_table(c_commands, &c_mode);

Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- extras.c    21 Mar 2014 20:49:30 -0000      1.25
+++ extras.c    23 Mar 2014 01:11:34 -0000      1.26
@@ -298,6 +298,37 @@
     eb_untabify(s->b, s->b->mark, s->offset);
 }
 
+void do_indent_region(EditState *s)
+{
+    int col_num, line1, line2;
+
+    /* deactivate region hilite */
+    s->region_style = 0;
+
+    /* Swap point and mark so mark <= point */
+    if (s->offset < s->b->mark) {
+        int tmp = s->b->mark;
+        s->b->mark = s->offset;
+        s->offset = tmp;
+    }
+    /* We do it with lines to avoid offset variations during indenting */
+    eb_get_pos(s->b, &line1, &col_num, s->b->mark);
+    eb_get_pos(s->b, &line2, &col_num, s->offset);
+
+    if (col_num == 0)
+        line2--;
+
+    /* Iterate over all lines inside block */
+    for (; line1 <= line2; line1++) {
+        if (s->mode->indent_func) {
+            (s->mode->indent_func)(s, eb_goto_pos(s->b, line1, 0));
+        } else {
+            s->offset = eb_goto_pos(s->b, line1, 0);
+            do_tab(s, 1);
+        }
+    }
+}
+
 void do_show_date_and_time(EditState *s, int argval)
 {
     time_t t = argval;
@@ -1008,6 +1039,8 @@
           "untabify-region", do_untabify_region, ES, "*")
     CMD2( KEY_NONE, KEY_NONE,
           "untabify-buffer", do_untabify_buffer, ES, "*")
+    CMD2( KEY_META(KEY_CTRL('\\')), KEY_NONE,
+          "indent-region", do_indent_region, ES, "*")
 
     CMD2( KEY_CTRLX('t'), KEY_NONE,
           "show-date-and-time", do_show_date_and_time, ESi, "ui")

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -b -r1.155 -r1.156
--- qe.h        21 Mar 2014 20:49:30 -0000      1.155
+++ qe.h        23 Mar 2014 01:11:34 -0000      1.156
@@ -971,6 +971,7 @@
 int eb_goto_bol(EditBuffer *b, int offset);
 int eb_goto_bol2(EditBuffer *b, int offset, int *countp);
 int eb_is_blank_line(EditBuffer *b, int offset, int *offset1);
+int eb_is_in_indentation(EditBuffer *b, int offset);
 int eb_goto_eol(EditBuffer *b, int offset);
 int eb_next_line(EditBuffer *b, int offset);
 
@@ -1225,6 +1226,7 @@
 
     EditBufferDataType *data_type; /* native buffer data type (NULL = raw) */
     void (*get_mode_line)(EditState *s, buf_t *out);
+    void (*indent_func)(EditState *s, int offset);
 
     /* mode specific key bindings */
     struct KeyDef *first_key;

Index: tty.c
===================================================================
RCS file: /sources/qemacs/qemacs/tty.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -b -r1.59 -r1.60
--- tty.c       19 Mar 2014 19:42:31 -0000      1.59
+++ tty.c       23 Mar 2014 01:11:34 -0000      1.60
@@ -414,10 +414,18 @@
 
     switch (ts->input_state) {
     case IS_NORM:
-        if (ch == '\033')
+        if (ch == '\033') {
+            if (!tty_term_is_user_input_pending(s)) {
+                /* Trick to distinguish the ESC key from function and meta
+                 * keys  transmitting escape sequences starting with \033
+                 * but followed immediately by more characters.
+                 */
+                goto the_end;
+            }
             ts->input_state = IS_ESC;
-        else
+        } else {
             goto the_end;
+        }
         break;
     case IS_ESC:
         if (ch == '\033') {
@@ -425,6 +433,11 @@
             goto the_end;
         }
         if (ch == '[') {
+            if (!tty_term_is_user_input_pending(s)) {
+                ch = KEY_META('[');
+                ts->input_state = IS_NORM;
+                goto the_end;
+            }
             ts->input_state = IS_CSI;
             ts->input_param = 0;
         } else if (ch == 'O') {



reply via email to

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