Emacs lisp“;“区域上的shell命令”;

Emacs lisp“;“区域上的shell命令”;,emacs,lisp,elisp,Emacs,Lisp,Elisp,在GNU Emacs中,我想在当前选定的文本上运行一个程序figlet。然后,我想对制作的区域进行评论 我已经找到了使用标准Emacs命令的方法: 在单词的开头用C-标记 将光标移到单词的末尾 区域RET figlet RET上的C-u M-x shell命令 M-x注释区域RET 然而,我没有弄清楚如何编写一个Emacs lisp程序来完成所有这些。以下是我的尝试: (defun figlet-region () (interactive) (push-mark) (shel

在GNU Emacs中,我想在当前选定的文本上运行一个程序figlet。然后,我想对制作的区域进行评论

我已经找到了使用标准Emacs命令的方法:

  • 在单词的开头用C-标记
  • 将光标移到单词的末尾
  • 区域RET figlet RET上的C-u M-x shell命令
  • M-x注释区域RET
然而,我没有弄清楚如何编写一个Emacs lisp程序来完成所有这些。以下是我的尝试:

(defun figlet-region () 
  (interactive)
  (push-mark)
  (shell-command-on-region "figlet")
  (comment-region (mark) (point))
  (pop-mark)
)

(global-set-key "\C-c\C-f" 'figlet-region)
然后
C-;M-x figlet区域产生垃圾:

figlet-region: Wrong number of arguments: #[(start end command &optional output-buffer replace error-buffer display-error-buffer) "ÆÇÈ \"!É 'jÊ!j;j 0Wb ?Ë`Ì\"Í ÎQÎDRÎÉ!\"& ffÏ )ãÐqÑ!#Ò#p=¬É$]d|e^|Íed ΠÎD¡ÎÉ!\"&â%&#qÉ$Á&%Ó *Í ÉØ#DÚ#É!\"&*#Ô!#ÕÖ×!8WrÐ!qd`Z'o ØcÙÉ\"d'Zb)(Úp!)Û!*" [error-buffer small-temporary-file-directory temporary-file-directory exit-status error-file replace make-temp-file expand-file-name "scor" nil ...] 9 1945557 (let (string) (unless (mark) (error "The mark is not set now, so there is no region")) (setq string (read-from-minibuffer "Shell command on region: " nil nil nil (quote shell-command-history))) (list (region-beginning) (region-end) string current-prefix-arg current-prefix-arg shell-command-default-error-buffer t))], 1 (这是基于特雷·杰克逊的回答。)

示例(Lisp交互模式)
;uuu
;; | |_| |__   __ _ _ __ | | _____ 
;; | __| '_ \ / _` | '_ \| |/ / __|

;; | |_| | | | (124; | | | | |嗯,我不确定垃圾是从哪里来的,但错误本身来自
shell命令区域
。在
elisp
中使用时,它至少需要3个参数,
START
END
command

此外,一般来说,在函数中弄乱标记是不好的做法。以下是push mark的文档对此主题的说明:

Emacs Lisp程序员新手经常 试着用这个标记来表示错误的意思 目的。请参阅 `有关详细信息,请设置“标记”


我不确定你想通过推动和弹出标记来实现什么,我相信你会通过这样做获得相同的功能:

(defun figlet-region (&optional b e) 
  (interactive "r")
  (shell-command-on-region b e "figlet")
  (comment-region b e))

interactive的参数告诉Emacs将区域(点和标记)作为前两个参数传递给命令。

在lisp程序中使用区域上的shell命令这样的交互式命令不是一个很好的主意。您应该改为使用:


它应该对各种用户选项更具弹性。

请注意,区域上的
shell命令
可能会修改区域,因此最后一行应为
(注释区域(标记)(点))
,与我的答案中的一样。在我的答案中使用的形式中,它不会修改区域(除非您是从缓冲区调用它,
*Shell命令输出*
,这很奇怪)。如果您要使用
(标记)
(点)
-通过参数传递区域没有意义,因为如果不以交互方式调用它,它将无法按预期工作。想象一下,区域上的
shell命令
将区域
b
-
e
替换为空字符串。然后
注释区域
DRT吗?如果调用了区域上的
shell命令
,则是如果有更多的参数,那么您所说的是正确的。但事实并非如此(在我的示例中),因此您的观点不适用。我的答案并不能解决他的全部问题,但他已经解决了。请注意,在调用“call process region”时,在调用“call process region”后使用第一个“t”可以删除该区域。此函数的签名是:
;;  _   _                 _        
;; | |_| |__   __ _ _ __ | | _____ 
;; | __| '_ \ / _` | '_ \| |/ / __|
;; | |_| | | | (_| | | | |   <\__ \
;;  \__|_| |_|\__,_|_| |_|_|\_\___/
#  _   _                 _        
# | |_| |__   __ _ _ __ | | _____ 
# | __| '_ \ / _` | '_ \| |/ / __|
# | |_| | | | (_| | | | |   <\__ \
#  \__|_| |_|\__,_|_| |_|_|\_\___/
(defun figlet-region (&optional b e) 
  (interactive "r")
  (shell-command-on-region b e "figlet")
  (comment-region b e))
(defun figlet-region (&optional b e) 
  (interactive "r")
  (call-process-region b e "figlet" t t)
  (comment-region (mark) (point)))