qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs extras.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs extras.c
Date: Fri, 23 Dec 2016 15:12:05 -0500 (EST)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        16/12/23 15:12:05

Modified files:
        .              : extras.c 

Log message:
        buffer: improvements
        - fixed `do_forward_block()` to handle very long lines gracefully
        - simplified `to_transpose()`
        - add `do_describe_window()` for `describe-window` command on C-h w

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.46&r2=1.47

Patches:
Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -b -r1.46 -r1.47
--- extras.c    23 Dec 2016 19:51:48 -0000      1.46
+++ extras.c    23 Dec 2016 20:12:05 -0000      1.47
@@ -420,58 +420,101 @@
 /* forward / backward block */
 #define MAX_LEVEL     32
 
+/* Return the matching delimiter for all pairs */
+static int matching_delimiter(int c) {
+    static const char pairs[] = "(){}[]<>";
+    for (int i = 0; pairs[i]; i++) {
+        if (pairs[i] == c)
+            return pairs[i ^ 1];
+    }
+    return c;
+}
+
 static void do_forward_block(EditState *s, int dir)
 {
     unsigned int buf[COLORED_MAX_LINE_SIZE];
     char balance[MAX_LEVEL];
-    int line_num, col_num, offset, offset1, len, pos, style, c, c1, level;
-
-    eb_get_pos(s->b, &line_num, &col_num, s->offset);
-    offset = eb_goto_bol2(s->b, s->offset, &pos);
-    offset1 = offset;
-    /* XXX: deal with truncation */
+    int use_colors;
+    int line_num, col_num, style, style0, c, level;
+    int pos;      /* position of the current character on line */
+    int len;      /* number of colorized positions */
+    int offset;   /* offset of the current character */
+    int offset0;  /* offset of the beginning of line */
+    int offset1;  /* offset of the beginning of the next line */
+
+    offset = s->offset;
+    eb_get_pos(s->b, &line_num, &col_num, offset);
+    offset1 = offset0 = eb_goto_bol2(s->b, offset, &pos);
+    use_colors = s->colorize_func || s->b->b_styles;
+    style0 = 0;
+    len = 0;
+    if (use_colors) {
+        /* XXX: should only query the syntax colorizer */
     len = s->get_colorized_line(s, buf, countof(buf), offset1, &offset1, 
line_num);
-    if (pos > len) {
-        /* cannot use colorized line buffer */
-        /* XXX: should use buffer contents */
-        pos = len;
+        if (len < countof(buf) - 2) {
+            if (pos < len) {
+                style0 = buf[pos] >> STYLE_SHIFT;
+            }
+        } else {
+            /* very long line detected, use fallback version */
+            use_colors = 0;
+            len = 0;
+        }
     }
-    style = buf[pos] >> STYLE_SHIFT;
     level = 0;
 
     if (dir < 0) {
         for (;;) {
-            if (pos == 0) {
+            c = eb_prevc(s->b, offset, &offset);
+            if (c == '\n') {
                 if (offset <= 0)
                     break;
                 line_num--;
-                offset = eb_prev_line(s->b, offset);
-                offset1 = offset;
-                /* XXX: this will actually ignore the end of very long lines */
-                /* XXX: deal with truncation */
-                pos = s->get_colorized_line(s, buf, countof(buf), offset1, 
&offset1, line_num);
-                continue;
+                offset1 = offset0 = eb_goto_bol2(s->b, offset, &pos);
+                len = 0;
+                if (use_colors) {
+                    /* XXX: should only query the syntax colorizer */
+                    len = s->get_colorized_line(s, buf, countof(buf), offset1, 
&offset1, line_num);
+                    if (len >= countof(buf) - 2) {
+                        /* very long line detected, use fallback version */
+                        use_colors = 0;
+                        len = 0;
+                        style0 = 0;
+                    }
             }
-            c = buf[--pos];
-            if (style != c >> STYLE_SHIFT) {
-                if (style == 0)
                     continue;
+            }
                 style = 0;
-                if ((c >> STYLE_SHIFT) != 0)
+            --pos;
+            if (pos >= 0 && pos < len) {
+                style = buf[pos] >> STYLE_SHIFT;
+            }
+            if (style != style0) {
+                if (style0 == 0)
+                    continue;
+                style0 = 0;
+                if (style != 0)
                     continue;
             }
-            switch (c &= CHAR_MASK) {
+            switch (c) {
+            case '\"':
+            case '\'':
+                if (pos >= len) {
+                    /* simplistic string skip with escape char */
+                    int c1, off;
+                    while ((c1 = eb_prevc(s->b, offset, &off)) != '\n') {
+                        offset = off;
+                        pos--;
+                        if (c1 == c && eb_prevc(s->b, offset, &off) != '\\')
+                            break;
+                    }
+                }
+                break;
             case ')':
-                c1 = '(';
-                goto push;
             case ']':
-                c1 = '[';
-                goto push;
             case '}':
-                c1 = '{';
-            push:
                 if (level < MAX_LEVEL) {
-                    balance[level] = c1;
+                    balance[level] = matching_delimiter(c);
                 }
                 level++;
                 break;
@@ -480,54 +523,82 @@
             case '{':
                 if (level > 0) {
                     --level;
-                    if (balance[level] != c) {
-                        put_status(s, "Unmatched delimiter");
+                    if (level < MAX_LEVEL && balance[level] != c) {
+                        /* XXX: should set mark and offset */
+                        put_status(s, "Unmatched delimiter %c <> %c",
+                                   c, balance[level]);
+                        return;
+                    }
+                    if (level == 0) {
+                        s->offset = offset;
                         return;
                     }
-                    if (level <= 0)
-                        goto the_end;
+                } else {
+                    /* silently move up one level */
                 }
                 break;
             }
         }
     } else {
         for (;;) {
-            if (pos >= len) {
-                /* Should simplify with get_colorized_line updating
-                 * offset
-                 */
+            c = eb_nextc(s->b, offset, &offset);
+            if (c == '\n') {
                 line_num++;
-                pos = 0;
-                offset = eb_next_line(s->b, offset);
                 if (offset >= s->b->total_size)
                     break;
-                offset1 = offset;
-                /* XXX: this will actually ignore the end of very long lines */
-                /* XXX: deal with truncation */
+                offset1 = offset0 = offset;
+                len = 0;
+                if (use_colors) {
+                    /* XXX: should only query the syntax colorizer */
                 len = s->get_colorized_line(s, buf, countof(buf), offset1, 
&offset1, line_num);
+                    if (len >= countof(buf) - 2) {
+                        /* very long line detected, use fallback version */
+                        use_colors = 0;
+                        len = 0;
+                        style0 = 0;
+                    }
+                }
+                pos = 0;
                 continue;
             }
-            c = buf[pos];
+            style = 0;
+            if (pos < len) {
+                style = buf[pos] >> STYLE_SHIFT;
+            }
             pos++;
-            if (style != c >> STYLE_SHIFT) {
-                if (style == 0)
+            if (style0 != style) {
+                if (style0 == 0)
                     continue;
-                style = 0;
-                if ((c >> STYLE_SHIFT) != 0)
+                style0 = 0;
+                if (style != 0)
                     continue;
             }
-            switch (c &= CHAR_MASK) {
+            switch (c) {
+            case '\"':
+            case '\'':
+                if (pos >= len) {
+                    /* simplistic string skip with escape char */
+                    int c1, off;
+                    while ((c1 = eb_nextc(s->b, offset, &off)) != '\n') {
+                        offset = off;
+                        pos++;
+                        if (c1 == '\\') {
+                            if (eb_nextc(s->b, offset, &off) == '\n')
+                                break;
+                            offset = off;
+                            pos++;
+                        } else
+                        if (c1 == c) {
+                            break;
+                        }
+                    }
+                }
+                break;
             case '(':
-                c1 = ')';
-                goto push1;
             case '[':
-                c1 = ']';
-                goto push1;
             case '{':
-                c1 = '}';
-            push1:
                 if (level < MAX_LEVEL) {
-                    balance[level] = c1;
+                    balance[level] = matching_delimiter(c);
                 }
                 level++;
                 break;
@@ -536,23 +607,29 @@
             case '}':
                 if (level > 0) {
                     --level;
-                    if (balance[level] != c) {
-                        put_status(s, "Unmatched delimiter");
+                    if (level < MAX_LEVEL && balance[level] != c) {
+                        /* XXX: should set mark and offset */
+                        put_status(s, "Unmatched delimiter %c <> %c",
+                                   c, balance[level]);
                         return;
                     }
-                    if (level <= 0)
-                        goto the_end;
+                    if (level == 0) {
+                        s->offset = offset;
+                        return;
                 }
-                break;
+                } else {
+                    /* silently move up one level */
             }
+                break;
         }
     }
-the_end:
-    while (pos > 0) {
-        eb_nextc(s->b, offset, &offset);
-        pos--;
     }
+    if (level != 0) {
+        /* XXX: should set mark and offset */
+        put_status(s, "Unmatched delimiter");
+    } else {
     s->offset = offset;
+    }
 }
 
 static void do_kill_block(EditState *s, int dir)
@@ -578,21 +655,23 @@
     if (check_read_only(s))
         return;
 
+    /* compute positions of ranges to swap:
+       offset0..offset1 and offset2..offset3
+       end_offset is the ending position after the swap
+    */
     switch (cmd) {
     case CMD_TRANSPOSE_CHARS:
         /* at end of line, transpose previous 2 characters,
          * otherwise transpose characters before and after point.
          */
-        end_offset = offset2 = s->offset;
+        offset1 = offset2 = s->offset;
+        offset0 = eb_prev(b, offset1);
         if (eb_nextc(b, offset2, &offset3) == '\n') {
-            offset3 = offset2;
-            offset2 = eb_prev(b, offset3);
-            end_offset = s->offset;
-            offset1 = offset2;
+            end_offset = offset3 = offset2;
+            offset1 = offset2 = offset0;
             offset0 = eb_prev(b, offset1);
         } else {
-            offset1 = offset2;
-            offset0 = eb_prev(b, offset1);
+            /* XXX: should have specific flag */
             if (s->qe_state->flag_split_window_change_focus) {
                 /* keep current position between characters */
                 end_offset = offset0 + offset3 - offset2;
@@ -1170,6 +1249,74 @@
     }
 }
 
+static void do_describe_window(EditState *s, int argval)
+{
+    EditBuffer *b1;
+    int show;
+
+    b1 = new_help_buffer(&show);
+    if (!b1)
+        return;
+
+    eb_printf(b1, "Window Description\n\n");
+
+    int w = 28;
+    eb_printf(b1, "%*s: %d, %d\n", w, "xleft, ytop", s->xleft, s->ytop);
+    eb_printf(b1, "%*s: %d, %d\n", w, "width, height", s->width, s->height);
+    eb_printf(b1, "%*s: %d, %d, %d, %d\n", w, "x1, y1, x2, y2", s->x1, s->y1, 
s->x2, s->y2);
+    eb_printf(b1, "%*s: %#x %s%s%s%s%s\n", w, "flags", s->flags,
+              (s->flags & WF_POPUP) ? " POPUP" : "",
+              (s->flags & WF_MODELINE) ? " MODELINE" : "",
+              (s->flags & WF_RSEPARATOR) ? " RSEPARATOR" : "",
+              (s->flags & WF_POPLEFT) ? " POPLEFT" : "",
+              (s->flags & WF_HIDDEN) ? " HIDDEN" : "");
+    eb_printf(b1, "%*s: %d\n", w, "offset", s->offset);
+    eb_printf(b1, "%*s: %d\n", w, "offset_top", s->offset_top);
+    eb_printf(b1, "%*s: %d\n", w, "offset_bottom", s->offset_bottom);
+    eb_printf(b1, "%*s: %d\n", w, "y_disp", s->y_disp);
+    eb_printf(b1, "%*s: %d, %d\n", w, "x_disp[]", s->x_disp[0], s->x_disp[1]);
+    eb_printf(b1, "%*s: %d\n", w, "minibuf", s->minibuf);
+    eb_printf(b1, "%*s: %d\n", w, "dump_width", s->dump_width);
+    eb_printf(b1, "%*s: %d\n", w, "hex_mode", s->hex_mode);
+    eb_printf(b1, "%*s: %d\n", w, "unihex_mode", s->unihex_mode);
+    eb_printf(b1, "%*s: %d\n", w, "hex_nibble", s->hex_nibble);
+    eb_printf(b1, "%*s: %d\n", w, "insert", s->insert);
+    eb_printf(b1, "%*s: %d\n", w, "bidir", s->bidir);
+    eb_printf(b1, "%*s: %d\n", w, "cur_rtl", s->cur_rtl);
+    eb_printf(b1, "%*s: %d  %s\n", w, "wrap", s->wrap,
+              s->wrap == WRAP_TRUNCATE ? "TRUNCATE" :
+              s->wrap == WRAP_LINE ? "LINE" : 
+              s->wrap == WRAP_WORD ? "WORD" : "???");
+    eb_printf(b1, "%*s: %d\n", w, "line_numbers", s->line_numbers);
+    eb_printf(b1, "%*s: %d\n", w, "indent_size", s->indent_size);
+    eb_printf(b1, "%*s: %d\n", w, "indent_tabs_mode", s->indent_tabs_mode);
+    eb_printf(b1, "%*s: %d\n", w, "interactive", s->interactive);
+    eb_printf(b1, "%*s: %d\n", w, "force_highlight", s->force_highlight);
+    eb_printf(b1, "%*s: %d\n", w, "mouse_force_highlight", 
s->mouse_force_highlight);
+    eb_printf(b1, "%*s: %p\n", w, "get_colorized_line", 
(void*)s->get_colorized_line);
+    eb_printf(b1, "%*s: %p\n", w, "colorize_func", (void*)s->colorize_func);
+    eb_printf(b1, "%*s: %d\n", w, "default_style", s->default_style);
+    eb_printf(b1, "%*s: %s\n", w, "buffer", s->b->name);
+    if (s->last_buffer)
+        eb_printf(b1, "%*s: %s\n", w, "last_buffer", s->last_buffer->name);
+    eb_printf(b1, "%*s: %s\n", w, "mode", s->mode->name);
+    eb_printf(b1, "%*s: %d\n", w, "colorize_nb_lines", s->colorize_nb_lines);
+    eb_printf(b1, "%*s: %d\n", w, "colorize_nb_valid_lines", 
s->colorize_nb_valid_lines);
+    eb_printf(b1, "%*s: %d\n", w, "colorize_max_valid_offset", 
s->colorize_max_valid_offset);
+    eb_printf(b1, "%*s: %d\n", w, "busy", s->busy);
+    eb_printf(b1, "%*s: %d\n", w, "display_invalid", s->display_invalid);
+    eb_printf(b1, "%*s: %d\n", w, "borders_invalid", s->borders_invalid);
+    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");
+
+    b1->flags |= BF_READONLY;
+    if (show) {
+        show_popup(b1);
+    }
+}
+
 /*---------------- buffer contents sorting ----------------*/
 
 struct chunk_ctx {
@@ -1321,7 +1468,7 @@
 
     CMD0( KEY_CTRLH('?'), KEY_F1,
           "about-qemacs", do_about_qemacs)
-    CMD2( KEY_CTRLH('a'), KEY_NONE,
+    CMD2( KEY_CTRLH('a'), KEY_CTRLH(KEY_CTRL('A')),
           "apropos", do_apropos, ESs,
           "s{Apropos: }|apropos|")
     CMD0( KEY_CTRLH('b'), KEY_NONE,
@@ -1329,6 +1476,10 @@
     CMD2( KEY_CTRLH('B'), KEY_NONE,
           "show-bindings", do_show_bindings, ESs,
           "s{Show bindings of command: }[command]|command|")
+    CMD2( KEY_CTRLH(KEY_CTRL('B')), KEY_NONE,
+          "describe-buffer", do_describe_buffer, ESi, "ui")
+    CMD2( KEY_CTRLH('w'), KEY_CTRLH(KEY_CTRL('W')),
+          "describe-window", do_describe_window, ESi, "ui")
 
     CMD2( KEY_CTRLC('c'), KEY_NONE,
           "set-region-color", do_set_region_color, ESs,
@@ -1342,8 +1493,6 @@
     CMD2( KEY_NONE, KEY_NONE,
           "set-eol-type", do_set_eol_type, ESi,
           "ui{EOL Type [0=Unix, 1=Dos, 2=Mac]: }")
-    CMD2( KEY_NONE, KEY_NONE,
-          "describe-buffer", do_describe_buffer, ESi, "ui")
 
     CMD3( KEY_NONE, KEY_NONE,
           "sort-buffer", do_sort_buffer, ESi, 0, "*v")



reply via email to

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