Diferentes estilos de sangría para diferentes proyectos.

29

Trabajo en muchos proyectos C diferentes con estilos de sangría únicos. ¿Cómo hago para que Emacs haga configuraciones de sangría por proyecto sin contaminar los árboles del proyecto aguas arriba con .dir-locals.elarchivos? Quiero unir los proyectos usando sus rutas en el disco.

artagnon
fuente
2
¿Qué tal usar EditorConfig en lugar de .dir-locals.el. ¿Pueden ser compañeros de trabajo les gustaría esta idea?
welldan97

Respuestas:

21

.dir-locals.el es mi método preferido cuando es posible, especialmente porque se aplica a todos los usuarios de Emacs que trabajan en ese proyecto.

Para proyectos que son hostiles para los usuarios de Emacs o que de otro modo no desean .dir-locals.elarchivos, o si desea tener preferencias personales (presumiblemente no sangría) que no deberían aplicarse a otras personas, si usa un sistema de control de versiones distribuido, una opción es para trabajar siempre en ramas personales que tengan tu .dir-locals.el. Sin embargo, no conozco una forma de usar un DCVS que lo haga indoloro.

Otra opción es no registrar los .dir-locals.elarchivos. Por ejemplo, con git, agréguelo a .git/info/exclude. Eso es doloroso cuando tienes muchos pagos de un proyecto, por supuesto.

Lo que hice donde .dir-locals.elno era una opción es agregar un gancho que busca buffer-file-namevalores conocidos.

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

(Advertencia: código escrito directamente en mi navegador ya que no tengo acceso a mi código real en este momento).

Gilles 'SO- deja de ser malvado'
fuente
2
Agregar .dir-locals.ela .git/info/excludeparece una buena opción.
shosti
¿Qué tiene de malo agregarlo .gitignoreen la raíz de un proyecto?
Calamarly
@ Nada, pero algunos proyectos no quieren archivos específicos del editor allí.
Gilles 'SO- deja de ser malvado'
Para los usuarios de git, puede agregar .dir-locals.ela su gitignore global en ~/.config/git/ignore.
Jeremy Heiler
7

No puede convencer a proyectos anteriores como llvm y linux para que ingresen a .dir-locals.el.

Una solución elaborada 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)))))))

Usado de la siguiente manera:

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

Tengo una macro similar para otros modos de idioma también.

artagnon
fuente
6

distribuir .dir-locals.el en diferentes proyectos es difícil de mantener.

Mi camino es bastante simple, pon todo el código en uno ~ / .custom.el.

Básicamente, el código se ejecutará en prog-mode-hook (o your-whatever-major-mode-hook) y hará lo siguiente:

  • analizar si la ruta completa del archivo contiene el nombre específico del proyecto
  • si es verdadero, realice la configuración para ese proyecto (incluido el ajuste de la sangría).

He estado usando este método con éxito durante un año.

Aquí está el código (llame a my-setup-development-environment en 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)
Chen Bin
fuente
2

La forma normal de hacerlo es usar .dir-locals. Por eso se introdujeron en primer lugar. Por qué no? Que yo sepa, la mayoría de las herramientas relacionadas con proyectos tienden a mantener sus configuraciones en el directorio raíz del proyecto: git, svn, Eclipse y muchos otros ...

Simplemente no olvide agregar el archivo .gitignoreo similar.

Vlad
fuente
2

Yo uso guess-style.el .

Funciona bastante bien al adivinar el estilo de sangría preferido de un archivo.

NateEag
fuente