emacs - 如何在 Emacs 中建议原语

标签 emacs elisp advising-functions defadvice

我试图回答 another SO question当我遇到一些非常奇怪的行为时。这是我的小测试用例:

(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-only在。
  • /tmp/fooxxfoo不存在。
  • /tmp可由我登录的用户写入。

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

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

    最佳答案

    您的代码看起来不错,只是缺少一个键。您需要适本地设置返回值:

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

    这记录在 advice manual 中.

    关于emacs - 如何在 Emacs 中建议原语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3075862/

    相关文章:

    emacs - 组织模式下的自定义议程 View : Combining Dates and Tags

    terminal - "solarized"配色方案中的颜色略有偏差

    emacs - 在 emacs 中移动区域或行

    Emacs/Emacs Lisp : can I insert advice before interactive form? 或者如何智能预设编译命令?

    python - 如何在不打开 Python shell 的情况下快速显示 emacs 中的 python 帮助文档?

    emacs - ISO emacs/elisp 用于确定与一周的第一天/最后一天相对应的日期,例如ISO 8601 2013-WW47

    datetime - 如何使用Emacs Lisp在Emacs中添加日期?

    emacs - 获取kill-ring的内容

    Emacs - 跳过空白杀死

    Emacs 术语模式 : stop setting remote default-directory on some hosts