[Top][All Lists]

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

Re: customize-face

From: martin rudalics
Subject: Re: customize-face
Date: Mon, 05 Dec 2005 09:55:28 +0100
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

>     `widget-before-change' may modify text preceding the editable field.  As
>     a consequence FROM and TO values passed to `widget-after-change' get
>     messed up.
> I don't entirely understand the reasoning.  Why can
> `widget-before-change' modify that text?  Is this solely because of
> doing :notify?  (What does :notify do?)

I believe the following happens: My .emacs contains

 '(isearch ((((class color) (min-colors 88) (background light))
             (:background "magenta" :foreground "lightskyblue1")))))

I open a customization buffer for isearch and append a "3" to "magenta".
`widget-before-change' does

             (widget-apply from-field :notify from-field))))))

:notify will now change the text following the State button from "SAVED
and set." to "EDITED, shown value does not take effect until you set or
save it."  The first of these strings is 14 characters long, the second
66.  The difference of their length is 52.  `widget-after-change' does

  (let ((field (widget-field-find from))
        (other (widget-field-find to)))
    (when field
      (unless (eq field other)
        (error "Change in different fields"))

where the value of TO exceeds that of FROM by 53, which equals the sum
of 52 (see above) and 1 (apparently accounting for the character I
inserted).  (widget-field-find from) will now evaluate to the foreground
color widget and (widget-field-find to) to the background color widget
thus triggering the error.

Apparently the bug will show up iff you

(1) make a first change in a customization buffer - this will assert
that :notify modifies some text in the buffer - and

(2) your change occurs in an editable field of a widget that specifies a
preceding editable field in order to trigger the "two fields" error.

>                Finally, the bug will remove `widget-after-change' which
>     breaks the entire customization buffer.
> I don't understand--what does it mean to "remove" `widget-after-change'?

Due to the two fields error `widget-after-change' gets removed from
after-change-functions.  As a consequence, the read-only property of the
customize buffer is lost and editing that buffer becomes completely
unreliable.  (The error should be probably wrapped in a condition-case.)

>     More precisely FROM is that of `widget-before-change' but TO
>     does account for the text change.
> If we arrange for FROM to take account of the text change,
> would that solve the problem?  If you try manually or artificially
> altering FROM in this case, does that make the bug go away?
>       Moreover, undoing still doesn't
>     work reliably.
> How does it fail?

In practice the check

      (unless (eq field other)
        (error "Change in different fields"))

is pretty useless - you can't produce it by simply typing in some text
in an editable field, you have to write a function that inserts text in
two such fields - hence it could be omitted.  Unfortunately, the FROM
and TO values will also show up in `buffer-undo-list' and that messes up
undoing.  To keep buffer-undo-list clean I'd avoid modifying FROM or TO
artificially during a buffer change.

The simple patch below uses an overlay for displaying information like
"SET for current session only."  I don't know whether that's acceptable.
Also it does not solve _all_ undo problems in customization buffers.
Field size adjustment in `widget-after-change' seems to intercept the
undo/redo mechanism.  Moreover undoing changes to check-boxes is broken.

*** cus-edit.el Fri Dec  2 10:16:20 2005
--- cus-edit.el Sat Dec  3 14:55:44 2005
*** 1870,1885 ****
             :mouse-down-action 'widget-magic-mouse-down-action
             :tag "State")
!       (insert ": ")
!       (let ((start (point)))
!       (if (eq custom-magic-show 'long)
!           (insert text)
!         (insert (symbol-name state)))
!       (cond ((eq form 'lisp)
!              (insert " (lisp)"))
!             ((eq form 'mismatch)
!              (insert " (mismatch)")))
!       (put-text-property start (point) 'face 'custom-state))
        (insert "\n"))
      (when (and (eq category 'group)
               (not (and (eq custom-buffer-style 'links)
--- 1870,1890 ----
             :mouse-down-action 'widget-magic-mouse-down-action
             :tag "State")
!       (insert ":  ")
!       (let* ((start (point))
!              (text-overlay (make-overlay (1- start) start))
!              (text-overlay-text
!               (concat
!                (if (eq custom-magic-show 'long)
!                    text
!                  (symbol-name state))
!                (cond ((eq form 'lisp)
!                       " (lisp)")
!                      ((eq form 'mismatch)
!                       " (mismatch)")))))
!         (overlay-put text-overlay 'display text-overlay-text)
!       (overlay-put text-overlay 'face 'custom-state)
!         (overlay-put text-overlay 'evaporate t))
        (insert "\n"))
      (when (and (eq category 'group)
               (not (and (eq custom-buffer-style 'links)

reply via email to

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