
Mit Vim kann ich problemlos
$ echo 123 | vim -
Ist das mit Emacs möglich?
$ 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
Ist es wirklich unmöglich, einen Puffer aus einer Unix-Pipe zu lesen?
Bearbeiten: Als Lösung habe ich einen Shell-Wrapper mit dem Namen geschrieben emacspipe
:
#!/bin/sh
TMP=$(mktemp) && cat > $TMP && emacs23 $TMP ; rm $TMP
Antwort1
Richtig, es ist unmöglich, einen Puffer von stdin zu lesen.
Die einzige Erwähnung von stdin auf den Emacs-Infoseiten istDas, was sagt:
Im Batch-Modus zeigt Emacs den bearbeiteten Text nicht an und die Standard-Interruptzeichen des Terminals wie
C-z
undC-c
haben weiterhin ihre normale Wirkung. Die Funktionenprin1
,princ
undstdout
statt an den Echobereich aus, währendmessage
und Fehlermeldungen an ausgegeben werdenstderr
. Funktionen, die normalerweise aus dem Minipuffer lesen würden, beziehen ihre Eingabestdin
stattdessen von.
Und dasread
Die Funktion kann von lesen stdin
, aber nur im Batchmodus.
Sie können dies also nicht einmal umgehen, indem Sie benutzerdefiniertes Elisp schreiben.
Antwort2
Du könntest benutzenProzesssubstitution:
$ emacs --insert <(echo 123)
Antwort3
Sie können zu einer Datei weiterleiten und dann die Datei öffnen. Beispiel:
echo 123 > temp; emacs temp
jweede weist darauf hin, dass Sie Folgendes tun können, wenn Sie möchten, dass die temporäre Datei automatisch entfernt wird:
echo 123 > temp; emacs temp; rm temp
Mit Emacsy geht das so:um den Shell-Befehl in Emacs auszuführen.
M-! echo 123 RET
Dadurch erhalten Sie einen Puffer mit dem Namen *Shell-Befehlsausgabe* mit den Ergebnissen des Befehls.
Antwort4
Es istmöglich, eine einfache Shell-Funktion zu erstellendas funktioniert, als würde es von stdin lesen (obwohl es tatsächlich in eine temporäre Datei schreibt und diese dann liest). Hier ist der Code, den ich verwende:
# 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
}
Sie verwenden die Funktion einfach als Alias für Emacs, zB
echo "hello world" | e -
oder wie gewohnt aus Dateien
e hello_world.txt
Das Ersetzen emacs
durch emacsclient
funktioniert in der Funktion ebenfalls.