如何让 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管道读取缓冲区真的不可能吗?

编辑:作为解决方案,我编写了一个名为的 shell 包装器emacspipe

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

答案1

正确,不可能从标准输入读取缓冲区。

Emacs 信息页面中唯一提到 stdin 的是,其中写道:

在批处理模式下,Emacs 不显示正在编辑的文本,标准终端中断字符(如C-z和)C-c继续发挥其正常作用。函数prin1princprint 输出到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 中运行 shell 命令

M-! echo 123 RET

这会为您提供一个名为 *Shell 命令输出* 的缓冲区,其中包含命令的结果。

答案4

它是可以创建一个简单的 shell 函数它的工作原理是读取 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

相关内容