Wie bringt man Emacs dazu, den Puffer beim Start von der Standardeingabe zu lesen?

Wie bringt man Emacs dazu, den Puffer beim Start von der Standardeingabe zu lesen?

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-zund C-chaben weiterhin ihre normale Wirkung. Die Funktionen prin1, princund print geben an stdoutstatt an den Echobereich aus, während messageund Fehlermeldungen an ausgegeben werden stderr. Funktionen, die normalerweise aus dem Minipuffer lesen würden, beziehen ihre Eingabe stdinstattdessen von.

Und dasreadDie 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 emacsdurch emacsclientfunktioniert in der Funktion ebenfalls.

verwandte Informationen