Я создаю программу, которая взаимодействует с Emacs, и одна из проблем, с которой я столкнулся, - это написать функцию фильтра процесса Emacs. Его входная строка представляет собой серию s-выражений для оценки. Вот пример:Как написать приличный фильтр процесса?
(gimme-append-to-buffer "25 - William Christie dir, Les Arts Florissants - Scene 2. Prelude - Les Arts Florissants\n")
(gimme-append-to-buffer "26 - William Christie dir, Les Arts Florissants - Cybele: 'Je Veux Joindre' - Les Arts Florissants\n")
(gimme-append-to-buffer "27 - William Christie dir, Les Arts Florissants - Scene 3. Cybele: 'Tu T'Etonnes, Melisse' - Les Arts Florissants\n")
(gimme-append-to-buffer "28 - William Christie dir, Les Arts Florissants - Cybele: 'Que Les Plus Doux Zephyrs'. Scene 4. - Les Arts Florissants\n")
(gimme-append-to-buffer "29 - William Christie dir, Les Arts Florissants - Entree Des Nations - Les Arts Florissants\n")
(gimme-append-to-buffer "30 - William Christie dir, Les Arts Florissants - Entree Des Zephyrs - Les Arts Florissants\n")
(gimme-append-to-buffer "31 - William Christie dir, Les Arts Florissants - Choeur Des Nations' 'Que Devant Vous' - Les Arts Florissants\n")
(gimme-append-to-buffer "32 - William Christie dir, Les Arts Florissants - Atys: 'Indigne Que Je Suis' - Les Arts Florissants\n")
(gimme-append-to-buffer "33 - William Christie dir, Les Arts Florissants - Reprise Du Choeur Des Nations : 'Que Devant Nous' - Les Arts Florissants\n")
(gimme-append-to-buffer "34 - William Christie dir, Les Arts Flor*emphasized text*issants - Reprise De L'Air Des Zephyrs - Les Arts Florissants\n")
Первая проблема, с которой я столкнулся в том, что строка как-то не полностью сформирована, когда функция так называемого, поэтому писать что-то вроде (mapcar 'eval (format "(%s)" input-string))
не будет работать.
Чтобы справиться с этой первой проблемой, я использовал цикл. Полнофункциональный я написал это:
(defun eval-all-sexps (s)
(loop for x = (ignore-errors (read-from-string s))
then (ignore-errors (read-from-string (substring s position)))
while x
summing (or (cdr x) 0) into position
doing (eval (car x))))
Теперь вторая проблема, которая появилась в том, что функция вызывается дважды с несколько большим входом, первый с действительным, но частичным содержанием, то с тем, что выглядит как кусочки оставшегося данные.
Чтобы решить эту проблему, я рассматриваю возможность использования мусорной переменной, чтобы удержать то, что осталось от цикла, а затем объединить ее со входом следующего вызова, но мне было интересно, есть ли у вас другие предложения о том, как для решения этой проблемы более элегантно.
Спасибо!