如何在Emacs中提供原语 [英] How to advise primitives in Emacs

查看:164
本文介绍了如何在Emacs中提供原语的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试回答另一个SO问题,当我打了一些非常奇怪的行为。这是我的小测试用例:

I was trying to answer another SO question when I hit upon some very odd behavior. Here's 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's 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")))))

其中:


  • / tmp / foofoo 是一个只读文件,我访问过并运行 my-override-toggle-read-只有 in。

  • / tmp / fooxxfoo 不存在。

  • / tmp 可由用户登录。

  • /tmp/foofoo is a read-only file that I've visited and run my-override-toggle-read-only in.
  • /tmp/fooxxfoo does not exist.
  • /tmp is writable by the user I'm logged in as.

如果我在缓冲区中运行 tester-fn ,其中设置了 my-override-mode-on-save t 然后我得到一个意想不到的结果: XXX:否 - YYY:否。如果我在某些其他缓冲区(例如 scratch )中运行 tester-fn ,我会在minibuffer中获得预期的响应: XXX:不 - YYY:是。通过调试器跟踪建议表明它正在做我正在做的事情,执行我期望的部分,跳过我期望的部分,返回我期望的值。然而,通过调试器跟踪 tester-fn 显示返回的值非常不同( nil & t 如果变量评估为nil, nil & nil 为非零)。 nil & nil 返回真的是我发现奇怪的。

If I run tester-fn in a buffer where my-override-mode-on-save is set to t then I get an unexpected result: XXX: no - YYY: no. If I run tester-fn while in some other buffer (e.g. scratch) I get the expected response in the minibuffer: XXX: no - YYY: yes. Tracing the advice through the debugger shows it to be doing exactly what I think it should be doing, executing the parts I expect it to, skipping the parts I expect it to, returning the value I expect it to. However, tracing tester-fn through the debugger shows very different values being returned (nil & t if the variable evaluates as nil, nil & nil if the variable evaluates as non-nil). The nil & nil return is really what I find bizarre.

我不知道这里发生了什么。任何人知道为什么我没有得到我期望的结果?

I have no clue what's happening here. Anyone know why I'm not getting the results I expect?

推荐答案

你的代码看起来不错,除了一个缺少的键。您需要适当地设置返回值:

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

(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)))

这在建议手册中有记录。

这篇关于如何在Emacs中提供原语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆