Unterschiedliche Einrückungsstile für unterschiedliche Projekte


29

Ich arbeite an vielen verschiedenen C-Projekten mit einzigartigen Einrückungsstilen. Wie kann ich Emacs dazu bringen, pro Projekt Einrückungseinstellungen vorzunehmen, ohne die vorgelagerten Projektbäume mit .dir-locals.elDateien zu verschmutzen ? Ich möchte die Projekte anhand ihrer Pfade auf der Festplatte zuordnen.


2
Wie wäre es mit EditorConfig anstelle von .dir-locals.el. Mögen Kollegen diese Idee mögen?
Welldan97

Antworten:


21

.dir-locals.el ist meine bevorzugte Methode, wenn dies möglich ist, insbesondere, da sie für alle Emacs-Benutzer gilt, die an diesem Projekt arbeiten.

Für Projekte, die Emacs-Benutzern feindlich gegenüberstehen oder auf andere Weise keine .dir-locals.elDateien oder persönliche Einstellungen (vermutlich keine Einrückung) haben möchten, die für andere Personen nicht gelten sollten, ist eine Option, wenn Sie ein verteiltes Versionskontrollsystem verwenden um immer an persönlichen Zweigen zu arbeiten, die deine .dir-locals.el. Ich kenne keine Möglichkeit, ein DCVS zu verwenden, das dies jedoch schmerzlos macht.

Eine andere Möglichkeit ist, die .dir-locals.elDateien nicht einzuchecken . Zum Beispiel, mit git, füge es hinzu .git/info/exclude. Das ist natürlich schmerzhaft, wenn Sie viele Kassen eines Projekts haben.

Was ich getan habe, wo .dir-locals.elkeine Option war, ist das Hinzufügen eines Hakens, der nach buffer-file-namebekannten Werten sucht .

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

(Warnung: Code wurde direkt in meinen Browser eingegeben, da ich momentan keinen Zugriff auf meinen echten Code habe.)


2
Das Hinzufügen .dir-locals.elzu .git/info/excludescheint eine gute Option zu sein.
Shosti

Was ist falsch daran, es .gitignoreim Stammverzeichnis eines Projekts hinzuzufügen ?
Squidly

@Nichts, aber einige Projekte wollen dort keine editor-spezifischen Dateien.
Gilles 'SO- hör auf böse zu sein'

Für Git-Benutzer können Sie .dir-locals.elIhren globalen Gitignore unter hinzufügen ~/.config/git/ignore.
Jeremy Heiler

7

Sie können vorgelagerte Projekte wie llvm und linux nicht davon überzeugen, a einzuchecken .dir-locals.el.

Eine durchdachte Lösung des Problems:

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

Wird wie folgt verwendet:

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

Ich habe ein ähnliches Makro auch für andere Sprachmodi.


6

Die Verteilung von .dir-locals.el in verschiedenen Projekten ist schwierig.

Mein Weg ist ziemlich einfach, stecke den gesamten Code in ein ~ / .custom.el.

Grundsätzlich wird der Code im Prog-Modus-Hook (oder in Ihrem-Was-auch-auch-auch-wichtigen-Modus-Hook) ausgeführt und führt die folgenden Schritte aus:

  • Analysieren Sie, ob der vollständige Dateipfad den spezifischen Projektnamen enthält
  • Wenn dies der Fall ist, nehmen Sie die Einrichtung für dieses Projekt vor (einschließlich der Änderung des Einzugs).

Ich benutze diese Methode seit einem Jahr erfolgreich.

Hier ist der Code (rufe meine-Setup-Entwicklungsumgebung in Prog-Mode-Hook auf):

(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

Die normale Methode ist die Verwendung von .dir-locals. Deshalb wurden sie überhaupt erst eingeführt. Warum nicht? Meines Wissens tendieren die meisten projektbezogenen Tools dazu, ihre Konfigurationsdateien im Stammverzeichnis des Projekts zu behalten: git, svn, Eclipse und viele andere ...

Vergessen Sie nur nicht, die Datei .gitignoreoder ähnliches hinzuzufügen .


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.