作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在构建一个与 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))))
现在出现的第二个问题是函数被调用两次,输入有点大,第一次是有效但部分内容,然后是看起来像剩余数据的片段。
为了解决这个问题,我正在考虑使用垃圾变量来保存循环中剩余的内容,然后将其连接到下一次调用的输入,但我想知道你们是否有任何其他建议更优雅地处理这样的问题。
谢谢!
最佳答案
这就是我在我使用的 shell 模式下所做的。
我在流程输出中寻找一个特殊的记录结束字符串,以了解输出何时完成。在那之前,我将 block 连接起来。
(defun my-shell-exec-filter (process result)
(let ((end-of-result (string-match my-shell-end-of-record-string result)))
(if (and end-of-result
(numberp end-of-result)
(> end-of-result 0))
(setq my-shell-reply
(concat my-shell-reply
(substring (substring result 0 end-of-result) 0 -1)))
(progn
(setq my-shell-reply (concat my-shell-reply result))
(accept-process-output process my-shell-exec-timeout 5)))))
这不太正确,因为记录结束字符串可以在该过滤器 fn 的多次调用中拆分。所以为了正确,它应该先连接,然后检查匹配。但无论如何你明白了。
它还会递归,因此,对于非常非常长的输入,它可能会导致堆栈溢出异常。所以它肯定没有我想要的那么干净。
事情是从
开始的 (setq my-shell-reply nil)
(set-process-filter proc my-shell-exec-filter)
(process-send-string proc "whatever...")
(if (not (accept-process-output proc my-shell-exec-timeout 100))
(error "unexpected response."))
;; examine my-shell-reply here ...
关于emacs - 如何编写一个像样的进程过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2862209/
我是一名优秀的程序员,十分优秀!