Ошибка defadvice для isearch-search-fun-default

Это продолжение моего предыдущего поста ( возможно ли предварительно обработать входную строку перед isearch-forward в Emacs). Я пытаюсь реализовать jpkottaответ с использованием переменной isearch-search-fun-function, Вместо того, чтобы писать свою собственную функцию, я просто советую isearch-search-fun-default включить мои собственные функции (isearch-str-forward а также isearch-str-backward, просто для демонстрации), так что каждый раз, когда я набираю "abc", isearch будет выделять и искать регулярное выражение a[ ]*b[ ]*c[ ]*,

Проблема в том, что когда я посоветовал функцию, а затем выполнить поиск "abc", он дал мне ошибку I-search: abc [(void-function nil)], Но если я положу код внутри моего defadvise в оригинал isearch-search-fun-default функция, это работает! Так что я запутался. Руководство Elisp сказал ad-do-it это просто заполнитель для исходного кода функции, поэтому эти два подхода, советующие функцию или изменяющие исходную функцию, должны, наконец, сгенерировать один и тот же код. Почему ошибка, когда я советую это?

(defun isearch-mangle-str (str)
  "For input STR \"abc\", it will return \"a[ ]*b[ ]*c[ ]*\"."
  (let ((i 0) (out ""))
    (dotimes (i (length str))
      (setq out (concat out (substring str i (1+ i)) "[ ]" "*")))
    out))

(defun isearch-str-forward (str &optional bound noerror)
  "Search forward for STR."
  (let ((string (isearch-mangle-str str)))
    (re-search-forward string bound noerror)))

(defun isearch-str-backward (str &optional bound noerror)
  "Search backward for STR."
  (let ((string (isearch-mangle-str str)))
    (re-search-backward string bound noerror)))

(defvar my-search-p t)
(defadvice isearch-search-fun-default (around my-isearch-search-fun activate)
  (if my-search-p
      (if isearch-forward 'isearch-str-forward
        'isearch-str-backward)
    ad-do-it))

1 ответ

Решение

Я не совсем уверен, почему вы получаете эти ошибки (я думаю, что вам, вероятно, нужно использовать ad-return-value) но зачем пользоваться советами? Обычно это должно быть последнее средство, и в этом случае очень легко избежать советовать.

Кроме того, не добавляйте префиксы имен ваших имен в isearch. Поскольку в emacs есть только одно пространство имен (я не говорю о lisp1 против lisp2), хорошей практикой является уникальное именование ваших переменных и функций. Лично я использую префикс "jpk/", но здесь я использовал "my-".

(defun my-isearch-mangle-str (str)
  "For input STR \"abc\", it will return \"a[ ]*b[ ]*c[ ]*\"."
  (let ((i 0) (out ""))
    (dotimes (i (length str))
      (setq out (concat out (substring str i (1+ i)) "[ ]" "*")))
    out))

(defun my-isearch-str-forward (str &optional bound noerror)
  "Search forward for STR."
  (let ((string (my-isearch-mangle-str str)))
    (re-search-forward string bound noerror)))

(defun my-isearch-str-backward (str &optional bound noerror)
  "Search backward for STR."
  (let ((string (my-isearch-mangle-str str)))
    (re-search-backward string bound noerror)))

(defvar my-isearch-p t)

(defun my-isearch-search-fun ()
  (if my-isearch-p
      (if isearch-forward 'my-isearch-str-forward 'my-isearch-str-backward)
    (isearch-search-fun-default)))

(setq isearch-search-fun-function 'my-isearch-search-fun)

Кроме того, я не уверен, что именно вы хотите, но это похоже на мой пакет flex-isearch.

Другие вопросы по тегам