Різні стилі відступу для різних проектів


29

Я працюю над багатьма різними проектами C з унікальними стилями відступу. Як змусити Emacs робити налаштування відступу за проектом, не забруднюючи дерева верхніх проектів .dir-locals.elфайлами? Я хочу відповідати проектам, використовуючи їх контури на диску.


2
Як щодо використання EditorConfig замість .dir-locals.el. Може, колегам сподобається ця ідея?
welldan97

Відповіді:


21

.dir-locals.el є моїм кращим методом, коли це можливо, особливо якщо це стосується всіх користувачів Emacs, які працюють над цим проектом.

Для проектів, ворожих користувачам Emacs або не хочуть .dir-locals.elфайлів, або якщо ви хочете мати особисті переваги (імовірно, не відступ), які не повинні застосовуватися до інших людей, якщо ви використовуєте розподілену систему контролю версій, можливим є завжди працювати над особистими галузями, які мають ваше .dir-locals.el. Я не знаю, як використовувати DCVS, який робить це безболісним.

Ще один варіант - не перевіряти .dir-locals.elфайли. Наприклад, за допомогою git додайте його в .git/info/exclude. Це боляче, коли у вас, звичайно, багато замовлень на проект.

Те, що я робив там, де .dir-locals.elне було можливості, - це додати гачок, який виглядає buffer-file-nameпроти відомих значень.

(defvar guessed-project nil)
(make-variable-buffer-local 'guessed-project)
(defun guess-project-from-file-name ()
  (save-match-data
    (setq guessed-project
          (cond
           ((string-match "/linux-kernel/" buffer-file-name)
            'linux-kernel)
           ((string-match "/gnu/" buffer-file-name)
            'gnu)
           ; etc.
          ))))
(defun c-my-project-hook ()
  (guess-project-from-file-name)
  (case guessed-project
    ((gnu) (c-sty-style 'gnu))
    ((linux-kernel) (c-sty-style 'linux))
  ))
(add-hook 'c-mode-hook 'c-my-project-hook)

(Попередження: код вводиться безпосередньо в моєму браузері, оскільки я зараз не маю доступу до свого реального коду.)


2
Додавання .dir-locals.elдо .git/info/excludeздається, варіант хороший.
shosti

Що не в тому, щоб додати його до .gitignoreкореня проекту?
Кальмар

@Ніщо, але деякі проекти не хочуть, щоб файли, що стосуються редактора, там.
Жил "ТАК - перестань бути злим"

Для користувачів git ви можете додати .dir-locals.elдо свого глобального gitignore за адресою ~/.config/git/ignore.
Джеремі Хайлер

7

Ви не можете переконати такі проекти, як llvm та linux, перевірити .dir-locals.el.

Детальне вирішення проблеми:

(defmacro define-new-c-style (name derived-from style-alist match-path)
  `(progn
     (c-add-style ,name
                  '(,derived-from ,@style-alist))
     (add-hook 'c-mode-hook
               (lambda ()
                 (let ((filename (buffer-file-name)))
                   (when (and filename
                              (string-match (expand-file-name ,match-path) filename))
                     (c-set-style ,name)))))))

Використовується наступним чином:

(define-new-c-style "llvm" "gnu" ((fill-column . 80)
                                  (c++-indent-level . 2)
                                  (c-offsets-alist . ((innamespace 0))))
  "~/src/llvm")

(define-new-c-style "emacs" "gnu" nil "~/src/emacs")

У мене є аналогічний макрос і для інших мовних режимів.


6

розповсюдження .dir-locals.el у різних проектах важко підтримувати.

Мій шлях досить простий, увесь код покладіть в один ~ / .custom.el.

В основному, код буде запускатися в прог-режимі-гачку (або вашому-будь-якому-мажорі-режимі-гачку) і робити наступні дії:

  • проаналізуйте, чи містить повний шлях файлу конкретну назву проекту
  • якщо це правда, то зробіть налаштування для цього проекту (включаючи налаштування відступу).

Я успішно використовую цей метод протягом одного року.

Ось код (зателефонуйте my-setup-development-environment в прог-режим-гачок):

(defun my-project-name-contains-substring (REGEX)
  (let ((dir (if (buffer-file-name)
                 (file-name-directory (buffer-file-name))
               "")))
    (string-match-p REGEX dir)))

(defun my-office-code-style ()
  (interactive)
  (message "Office code style!")
  ;; web development
  (setq coffee-tab-width 4)
  (setq javascript-indent-level 4)
  (setq js-indent-level 4)
  (setq js2-basic-offset 4)
  (setq web-mode-indent-style 4)
  (setq web-mode-markup-indent-offset 4)
  (setq web-mode-css-indent-offset 4)
  (setq web-mode-code-indent-offset 4)
  )

(defun my-personal-code-style ()
  (interactive)
  (message "My personal code style!")
  (setq coffee-tab-width 4)
  (setq javascript-indent-level 2)
  (setq js-indent-level 2)
  (setq js2-basic-offset 2)
  (setq web-mode-indent-style 2)
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-css-indent-offset 2)
  (setq web-mode-code-indent-offset 2)
  )

(defun my-setup-develop-environment ()
  (interactive)
  (cond
   ;; company's project for ttag
   ((my-project-name-contains-substring "commerical-proj1")
    (my-office-code-style))
   ((my-project-name-contains-substring "hobby-proj1")
    (my-personal-code-style))
  )
)
(add-hook 'prog-mode-hook 'my-setup-develop-environment)

2

Нормальний спосіб зробити це - використання .dir-locals. Саме тому їх запровадили в першу чергу. Чому ні? Наскільки мені відомо, більшість інструментів, що стосуються проектів, як правило, зберігають свої конфігурації у кореневій каталозі проектів: git, svn, Eclipse та багато інших ...

Просто не забудьте додати файл до .gitignoreподібного.


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