Zapamiętaj tryby plików bez rozszerzeń

10

Zacząłem edytować wiele plików, które nie mają rozszerzeń, ale nadal są w formacie trybu głównego.

Jestem jedynym użytkownikiem Emacsa w zespole i nie chcę, aby boleśnie oczywiste było, że mój edytor potrzebuje specjalnych rzeczy. Chciałbym uniknąć zmiany bazy kodu.

  • Nie mogę zmienić nazwy pliku
  • Nie mogę używać specjalnych komentarzy Emacsa

Chciałbym, aby Emacs pamiętał, w jakim trybie ręcznie umieściłem plik na końcu (powiedzmy, z M-x conf-mode) i automatycznie aktywował ten tryb, gdy ponownie go odwiedzę.

Używam savehist-modedo radzenia sobie z wytrwałością.

Czy mogę to zrobić bezboleśnie?

PythonNut
źródło
1
Jeśli jest to plik, który możesz edytować, zazwyczaj możesz dodać pierwszy wiersz z komentarzem: # -*- mode: conf -*-i to wskazałoby Emacsa na użycie conf-mode. Jeśli jest ich niewiele i możesz je dopasować za pomocą wyrażeń regularnych, możesz dodać wyrażenie regularne do automode-alist.
wvxvw
2
@wvxvw jednym z moich ograniczeń jest to, że „ nie mogę używać specjalnych komentarzy Emacsa ”.
PythonNut
2
Przykro mi, nie rozumiem, jak to przeoczyłem. Poza tym to auto-mode-alistmoje złe.
wvxvw
Oczywiście poprawną odpowiedzią jest zachęcenie reszty zespołu do korzystania z Emacsa. Każda inna odpowiedź to tylko obejście.
Malabarba

Odpowiedzi:

13

Istnieje wiele sposobów identyfikowania głównego trybu dla pliku, który nie zależy od rozszerzenia, patrz Wybieranie trybów plików w instrukcji.

W zależności od rodzaju plików, z którymi masz do czynienia, być może możesz użyć magic-mode-alist. Pamiętaj też, że auto-mode-alistnie ogranicza się to do dopasowywania rozszerzeń: możesz dopasować dowolną część nazwy pliku lub ścieżki.

Jeśli pliki, z którymi masz do czynienia, nie są wystarczająco spójne dla tych mechanizmów, jedną z opcji jest dodanie auto-mode-alistpozycji pasujących do całej nazwy pliku lub ścieżki katalogu głównego projektu i wywołanie funkcji niestandardowej w celu dopasowania nazw do trybów.

Jeśli wszystkie pliki w danym katalogu są tego samego typu, można również użyć zmiennej lokalnej dla katalogu, aby ustawić tryb. Zmienne katalogowe można ustawić w pliku inicjującym zamiast w pliku .dir-locals - szczegółowe informacje można znaleźć w Zmiennych katalogowych .

Aktualizacja

Oto szybka próba zarządzania własną listą bezwzględnych nazw plików i głównych trybów.

(defvar my-custom-mode-alist '())
(defvar my-custom-mode-alist-file (expand-file-name "custom-file-assoc" user-emacs-directory))

;; command to save the file->mode association of the current buffer
(defun save-file-mode-association ()
  (interactive)
  (when buffer-file-name
    (add-to-list 'my-custom-mode-alist (cons buffer-file-name major-mode))
    (write-custom-mode-alist my-custom-mode-alist-file)))

(defun write-custom-mode-alist (file)
  (with-current-buffer (get-buffer-create " *Custom File Assocations*")
    (goto-char (point-min))
    (delete-region (point-min) (point-max))
    (pp my-custom-mode-alist (current-buffer))
    (condition-case nil
        (write-region (point-min) (point-max) file)
      (file-error (message "Can't write %s" file)))
    (kill-buffer (current-buffer))
    (message "Wrote custom file associations to file %s" file)))

(defun load-custom-mode-alist (file)
  (when (file-exists-p file)
    (with-current-buffer
        (let ((enable-local-variables nil))
          (find-file-noselect file))
      (goto-char (point-min))
      (setq my-custom-mode-alist (read (current-buffer)))
      (setq auto-mode-alist (append auto-mode-alist my-custom-mode-alist))
      (kill-buffer (current-buffer)))))

;; Load any custom file associations and add them to auto-mode-alist
(load-custom-mode-alist my-custom-mode-alist-file)
glucas
źródło
Niestety pliki są dość luźno sformatowane i mają bardzo ogólne nazwy. Dzięki za wskazanie szczegółów auto-mode-alist. Pewnie magic-mode-alistw przyszłości będę pamiętać o czymś innym.
PythonNut
4

Poniższe, oparte na radach Glucas, wydaje się działać idealnie.

(defvar file-name-mode-alist '())
;; other stuff here, of course
(setq savehist-additional-variables '(file-name-mode-alist))
(savehist-mode +1)
(setq auto-mode-alist (append auto-mode-alist file-name-mode-alist))

(add-hook 'after-change-major-mode-hook
  (lambda ()
    (when (and
            buffer-file-name
            (not
              (file-name-extension
                buffer-file-name)))
       (setq file-name-mode-alist
        (cons
          (cons buffer-file-name major-mode)
          file-name-mode-alist))
      (setq auto-mode-alist
        (append auto-mode-alist
          (list (cons buffer-file-name major-mode)))))))
PythonNut
źródło
1
Miły. Bardziej eleganckie rozwiązanie niż to, które razem zhakowałem. :-)
glucas