시작시 stdin에서 Emacs 읽기 버퍼를 만드는 방법은 무엇입니까?


40

Vim으로 쉽게 할 수 있습니다

$ echo 123 | vim -

이맥스와 관련이 있습니까?

$ 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

유닉스 파이프에서 버퍼를 읽는 것이 실제로 불가능합니까?

편집 : 솔루션으로 다음과 같은 쉘 래퍼를 작성했습니다 emacspipe.

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

답변:


15

stdin에서 버퍼를 읽는 것은 불가능합니다.

Emacs 정보 페이지에서 stdin에 대한 유일한 언급은 this입니다 .

배치 모드에서, 이맥스는 텍스트를 편집중인 표시되지 않으며, 같은 표준 터미널 인터럽트 문자 C-zC-c정상 영향을 계속한다. 기능 prin1, princprint 출력 stdout대신 에코 영역 반면 message, 오류 메시지를 출력 stderr. 미니 버퍼에서 일반적으로 읽는 함수는 stdin대신 입력을받습니다 .

그리고 read함수는에서 읽을 수 stdin있지만 배치 모드에서만 읽을 수 있습니다 .

따라서 맞춤 elisp를 작성하여이 문제를 해결할 수도 없습니다.


10
나는 누구에게도 무례하지 않다는 것을 의미하지만 이것은 끔찍하다. 이것은 매우 기본적인 편집기 기능이며 GNU EMACS는 수십 년 동안 사용되었습니다. 내장되어야합니다.
user787832

35

프로세스 대체를 사용할 수 있습니다 .

$ emacs --insert <(echo 123)

이것은 Vim 기능에 가장 가까운 해답입니다. 파이프 된 부분을 서브 프로세스 대체로 옮기는 것입니다.
dbmikus

@dbmikus 나는 내 것과 Tomasz Obrębski 사이에서 어느 것을 선호하는지 결정할 수 없다.
Andrew Wood

Tomasz의 결과 어떤 이유로 다음과 같은 오류가 발생합니다. emacs: standard input is not a tty
dbmikus

아 참으로! 나는 그가 게시하기 전에 테스트했다고 가정했다.
Andrew Wood

1
아마도 달에 따라 다릅니다.
dbmikus

14

파일로 리디렉션 한 다음 파일을 열 수 있습니다. 예 :

echo 123 > temp; emacs temp

jweede는 임시 파일을 자동으로 제거하려면 다음을 수행 할 수 있습니다.

echo 123 > temp; emacs temp; rm temp

Emacsy를 수행하는 방법 은 Emacs에서 shell 명령을 실행하는 것 입니다.

M-! echo 123 RET

그러면 명령 결과와 함께 * Shell Command Output *이라는 버퍼가 제공됩니다.


예, 나는 이맥스 방법이 있다는 것을 알고 있지만 그것이 유닉스 방식으로 사용될 수 있기를 바랍니다. 임시 파일을 만드는 것은 그리 좋은 옵션이 아닙니다 (나중에 삭제해야 함).
sastanin

1
같은 :echo 123 > temp; emacs temp; rm temp
jweede

2
일반적으로 Emacs와 Unix 사이에는 높은 임피던스가 있습니다. 또는 적어도 Emacs와 전통적인 Unix 워크 플로우 사이.
Richard Hoskins

2
@jweede M-을 추가하려면! 귀하의 답변 중 일부인 경우 답변을 삭제할 수 있습니다. 우리의 답변에는 겹치는 부분이 있지만 메타 뱅은 미래 독자들에게 중요하다고 생각합니다.
Richard Hoskins

1
현재 디렉토리에 temp가 이미 존재할 수 있지만 안전하지는 않습니다. 솔루션으로 래퍼를 작성했습니다 TMP=$(mktemp) && cat > $TMP && emacs23 $TMP ; rm $TMP. 모두 고마워요!
sastanin

9

가능합니다 https : //.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))
    ))

6

그건 간단한 쉘 기능을 만들 수 있습니다 (실제로는 그 읽기 임시 파일에 기록되어 있지만)이 표준 입력에서 읽고으로 작동합니다. 사용중인 코드는 다음과 같습니다.

# 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기능에하는 것은뿐만 아니라 작동합니다.


이것은 나에게 잘 작동하지만 _emacsfun은이어야 emacsclient -c -t $@하거나 최소한 -n 옵션을 삭제 해야합니다 . 맨 페이지와 함께 emacsclient -t --eval "(man \"$1\")" --eval "(delete-window)" (그리고 지금 당신은 helm-swoopMan Glory로 갈 수 있습니다!)
Alejandro

1
이것은 emacsclient로 작업 할 수있는 유일한 대답입니다. 기본 아이디어로 쉘 스크립트를 만들었으므로 i3 구성에서 호출 할 수 있습니다. +1
ergosys

6

이것은 작동합니다 :

echo 123 | emacs --insert <(cat)

그러나 어떤 이유로 든 그래픽 모드 이맥 (Gnome, Konsole, GNU Emacs 23.4.1) 만 사용합니다. 명령 :

echo 123 | emacs -nw --insert <(cat)

'emacs : 표준 입력이 tty가 아닙니다'오류가 발생합니다. 원시 텍스트 콘솔에서 시도 할 때 동일한 오류가 나타납니다.


echo 123 | exec emacs -nw --insert <(cat) </dev/tty작동해야합니다.
불꽃 폭발

작동합니다. 왜 exec인가? emacs -nw --insert <(echo 123) </ dev / tty
RoyM

Go go : Cygwin의 Emacs (w32)에서 아름답게 작동합니다. Cygwin에서는 다른 설정이 많지 않습니다
Charles Roberto Canato

5

이전 답변 중 언급되지 않은 또 다른 가능성은 /dev/stdin선택한 유닉스 변형이 있으면 사용 하는 것입니다.

/dev/stdinEmacs가 몇 가지 검사를 한 다음보고하기 때문에 직접 열기 만으로는 작동하지 않습니다 Symbolic link that points to nonexistent file. (그리고 Emacs가 파일을로드하도록 허용했다면 /dev/stdin, 사용자가 예상 한대로 거의하지 않는 것처럼 파일을 다시 저장하려고 시도하십시오 .)

그러나 인수 /dev/stdin와 결합 하면 효과 --insert가 있습니다.

echo 123 | emacs --insert /dev/stdin

이 버전은 X를 사용할 때만 작동합니다. 터미널에서 작동하는 솔루션이 필요한 경우 다른 답변을 참조하십시오 .


내가 가지고 emacs: standard input is not a tty리눅스와 BSD에서 테스트 메시지

1
@ Chinggis6 내 제안은 X11을 사용할 때만 작동하는 것 같습니다. 처음을 입력 unset DISPLAY하면 동일한 오류 메시지가 나타납니다.
kasperd

1
@ Chinggis6 X가 작동하려면 X가 필요하고 X 없이는 작동하는 응답을 가리 키도록 답변을
kasperd

2

손과 같은 것 :

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

또는

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

옵션입니다. Emacs는 vim처럼 UNIX와 통합되지 않습니다.


1
역사를 감안할 때 Emacs가 UNIX와 더 잘 통합되지 않는다는 사실과 UNIX의 주요 신조 중 하나가 "모든 것이 파일"이라는 것은 놀라운 일입니다. 출력을 Emacs로 직접 파이프하는 것은 직관적입니다.
SabreWolfy

5
@SabreWolfy GNU Emacs는 Unix에서 가장 일반적으로 호스팅되지만 Vim과 같은 방식으로 "Unix 프로그램"이 아니라 플랫폼 독립적 인 텍스트 편집기를 구현하는 Lisp 시스템입니다. (리차드 호스킨스의 답변을 참조하십시오.이 작업을 수행하는 "이맥스 방식"은 쉘 명령을 Emacs로 파이프하는 것이 아니라을 통해 Emacs에서 쉘 명령을 호출 M-!하여 결과 출력을 임시 버퍼에 자동으로 캡처하는 것입니다.) 전쟁은 제쳐두고, 어느 쪽의 편집자도 다른 편보다 더 낫다. 그들은 거의 모든 것에 대해 매우 다른 관점을 가지고 있습니다.
Aaron Miller

당신이 쉘에 있고 curl foo.bar | vim -.. 와 같은 것을하고 싶을 때를 제외하고는 미안합니다. curl foo.bar | emacs당신이 할 수 없다는 것을 제외하고는
dylnmc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.