help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: Help setting nadvice for indent-region


From: Kaushal Modi
Subject: Re: Help setting nadvice for indent-region
Date: Thu, 11 Feb 2016 17:36:40 +0000

Thanks for the reply Stefan.

I have just one concern.. that this will not work for advising functions
like eval-defun.

I tried it out and when I do C-M-x while a point is in a function (without
any region selected), it evaluates the whole buffer instead of just the
defun.

So I have to use the :around advice so that I can access the args and then
do a (null args) check to control when to modify the args. Does that look
like a fair way to implement this? Or is it possible to somehow check the
value of provided args inside the (interactive ..) form?

I now have something that's a result of a mix of suggestions given by
everyone over here :)
- avoided using macro as it's not quite needed
- Using this-command to print the current command name as that works for
this case (where I intend to advice the functions when when called directly
as commands).

(defun modi/advice-region-or-whole (orig-fn &rest args)
  (interactive) ; Required to override the "r" argument of `interactive'
                                        ; in functions like `indent-region'
                                        ; so that that function can be
called
                                        ; without an active region.
  (let (msg)
    ;; Execute the original SYMBOL function if it is called indirectly.
    ;; Example: We do not want to modify the ARGS if `eval-region'
    ;;          is called via `eval-defun', because in that case, the
    ;;          ARGS are set by the wrapper function `eval-defun'.
    (when (null args)
      (if (use-region-p) ; when region is selected
          (setq args (list (region-beginning) (region-end)))
        (progn
          (setq args (list (point-min) (point-max)))
          (setq msg (format "Executed %s on the whole buffer."
                            (propertize (symbol-name this-command)
                                        'face
                                        'font-lock-function-name-face))))))
    (apply orig-fn args)
    (when msg
      (message msg))))

(dolist (fn modi/region-or-whole-fns)
  (advice-add fn :around #'modi/advice-region-or-whole))




On Thu, Feb 11, 2016 at 9:05 AM Stefan Monnier <monnier@iro.umontreal.ca>
wrote:

> > (defun modi/region-or-whole-advice (orig &rest _)
> >   (interactive)
> >   (if (use-region-p)
> >       (funcall orig (region-beginning) (region-end))
> >     (funcall orig (point-min) (point-max))))
> > (dolist (fn modi/region-or-whole-fns)
> >   (advice-add fn :around #'modi/region-or-whole-advice))
>
> This will affect all calls to these functions and is hence sure to cause
> some breakage somewhere.  You want something more like:
>
>     (defun modi/region-or-whole-advice (&rest _)
>       (interactive
>        (if (use-region-p)
>            (list (region-beginning) (region-end))
>         (list (point-min) (point-max))))
>       nil)
>     (dolist (fn modi/region-or-whole-fns)
>       (advice-add fn :before #'modi/region-or-whole-advice))
>
> So you only modify the interactive spec (i.e. change the *command*'s
> behavior) without changing the *function*'s behavior.
>
>
> -- Stefan
>
>
>


reply via email to

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