도움말에서 Emacs 소스 코드를 탐색 할 때보기 전용 모드로 들어가는 방법은 무엇입니까?


10

를 통해 Emacs 도움말을 탐색 할 때 C-h f종종 Elisp / C 구현을 살펴보고 싶습니다. view-mode불필요한 수정을 피하기 위해이 방법으로 소스 코드에 액세스 할 때 자동으로 입력하고 싶습니다 . 이것을 달성하기 위해 조언 할 수있는 후크 또는 기능이 있습니까?


2
다음은 열린 파일을 실수로 수정하는 것을 방지하기 위해 사용하는 것이며 소스 코드를 편집하려는 경우 emacs-lisp-mode에만 수행 C-x C-q합니다. (defun set-buffer-read-only () (setq buffer-read-only t)) (add-hook 'emacs-lisp-mode-hook 'set-buffer-read-only)
lawlist

답변:


2

업데이트 (야간 후) : 이 답변에는 큰 결함이 있습니다. 이맥스 소스뿐만 아니라 모든 기능을 view-mode탐색 할 때 가능 합니다. 이 문제는 해결 될 수 있지만 @phils 의 답변을 사용 하는 것이 좋습니다 .

이렇게함으로써 C-h f describe-function RET다음의 소스 코드를 읽기 describe-functionI를이 함수 정의에 대한 링크는 특별한 유형의 "버튼"을 생성하는 발견했다 help-function-def.

zrgrep이 문자열 ( " help-function-def")로 실행 하면을 가리 켰습니다 help-mode.el.gz.

이 모든 것을 파고 나면이 버튼 유형을 자체 버튼으로 바꿀 수 있습니다 (코드의 주석 참고).

(define-button-type 'help-function-def
  :supertype 'help-xref
  'help-function (lambda (fun file)
               (require 'find-func)
               (when (eq file 'C-source)
                 (setq file
                       (help-C-file-name (indirect-function fun) 'fun)))
               ;; Don't use find-function-noselect because it follows
               ;; aliases (which fails for built-in functions).
               (let ((location
                      (find-function-search-for-symbol fun nil file)))
                 (pop-to-buffer (car location))
                 (if (cdr location)
                     (goto-char (cdr location))
                   (message "Unable to find location in file")))
                   (view-mode t)) ; <= new line: enable view-mode
  'help-echo (purecopy "mouse-2, RET: find function's definition"))

내가 알 수있는 한 조언을 추가 할 기능이 없습니다 : Emacs는 lambda여기를 사용합니다 . 반면에 @rationalrevolt 로 지적한 것처럼 버튼 유형 의 help-function속성을 바꿀 수 있습니다 help-function-def.

(require 'help-mode)
(let ((help-func (button-type-get 'help-function-def 'help-function)))
  (button-type-put 'help-function-def 'help-function
                   `(lambda (func file)
                      (funcall ,help-func func file) (view-mode t))))

1
나는 람다를 기존 람다로 전달하는 내 자신의 람다 를 사용 button-type-get하고 button-type-put교체 하려고 시도 할 수 있다고 생각 합니다.
rationalrevolt

@rationalrevolt : 좋은 생각이야! (약간 깨지기 쉬운 것 같지만, 이것도 깨지기 쉬운 것 같습니다.)
Constantine

@rationalrevolt : 업데이트 된 답변을 참조하십시오. (의견에 줄 바꿈을 할 수는 없습니다 ...)
Constantine

감사! 나는 비슷한 시도하지만있는 초보자를 내가 동적 바인딩에 물린 된 elisp하고 :) 일 내 폐쇄 얻을 수 있었다
rationalrevolt

16

디렉토리 로컬 변수 를 사용하여 기본적으로 Emacs의 소스 파일을 읽기 전용으로 만들 수 있습니다 . (도 참조 C-hig (emacs) Directory Variables RET).

.dir-locals.el보호하려는 디렉토리 트리의 루트에서 다음 내용 으로 파일을 작성하십시오 .

((nil . ((eval . (view-mode 1)))))

편집 : Michał Politowski view-mode는이 방법으로 활성화 하면 문제가 있음을 q지적 합니다. 버퍼를 해제하면 모드도 비활성화되므로 다음에 버퍼를 방문 할 view-mode때 활성화되지 않습니다.

편집 2 : Constantine은 아래 주석에서 해당 문제에 대한 해결책을 제공했습니다.

((nil . ((eval . (when buffer-file-name (view-mode-enter nil #'kill-buffer))))))

이것은 버퍼가 이미 파일을 방문하고 있는지 확인하는 테스트를 유용하게 추가하지만 , 전자 가 입력 될 때 수행 할 작업을 결정 하는 인수를 사용하므로 키 변경은 view-mode-enter대신 대신 사용하는 것입니다 . 이 경우 종료 조치는 버퍼를 강제 종료하여 다음에 파일을 방문 할 때 파일이 다시 종료되도록합니다 .view-modeEXIT-ACTIONqview-mode

편집 3 : 해당 경로를 따라 지정된 함수 EXIT-ACTION가 궁극적으로 view-mode-exit함수에 전달되고 docstring이 대체 솔루션을 제공 한다는 것을 알 수 있습니다 .

view-no-disable-on-exit is a variable defined in `view.el'.
Its value is nil

Documentation:
If non-nil, View mode "exit" commands don't actually disable View mode.
Instead, these commands just switch buffers or windows.
This is set in certain buffers by specialized features such as help commands
that use View mode automatically.

따라서 다음을 사용할 수 있습니다.

((nil . ((eval . (when buffer-file-name
                   (setq-local view-no-disable-on-exit t)
                   (view-mode-enter))))))

파일을 작성하는 대신 init 파일에 완전히 지정할 수있는 대체 방법을 .dir-locals.el사용하고 파일을 사용하지 않고 읽기 전용으로 만듭니다 view-mode. 내 구성은 다음과 같습니다.

;; Emacs
(dir-locals-set-class-variables
 'emacs
 '((nil . ((buffer-read-only . t)
           (show-trailing-whitespace . nil)
           (tab-width . 8)
           (eval . (whitespace-mode -1))))))

(dir-locals-set-directory-class "/usr/local/src/emacs" 'emacs)
(dir-locals-set-directory-class "/usr/local/share/emacs" 'emacs)
(dir-locals-set-directory-class "/usr/share/emacs" 'emacs)

분명히 elpa 디렉토리와 타사 소스 코드가 포함 된 다른 디렉토리에 대해 동일한 작업을 수행 할 수 있습니다.


큰! 이것은 내가 생각해 낸 것보다 분명히 낫습니다. (내가 무엇을 생각하고 있 었는가? .dir-locals.el나 자신을 알고 사용 한다 ...)
Constantine

나는 a find-file-hookread-only-dirs목록을 기반으로 같은 줄을 따라 왔지만이 접근법을 좋아합니다.
glucas

이것은 매우 깨끗한 접근법처럼 보입니다. 그래도 사소한 문제가 하나 있습니다. 로 ((nil . ((eval . (view-mode 1)))))만들 수있는 간단한 방법은 무엇인가 View-quit도움을 통해 액세스 할 수있는 버퍼를 죽일 수는? 그렇지 않으면을 눌러 소스보기를 종료 한 후 q버퍼가 유지되고 나중에 도움말에서 동일한 파일에서 소스에 액세스 할 때 다시보기 모드가 시작되지 않습니다.
Michał Politowski

Michał Politowski : 맞습니다. 그 사실을 통합하기 위해 답변을 업데이트했지만 해결 방법이 없습니다. Constantine의 (편집 된) 답변은을 사용하는 가장 좋은 솔루션 일 수 있습니다 view-mode.
phils

1
오늘 나는 @ MichałPolitowski가 지적한 문제에 대한 해결 방법이 필요하다는 것을 알았습니다 .- 하나를 사용했습니다 : use ((nil . ((eval . (when buffer-file-name (view-mode-enter nil #'kill-buffer))))))( (view-mode-enter ...)대신에 note (view-mode 1)). 누르면 이런 식으로 q버퍼를 죽이고 view-mode 있다 내가 같은 파일을 방문 할 때 할 수 있었다.
Constantine

0

나는 당신이 필요한 모든 후크 를 추가하는 것 같아요 :

(add-hook 'find-function-after-hook 'view-mode)

이것은 나의 괴물보다 더 나은,하지만 여전히 정말 질문을 일치하지 않습니다이 켜집니다 view-mode를 탐색 할 때 어떤 사용하는 기능 C-h f뿐만 아니라 이맥스 소스를.
콘스탄틴

실험적으로 도움말 링크는 실제로이 후크를 실행하지 않습니다. 대화식 find-THING명령 만이 후크를 사용 하는 것처럼 보이고 도움말 단추가이를 무시합니다.
phils

0

이것은 특정한 경우를 다루지는 않지만 view-mode도움말 버퍼에서 소스 파일을 방문 할 때마다 전환하는보다 일반적인 경우입니다 . 나는 주석으로 읽을 수 없기 때문에 @Constantine의 답변에 대한 대안으로 제공하고 있습니다.

나는 원래 EmacsWiki 에서 이것을 얻은 것 같습니다 .

(defadvice find-function-search-for-symbol (after view-function-source last (symbol type library) activate)
  "When visiting function source via Help, switch to view-mode"
  (with-current-buffer (car ad-return-value)
    (view-mode 1)))

(defadvice find-variable-noselect (after view-var-source last (variable &optional file) activate)
  "When visiting variable source via Help, switch to view-mode"
  (with-current-buffer (car ad-return-value)
    (view-mode 1)))

0

다음은 내장 문서에 적합한 솔루션과 ELPA로 확장하는 방법을 보여주는 예입니다. 현재 파일의 경로를 일부 정규 표현식과 read-only-mode일치시키고 일치하는 경우 적용하여 작동합니다.

dired도움말뿐 아니라 방문해도 버퍼는 읽기 전용 입니다.

입력 후 실행되는 후크를 추가 emacs-lisp-mode하여 파일 경로가 일치하는지 확인 /\.el\.gz$/하고 일치하는 경우 읽기 전용 모드를 적용합니다.

(defun readonly-if-el-gz ()
  (cond
   ((string-match "\\.el\\.gz\\'" (or (buffer-file-name) ""))
    (read-only-mode +1))))

(add-hook 'emacs-lisp-mode-hook 'readonly-if-el-gz)

다음 .emacs.d/elpa은 포함하는 경로 가 실제로 ELPA 코드 라는 휴리스틱을 사용하여 ELPA도 검사하는 예입니다 .

(defun readonly-if-internal ()
  (let
      ((name (or (buffer-file-name) "")))
    (cond
     ((string-match "\\.el\\.gz\\'" name) (read-only-mode +1))
     ((string-match "\\.emacs\\.d/elpa" name) (read-only-mode +1)))))

(add-hook 'emacs-lisp-mode-hook 'readonly-if-internal)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.