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: Tue, 13 Dec 2016 13:29:31 +0000 (UTC)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        16/12/13 13:29:31

Modified files:
        .              : extras.c 

Log message:
        extras: added sorting commands:
          - sort-buffer, reverse-sort-buffer, sort-region, reverse-sort-region

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

Patches:
Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -b -r1.44 -r1.45
--- extras.c    13 Dec 2016 13:26:16 -0000      1.44
+++ extras.c    13 Dec 2016 13:29:31 -0000      1.45
@@ -253,7 +253,7 @@
     /* XXX: should extend for language modes to not replace spaces
      * inside character constants, strings, regex, comments,
      * preprocessor, etc.  Implementation is not too difficult with a
-     * new buffer reader eb_nextc_style() using with colorizer and a
+     * new buffer reader eb_nextc_style() using colorizer and a
      * one line cache.
      */
     int tw = b->tab_width > 0 ? b->tab_width : 8;
@@ -1170,6 +1170,102 @@
     }
 }
 
+/*---------------- buffer contents sorting ----------------*/
+
+struct chunk_ctx {
+    EditBuffer *b;
+    int flags;
+#define SF_REVERSE  1
+#define SF_FOLD     2
+#define SF_DICT     4
+#define SF_NUMBER   8
+    int dir;
+};
+
+struct chunk {
+    int start, end;
+};
+
+static int chunk_cmp(void *vp0, const void *vp1, const void *vp2) {
+    const struct chunk_ctx *cp = vp0;
+    const struct chunk *p1 = vp1;
+    const struct chunk *p2 = vp2;
+    int pos1 = p1->start;
+    int pos2 = p2->start;
+    // XXX: should support SF_DICT and SF_NUMBER
+    for (;;) {
+        int c1, c2;
+        c1 = (pos1 < p1->end) ? eb_nextc(cp->b, pos1, &pos1) : 0;
+        c2 = (pos2 < p2->end) ? eb_nextc(cp->b, pos2, &pos2) : 0;
+        if (cp->flags & SF_FOLD) {
+            // XXX: should support unicode case folding
+            c1 = qe_toupper(c1);
+            c2 = qe_toupper(c2);
+        }
+        if (c1 < c2)
+            return -cp->dir;
+        if (c1 > c2)
+            return +cp->dir;
+        if (c1 == 0)
+            return 0;
+    }
+}
+
+static void do_sort_span(EditState *s, int p1, int p2, int flags) {
+    struct chunk_ctx ctx;
+    EditBuffer *b;
+    int i, offset, line1, line2, col1, col2, lines;
+    struct chunk *chunk_array;
+
+    s->region_style = 0;
+
+    if (p1 > p2) {
+        int tmp = p1;
+        p1 = p2;
+        p2 = tmp;
+    }
+    ctx.b = s->b;
+    ctx.flags = flags;  //  SF_FOLD ?
+    ctx.dir = (flags & SF_REVERSE) ? -1 : +1;
+    eb_get_pos(s->b, &line1, &col1, p1); /* line1 is included */
+    eb_get_pos(s->b, &line2, &col2, p2); /* line1 is excluded? */
+    lines = line2 - line1;
+    chunk_array = qe_malloc_array(struct chunk, lines);
+    if (!chunk_array) {
+        put_status(s, "Out of memory");
+        return;
+    }
+    offset = eb_goto_bol(s->b, p1);
+    for (i = 0; i < lines; i++) {
+        chunk_array[i].start = offset;
+        chunk_array[i].end = offset = eb_goto_eol(s->b, offset);
+        eb_nextc(s->b, offset, &offset);
+    }
+    qsort_r(chunk_array, lines, sizeof(*chunk_array), &ctx, chunk_cmp);
+        
+    b = eb_new("*sorted*", BF_SYSTEM);
+    eb_set_charset(b, s->b->charset, s->b->eol_type);
+
+    for (i = 0; i < lines; i++) {
+        eb_insert_buffer(b, b->total_size, s->b, chunk_array[i].start,
+                         chunk_array[i].end - chunk_array[i].start);
+        eb_putc(b, '\n');
+    }
+    eb_delete_range(s->b, p1, p2);
+    s->b->mark = p1;
+    s->offset = p1 + eb_insert_buffer(s->b, p1, b, 0, b->total_size);
+    eb_free(&b);
+    qe_free(&chunk_array);
+}
+
+static void do_sort_region(EditState *s, int flags) {
+    do_sort_span(s, s->b->mark, s->offset, flags);
+}
+
+static void do_sort_buffer(EditState *s, int flags) {
+    do_sort_span(s, 0, s->b->total_size, flags);
+}
+
 static CmdDef extra_commands[] = {
     CMD2( KEY_META('='), KEY_NONE,
           "compare-windows", do_compare_windows, ESi, "ui" )
@@ -1249,6 +1345,15 @@
     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")
+    CMD3( KEY_NONE, KEY_NONE,
+          "sort-region", do_sort_region, ESi, 0, "*v")
+    CMD3( KEY_NONE, KEY_NONE,
+          "reverse-sort-buffer", do_sort_buffer, ESi, SF_REVERSE, "*v")
+    CMD3( KEY_NONE, KEY_NONE,
+          "reverse-sort-region", do_sort_region, ESi, SF_REVERSE, "*v")
+
     CMD_DEF_END,
 };
 



reply via email to

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