回答:
更新(夜の睡眠後):この回答には大きな欠陥があります。Emacsソースだけでなく、任意の関数view-mode
に移動するときに有効になります。これは修正できますが、@ philsの回答を使用したほうがよいでしょう。
実行してC-h f describe-function RET
からソースコードを読み取ると、describe-function
関数定義へのリンク用の特別なタイプの「ボタン」が作成されることがわかりました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
hereを使用します。一方(@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))))
button-type-get
とbutton-type-put
、既存のラムダに転送することを自分でラムダを交換します。
デフォルトでは、ディレクトリローカル変数を使用して、Emacsのソースファイルを読み取り専用にすることができます。(も参照C-hig (emacs) Directory Variables
RET)。
.dir-locals.el
保護するディレクトリツリーのルートで呼び出されるファイルを作成し、次の内容を含めます。
((nil . ((eval . (view-mode 1)))))
編集: MichałPolitowskiはコメントで指摘しているようにview-mode
、この方法で有効にすると問題が発生します。これを使用してバッファーを閉じるとq、モードも無効になるため、次回そのバッファーにアクセスしたときview-mode
に有効にならないためです。
編集2:コンスタンティンは、以下のコメントでその問題の解決策を提供しています:
((nil . ((eval . (when buffer-file-name (view-mode-enter nil #'kill-buffer))))))
これが有効にバッファがすでにファイルを訪問していることを確認するためのテストが追加されますが、キーの変更は、の使用であるview-mode-enter
代わりに、view-mode
前者がかかるとして、EXIT-ACTION
ときに何をすべきかを決定する引数q入力されています。この場合、終了アクションはバッファを強制終了することであり、次回ファイルにアクセスしたときに、再びバッファが終了するようにしview-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))))))
(ファイルを作成するの.dir-locals.el
ではなく)initファイルで完全に指定できる別の方法を使用し、を使用するのではなく、単にファイルを読み取り専用にし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
自分自身を使います...)
find-file-hook
とread-only-dirs
listに基づいて同じことをやっていますが、このアプローチが好きです。
((nil . ((eval . (view-mode 1)))))
にする最も簡単な方法は何かView-quit
の助けを介してアクセスバッファを殺しますか?それ以外の場合、を押してソースビューを終了した後q
、バッファは遅れたままになり、後でヘルプから同じファイルのソースに再度アクセスしても、ビューモードは開始されません。
view-mode
。
((nil . ((eval . (when buffer-file-name (view-mode-enter nil #'kill-buffer))))))
(の(view-mode-enter ...)
代わりに注意(view-mode 1)
)。押すとこのようにq
、バッファを殺すとview-mode
された私は、同じファイルを訪問する次の時間を可能にしました。
これは特定のケースではなく、view-mode
ヘルプバッファからソースファイルにアクセスするたびに切り替わる、より一般的なケースです。コメントとして読むことができなかったので、@ Constantineの回答の代わりとして提供しています。
(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)))
以下は、組み込みのドキュメントで機能するソリューションと、それを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)
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)