tutorial - emacs vs vim
Filtrado de texto a través de un comando de shell en Emacs (3)
En vi [m] está el !
comando que me permite canalizar texto a través de un comando de shell, como ordenar o sangrar, y recuperar el texto filtrado en el búfer. ¿Hay un equivalente en emacs?
Lo escribí hace unos años, podría ayudarte:
(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)))))
He encontrado que esta función es muy útil. Si también lo encuentras útil, sugiero que lo vincules a alguna tecla de función por conveniencia, personalmente uso F3
:
(global-set-key [f3] ''generalized-shell-command)
Puede seleccionar una región y escribir `Cu M- | comando RET '', y reemplaza la región con el resultado del comando en el mismo búfer debido al argumento de prefijo interactivo de shell-command-on-region.
Edición tardía : por mucho que aprecio los votos por contestar, la respuesta de Jurta es el camino a seguir. Y el truco de Greg es más limpio que el mío.
Dejaré el resto aquí porque podría valer algo, pero ...
Mx shell-command-on-region
, que parece estar vinculado a M-|
por defecto.
Veo que esto no hace exactamente lo que Rohit pidió. El uso de Ch f shell-command-on-region
revela que el comportamiento deseado está disponible en la versión no interactiva del comando (estableciendo el argumento replace
en non-nil). Deberíamos poder escribir un contenedor para hacer esto.
Pruebe esto (cárguelo en *scratch*
y ejecute Mx eval-buffer
, si funciona, cópielo en su archivo .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)
)
Y tenga en cuenta, como digo en los comentarios, que esto no es muy fácil de hacer. Pero creo que funciona
Para cualquier lector que no sepa cómo seleccionar una región:
- Mueva el "punto" (posición actual del cursor) a un extremo de la región, y use
C-space
para activar la "marca" - Mueva el punto al otro extremo de la región
- Hecho, invoque el comando