emacs 내에서 emacs를 다시 시작하십시오


44

이맥스를 많이 다시 시작합니다. 내가하고 싶은 것은 현재 emacs를 죽이는 대신 새로운 emacs를 생성하는 함수를 만드는 것입니다. 이상적으로는 TTY에서도 작동합니다.


8
호기심 때문에 왜 그렇게 자주 죽이고 다시 시작합니까?
Dan

2
나는 매우 적극적으로 개발 .emacs.d하고 있습니다. 즉, 환경에 폭발 한 모든 쓰레기를 제거하기 위해 이맥스를 다시 시작합니다. 이 작업을 수행하는 다른 사용 사례가 몇 가지 있지만 가장 큰 것입니다.
PythonNut

1
@PythonNut, 나는 당신이 당신의 질문을 조금 재구성해야한다고 생각합니다. bash종료 후 다시 시작 하라고 말할 수 있습니까 ? 아니면 vi? 아니면 원칙적으로 다른 프로세스가 있습니까? 아니요, 이는 해당 범위를 벗어나며 외부에서 올바르게 처리되기 때문입니다. 어쨌든, 실제로 원하는 것은 VM을 지우고 프로세스를 종료 하지 않고 init 코드를 다시 실행하여 emacs 를 다시 초기화 하는 방법 입니다. 그것은 이맥스에게 유용하고 적절할 것입니다. 그래도 존재하는지 모르겠습니다 :)
harpo

4
@ harpo 예, bash로 다시 시작할 수 있습니다 exec bash. 나는 vim에 대해 전혀 모른다.
PythonNut

11
FWIW, 나는 Emacs 의 인스턴스 를 시작하여 구성 변경을 테스트하는 대신 종료하고 다시 시작하는 경향이 있습니다. 왜? 내 코드에 오류가 있으면 Emacs가 다시 시작할 때 구성을로드하지 못할 수 있으며 그 시점에서 실제로는 기본 설정으로 실행중인 인스턴스를 얻을 수 없으므로 익숙하지 않은 편집을 사용해야합니다 버그를 수정하는 환경. 자주 발생하지는 않지만 성가시다. emacs -q물론 문제를 실행 하고 해결할 수는 있지만 구성을 해킹 할 때 항상 안전하기 위해 항상 '좋은'인스턴스를 실행하는 것을 선호합니다.
phils

답변:


25

참고 : 여기에restart-emacs 사용 가능한 패키지로 다음을 포장했습니다 .


다음은 순수한 elisp를 사용하여 원하는 것을 얻는 다른 방법입니다 (실제로 쉘에 의존하기 때문에 아닙니다). 트릭은 현재 이맥스가 죽기 직전에 다른 이맥스 프로세스를 생성하는 것입니다.

(defun launch-separate-emacs-in-terminal ()
  (suspend-emacs "fg ; emacs -nw"))

(defun launch-separate-emacs-under-x ()
  (call-process "sh" nil nil nil "-c" "emacs &"))

(defun restart-emacs ()
  (interactive)
  ;; We need the new emacs to be spawned after all kill-emacs-hooks
  ;; have been processed and there is nothing interesting left
  (let ((kill-emacs-hook (append kill-emacs-hook (list (if (display-graphic-p)
                                                           #'launch-separate-emacs-under-x
                                                         #'launch-separate-emacs-in-terminal)))))
    (save-buffers-kill-emacs)))

emacs의 GUI 버전을 시작하는 코드는 간단합니다. 터미널에서 emacs를 시작하는 코드는 약간 까다 롭습니다. suspend-emacs터미널 입력으로 전달 될 문자열을 상위 프로세스 (쉘)에 전달할 수 있다는 사실을 사용합니다 . 설명서에서

(일시 중단 및 선택 사항 STUFFSTRING)

Emacs를 중지하고 우수한 프로세스로 돌아갑니다. 나중에 다시 시작할 수 있습니다. `susnot-suspend '가 non-nil이거나 시스템이 작업 제어를 지원하지 않으면, 대신 서브 쉘을 실행하십시오.

선택적인 arg STUFFSTRING이 0이 아닌 경우, 문자는 일시 중단 후 Emacs의 상위에서 터미널 입력으로 읽도록 채워집니다.

따라서 기본적으로 emacs가 종료되기 직전에 emacs를 일시 중단하여 상위 쉘에 현재 일시 중단 된 emacs를 재개하고 (곧 종료 될 예정 임) 다른 emacs 프로세스를 시작하십시오. 이것은 터미널 emacs가 실제로 일시 중단되지 않고 서브 쉘을 시작하는 플랫폼 (예 : Windows)에서는 작동하지 않습니다.


이것은 나를 위해 작동하지 않습니다 : sh -c "emacs &"쉘에서 실행 하면 " emacs: standard input is not a tty"로 중지됩니다 . ( M-x restart-emacs이 오류 메시지가 표시되지 않으면 Emacs가 종료됩니다.)
Constantine

X에서 작동합니다. stdin 및 stdout을 / dev / null로 리디렉션하기 때문에 터미널에서 작동하지 않습니다. 부모 tty를 서브 프로세스에 전달하는 것은 가능하지만 까다로울 수 있습니다.
Beni Cherniavsky-Paskin

1
이것은 완벽하게 작동하며 실제로 약간 무섭습니다. 지구상에서 Emacs가 포함 된 쉘에 명령을 전달할 수있는 이유는 무엇입니까?
Radon Rosborough

어떤 키 바인딩을 사용합니까?
slk500

32

내가 아는 한, Emacs가 종료 후 다시 시작하도록 할 수는 없지만, Emacs를 처음 시작한 프로세스가 다시 시작하려는 것을 감지 할 수 있도록 종료 코드를 설정할 수 있습니다.

예를 들어,이 쉘 스크립트는 코드 123으로 종료 된 경우 Emacs를 다시 시작합니다.

#!/bin/sh
while emacs -nw "$@"; [ $? = 123 ]; do :; done

다음으로, 우리 kill-emacs-and-restart는 Emacs가 종료 코드를 스크립트가 인식하는 매직 넘버와 같은 것으로 종료하도록 정의 합니다 :

(defun kill-emacs-and-restart ()
  (interactive)
  (kill-emacs 123))

이제이 스크립트를 통해 Emacs를 실행하면 다시 시작 M-x kill-emacs-and-restart하거나 키 시퀀스에 바인딩 할 수 있습니다.


문제를 둘러싼 좋은 방법! 이유를 말씀해 주시면이 내용을 수락하겠습니다 you cannot tell Emacs to re-start after terminating. 이것이 기술적 한계입니까?
PythonNut

3
@ PythonNut : 프로세스를 다시 시작하는 유일한 방법은 exec...POSIX 시스템 에서 패밀리 의 기능 중 하나를 사용하는 것입니다 . Emacs Lisp 프로세스 제어 기능 은 이러한 저수준 호출을 노출시키지 않습니다. 그러나 나는 전문가가 아니기 때문에 더 많은 지식이있는 사람이 들어올 수 있기를 바랍니다.
Constantine

2

명백히 https://unix.stackexchange.com/questions/114238/is-it-possibe-to-change-parent-shells-working-directory-programmatically 에서 도난당했습니다.

문자열에 "을 포함시키는 구문이 맞다고 가정하면 이렇게해야합니다.

(defun restart-emacs ()
  (call-process "sh" nil nil nil "-c" "gdb -p $(ps h -o ppid -p $$) -ex 'call execl(\"/bin/sh\", \"/bin/sh\", \"-c\", \"exec emacs\")'"))

11
제발 하지마 이는 모든 Emacs의 내부 정리를 무시 하고 확인없이 모든 현재 상태 (예 : 수정 된 버퍼) 버립니다 .
lunaryorn

lunaryorn의 경고가 정확합니다.
Joshua
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.