在vi [m]中,有一个!
命令可以让我通过shell命令(例如sort或indent)将文本传递给管道,然后将过滤后的文本送回缓冲区。emacs中有等效的东西吗?
Answers:
您可以选择一个区域并输入`Cu M- | 命令RET',由于shell-command-on-region的交互式前缀参数,它用同一缓冲区中的命令输出替换该区域。
C-h i d m Emacs RET') and looking for the command name in the index -
i shell-command-on-region RET')打开Emacs的文档
C-u M-| perl -pi -e 's/pattern/replace/g' RET
。Evil也支持Vim命令(:%!perl -pi -e ... RET
)。
几年前,我写了这篇文章,可能对您有帮助:
(defun generalized-shell-command (command arg)
"Unifies `shell-command' and `shell-command-on-region'. If no region is
selected, run a shell command just like M-x shell-command (M-!). If
no region is selected and an argument is a passed, run a shell command
and place its output after the mark as in C-u M-x `shell-command' (C-u
M-!). If a region is selected pass the text of that region to the
shell and replace the text in that region with the output of the shell
command as in C-u M-x `shell-command-on-region' (C-u M-|). If a region
is selected AND an argument is passed (via C-u) send output to another
buffer instead of replacing the text in region."
(interactive (list (read-from-minibuffer "Shell command: " nil nil nil 'shell-command-history)
current-prefix-arg))
(let ((p (if mark-active (region-beginning) 0))
(m (if mark-active (region-end) 0)))
(if (= p m)
;; No active region
(if (eq arg nil)
(shell-command command)
(shell-command command t))
;; Active region
(if (eq arg nil)
(shell-command-on-region p m command t t)
(shell-command-on-region p m command)))))
我发现此功能非常有帮助。如果您也觉得它有用,我建议您将它绑定到一些功能键上,以方便我个人使用F3
:
(global-set-key [f3] 'generalized-shell-command)
后期编辑:就我对投票的赞赏而言,Jurta的答案是正确的方法。格雷格的骇客比我的更整洁。
我将把其余的内容留在这里,因为它可能值钱,但是...
M-x shell-command-on-region
,似乎与 M-|
默认情况下。
我发现这并不能完全满足Rohit的要求。使用可以C-h f shell-command-on-region
显示所需的行为在命令的非交互式版本中可用(通过将参数设置replace
为non-nil)。我们应该能够编写一个包装器来做到这一点。
试试这个(将其加载*scratch*
并运行M-x eval-buffer
,如果可行,请将其复制到您的.emacs文件中):
(defun shell-command-on-region-replace (start end command)
"Run shell-command-on-region interactivly replacing the region in place"
(interactive (let (string)
(unless (mark)
(error "The mark is not set now, so there is no region"))
;; Do this before calling region-beginning
;; and region-end, in case subprocess output
;; relocates them while we are in the minibuffer.
;; call-interactively recognizes region-beginning and
;; region-end specially, leaving them in the history.
(setq string (read-from-minibuffer "Shell command on region: "
nil nil nil
'shell-command-history))
(list (region-beginning) (region-end)
string)))
(shell-command-on-region start end command t t)
)
并请注意,正如我在评论中所说的那样,这并不是一件很令人毛骨悚然的事情。但我认为这可行。
对于任何不知道如何选择区域的读者:
C-space
激活“标记”