Dizinli arabelleklerde, noktayı bu dizinin en önemli dosyasına yerleştirin


14

Emacs'ta bir dizini ziyaret ettiğim zamanın% 90'ı, yaptığım ilk şey, noktayı belirli bir dosyaya taşımak ve açmak. Çoğu zaman açmam gereken dosya çok tahmin edilebilir. Örneğin:

  • .texBu dizinde dosyalar varsa , genellikle doğrudan gidin master.tex.
  • Android projelerinin kökeninde, genellikle AndroidManifest.xml.
  • Bir emacs paketi geliştirdiğim bir dizinde, neredeyse her zaman paketin ana kaynak dosyasıdır. Bu genellikle, ancak her zaman değil, .elbu dizindeki tek dosyadır.

Bu dizinleri açtığımda bu dosyaların üzerine otomatik olarak nokta yerleştirebileceğim bir yol var mı?

Bu, (sadece vurarak açabileceğim gibi) çok fazla kolaylık sunacaktı RET, ancak yine de diğer dosyaları ziyaret etme esnekliğini verecekti.

Yanıtlar:


16

İçin özel bir işlev yazın dired-initial-position-hook. Bu işlevde, dosyaları aramak için çeşitli yön işlevlerini kullanabilir ve sonunda dired-goto-filenoktayı "en iyi" dosyaya taşımak için çağırabilirsiniz :

(defun my-dired-goto-important-file ()
  "Go to an important file in the current dired buffer."
  (unless (bound-and-true-p save-place)
    (let ((candidates '("master.tex" "AndroidManifest.xml"))
          candidate)
      (while (and candidates
                  (not (dired-goto-file (expand-file-name (pop candidates)))))
        nil))))

(add-hook 'dired-initial-position-hook #'my-dired-goto-important-file)

Aşağıda bu işlevin belirli yönlerini açıklayacağım ve potansiyel uzantıları vurgulayacağım.

Dosyalara atlama

dired-goto-filenildosya geçerli dired arabelleğinde yoksa geri döner , bu yüzden önceden kontrol etmeden aramak güvenlidir. Bununla birlikte dired-goto-file, mutlak bir dosya adı gerektirir (göreli adlarda hata yapar) expand-file-name.

Dosya arama

Dired, dosyaları aramak için basit bir API sağlamaz. Genellikle, tıpkı bir arabellekteki tüm satırlarda yinelediğiniz gibi tüm dosyalar üzerinde yineleme yapabilirsiniz:

(let (files)
  (goto-char (point-min))
  (while (not (eobp))
    (let ((filename (dired-get-filename nil 'no-error)))
      (when filename
        (push filename files)))
    (forward-line 1))
  ;; Now `files' is a list of files, which you can search for patterns
  ;; …
  )

Ancak, işaretleme işlevlerini kullanmak daha uygundur. Mevcut etkileşimli işaretleri kaybetmemek için “alışılmadık” işaretçi karakterleri kullanmaya dikkat edin:

(unwind-protect
    (when (dired-mark-files-regexp (rx ".tex" string-end) ?t)
      (dired-goto-file (expand-file-name "master.tex")))
  (dired-unmark-all-files ?t))

Yer Modunu Kaydet

Etkinleştirmeniz durumunda, Yer Modunu Kaydetme konusunda da dikkatli olmanız gerekir. Dired tamponlarında Yer Kaydetme Modu, nokta modunu diğer modlarda olduğu gibi hatırlamaz, bunun yerine son dosya adı noktası açıktır. Bu dosya ismini aynen yaptığımız gibi geri yükler: İçine girer dired-initial-position-hookve çağırır dired-goto-file(aslında, bu kodu buradan çaldım :)).

Kancamız yer kaydetmeden önce gelirse, Yer Kaydetme Modu koşulsuz olarak konumumuzun üzerine yazacaktır. Ancak, kancadan önce gelirse (bu kancayı kurduktan sonra Yeri Kaydet etkin olduğunda olduğu gibi), işlevimiz aslında istenmeyen Yeri Kaydet'in üzerine yazacaktır. Ancak, herhangi bir arabellekte olduğu gibi, Yeri Kaydet yerel değişkeni save-placesıfır olmayan bir değere ayarlar , bu yüzden bunu kontrol edebilir ve yalnızca Yeri Kaydet'in bir dosya adını geri yüklemediğini söyleyebiliriz.

Bunun yerine “gevşek” Kaydet Yeri şeyler yapsa için işareti kaldırın save-placeve bizim kanca çalıştırmak emin olun sonra Kaydet Yeri Modu etkinleştirerek, Kaydet Yeri ilk çağıran sonra ve add-hookonun için olmayan bir sıfır değerine sahip APPENDargüman.


Mükemmel cevap. Tanımlamak isteyebilirsiniz bound-and-true-p. :-)
Malabarba

@Malabarba bound-and-true-pyerleşik bir makrodur bindings.el.
lunaryorn

Sevgili tanrım, beni daha kötü hissettiren şey değil, bunu bilmiyordum ya da kontrol etmediğim gerçeği.
Malabarba

@Malabarba Boş ver, bu işlevin varlığını keşfetmem bir yıl sürdü.
lunaryorn

Evet, şimdiye kadar hiç duymadığım harika bir işlev!
sanityinc
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.