web-dev-qa-db-ja.com

Emacsに開始時に標準入力からバッファを読み取らせる方法は?

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
40
sastanin

正解です。標準入力からバッファを読み取ることはできません。

Emacsの情報ページでstdinについて言及しているのは this だけです。

バッチモードでは、Emacsは編集中のテキストを表示せず、C-zC-cなどの標準の端末割り込み文字は通常の効果を続けます。関数prin1princおよびprintは、エコー領域ではなくstdoutに出力しますが、messageおよびエラーメッセージはstderr。通常ミニバッファーから読み取る関数は、代わりにstdinから入力を受け取ります。

そして read 関数はstdinから読み取ることができますが、バッチモードでのみ可能です。

したがって、カスタムelispを作成してこれを回避することもできません。

15
Trey Jackson

プロセス置換 を使用できます:

$ emacs --insert <(echo 123)
36
Andrew Wood

ファイルにリダイレクトしてから、ファイルを開くことができます。例えば.

echo 123 > temp; emacs temp

jweedeは、一時ファイルを自動的に削除したい場合は、次のことができると述べています。

echo 123 > temp; emacs temp; rm temp

これを行うEmacsyの方法はEmacsでシェルコマンドを実行するです。

M-! echo 123 RET

これにより、* Shell Command Output *という名前のバッファーにコマンドの結果が表示されます。

14
Richard Hoskins

可能です https://stackoverflow.com/questions/2879746/idomatic-batch-processing-of-text-in-emacs を参照してください

以下は、emacsスクリプトのエコーです(上記のリンクからコピー)。

#!/usr/bin/emacs --script
(condition-case nil
    (let (line)
      (while (setq line (read-from-minibuffer ""))
        (princ line)
        (princ "\n")))
  (error nil))

またはそれをバッファに読み込んで、一度にすべて出力する

#!/usr/bin/emacs --script
(with-temp-buffer
  (progn
    (condition-case nil
    (let (line)
      (while (setq line (read-from-minibuffer ""))
        (insert line)
        (insert "\n")))
      (error nil))
    (princ (buffer-string))
    ))
9
cwitte

前の回答のいずれにも記載されていない別の可能性は、/dev/stdin選択したUnixバリアントに含まれている場合。

単に/dev/stdinは直接機能しません。Emacsがいくつかのチェックを行ってから報告するためですSymbolic link that points to nonexistent file。 (もしEmacsがあなたにファイルをロードすることを許可したとしたら、/dev/stdinは、ユーザーが期待したことをほとんど行いません。)

ただし、/dev/stdin とともに --insert引数は機能します:

echo 123 | emacs --insert /dev/stdin

このバージョンはXを使用する場合にのみ機能することに注意してください。ターミナルで機能するソリューションが必要な場合は、 別の回答 を参照することをお勧めします。

6
kasperd

それは 単純なシェル関数を作成することが可能 です。これは、stdinから読み取っているときに機能します(実際には一時ファイルに書き込んでから、それを読み取ります)。これが私が使っているコードです:

# The emacs or emacsclient command to use
function _emacsfun
{
    # Replace with `emacs` to not run as server/client
    emacsclient -c -n [email protected]
}

# 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 "[email protected]"
    fi
}

関数をemacsのエイリアスとして使用するだけです。

echo "hello world" | e -

または通常どおりファイルから

e hello_world.txt

関数のemacsemacsclientで置き換えることもできます。

6
dshepherd

オフハンド、次のようなもの:

$ echo 123 > tmp.txt; emacs tmp.txt

または

$ echo 123 > tmp.txt; emacs tmp.txt; rm tmp.txt

オプションです。 EmacsはvimのようにUNIXと統合しないだけです。

2
jweede