Помогите с интерактивной функцией Emacs Lisp для замены текста

Я использую Emacs уже пару месяцев и хочу начать программировать на elisp. В частности, я хотел бы написать свою собственную функцию interactive. Тем не менее, я больше, чем немного потерян. (interactive ...) есть множество вариантов, и я не уверен, какой из них мне нужен. Тогда я действительно не знаю, как называются нужные мне функции. Если бы кто-нибудь мог помочь мне превратить мой псевдокод в настоящий код, я был бы очень признателен! (И, как всегда, любые ссылки на информативные места были бы хороши. Прямо сейчас я только что прочитал это.)

Вот псевдокод того, что я хотел бы сделать:

(defun my-func (buffer) ; I think I need the buffer as an arg?
  "does some replacements"
  (interactive ???) ; ?
  (let (replacements (list
   '("a-regexp-string" . "a-replacement-string-with-backreferences")
   ...)) ; more of the above
    (while replacements
      (let (current (car replacements)) ; get a regexp-replacement pair
        (some-regexp-replace-func buffer (car current) (cdr current)) ; do the replacement
        (setq replacements (cdr replacements))))))

person J Cooper    schedule 17.01.2009    source источник


Ответы (1)


Во-первых, судя по внешнему виду вашей функции, вы, вероятно, будете делать это в текущем буфере, поэтому нет, вам не нужен аргумент «буфер». Если это плохое предположение, я могу изменить код. Далее, в 'let', если вы назначаете переменные, вам нужен еще один набор скобок вокруг каждой пары var/value. Наконец, при переборе списка я предпочитаю использовать функции, подобные функциям функционального программирования (mapcar, mapc и т. д.). Я постараюсь вставить некоторые комментарии здесь:

(defun my-func ()
  "Do some replacements"
  (interactive)
  (let ((replacements (list '("foo" . "bar")
                            '("baz" . "quux"))))
    (save-excursion ; So point isn't moved after this function
      (mapc (lambda (x) ; Go through the list, with this 'inline' function
                        ; being called with each element as the variable 'x'
              (goto-char (point-min)) ; Start at the beginning of the buffer
              (while (re-search-forward (car x) nil t) ; Search for the car of the replacement
                (replace-match (cdr x)))) ; And replace it with the cdr
            replacements)))) ; The list we're mapc'ing through

Что касается того, что читать, я бы посоветовал руководство по Elisp, которое поставляется с Emacs.

person scottfrazer    schedule 18.01.2009
comment
Большое спасибо, что помогли мне понять, что происходит, и встать на правильный путь. Мне просто нужно было использовать re-search-forward вместо версии без регулярных выражений и не передавать t в replace-match, чтобы работала ссылка на совпадающие группы. Еще раз спасибо! - person J Cooper; 18.01.2009
comment
Да, я как раз возвращался, чтобы починить их :) - person scottfrazer; 18.01.2009