emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] feature/noverlay c2826d9 2/2: Adapt overlays when multibyt


From: Andreas Politz
Subject: [Emacs-diffs] feature/noverlay c2826d9 2/2: Adapt overlays when multibyteness changes
Date: Fri, 6 Oct 2017 15:44:50 -0400 (EDT)

branch: feature/noverlay
commit c2826d9a0312981e2553f699d3afe9b39880f6ce
Author: Andreas Politz <address@hidden>
Commit: Andreas Politz <address@hidden>

    Adapt overlays when multibyteness changes
    
    * src/buffer.c
      (set_overlays_multibyte): New function.
      (set-buffer-multibyte): Use function.
---
 src/buffer.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/src/buffer.c b/src/buffer.c
index 21c040a..122c60f 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -879,6 +879,56 @@ delete_all_overlays (struct buffer *b)
   interval_tree_clear (b->overlays);
 }
 
+/* Adjust the position of overlays in the current buffer according to
+   MULTIBYTE.
+
+   Assume that positions currently correspond to byte positions, if
+   MULTIBYTE is true and to character positions if not.
+*/
+
+static void
+set_overlays_multibyte (bool multibyte)
+{
+  if (! current_buffer->overlays || Z == Z_BYTE)
+    return;
+
+  struct interval_node **nodes = NULL;
+  struct interval_tree *tree = current_buffer->overlays;
+  const intmax_t size = interval_tree_size (tree);
+
+  USE_SAFE_ALLOCA;
+  SAFE_NALLOCA (nodes, 1, size);
+  interval_tree_nodes (tree, nodes, ITREE_ASCENDING);
+
+  for (int i = 0; i < size; ++i, ++nodes)
+    {
+      struct interval_node * const node = *nodes;
+
+      if (multibyte)
+        {
+          ptrdiff_t begin = interval_node_begin (tree, node);
+          ptrdiff_t end = interval_node_end (tree, node);
+
+          /* This models the behavior of markers.  (The behavior of
+             text-intervals differs slightly.) */
+          while (begin < Z_BYTE
+                 && !CHAR_HEAD_P (FETCH_BYTE (begin)))
+            begin++;
+          while (end < Z_BYTE
+                 && !CHAR_HEAD_P (FETCH_BYTE (end)))
+            end++;
+          interval_node_set_region (tree, node, BYTE_TO_CHAR (begin),
+                                    BYTE_TO_CHAR (end));
+        }
+      else
+        {
+          interval_node_set_region (tree, node, CHAR_TO_BYTE (node->begin),
+                                    CHAR_TO_BYTE (node->end));
+        }
+    }
+  SAFE_FREE ();
+}
+
 /* Reinitialize everything about a buffer except its name and contents
    and local variables.
    If called on an already-initialized buffer, the list of overlays
@@ -2456,6 +2506,7 @@ current buffer is cleared.  */)
       /* Do this first, so it can use CHAR_TO_BYTE
         to calculate the old correspondences.  */
       set_intervals_multibyte (0);
+      set_overlays_multibyte (0);
 
       bset_enable_multibyte_characters (current_buffer, Qnil);
 
@@ -2648,6 +2699,7 @@ current buffer is cleared.  */)
       /* Do this last, so it can calculate the new correspondences
         between chars and bytes.  */
       set_intervals_multibyte (1);
+      set_overlays_multibyte (1);
     }
 
   if (!EQ (old_undo, Qt))



reply via email to

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