
Con Vim puedo hacer fácilmente
$ echo 123 | vim -
¿Es posible hacerlo con Emacs?
$ echo 123 | emacs23
... Emacs starts with a Welcome message
$ echo 123 | emacs23 -
... Emacs starts with an empty *scratch* buffer and “Unknown option”
$ echo 123 | emacs23 --insert -
... “No such file or directory”, empty *scratch* buffer
¿Es realmente imposible leer un búfer desde una tubería Unix?
Editar: Como solución, escribí un contenedor de shell llamado emacspipe
:
#!/bin/sh
TMP=$(mktemp) && cat > $TMP && emacs23 $TMP ; rm $TMP
Respuesta1
Correcto, es imposible leer un búfer desde la entrada estándar.
La única mención de stdin en las páginas de información de Emacs eseste, que dice:
En modo por lotes, Emacs no muestra el texto que se está editando y los caracteres de interrupción de terminal estándar como
C-z
yC-c
continúan teniendo su efecto normal. Las funcionesprin1
y envían a en lugar del área de eco, mientras queprinc
los mensajes de error se envían a . Las funciones que normalmente leerían desde el minibúfer toman sus entradas en su lugar.stdout
message
stderr
stdin
Y elread
La función puede leer desde stdin
, pero solo en modo por lotes.
Por lo tanto, ni siquiera puedes solucionar este problema escribiendo elisp personalizado.
Respuesta2
Podrías usarsustitución de procesos:
$ emacs --insert <(echo 123)
Respuesta3
Puede redirigir a un archivo y luego abrir el archivo. p.ej
echo 123 > temp; emacs temp
jweede señala que si desea que el archivo temporal se elimine automáticamente, puede:
echo 123 > temp; emacs temp; rm temp
La forma en que Emacsy hace esto espara ejecutar el comando shell en Emacs.
M-! echo 123 RET
Eso le proporciona un búfer llamado *Salida del comando Shell* con los resultados del comando.
Respuesta4
Esposible crear una función de shell simpleque funciona mientras lee desde la entrada estándar (aunque en realidad escribe en un archivo temporal y luego lo lee). Aquí está el código que estoy usando:
# The emacs or emacsclient command to use
function _emacsfun
{
# Replace with `emacs` to not run as server/client
emacsclient -c -n $@
}
# An emacs 'alias' with the ability to read from stdin
function e
{
# If the argument is - then write stdin to a tempfile and open the
# tempfile.
if [[ $# -ge 1 ]] && [[ "$1" == - ]]; then
tempfile="$(mktemp emacs-stdin-$USER.XXXXXXX --tmpdir)"
cat - > "$tempfile"
_emacsfun --eval "(find-file \"$tempfile\")" \
--eval '(set-visited-file-name nil)' \
--eval '(rename-buffer "*stdin*" t))'
else
_emacsfun "$@"
fi
}
Simplemente usa la función como alias para emacs, por ejemplo
echo "hello world" | e -
o como de costumbre desde archivos
e hello_world.txt
Reemplazar emacs
por emacsclient
en la función también funciona.