Yardımdan Emacs kaynak koduna göz atarken salt görüntüleme moduna nasıl girilir?


10

İşlevler için Emacs yardımına C-h fgöz attığımda, genellikle Elisp / C uygulamasına bakmak istiyorum. view-modeGereksiz değişikliklerden kaçınmak için kaynak koduna bu şekilde eriştiğimde otomatik olarak girmek istiyorum . Bunu yapmak için önerebileceğim bir kanca veya fonksiyon var mı?


2
İşte açılan dosyalarımın herhangi birinde yanlışlıkla değiştirilmesini önlemek için kullandığım emacs-lisp-modeve sadece C-x C-qkaynak kodunu düzenlemek istersem yapacağım. (defun set-buffer-read-only () (setq buffer-read-only t)) (add-hook 'emacs-lisp-mode-hook 'set-buffer-read-only)
hukukçu

Yanıtlar:


2

Güncelleme (bir gece uykusundan sonra): Bu cevabın büyük bir kusuru vardır: sadece Emacs kaynaklarına değil, herhangi bir işleve view-modegiderken de etkinleştirir . Bu düzeltilebilir, ancak @phils tarafından verilen cevabı kullanmanız daha iyi olur .

Yaparak C-h f describe-function RETve daha sonra kaynak kodunu okuyarak describe-functionI o fonksiyon tanımları bağlantılar için özel bir türde bir "renkli" yarattığını keşfetti: help-function-def.

zrgrepBu ip ile koşmak (" help-function-def") beni işaret etti help-mode.el.gz.

Tüm bu kazma işleminden sonra bu düğme türünü kendi kodumuzla değiştirebiliriz (koddaki açıklamaya dikkat edin):

(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"))

Anlayabildiğim kadarıyla tavsiye eklemek için bir işlev yok: Emacs lambdaburada kullanıyor . Öte yandan ( @rationalrevolt tarafından işaret edildiği gibi ) help-function, help-function-defdüğme türünün özelliği değiştirilebilir :

(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
Sanırım lambda'yı mevcut lambdaya yönlendiren kendi lambamı kullanmaya button-type-getve button-type-putdeğiştirmeye çalışabilirim .
rationalrevolt

@rationalrevolt: İyi fikir! (Biraz kırılgan görünüyor, ama sanırım bu da kırılgan.)
Konstantin

@rationalrevolt: Lütfen güncellenmiş cevaba bakınız. (Yorumlarda yeni satırlar olamaz, öyle görünüyor ...)
Konstantin

Teşekkürler! Ben benzer bir şey deniyordu ama elisp için bir acemi olmak dinamik bağlama tarafından ısırıldı ve çalışmak için benim kapanış alamadım :)
rationalrevolt

16

Emacs'ın kaynak dosyalarını varsayılan olarak salt okunur yapmak için dizin-yerel değişkenleri kullanabilirsiniz. (Ayrıca bakınız C-hig (emacs) Directory Variables RET).

.dir-locals.elAşağıdaki içeriklerle korumak istediğiniz dizin ağacının kökünde adlı bir dosya oluşturun :

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

Düzenleme: Michał Politowski view-mode, bu şekilde etkinleştirmenin sorunlu olduğunu belirtiyor , çünkü arabelleği kapattığınızda qmodu da devre dışı bırakıyor, yani bir sonraki ziyaretinizde bu tampon view-modeetkinleştirilmeyecek.

Edit 2: Constantine, aşağıdaki yorumlarda bu soruna bir çözüm sundu:

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

Bu, ara belleğin zaten bir dosyayı ziyaret ettiğinden emin olmak için bir test ekler, ancak anahtar değişikliği, view-mode-enteryerine yazıldığında ne yapılacağını belirleyen view-modebir EXIT-ACTIONargüman aldığından bunun yerine kullanımıdır q. Bu durumda, çıkış eylemi arabelleği öldürmek ve dosyanın bir sonraki ziyaretinde dosyanın tekrar sonuçlanmasını sağlamaktır view-mode.

Düzenleme 3: Bu yolu takip ederek, belirtilenin EXIT-ACTIONsonuçta view-mode-exitişleve geçtiğini ve doktrinin bize alternatif bir çözüm sunduğunu da görebiliriz :

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.

Bu nedenle aşağıdakileri kullanabiliriz:

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

Tamamen init dosyanızda (dosya oluşturmanın aksine) belirtebileceğiniz alternatif yaklaşımı kullanıyorum ve .dir-locals.eldosyaları kullanmak yerine salt okunur hale getiriyorum view-mode. Benim yapılandırma şöyle görünür:

;; 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)

Aynı şeyi elpa dizininiz ve üçüncü taraf kaynak kodu içeren diğer dizinler için de yapabilirsiniz.


Harika! Bu, ortaya çıkardığımdan daha iyi. (Ne düşünüyordum? Kendimi tanıyorum ve kullanıyorum .dir-locals.el...)
Konstantin

A find-file-hookve read-only-dirslisteye dayanan aynı çizgide bir şey oldum , ama bu yaklaşımı seviyorum.
glucas

Bu çok temiz bir yaklaşım gibi görünüyor. Ama küçük bir sorunum var. İle ((nil . ((eval . (view-mode 1)))))yapmak için en basit yolu nedir View-quityardım aracılığıyla erişilen tampon öldürmek? Aksi takdirde, kaynak görünümünden düğmesine basıldıktan qsonra arabellek geride kalır ve daha sonra aynı dosyadan gelen kaynaklara yardımdan yeniden erişildiğinde, görünüm modu başlatılmaz.
Michał Politowski

Michał Politowski: Haklısın. Bu gerçeği dahil etmek için cevabı güncelledim, ancak bir çözümüm yok. Constantine'ın (düzenlenmiş) yanıtı kullanmak için en iyi çözüm olabilir view-mode.
phils

1
Bugün @ MichałPolitowski'nin işaret ettiği sorun için bir çözüme ihtiyacım olduğunu anladım ve bir tane buldum: kullanım ((nil . ((eval . (when buffer-file-name (view-mode-enter nil #'kill-buffer))))))(not (view-mode-enter ...)yerine (view-mode 1)). Basarak Bu şekilde qtampon öldürür ve view-mode bir ben aynı dosyayı bir sonraki ziyaretinizde sağladı.
Konstantin

0

Tek ihtiyacınız olan bir kanca eklemek olduğunu düşünüyorum :

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

Bu benim canavarlığımdan daha iyi, ama yine de soru ile gerçekten eşleşmiyor: sadece Emacs kaynaklarını değil, herhangi bir işleve view-modegiderken yanar . C-h f
Konstantin

Deneysel olarak, yardım bağlantıları aslında bu kancayı çalıştırmaz. find-THINGBu kancayı yalnızca etkileşimli komutlar kullanıyor ve yardım düğmeleri atlıyor.
phils

0

Bu, özel durumunuzu değil, view-modebir yardım arabelleğinden bir kaynak dosyasını her ziyaret ettiğinizde geçiş yapmanın daha genel örneğidir . @ Constantine'ın cevabına alternatif olarak sunuyorum, çünkü yorum olarak okunamıyor.

Görünüşe göre bunu EmacsWiki'den aldım .

(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

Yerleşik belgeler için çalışan bir çözüm ve bunu ELPA'ya nasıl genişleteceğinizi gösteren bir örnek. Bazı normal ifadelere karşı geçerli dosyanın yolunu eşleştirerek ve read-only-modebunlardan herhangi biri eşleşiyorsa uygulayarak çalışır.

Yalnızca diredyardım yoluyla değil, aynı zamanda ziyaret ederseniz ara belleğin salt okunur olduğunu unutmayın .

emacs-lisp-modeDosyaya giden yolun eşleşip eşleşmediğini kontrol eden girdikten sonra çalışan bir kanca ekledim /\.el\.gz$/ve varsa salt okunur modu uyguladım.

(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)

Aşağıda, içeren herhangi bir yolun .emacs.d/elpaaslında ELPA kodu olduğu sezgisel yöntemini kullanarak ELPA'yı kontrol eden bir örnek verilmiştir .

(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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.