qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs qe.c extras.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs qe.c extras.c
Date: Fri, 17 Jan 2014 13:19:15 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/01/17 13:19:15

Modified files:
        .              : qe.c extras.c 

Log message:
        fix problems with do_transpose and compute_crc
        
        * improve compute_crc: no longer fail on simple 1 character 
transposition
        * remove limitations on block size in do_transpose
        * preserve styles in do_transpose

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.127&r2=1.128
http://cvs.savannah.gnu.org/viewcvs/qemacs/extras.c?cvsroot=qemacs&r1=1.13&r2=1.14

Patches:
Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.127
retrieving revision 1.128
diff -u -b -r1.127 -r1.128
--- qe.c        16 Jan 2014 15:18:44 -0000      1.127
+++ qe.c        17 Jan 2014 13:19:14 -0000      1.128
@@ -2475,15 +2475,28 @@
 
 /* CRC to optimize redraw. */
 /* XXX: is it safe enough ? */
-static unsigned int compute_crc(unsigned char *data, int size, unsigned int 
sum)
+static unsigned int compute_crc(const void *p, int size, unsigned int sum)
 {
+    const u8 *data = (const u8 *)p;
+
+    /* Rotating sum necessary to prevent trivial collisions on
+     * line_chars because it is an array of code points stored as u32.
+     */
+    /* XXX: We still have a bug when transposing two 31 byte words as in
+     * B123456789012345678901234567890 A123456789012345678901234567890
+     */
+    while (((uintptr_t)data & 3) && size > 0) {
+        sum += ((sum >> 31) & 1) + sum + *data;
+        data++;
+        size--;
+    }
     while (size >= 4) {
-        sum += ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
+        sum += ((sum >> 31) & 1) + sum + *(const uint32_t *)data;
         data += 4;
         size -= 4;
     }
     while (size > 0) {
-        sum += data[0] << (size * 8);
+        sum += ((sum >> 31) & 1) + sum + *data;
         data++;
         size--;
     }
@@ -2544,10 +2557,8 @@
         unsigned int crc;
 
         /* test if display needed */
-        crc = compute_crc((unsigned char *)fragments,
-                          sizeof(TextFragment) * nb_fragments, 0);
-        crc = compute_crc((unsigned char *)s->line_chars,
-                          s->line_index * sizeof(int), crc);
+        crc = compute_crc(fragments, sizeof(*fragments) * nb_fragments, 0);
+        crc = compute_crc(s->line_chars, sizeof(*s->line_chars) * 
s->line_index, crc);
         if (s->line_num >= e->shadow_nb_lines) {
             /* realloc shadow */
             int n = e->shadow_nb_lines;

Index: extras.c
===================================================================
RCS file: /sources/qemacs/qemacs/extras.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- extras.c    16 Jan 2014 14:24:03 -0000      1.13
+++ extras.c    17 Jan 2014 13:19:15 -0000      1.14
@@ -282,16 +282,36 @@
 
 static void do_transpose(EditState *s, int cmd)
 {
-    char buf[1024];
-    int offset0, offset1, offset2, offset3;
+    int offset0, offset1, offset2, offset3, end_offset;
     int size0, size1, size2;
+    EditBuffer *b = s->b;
+
+    if (check_read_only(s))
+        return;
 
     switch (cmd) {
     case CMD_TRANSPOSE_CHARS:
-        offset3 = s->offset;
-        eb_prevc(s->b, offset3, &offset2);
+        /* at end of line, transpose previous 2 characters,
+         * otherwise transpose characters before and after point.
+         */
+        end_offset = offset2 = s->offset;
+        if (eb_nextc(b, offset2, &offset3) == '\n') {
+            offset3 = offset2;
+            eb_prevc(b, offset3, &offset2);
+            end_offset = s->offset;
         offset1 = offset2;
-        eb_prevc(s->b, offset1, &offset0);
+            eb_prevc(b, offset1, &offset0);
+        } else {
+            offset1 = offset2;
+            eb_prevc(b, offset1, &offset0);
+            if (s->qe_state->flag_split_window_change_focus) {
+                /* keep current position between characters */
+                end_offset = offset0 + offset3 - offset2;
+            } else {
+                /* set position past second character (emacs behaviour) */
+                end_offset = offset3;
+            }
+        }
         break;
     case CMD_TRANSPOSE_WORDS:
         word_right(s, 1);
@@ -305,10 +325,10 @@
         offset0 = s->offset;
         if (s->qe_state->flag_split_window_change_focus) {
             /* set position to end of first word */
-            s->offset = offset0 + offset3 - offset2;
+            end_offset = offset0 + offset3 - offset2;
         } else {
             /* set position past last word (emacs behaviour) */
-            s->offset = offset3;
+            end_offset = offset3;
         }
         break;
     case CMD_TRANSPOSE_LINES:
@@ -316,17 +336,16 @@
         offset3 = s->offset;
         do_bol(s);
         offset2 = s->offset;
-        if (offset2)
-            s->offset--;
-        offset1 = s->offset;
+        eb_prevc(b, offset2, &offset1);    /* skip line feed */
+        s->offset = offset1;
         do_bol(s);
         offset0 = s->offset;
         if (s->qe_state->flag_split_window_change_focus) {
             /* set position to start of second line */
-            s->offset = offset0 + offset3 - offset1;
+            end_offset = offset0 + offset3 - offset1;
         } else {
             /* set position past second line (emacs behaviour) */
-            s->offset = offset3;
+            end_offset = offset3;
         }
         break;
     default:
@@ -335,14 +354,27 @@
     size0 = offset1 - offset0;
     size1 = offset2 - offset1;
     size2 = offset3 - offset2;
-    if (size0 + size1 + size2 > ssizeof(buf)) {
-        /* Should use temporary buffers */
-        return;
+
+    if (!b->b_styles && size0 + size1 + size2 <= 1024) {
+        u8 buf[1024];
+        /* Use fast method and generate single undo record */
+        eb_read(b, offset2, buf, size2);
+        eb_read(b, offset1, buf + size2, size1);
+        eb_read(b, offset0, buf + size2 + size1, size0);
+        eb_write(b, offset0, buf, size0 + size1 + size2);
+    } else {
+        EditBuffer *b1 = eb_new("*tmp*", BF_SYSTEM | (b->flags & BF_STYLES));
+
+        eb_set_charset(b1, b->charset);
+        eb_insert_buffer_convert(b1, 0, b, offset2, size2);
+        eb_insert_buffer_convert(b1, size2, b, offset1, size1);
+        eb_insert_buffer_convert(b1, size2 + size1, b, offset0, size0);
+        /* XXX: This will create 2 undo records */
+        eb_delete(b, offset0, size0 + size1 + size2);
+        eb_insert_buffer_convert(b, offset0, b1, 0, size0 + size1 + size2);
+        eb_free(b1);
     }
-    eb_read(s->b, offset2, buf, size2);
-    eb_read(s->b, offset1, buf + size2, size1);
-    eb_read(s->b, offset0, buf + size2 + size1, size0);
-    eb_write(s->b, offset0, buf, size0 + size1 + size2);
+    s->offset = end_offset;
 }
 
 /* remove a key binding from mode or globally */



reply via email to

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