Как посоветовать примитивы в Emacs - PullRequest
4 голосов
/ 19 июня 2010

Я пытался ответить на еще один вопрос , когда столкнулся с очень странным поведением. Вот мой маленький тестовый пример:

(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 in.
  • /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 действительно то, что я нахожу странным.

Понятия не имею, что здесь происходит. Кто-нибудь знает, почему я не получаю ожидаемых результатов?

1 Ответ

4 голосов
/ 19 июня 2010

Ваш код выглядит хорошо, за исключением одного отсутствующего ключа. Вам необходимо установить возвращаемое значение соответствующим образом:

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

Это описано в руководстве .

...