如何讓 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-zC-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 Command Output* 的緩衝區,其中包含命令的結果。

答案4

它是可以建立一個簡單的 shell 函數它的工作原理是從標準輸入讀取(儘管實際上它是寫入臨時檔案然後讀取該檔案)。這是我正在使用的程式碼:

# 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

在函數中替換emacsby也有效。emacsclient

相關內容