emacs-devel
[Top][All Lists]
Advanced

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

Re: `make-overlay' very slow


From: Werner LEMBERG
Subject: Re: `make-overlay' very slow
Date: Sat, 11 Apr 2009 08:11:50 +0200 (CEST)

> overlays have a poor algorithmic behavior (many operations take a
> time proportional to the number of overlays in the buffer).  Better
> use text-properties (which are implemented with a tree and should
> provide something closer to O(log N) complexity instead).

I did that (see attachment for reference), and it really works at a
reasonable speed.  However, it is the completely wrong concept since
it sets the `modified' flag and stores undo information, and it fails
with modes which use the `invisible' and `intangible' properties.

So here's my item to the Emacs wishlist: Improve speed of
(make-overlay) and related functions to be as fast as setting text
properties.


    Werner
(defun make-lines-invisible (regexp &optional arg)
  "Make all lines matching a regexp invisible and intangible.
With a prefix arg, make them visible again.  It is not necessary
that REGEXP matches the whole line; if a hit is found, the
affected line gets automatically selected.

This function affects the whole buffer.

Note that this function modifies the `invisible' and `intangible'
text properties; it may thus interfere with modes which use them.
Due to implementation restrictions in current Emacs versions it
is not possible to use overlays -- which would avoid text
property modifications -- without becoming unbearably slow for
large buffers with many matches."
  (interactive "MRegexp: \nP")
  (save-excursion
    (cond
     (arg
      (let ((next-pos (point-min)))
        (while (setq next-pos
                     (text-property-any next-pos
                                        (point-max)
                                        'make-lines-invisible
                                        t))
          (goto-char next-pos)
          (setq next-pos (or (next-single-property-change
                              (point)
                              'make-lines-invisible)
                             (point-max)))
          (remove-list-of-text-properties (point)
                                          next-pos
                                          '(make-lines-invisible
                                            invisible
                                            intangible)))))
    (t
     (goto-char (point-min))
     (while (re-search-forward regexp nil t)
       (add-text-properties (line-beginning-position)
                            (1+ (line-end-position)) ; handle \n
                            '(make-lines-invisible t
                              invisible t
                              intangible t))
       (goto-char (line-end-position)))))))

(global-set-key "\C-cz" 'make-lines-invisible)

reply via email to

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