Diversi stili di rientro per diversi progetti


29

Lavoro a diversi progetti C con stili di rientro unici. Come faccio a far sì che Emacs esegua le impostazioni di rientro per progetto senza inquinare gli alberi del progetto a monte con i .dir-locals.elfile? Voglio abbinare i progetti usando i loro percorsi su disco.


2
Che ne dici di usare EditorConfig invece di .dir-locals.el. Possono essere colleghi vorrebbe questa idea?
welldan97,

Risposte:


21

.dir-locals.el è il mio metodo preferito quando è possibile, soprattutto perché si applica a tutti gli utenti Emacs che lavorano su quel progetto.

Per i progetti ostili agli utenti di Emacs o che altrimenti non desiderano .dir-locals.elfile o se si desidera avere preferenze personali (presumibilmente non rientranti) che non dovrebbero essere applicate ad altre persone, se si utilizza un sistema di controllo della versione distribuito, un'opzione è lavorare sempre su rami personali che hanno il tuo .dir-locals.el. Non so come usare un DCVS che lo rende indolore.

Un'altra opzione è quella di non .dir-locals.elarchiviare i file. Ad esempio, con git, aggiungilo a .git/info/exclude. Questo è doloroso quando hai molti checkout di un progetto, ovviamente.

Quello che ho fatto dove .dir-locals.elnon c'era un'opzione è quello di aggiungere un hook che cerca buffer-file-namevalori noti.

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

(Avviso: il codice digitato direttamente nel mio browser in quanto non ho accesso al mio codice reale in questo momento.)


2
L'aggiunta .dir-locals.ela .git/info/excludesembra una buona opzione.
shosti,

Cosa c'è di sbagliato nell'aggiungerlo .gitignorenella radice di un progetto?
Squidly,

@Niente, ma alcuni progetti non vogliono file specifici dell'editor lì.
Gilles 'SO- smetti di essere malvagio' il

Per gli utenti git, puoi aggiungere .dir-locals.ela gitignore globale all'indirizzo ~/.config/git/ignore.
Jeremy Heiler,

7

Non puoi convincere i progetti a monte come llvm e linux a fare il check in a .dir-locals.el.

Una soluzione elaborata al problema:

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

Usato come segue:

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

Ho una macro simile anche per altre modalità linguistiche.


6

distribuire .dir-locals.el in diversi progetti è difficile da mantenere.

La mia strada è piuttosto semplice, metto tutto il codice in uno ~ / .custom.el.

Fondamentalmente, il codice verrà eseguito in hook prog-mode (o your-qualunque-major-mode-hook) e farà le seguenti cose:

  • analizzare se il percorso completo del file contiene il nome specifico del progetto
  • se vero, allora fai il setup per quel progetto (incluso aggiustare il rientro).

Uso questo metodo con successo da un anno.

Ecco il codice (chiama my-setup-develop-environment in prog-mode-hook):

(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

Il modo normale per farlo è usare .dir-locals. Ecco perché sono stati introdotti in primo luogo. Perchè no? Per quanto ne sappia, la maggior parte degli strumenti relativi al progetto tendono a mantenere le proprie configurazioni nella directory principale del progetto: git, svn, Eclipse e molti altri ...

Basta non dimenticare di aggiungere il file .gitignoreo simili.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.