Flycheck z plikiem wykonywalnym względnego pliku eslint

21

Wiele projektów, nad którymi pracuję, instaluje eslint jako zależność programistów, z niestandardowym zestawem wtyczek eslint. Obecnie flycheck korzysta z globalnie zainstalowanej wersji eslinta zamiast wersji eslint zainstalowanej z każdym projektem.

Chciałbym zamiast tego wskazać Flycheck na node_modules / eslint / bin / eslint.js. Pełna ścieżka powinna zależeć od ścieżki bieżącego pliku bufora, dzięki czemu mogę pracować nad wieloma projektami jednocześnie z każdym buforem, używając potencjalnie innego pliku wykonywalnego eslint.

czy to możliwe? Wszelkie sugestie dotyczące tego, jak bym to zrobił?

pcardune
źródło

Odpowiedzi:

32

Możesz programowo zmienić flycheck-javascript-eslint-executable, np

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

Ten kod szuka node_moduleskatalogu w dowolnym katalogu nadrzędnym katalogu bufora i konfiguruje Flycheck, aby używał pliku wykonywalnego eslint z tego katalogu, jeśli taki istnieje.

księżycowy
źródło
Chciałbym, żeby moje emacs-fu były tak dobre. Dziękuję za odpowiedź!
pcardune 04.04.16
1
Jeśli masz ustawiony tryb globalnej kontroli, polecam (and eslint (file-executable-p eslint)) napotkać błędy, które w innym przypadku próbuję, tj. Edytować mój plik .emacs
Jason Dufair
Oto, co możesz zrobić, jeśli potrzebujesz wbudowanego haka (i unikaj dodawania niestandardowych funkcji): emacs-fu.blogspot.in/2008/12/hooks.html
Shivek Khurana
uwaga bezpieczeństwa: otwieraj tylko pliki w zaufanych folderach / projektach; będzie automatycznie wykonywać żadnych malicions eslint binarny
maxy
2
"node_modules/.bin/eslint"Użyłbym ścieżki , na wypadek gdyby eslint kiedykolwiek zmienił strukturę katalogów.
Cody Reichert,
3

Nie mam wystarczającej reputacji, aby skomentować zaakceptowane rozwiązanie. Ale zrobiłem jego odmianę, która działa dobrze z zagnieżdżonymi pakietami (na przykład przy użyciu lerna ). Jest to dokładnie ten sam kod, jednak node_modulesrekursywnie wyszukuje folder nadrzędny, aż znajdzie plik eslintbinarny i go używa. W ten sposób projekt Lerna może mieć tylko jedną konfigurację eslint, współużytkowaną przez wszystkie paczki.

(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
źródło
0

Jestem w systemie Windows i to nie działało dla mnie, myślę, że plik wykonywalny-p lub może flycheck nie potrafił zlokalizować poprawnego pliku. Gdy działa, wskazuje na .cmdplik, a nie na .jsplik.

Znalazłem komentarz we flycheck-eslint nie używa wersji eslinta zainstalowanej w projekcie JavaScript i ich wpisu na blogu, aby zamiast tego używać zmiennych katalogowych .

W katalogu głównym projektu utwórz plik .dir-locals.el

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

Teraz, kiedy odwiedzam plik javascript, flycheck-verify-setuppoprawnie go znajduje<dir>/node_modules/.bin/eslint.cmd

Bae
źródło
0

Moje poprzednie rozwiązanie utrudniało pracę nad różnymi projektami.

Zmodyfikowałem przyjętą odpowiedź na głupoty z twardego kodu.

(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
źródło
0

Oto rozwiązanie, które łączy odpowiedzi Bae i Lunaryorn przy użyciu dir-locals.elpliku w katalogu głównym projektu (a dokładniej w katalogu zawierającym node_modules/folder, w którym znajduje się eslintplik binarny). Utwórz wspomniany dir-locals.elplik o następującej treści.

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

Tutaj zakładam, że używasz js2-modetrybu głównego emacs do edycji plików javascript. Jeśli tak nie jest, zmień odpowiednio tę linię. Drugi wiersz pliku sprawia, że javascript-eslintmoduł sprawdzania składni jest jedynym, który można zastosować w tym projekcie. Trzeci wiersz ustawia zmienną flycheck-javascript-eslint-executablena <root-dir>/node_modules/.bin/eslint. W ten sposób nie modyfikujemy emacsa exec-path.

Ricardo
źródło
0

Wypróbowałem kilka różnych odmian tego i nigdy nie znalazłem dokładnie tego, czego chciałem. W końcu osiągnąłem wystarczająco wysoki poziom w seplenieniu Emacsa, aby zmodyfikować go według własnych upodobań. Moja wersja szuka lokalnego eslinta, a jeśli go nie znajdzie, wraca do globalnie zainstalowanego:

(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
źródło