2

该函数的 Emacs 帮助页面显示shell-command-on-region(省略空格):

(shell-command-on-region START END COMMAND &optional OUTPUT-BUFFER
REPLACE ERROR-BUFFER DISPLAY-ERROR-BUFFER)

...
The noninteractive arguments are START, END, COMMAND,
OUTPUT-BUFFER, REPLACE, ERROR-BUFFER, and DISPLAY-ERROR-BUFFER.
...

If the optional fourth argument OUTPUT-BUFFER is non-nil,
that says to put the output in some other buffer.
If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
If OUTPUT-BUFFER is not a buffer and not nil,
insert output in the current buffer.
In either case, the output is inserted after point (leaving mark after it).

If REPLACE, the optional fifth argument, is non-nil, that means insert
the output in place of text from START to END, putting point and mark
around it.

这不是最清楚的,但刚刚引用的最后几句话似乎是说,如果我希望将 shell 命令的输出插入到当前缓冲区中,而缓冲区的其他内容保持不变,我应该传递一个非nil论据 forOUTPUT-BUFFERnilfor REPLACE

但是,如果我在缓冲区中执行此代码*scratch*(不是我正在处理的真实代码,而是演示问题的最小案例):

(shell-command-on-region
 (point-min) (point-max) "wc" t nil)

缓冲区的全部内容被删除并替换为wc!

shell-command-on-region非交互使用时坏了,还是我误读了文档?如果是后者,我如何更改上面的代码以插入wcat point 的输出而不是替换缓冲区的内容?理想情况下,我想要一个通用的解决方案,它不仅可以像在最小示例中那样在整个缓冲区上运行命令(即(point-min)通过(point-max)),而且还可以用于以区域作为输入运行命令然后插入结果的情况在不删除区域的情况下。

4

3 回答 3

5

你错了

shell-command-on-region在 emacs lisp 代码中使用交互式命令不是一个好主意。改为使用call-process-region

Emacs 错了

有一个错误shell-command-on-region:它没有将replace参数传递给call-process-region; 这是修复:

=== modified file 'lisp/simple.el'
--- lisp/simple.el  2013-05-16 03:41:52 +0000
+++ lisp/simple.el  2013-05-23 18:44:16 +0000
@@ -2923,7 +2923,7 @@ interactively, this is t."
      (goto-char start)
      (and replace (push-mark (point) 'nomsg))
      (setq exit-status
-       (call-process-region start end shell-file-name t
+       (call-process-region start end shell-file-name replace
                     (if error-file
                     (list t error-file)
                       t)

我会尽快提交。

于 2013-05-23T18:45:27.617 回答
2

如果您点击函数源代码的链接,您会很快看到它确实如此:

(if (or replace
    (and output-buffer
     (not (or (bufferp output-buffer) (stringp output-buffer)))))

我不知道它为什么这样做,寿。无论如何,这主要是作为命令而不是函数。来自 Elisp,我建议您call-process-region改用。

于 2013-05-23T18:16:52.790 回答
1

就我而言(emacs 24.3,不知道您使用的是什么版本),可选参数中的文档略有不同:

Optional fourth arg OUTPUT-BUFFER specifies where to put the
command's output.  If the value is a buffer or buffer name, put
the output there.  Any other value, including nil, means to
insert the output in the current buffer.  In either case, the
output is inserted after point (leaving mark after it).

检查是否删除输出(当前)缓冲区内容的代码如下:

(if (or replace
    (and output-buffer
     (not (or (bufferp output-buffer) (stringp output-buffer)))))

很明显,t就像您的情况一样,它不是字符串或缓冲区,也不是零,因此它将用输出替换当前缓冲区内容。但是,如果我尝试:

(shell-command-on-region
 (point-min) (point-max) "wc" nil nil)

然后缓冲区不会被删除,输出会被放入“ Shell Command Output ”缓冲区。乍一看,我会说这个功能没有正确实现。甚至文档的两个版本似乎都与代码不对应。

于 2013-05-23T18:21:38.513 回答