emacs-devel
[Top][All Lists]
Advanced

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

Re: kill ring menu


From: Colin Walters
Subject: Re: kill ring menu
Date: 21 May 2002 16:31:25 -0400

On Tue, 2002-05-21 at 15:12, Richard Stallman wrote:
>     > In principle it is worth putting in a good interface--but what would
>     > make an interface better than this one?  What's wrong with this
>     > interface?  Could you propose one you think is better?
> 
>     I do think the `font-lock-face' interface is quite a bit easier to use. 
> 
> Can you show a real example done both ways?

I already have; with my implementation of `font-lock-face' posted
previously, I changed replace.el to use it. That's in 
Message-Id: <address@hidden>, but I'll
summarize here.  The changes for using `font-lock-face' in replace.el
looked like:

@@ -787,7 +791,7 @@
                                             (append
                                              '(occur-match t)
                                              (when match-face
-                                               `(face ,match-face)))
+                                               `(font-lock-face ,match-face)))
                                             curstring)
                        (setq start (match-end 0))))
                    ;; Generate the string to insert for this match
@@ -796,7 +800,7 @@
                             (apply #'propertize (format "%6d:" lines)
                                    (append
                                     (when prefix-face
-                                      `(face prefix-face))
+                                      `(font-lock-face prefix-face))
                                     '(occur-prefix t)))
                             curstring
                             "\n"))

So using `font-lock-face' is simple; you just substitute the `face' text
property with `font-lock-face' wherever you want faces to be controlled
by font-lock.  That's it.

On the other hand, using categories required creating the category alist
and referencing into it at runtime, to be sure we got the correct
uninterned symbol:

@@ -777,6 +781,8 @@
                    ;; Depropertize the string, and maybe
                    ;; highlight the matches
                    (let ((len (length curstring))
+                         (match-category (with-current-buffer out-buf
+                                           (car (nth 0 
font-lock-category-alist))))
                          (start 0))
                      (unless keep-props
                        (set-text-properties 0 len nil curstring))
@@ -785,7 +791,7 @@
                        (add-text-properties (match-beginning 0)
                                             (match-end 0)
                                             (append
-                                             '(occur-match t)
+                                             `(occur-match t category 
,match-category)
                                              (when match-face
                                                `(face ,match-face)))
                                             curstring)
@@ -842,35 +848,12 @@
                                       (append
                                        (when title-face
                                          `(face ,title-face))
-                                       `(occur-title ,buf))))
+                                       `(occur-title
+                                         ,buf category
+                                         ,(car (nth 1 
font-lock-category-alist))))))
                (goto-char (point-min)))))))
       ;; Return the number of matches
       globalcount)))

Note I ran into a somewhat subtle bug when changing replace.el to use
the category approach; inside the loop which matches on buffers, I had
to switch back into the original *Occur* buffer to get the correct
buffer-local uninterned symbol from `font-lock-category-alist'.

In ibuffer, I had to make some nontrivial changes to pass the ibuffer
buffer all the way down inside some functions to solve the same
problem.  Using `font-lock-face' wouldn't have required these changes.

It's obviously possible to implement things both ways; in the end, it
just comes down to the tradeoffs between the two approaches:

Pros of category approach/Cons of font-lock-face:

* The category approach doesn't really imply much of a commitment from
us; it has no impact on the Emacs C code.  We could quite easily
continue to support it even if we went with another approach later.
* `font-lock-face' does imply a commitment from us, since it touches C
code, and we would want to document it in the elisp reference as a
special property.

Cons of category approach/Pros of font-lock-face:

* I don't think many elisp authors are familiar with the `category'
property, and the indirection of putting a category property on text
which implies a face property is a bit unintuitive.  Also, having to
work with uninterned symbols is definitely a disadvantage.
* The category approach will generally require a bit more computation at
runtime, because of the need to reference into a data structure to get
uninterned symbols.
* On the other hand, `font-lock-face' is efficient, and should also be
relatively easy to understand for anyone who understands the `face'
property.

Both approaches are fully implemented.  It's just a question of which
one to pick.  So I have a suggestion: 

1) We use the category approach for now.
2) Since the only way we could get a majority of elisp mode authors to
use `font-lock-face'  is for it to be implemented in XEmacs too, we ask
them what they think of the API change.  If they agree that it is a good
idea, then we can use it.








reply via email to

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