How to advise primitives in Emacs

I was trying to answer another SO question when I came across some very strange behavior. Here is my little test case:

(make-variable-buffer-local (defvar my-override-mode-on-save nil "Can be set to automatically ignore read-only mode of a file when saving.")) (defadvice file-writable-p (around my-overide-file-writeable-p act) "override file-writable-p if `my-override-mode-on-save' is set." (or my-override-mode-on-save ad-do-it)) (defun my-override-toggle-read-only () "Toggle buffer read-only status, keeping `my-override-mode-on-save' in sync." (interactive) (setq my-override-mode-on-save (not my-override-mode-on-save)) (toggle-read-only)) (defun tester-fn () (interactive) (let ((xxx (file-writable-p "/tmp/foofoo")) (yyy (file-writable-p "/tmp/fooxxfoo"))) (message (concat "XXX: " (if xxx "yes" "no") " - YYY: " (if yyy "yes" "no"))))) 

Where:

  • /tmp/foofoo is the my-override-toggle-read-only file I visited and run my-override-toggle-read-only .
  • /tmp/fooxxfoo does not exist.
  • /tmp is writable by the user I logged in with.

If I run tester-fn in a buffer where my-override-mode-on-save set to t , I get an unexpected result: XXX: no - YYY: no . If I run tester-fn , and in some other buffer (for example, scratch), I get the expected answer in the minibuffer: XXX: no - YYY: yes . Following the advice through the debugger shows that it is doing exactly what I think it should do, doing the parts that I expect, skipping the parts that I expect, returning the expected value. However, tracing tester-fn through the debugger shows very different values ​​returned ( nil and t if the variable evaluates to nil, nil and nil if the variable evaluates to non-nil). The return of nil and nil really what I find strange.

I do not know what is going on here. Does anyone know why I am not getting the expected results?

+4
source share
1 answer

Your code looks good except for one missing key. You need to set the return value accordingly:

 (defadvice file-writable-p (around my-overide-file-writeable-p act) "override file-writable-p if `my-override-mode-on-save' is set." (setq ad-return-value (or my-override-mode-on-save ad-do-it))) 

This is described in the manual .

+4
source

Source: https://habr.com/ru/post/1313243/


All Articles