From b75fb81e362b8afbf37da0d2480676269430694c Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 30 Jul 2019 15:21:29 +0200 Subject: [PATCH] Extend button.el to take callback data * doc/lispref/display.texi (Button Buffer Commands) (Button Buffer Commands): Document this. * lisp/button.el (backward-button, forward-button): Accept a NO-ERROR parameter. (button-activate): Make it possible to have specific data in the callback action. --- doc/lispref/display.texi | 14 ++++++++++---- etc/NEWS | 6 ++++++ lisp/button.el | 32 +++++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 3c91092906c..cf0008df86c 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -6473,7 +6473,9 @@ that is the value of that property, passing it the single argument @var{button}). If @var{use-mouse-action} is non-@code{nil}, try to invoke the button's @code{mouse-action} property instead of @code{action}; if the button has no @code{mouse-action} property, use -@code{action} as normal. +@code{action} as normal. If the @code{button-data} property is +present in @var{button}, use that as the argument for the +@code{action} function instead of @var{button}. @end defun @defun button-label button @@ -6541,14 +6543,16 @@ event's position is used. If there's no button at @var{pos}, do nothing and return @code{nil}, otherwise return @code{t}. @end deffn -@deffn Command forward-button n &optional wrap display-message +@deffn Command forward-button n &optional wrap display-message no-error Move to the @var{n}th next button, or @var{n}th previous button if @var{n} is negative. If @var{n} is zero, move to the start of any button at point. If @var{wrap} is non-@code{nil}, moving past either end of the buffer continues from the other end. If @var{display-message} is non-@code{nil}, the button's help-echo string is displayed. Any button with a non-@code{nil} @code{skip} property -is skipped over. Returns the button found. +is skipped over. Returns the button found, and signals an error if no +buttons can be found. If @var{no-error} in non-@code{nil}, return nil +instead of signalling the error. @end deffn @deffn Command backward-button n &optional wrap display-message @@ -6558,7 +6562,9 @@ button at point. If @var{wrap} is non-@code{nil}, moving past either end of the buffer continues from the other end. If @var{display-message} is non-@code{nil}, the button's help-echo string is displayed. Any button with a non-@code{nil} @code{skip} property -is skipped over. Returns the button found. +is skipped over. Returns the button found, and signals an error if no +buttons can be found. If @var{no-error} in non-@code{nil}, return nil +instead of signalling the error. @end deffn @defun next-button pos &optional count-current diff --git a/etc/NEWS b/etc/NEWS index 1587eab1e29..cdf4bb29042 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1968,6 +1968,12 @@ valid event type. * Lisp Changes in Emacs 27.1 ++++ +** Buttons (created with 'make-button' and related functions) can +now use the 'button-data' property. If present, the data in this +property will be passed on to the 'action' function instead of the +button itself in 'button-activate'. + ** 'defcustom' now takes a ':local' keyword that can be either t or 'permanent', which mean that the variable should be automatically buffer-local. 'permanent' also sets the variable's 'permanent-local' diff --git a/lisp/button.el b/lisp/button.el index 921e84dfa68..ca6f0d3b6ea 100644 --- a/lisp/button.el +++ b/lisp/button.el @@ -235,15 +235,19 @@ The action can either be a marker or a function. If it's a marker then goto it. Otherwise if it is a function then it is called with BUTTON as only argument. BUTTON is either an overlay, a buffer position, or (for buttons in the mode-line or -header-line) a string." +header-line) a string. + +If BUTTON has a `button-data' value, call the function with this +value instad of BUTTON." (let ((action (or (and use-mouse-action (button-get button 'mouse-action)) - (button-get button 'action)))) + (button-get button 'action))) + (data (button-get button 'button-data))) (if (markerp action) (save-selected-window (select-window (display-buffer (marker-buffer action))) (goto-char action) (recenter 0)) - (funcall action button)))) + (funcall action (or data button))))) (defun button-label (button) "Return BUTTON's text label." @@ -324,6 +328,10 @@ using `make-text-button'. Note, however, that if there is an existing face property at the site of the button, the button face may not be visible. You may want to use `make-button' in that case. +If the property `button-data' is present, it will later be used +as the argument for the `action' callback function instead of the +default argument, which is the button itself. + BEG can also be a string, in which case it is made into a button. Also see `insert-text-button'." @@ -462,13 +470,17 @@ return t." (button-activate button use-mouse-action) t)))) -(defun forward-button (n &optional wrap display-message) +(defun forward-button (n &optional wrap display-message no-error) "Move to the Nth next button, or Nth previous button if N is negative. If N is 0, move to the start of any button at point. If WRAP is non-nil, moving past either end of the buffer continues from the other end. If DISPLAY-MESSAGE is non-nil, the button's help-echo string is displayed. Any button with a non-nil `skip' property is skipped over. + +If NO-ERROR, return nil if no further buttons could be found +instead of erroring out. + Returns the button found." (interactive "p\nd\nd") (let (button) @@ -497,22 +509,28 @@ Returns the button found." (unless (button-get button 'skip) (setq n (1- n))))))) (if (null button) - (user-error (if wrap "No buttons!" "No more buttons")) + (if no-error + nil + (user-error (if wrap "No buttons!" "No more buttons"))) (let ((msg (and display-message (button-get button 'help-echo)))) (when msg (message "%s" msg))) button))) -(defun backward-button (n &optional wrap display-message) +(defun backward-button (n &optional wrap display-message no-error) "Move to the Nth previous button, or Nth next button if N is negative. If N is 0, move to the start of any button at point. If WRAP is non-nil, moving past either end of the buffer continues from the other end. If DISPLAY-MESSAGE is non-nil, the button's help-echo string is displayed. Any button with a non-nil `skip' property is skipped over. + +If NO-ERROR, return nil if no further buttons could be found +instead of erroring out. + Returns the button found." (interactive "p\nd\nd") - (forward-button (- n) wrap display-message)) + (forward-button (- n) wrap display-message no-error)) (provide 'button) -- 2.39.2