tutorial mac emacs text-editor elisp

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:

  1. Mueva el "punto" (posición actual del cursor) a un extremo de la región, y use C-space para activar la "marca"
  2. Mueva el punto al otro extremo de la región
  3. Hecho, invoque el comando