перед defadvice не выполняется перед функцией? - PullRequest
0 голосов
/ 06 марта 2012

[Я прошу прощения за плохой титул, но не смог придумать лучший.]

Бен Чен спросил в Google +:

Как ввести относительный путь (имя-файла-буфера) в минибуфере после M-! в #emacs?

Я подумал, что если buffer-file-name сохранен в регистре, он должен быть доступен, вызвав insert-register ( C-x r i ), пока в приглашении shell-command.

(defun save-buffer-file-name-in-register ()
    (set-register ?F (buffer-file-name))
    (set-register ?D (file-name-directory buffer-file-name)))

(defadvice shell-command (before save-buffer-file-name)
  "Save buffer-file-name to register F before running shell-command"
  (save-buffer-file-name-in-register))

(ad-activate 'shell-command)

Когда я вызываю shell-command ( M -! ), за которым следует insert-register ( C-x r i ), я получаю сообщение об ошибке: Register does not contain any text.

Но когда я запускаю list-registers, я вижу, что регистры F и D установлены с соответствующими значениями. Если я снова запускаю shell-command, я могу получить доступ к значениям из ранее сохраненных регистров.

Возможно ли, что в первый раз регистры устанавливаются слишком поздно? Как я могу исправить код, чтобы сделать то, что я хочу?

Редактировать : изменено around на before (спасибо @phils)

Ответы [ 2 ]

2 голосов
/ 06 марта 2012

Когда запускается интерактивная форма, ваш совет еще не выполнен. Смотрите: этот вопрос

Вам нужно указать интерактивную форму в вашем совете, которая переопределяет оригинал, если вы хотите придерживаться этого подхода. Тем не менее, этот подход - немного модных штанов ради модных штанов.

Просто определите свою собственную интерактивную функцию, которая делает то, что вы хотите без регистров.

(defun insert-cur-dir ()
  (interactive)
  (let ((dir-name (file-name-directory (buffer-file-name (window-buffer (minibuffer-selected-window))))))
    (insert (or dir-name ""))))

(define-key minibuffer-local-map (kbd "C-c i") 'insert-cur-dir)

Альтернативный, но удивительный способ - использовать yasnippet .

2 голосов
/ 06 марта 2012

nb Вы определили around рекомендацию, а не before рекомендацию.

Around advice действует как обертка и должен включать токен ad-do-it для выполнения кода функции, которую он упаковывает.

Вы фактически заменили тело функции shell-command вызовом save-buffer-file-name-in-register

Что касается вашего основного вопроса, мне нужно проверить документацию, но я подозреваю, чтоТак как аргументы функции рекомендуемой функции доступны для рекомендации, объявление interactive исходной функции, вероятно, выполняется до рекомендации, что объясняет, почему значения вашего регистра не отображаются в командной строке интерактивной оболочки.

(Если around в приведенном выше коде действительно то, что вы использовали, тот факт, что вам все еще запрашивали команду оболочки, может показаться, что эта последовательность проверяется.)

...