aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Bernoulli2012-12-06 15:10:36 -0500
committerStefan Monnier2012-12-06 15:10:36 -0500
commit24fc9480399b2d018e8d85f34e9c5d8c327ce3bf (patch)
tree46246a1e160516229e938fc5b59c266199dd8529
parente86f51344b4bc58f8342b360eaf3d2b2ca0c470a (diff)
downloademacs-24fc9480399b2d018e8d85f34e9c5d8c327ce3bf.tar.gz
emacs-24fc9480399b2d018e8d85f34e9c5d8c327ce3bf.zip
* lisp/button.el: Make them work in header-lines.
(button-map): Add bindings for header-line and mode-line use. (button-get, button-put, button-label): `button' may now be a string. (button-activate): Don't make it a defsubst. (button--area-button-p, button--area-button-string): New functions. (make-text-button): Fix the return value when `beg' was a string. (push-button): Handle the mode-line case. Fixes: debbugs:12817
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/button.el73
2 files changed, 61 insertions, 22 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index d94ffbab67e..58b7e443798 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,13 @@
12012-12-06 Jonas Bernoulli <jonas@bernoul.li>
2
3 * button.el: Make them work in header-lines (bug#12817).
4 (button-map): Add bindings for header-line and mode-line use.
5 (button-get, button-put, button-label): `button' may now be a string.
6 (button-activate): Don't make it a defsubst.
7 (button--area-button-p, button--area-button-string): New functions.
8 (make-text-button): Fix the return value when `beg' was a string.
9 (push-button): Handle the mode-line case.
10
12012-12-06 Stefan Monnier <monnier@iro.umontreal.ca> 112012-12-06 Stefan Monnier <monnier@iro.umontreal.ca>
2 12
3 * progmodes/sql.el: Use cl-lib and lexical-binding; various cleanup. 13 * progmodes/sql.el: Use cl-lib and lexical-binding; various cleanup.
diff --git a/lisp/button.el b/lisp/button.el
index 3cf38fa64c6..c52dcabed08 100644
--- a/lisp/button.el
+++ b/lisp/button.el
@@ -64,6 +64,11 @@
64 ;; might get converted to ^M when building loaddefs.el 64 ;; might get converted to ^M when building loaddefs.el
65 (define-key map [(control ?m)] 'push-button) 65 (define-key map [(control ?m)] 'push-button)
66 (define-key map [mouse-2] 'push-button) 66 (define-key map [mouse-2] 'push-button)
67 ;; FIXME: You'd think that for keymaps coming from text-properties on the
68 ;; mode-line or header-line, the `mode-line' or `header-line' prefix
69 ;; shouldn't be necessary!
70 (define-key map [mode-line mouse-2] 'push-button)
71 (define-key map [header-line mouse-2] 'push-button)
67 map) 72 map)
68 "Keymap used by buttons.") 73 "Keymap used by buttons.")
69 74
@@ -184,10 +189,12 @@ changes to a supertype are not reflected in its subtypes)."
184 189
185(defun button-get (button prop) 190(defun button-get (button prop)
186 "Get the property of button BUTTON named PROP." 191 "Get the property of button BUTTON named PROP."
187 (if (overlayp button) 192 (cond ((overlayp button)
188 (overlay-get button prop) 193 (overlay-get button prop))
189 ;; Must be a text-property button. 194 ((button--area-button-p button)
190 (get-text-property button prop))) 195 (get-text-property 0 prop (button--area-button-string button)))
196 (t ; Must be a text-property button.
197 (get-text-property button prop))))
191 198
192(defun button-put (button prop val) 199(defun button-put (button prop val)
193 "Set BUTTON's PROP property to VAL." 200 "Set BUTTON's PROP property to VAL."
@@ -202,21 +209,30 @@ changes to a supertype are not reflected in its subtypes)."
202 ;; Disallow updating the `category' property directly. 209 ;; Disallow updating the `category' property directly.
203 (error "Button `category' property may not be set directly"))) 210 (error "Button `category' property may not be set directly")))
204 ;; Add the property. 211 ;; Add the property.
205 (if (overlayp button) 212 (cond ((overlayp button)
206 (overlay-put button prop val) 213 (overlay-put button prop val))
207 ;; Must be a text-property button. 214 ((button--area-button-p button)
208 (put-text-property 215 (setq button (button--area-button-string button))
209 (or (previous-single-property-change (1+ button) 'button) 216 (put-text-property 0 (length button) prop val button))
210 (point-min)) 217 (t ; Must be a text-property button.
211 (or (next-single-property-change button 'button) 218 (put-text-property
212 (point-max)) 219 (or (previous-single-property-change (1+ button) 'button)
213 prop val))) 220 (point-min))
214 221 (or (next-single-property-change button 'button)
215(defsubst button-activate (button &optional use-mouse-action) 222 (point-max))
223 prop val))))
224
225(defun button-activate (button &optional use-mouse-action)
216 "Call BUTTON's action property. 226 "Call BUTTON's action property.
217If USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action 227If USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action
218instead of its normal action; if the button has no mouse-action, 228instead of its normal action; if the button has no mouse-action,
219the normal action is used instead." 229the normal action is used instead.
230
231The action can either be a marker or a function. If it's a
232marker then goto it. Otherwise it it is a function then it is
233called with BUTTON as only argument. BUTTON is either an
234overlay, a buffer position, or (for buttons in the mode-line or
235header-line) a string."
220 (let ((action (or (and use-mouse-action (button-get button 'mouse-action)) 236 (let ((action (or (and use-mouse-action (button-get button 'mouse-action))
221 (button-get button 'action)))) 237 (button-get button 'action))))
222 (if (markerp action) 238 (if (markerp action)
@@ -228,7 +244,10 @@ the normal action is used instead."
228 244
229(defun button-label (button) 245(defun button-label (button)
230 "Return BUTTON's text label." 246 "Return BUTTON's text label."
231 (buffer-substring-no-properties (button-start button) (button-end button))) 247 (if (button--area-button-p button)
248 (substring-no-properties (button--area-button-string button))
249 (buffer-substring-no-properties (button-start button)
250 (button-end button))))
232 251
233(defsubst button-type (button) 252(defsubst button-type (button)
234 "Return BUTTON's button-type." 253 "Return BUTTON's button-type."
@@ -238,6 +257,12 @@ the normal action is used instead."
238 "Return t if BUTTON has button-type TYPE, or one of TYPE's subtypes." 257 "Return t if BUTTON has button-type TYPE, or one of TYPE's subtypes."
239 (button-type-subtype-p (button-get button 'type) type)) 258 (button-type-subtype-p (button-get button 'type) type))
240 259
260(defalias 'button--area-button-p 'stringp
261 "Return non-nil if BUTTON is an area button.
262Such area buttons are used for buttons in the mode-line and header-line.")
263
264(defalias 'button--area-button-string 'identity
265 "Return area button BUTTON's button-string.")
241 266
242;; Creating overlay buttons 267;; Creating overlay buttons
243 268
@@ -324,7 +349,7 @@ Also see `insert-text-button'."
324 (cons 'button (cons (list t) properties)) 349 (cons 'button (cons (list t) properties))
325 object) 350 object)
326 ;; Return something that can be used to get at the button. 351 ;; Return something that can be used to get at the button.
327 beg)) 352 (or object beg)))
328 353
329(defun insert-text-button (label &rest properties) 354(defun insert-text-button (label &rest properties)
330 "Insert a button with the label LABEL. 355 "Insert a button with the label LABEL.
@@ -405,7 +430,9 @@ POS may be either a buffer position or a mouse-event. If
405USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action 430USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action
406instead of its normal action; if the button has no mouse-action, 431instead of its normal action; if the button has no mouse-action,
407the normal action is used instead. The action may be either a 432the normal action is used instead. The action may be either a
408function to call or a marker to display. 433function to call or a marker to display and is invoked using
434`button-activate' (which see).
435
409POS defaults to point, except when `push-button' is invoked 436POS defaults to point, except when `push-button' is invoked
410interactively as the result of a mouse-event, in which case, the 437interactively as the result of a mouse-event, in which case, the
411mouse event is used. 438mouse event is used.
@@ -417,11 +444,13 @@ return t."
417 ;; POS is a mouse event; switch to the proper window/buffer 444 ;; POS is a mouse event; switch to the proper window/buffer
418 (let ((posn (event-start pos))) 445 (let ((posn (event-start pos)))
419 (with-current-buffer (window-buffer (posn-window posn)) 446 (with-current-buffer (window-buffer (posn-window posn))
420 (push-button (posn-point posn) t))) 447 (if (posn-area posn)
448 ;; mode-line or header-line event
449 (button-activate (car (posn-string posn)) t)
450 (push-button (posn-point posn)) t)))
421 ;; POS is just normal position 451 ;; POS is just normal position
422 (let ((button (button-at (or pos (point))))) 452 (let ((button (button-at (or pos (point)))))
423 (if (not button) 453 (when button
424 nil
425 (button-activate button use-mouse-action) 454 (button-activate button use-mouse-action)
426 t)))) 455 t))))
427 456