У розділених буферах помістіть крапку на найважливіший файл цього каталогу


14

У 90% часу, коли я відвідую каталог в Emacs, перше, що я роблю, - це перемістити точку на певний файл і відкрити його. Багато разів файл, який мені потрібно відкрити, дуже передбачуваний. Наприклад:

  • Якщо .texв цьому каталозі є файли, я зазвичай переходжу до них master.tex.
  • У корені Android-проектів це зазвичай AndroidManifest.xml.
  • У каталозі, де я розробляю пакет emacs, це майже завжди головний вихідний файл пакета. Це зазвичай, але не завжди, єдиний .elфайл у цьому каталозі.

Чи є спосіб, коли я можу автоматично перевести точку на ці файли, коли я відкриваю ці каталоги?

Це могло б запропонувати масу зручностей (оскільки я міг би відкрити їх, просто натиснувши RET), але все ж надав би гнучкість відвідування інших файлів.

Відповіді:


16

Напишіть власну функцію для dired-initial-position-hook. У цій функції ви можете використовувати різні функціоновані функції для пошуку файлів, а в кінцевому підсумку зателефонуйте, dired-goto-fileщоб перейти до «найкращого» файлу:

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

Далі я поясню конкретні аспекти цієї функції та висвітлюю потенційні розширення.

Перехід до файлів

dired-goto-fileповертається, nilякщо файл не існує в поточному набраному буфері, тому його можна зателефонувати без попередньої перевірки. Однак dired-goto-fileпотрібне абсолютне ім'я файлу (воно помилки щодо відносних імен), отже expand-file-name.

Пошук файлів

Dired не забезпечує прямий API для пошуку файлів. Як правило, ви можете перебирати всі файли так само, як ітерацію всіх рядків у буфері:

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

Однак зручніше використовувати функції маркування. Просто потурбуйтеся про використання незвичних символів маркера, щоб не втрачати існуючі інтерактивні позначки:

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

Зберегти режим місця

Ви також повинні бути обережними щодо режиму збереження місця, якщо ви його ввімкнули. У режимі "Подвійні буфери" режим збереження місця не запам'ятовує значення точки, як в інших режимах, а скоріше було включено точку імені останнього файлу. Він відновлює це ім'я файлу так само, як і ми: він підключається dired-initial-position-hookі дзвонить dired-goto-file(насправді саме там я вкрав цей код :).

Якщо наш гачок вийде до місця збереження, режим збереження місця безумовно замінить нашу позицію. Однак, якщо він постане перед нашим гаком (як це відбувається, коли зберегти місце місце після встановлення цього гака), наша функція насправді перезаписать місце збереження, що не бажано. Однак, як і в будь-якому буфері, Save Place встановлює локальну змінну save-placeне-нульовим значенням, тому ми можемо просто перевірити, що і тільки діяти Save Place не відновив ім’я файлу.

Якщо ви хочете скористатися "Місцем збереження", зніміть чек save-placeі переконайтеся, що наш гак запущений після " Зберегти місце", включивши спершу режим збереження місця , а потім зателефонувавши add-hookзі своїм значенням, що не має нульового значення для його APPENDаргументу.


Чудова відповідь. Ви можете визначитись bound-and-true-p. :-)
Малабарба

@Malabarba bound-and-true-p- це вбудований макрос із bindings.el.
місячник

Дорогий боже, я не те, що мене відчуває гірше, те, що я цього не знав, або факт, що я навіть не перевіряв.
Малабарба

@Malabarba Неважливо, мені знадобилося рік (буквально), щоб дізнатися про існування цієї функції.
місячник

Так, це прекрасна функція, про яку я також ще ніколи не чув!
sanityinc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.