Como fazer o Emacs ler o buffer do stdin no início?

Como fazer o Emacs ler o buffer do stdin no início?

Com o Vim eu posso fazer facilmente

$ echo 123 | vim -

É possível fazer isso com o 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

É realmente impossível ler um buffer de um pipe unix?

Editar: Como solução, escrevi um wrapper chamado emacspipe:

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

Responder1

Correto, é impossível ler um buffer do stdin.

A única menção ao stdin nas páginas de informações do Emacs éesse, que diz:

No modo batch, o Emacs não exibe o texto que está sendo editado e o terminal padrão interrompe caracteres como C-ze C-ccontinua a ter seu efeito normal. As funções prin1e saída para princem vez da área de eco, enquanto e mensagens de erro são enviadas para . Funções que normalmente seriam lidas no minibuffer recebem suas entradas .printstdoutmessagestderrstdin

E areadA função pode ler stdin, mas apenas no modo em lote.

Então, você não pode nem contornar isso escrevendo um elisp personalizado.

Responder2

Você poderia usarsubstituição de processo:

$ emacs --insert <(echo 123)

Responder3

Você pode redirecionar para um arquivo e abri-lo. por exemplo

echo 123 > temp; emacs temp

jweede observa que se quiser que o arquivo temporário seja removido automaticamente, você pode:

echo 123 > temp; emacs temp; rm temp

A maneira do Emacsy de fazer isso épara executar o comando shell no Emacs.

M-! echo 123 RET

Isso fornece um buffer chamado *Shell Command Output* com os resultados do comando.

Responder4

Isso épossível criar uma função shell simplesque funciona enquanto lê stdin (embora na verdade esteja gravando em um arquivo temporário e depois lendo-o). Aqui está o código que estou 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
}

Você apenas usa a função como um alias para o emacs, por exemplo

echo "hello world" | e -

ou normalmente a partir de arquivos

e hello_world.txt

Substituir emacspor emacsclientna função também funciona.

informação relacionada