[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Specifiers (was: face-remapping patch)
From: |
Stefan Monnier |
Subject: |
Specifiers (was: face-remapping patch) |
Date: |
Thu, 29 May 2008 11:45:25 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) |
>>> Miles, could you clarify why you are proposing a remapping list rather than
>>> "buffer-local faces"?
>>
>> I think adding "buffer-local faces" directly is no better. The good
>> thing about Miles's patch is that it leverages buffer-local variables to
>> modify faces buffer-locally. As a result, his patch is pretty small.
>>
>> To improve on this, I think we'd have to move to something more like
>> XEmacs's specifiers. But I haven't even seen any proposal for such
>> a thing yet.
> Proposal: allow a third argument for make-local-variable.
For me, any such proposal which uses variables is simply a non-starter.
To undestand why, consider the following, both from the point of view of
the implementation (where variable access needs to be fast) and of the
specification of meaningful semantics:
- what should (setq var val) do?
currently is magically uses either the global or the current-buffer
locus depending on whether the variable is already buffer-local.
but if it's buffer-local and frame-local, which setting should
be changed?
- how does it interact with make-variable-buffer-local?
I.e. if a variable is just window-local and you do (setq var val), is
it going to be made buffer-local?
- what about `let'? This one is really fun!
what does
(let ((var val)) .. (make-local-variable 'var locus) ..)
do? how 'bout
(make-local-variable 'var foo) .. (let ((var val)) .. (setq var foo)?
or
(make-local-variable 'var foo)..(let ((var val))..(select-other-foo..)var)?
BTW, for what it's worth, I have played a tiny bit with something
similar to what you propose (except that it is separate from variables,
as you may have guessed ;-). See sample code below.
Stefan
;;;; Settings
;; A "setting" is the Emacs equivalent of an XEmacs "specifier".
(defvar settings--table (make-hash-table :weakness 'key))
(defun settings--put (setting value context &optional overwrite)
(assert (not (hash-table-p value)))
(let ((table settings--table)
(selector setting))
(while context
(assert (hash-table-p table))
(let ((entry (gethash selector table)))
(if (hash-table-p entry)
(setq table entry)
(setq table (puthash selector (make-hash-table :weakness 'key) table))
(if entry (puthash t entry table))))
(setq selector (pop context)))
(if overwrite
(puthash selector value table)
(let ((prev (gethash selector table)))
(if (hash-table-p prev)
(puthash t value prev)
(puthash selector value table))))))
(defun settings--permute (xs &optional ys xss)
(if (null xs)
(cons ys xss)
(dolist (x xs)
(setq xss (settings--permute (remq x xs) (cons x ys) xss)))
xss))
(defun settings-put (setting value context)
(assert (and value (not (hash-table-p value))))
(assert (listp context))
(dolist (context (settings--permute context))
(settings--put setting value context)))
(defun settings--context ()
;; The order indicates the precedence: a buffer-local settings takes
;; precedence over a window-local setting, ...
(list (current-buffer)
(selected-window)
(selected-frame)
(selected-terminal)
major-mode))
(defun settings--get-closest (table)
(let ((workqueue (list table)))
(while workqueue
(setq table (pop workqueue))
(if (gethash t table)
(throw 'closest (gethash t table))
(maphash (lambda (k v)
(if (hash-table-p v)
;; Duh! O(N) insertion into the workqueue :-(
(setq worklist (append workqueue (list v)))
(throw 'closest v)))
table)))))
(defun settings--get (table context closest)
(let (entry)
(cond
((not (hash-table-p table)) table)
((not context)
(or (gethash t table)
(when closest
;; There is some setting somewhere in a subcontext: use it.
(catch 'closest
(settings--get-closest table)))))
(t
(or (and (setq entry (gethash (pop context) table))
(settings--get entry context closest))
(settings--get table context closest))))))
(defun settings-get (setting &optional context closest)
(unless context (setq context (settings--context)))
(let ((table (gethash setting settings--table)))
(if (not (hash-table-p table))
table
(settings--get table context closest))))
- Re: face-remapping patch, (continued)
- Re: face-remapping patch, Richard M Stallman, 2008/05/30
- Re: face-remapping patch, David Kastrup, 2008/05/30
- Re: face-remapping patch, Richard M Stallman, 2008/05/31
- Re: face-remapping patch, David Kastrup, 2008/05/31
- Re: face-remapping patch, Richard M Stallman, 2008/05/29
- Re: face-remapping patch, David Kastrup, 2008/05/29
- Specifiers (was: face-remapping patch),
Stefan Monnier <=
- Re: Specifiers, David Kastrup, 2008/05/29
- Re: Specifiers, Stefan Monnier, 2008/05/29
- Re: Specifiers, Stephen J. Turnbull, 2008/05/29
- Re: Specifiers (was: face-remapping patch), Richard M Stallman, 2008/05/29
- Re: Specifiers, Stefan Monnier, 2008/05/29
- Re: Specifiers, David Kastrup, 2008/05/30
- Re: Specifiers, Stefan Monnier, 2008/05/30
- Re: Specifiers, David Kastrup, 2008/05/30
- Re: Specifiers, Stefan Monnier, 2008/05/30
- Re: Specifiers, Richard M Stallman, 2008/05/31