Flycheck avec fichier exécutable eslint relatif

21

De nombreux projets sur lesquels je travaille installent eslint en tant que dépendance de développement, avec un ensemble personnalisé de plugins eslint. À l'heure actuelle, flycheck utilise la version globalement installée d'eslint plutôt que la version d'eslint installée avec chaque projet.

Je voudrais plutôt faire en sorte que flycheck pointe vers node_modules / eslint / bin / eslint.js. Le chemin complet doit dépendre du chemin du fichier du tampon actuel afin que je puisse travailler sur plusieurs projets en même temps avec chaque tampon en utilisant un exécutable eslint potentiellement différent.

Est-ce possible? Avez-vous des suggestions sur la façon de procéder?

pcardune
la source

Réponses:

32

Vous pouvez modifier flycheck-javascript-eslint-executablepar programme , par exemple

(defun my/use-eslint-from-node-modules ()
  (let* ((root (locate-dominating-file
                (or (buffer-file-name) default-directory)
                "node_modules"))
         (eslint
          (and root
               (expand-file-name "node_modules/.bin/eslint"
                                 root))))
    (when (and eslint (file-executable-p eslint))
      (setq-local flycheck-javascript-eslint-executable eslint))))

(add-hook 'flycheck-mode-hook #'my/use-eslint-from-node-modules)

Ce code recherche un node_modulesrépertoire dans n'importe quel parent du répertoire du tampon et configure Flycheck pour utiliser un exécutable eslint à partir de ce répertoire s'il en existe un.

lunaryorn
la source
Je souhaite que mes emacs-fu soient aussi bons. Merci d'avoir répondu!
pcardune
1
Si vous avez défini le mode global de contrôle de vol, je recommande que (and eslint (file-executable-p eslint)) je rencontre des erreurs dans le cas contraire, c'est-à-dire que je modifie mon fichier .emacs
Jason Dufair
Voici ce que vous pouvez faire si vous avez besoin d'un crochet en ligne (et évitez d'ajouter des fonctions personnalisées): emacs-fu.blogspot.in/2008/12/hooks.html
Shivek Khurana
note de sécurité: ouvrir uniquement les fichiers dans des dossiers / projets approuvés; vous exécuterez automatiquement tous les malicions eslint binary
maxy
2
J'utiliserais le chemin "node_modules/.bin/eslint", juste au cas où eslint changerait jamais sa structure de répertoire.
Cody Reichert
3

Je n'ai pas assez de réputation pour commenter la solution acceptée. Mais j'en ai fait une variante, qui fonctionne bien avec les paquets imbriqués (par exemple en utilisant lerna ). Il s'agit du même code, mais il recherche le node_modulesdossier parent de manière récursive jusqu'à ce qu'il trouve un eslintbinaire et l'utilise. De cette façon, un projet lerna peut avoir une seule configuration eslint, partagée entre tous les sous-packages.

(defun my/use-eslint-from-node-modules ()
  (let ((root (locate-dominating-file
               (or (buffer-file-name) default-directory)
               (lambda (dir)
                 (let ((eslint (expand-file-name "node_modules/eslint/bin/eslint.js" dir)))
                  (and eslint (file-executable-p eslint)))))))
    (when root
      (let ((eslint (expand-file-name "node_modules/eslint/bin/eslint.js" root)))
        (setq-local flycheck-javascript-eslint-executable eslint)))))
(add-hook 'flycheck-mode-hook #'my/use-eslint-from-node-modules)
Soreine
la source
0

Je suis sur Windows et cela ne fonctionnait pas pour moi, je pense que le fichier-exécutable-p ou peut-être que les internes du contrôle de vol ne parvenaient pas à localiser le fichier correct. Comme lorsqu'il fonctionne, il pointe vers le .cmdfichier et non vers le .jsfichier.

J'ai trouvé un commentaire dans flycheck-eslint n'utilise pas la version d'eslint installée dans le projet JavaScript et leur blog pour utiliser des variables de répertoire à la place.

Dans le répertoire racine du projet, créez un fichier .dir-locals.el

((nil . ((eval . (progn
                   (add-to-list 'exec-path (concat (locate-dominating-file default-directory ".dir-locals.el") "node_modules/.bin/")))))))

Maintenant, lorsque je visite le fichier javascript, il flycheck-verify-setuptrouve correctement le fichier<dir>/node_modules/.bin/eslint.cmd

Bae
la source
0

Ma solution précédente était difficile de travailler sur différents projets.

J'ai modifié la réponse acceptée aux stupidités des fenêtres de code en dur.

(defun my/use-eslint-from-node-modules ()
  (let* ((root (locate-dominating-file
                (or (buffer-file-name) default-directory)
                "node_modules"))
         (eslint (and root
                      (expand-file-name "node_modules/.bin/eslint.cmd"
                                        root))))
    (when (and eslint (file-exists-p eslint))
      (setq-local flycheck-javascript-eslint-executable eslint))))
Bae
la source
0

Voici une solution qui combine les réponses de Bae et de lunaryorn en utilisant un dir-locals.elfichier dans le répertoire racine du projet (ou, plus précisément, dans le répertoire qui contient le node_modules/dossier où réside le eslintbinaire). Créez ledit dir-locals.elfichier avec le contenu suivant.

((js2-mode
   (flycheck-checker . javascript-eslint)
   (eval . (setq-local flycheck-javascript-eslint-executable
             (concat (locate-dominating-file default-directory
                       ".dir-locals.el") "node_modules/.bin/eslint")))))

Ici, je suppose que vous utilisez le js2-modemode principal emacs pour modifier les fichiers javascript. Si ce n'est pas le cas, modifiez cette ligne en conséquence. La deuxième ligne du fichier fait du javascript-eslintvérificateur de syntaxe le seul à être utilisé dans ce projet. La troisième ligne définit la variable flycheck-javascript-eslint-executablesur <root-dir>/node_modules/.bin/eslint. De cette façon, nous ne modifions pas emacs ' exec-path.

Ricardo
la source
0

J'ai essayé plusieurs variantes de cela et je n'ai jamais trouvé exactement ce que je voulais. J'ai finalement suffisamment progressé dans Emacs lisp pour le modifier à mon goût. Ce que ma version fait, c'est chercher un eslint local et si un n'est pas trouvé, il revient à un installé mondialement:

(defun configure-web-mode-flycheck-checkers ()
    ;; See if there is a node_modules directory
    (let* ((root (locate-dominating-file
                  (or (buffer-file-name) default-directory)
                  "node_modules"))
           (eslint (or (and root
                            ;; Try the locally installed eslint
                            (expand-file-name "node_modules/eslint/bin/eslint.js" root))

                       ;; Try the global installed eslint
                       (concat (string-trim (shell-command-to-string "npm config get prefix")) "/bin/eslint"))))

      (when (and eslint (file-executable-p eslint))
        (setq-local flycheck-javascript-eslint-executable eslint)))

    (if eslint
        (flycheck-select-checker 'javascript-eslint)))
Ricky Nelson
la source