Как заставить Emacs читать буфер из stdin при запуске?

Как заставить Emacs читать буфер из stdin при запуске?

С Vim я могу легко сделать

$ echo 123 | vim -

Возможно ли это сделать с помощью 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

Неужели невозможно прочитать буфер из канала Unix?

Редактировать: В качестве решения я написал оболочку под названием emacspipe:

#!/bin/sh
TMP=$(mktemp) && cat > $TMP && emacs23 $TMP ; rm $TMP

решение1

Правильно, невозможно прочитать буфер из stdin.

Единственное упоминание stdin на страницах с информацией об Emacs —этот, в котором говорится:

В пакетном режиме Emacs не отображает редактируемый текст, а стандартные символы прерывания терминала, такие как C-zи C-cпродолжают оказывать свое обычное действие. Функции prin1, princи print выводят данные stdoutвместо эхо-области, messageа сообщения об ошибках выводят данные в stderr. Функции, которые обычно считывают данные из минибуфера, вместо этого берут входные данные из stdin.

ИreadФункция может читать из stdin, но только в пакетном режиме.

Таким образом, вы даже не сможете обойти это, написав собственный elisp.

решение2

Вы могли бы использоватьзамена процесса:

$ emacs --insert <(echo 123)

решение3

Вы можете перенаправить на файл, а затем открыть файл. Например:

echo 123 > temp; emacs temp

jweede отмечает, что если вы хотите, чтобы временный файл был автоматически удален, вы можете:

echo 123 > temp; emacs temp; rm temp

Способ сделать это в Emacsy:для запуска команды оболочки в Emacs.

M-! echo 123 RET

Это даст вам буфер с именем *Shell Command Output*, содержащий результаты выполнения команды.

решение4

Еговозможно создание простой функции оболочкичто работает так, как будто читает из stdin (хотя на самом деле пишет во временный файл, а затем читает его). Вот код, который я использую:

# 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
}

Вы просто используете функцию как псевдоним для emacs, например

echo "hello world" | e -

или как обычно из файлов

e hello_world.txt

Замена emacsна emacsclientв функции тоже работает.

Связанный контент