Skip to content

Commit

Permalink
use flymake-eslint-executable to access eslint indirectly (orzechowsk…
Browse files Browse the repository at this point in the history
  • Loading branch information
aecepoglu committed Dec 16, 2023
1 parent e30c9a1 commit 64e0779
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 45 deletions.
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Flymake backend for Javascript using eslint

## Installation

0. Make sure `eslint` is installed and present on your emacs `exec-path`. For Linux systems `exec-path` usually equals your `$PATH` environment variable; for other systems, you're on your own.
0. Make sure `eslint` is present on your `exec-path`. If you want to use an `eslint` local to your project (through `npx`) you must configure (see _Customization_ below) `flymake-eslint-executable` variable to `'("npx" "eslint")`.
For Linux systems `exec-path` usually equals your `$PATH` environment variable; for other systems, you're on your own.
1. Install:
- from MELPA: `M-x package-install [RET] flymake-eslint [RET]`
- manually: download and place inside `~/.emacs.d/lisp` then edit `~/.emacs` or equivalent:
Expand All @@ -24,13 +25,16 @@ Flymake backend for Javascript using eslint
useful variables are members of the `flymake-eslint` group and can be viewed and modified with the command `M-x customize-group [RET] flymake-eslint [RET]`.

```lisp
(defcustom flymake-eslint-executable-name "eslint"
"Name of executable to run when checker is called. Must be present in variable `exec-path'."
:type 'string
:group 'flymake-eslint)
(defcustom flymake-eslint-executable-args nil
"Extra arguments to pass to eslint."
(defcustom flymake-eslint-executable '("eslint")
"Name and arguments to call eslint with.
Examples:
'(\"eslint\") ; if eslint exists and available in exec-path
'(\"npx" "eslint\") ; if eslint is called through npx. Allows access to project-local eslint
'(\"npm\" \"exec\" \"--\" \"eslint\") ; equivalent to \"npx\"
You can also send additional arguments to eslint. For example to set eslint's --max-warnings to 13:
'(\"eslint\" \"--max-warnings\" \"13\")
'(\"npx\" \"eslint\" \"--max-warnings\" \"13\")"
:type 'string
:group 'flymake-eslint)
Expand Down Expand Up @@ -65,7 +69,9 @@ yes

## See Also

[flymake-stylelint](https://github.com/orzechowskid/flymake-stylelint)
* [flymake-stylelint](https://github.com/orzechowskid/flymake-stylelint)
* [npx](https://docs.npmjs.com/cli/v7/commands/npx)
* [eslint CLI](https://eslint.org/docs/latest/use/command-line-interface)

## License

Expand Down
63 changes: 27 additions & 36 deletions flymake-eslint.el
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,17 @@
:group 'programming
:prefix "flymake-eslint-")

(defcustom flymake-eslint-executable-name "eslint"
"Name of executable to run when checker is called.
Must be present in variable `exec-path'."
:type 'string
:group 'flymake-eslint)

(defcustom flymake-eslint-executable-args nil
"Extra arguments to pass to eslint."
:type '(choice string (repeat string))
(defcustom flymake-eslint-executable '("eslint")
"Arguments to execute `eslint'
Example values:
'(\"eslint\") ; to use an eslint available in exec-ptah
'(\"npx\" \"eslint\") ; to use eslint through npx. Allows access to project-local eslint
'(\"npm\" \"exec\" \"--\" \"eslint\") ; equivalent to \"npx\"
You can also send additional arguments to eslint. For example to set eslint's --max-warnings to 13:
'(\"eslint\" \"--max-warnings\" \"13\")
'(\"npx\" \"eslint\" \"--max-warnings\" \"13\")"
:type '(repeat string)
:group 'flymake-eslint)

(defcustom flymake-eslint-show-rule-name t
Expand Down Expand Up @@ -100,31 +102,28 @@ installation with JSON support."
"Enable Flymake and flymake-eslint.
Add this function to some js major mode hook."
(interactive)
(make-local-variable 'flymake-eslint-project-root)
(setq default-directory
(or flymake-eslint-project-root
(when (and (featurep 'project)
(project-current))
(project-root (project-current)))
default-directory))
(unless flymake-eslint-defer-binary-check
(flymake-eslint--ensure-binary-exists))
(make-local-variable 'flymake-eslint-project-root)
(flymake-mode t)
(add-hook 'flymake-diagnostic-functions 'flymake-eslint--checker nil t))

;;;;; Private

(defun flymake-eslint--executable-args ()
"Get additional arguments for `flymake-eslint-executable-name'.
Return `flymake-eslint-executable-args' value and ensure that
this is a list."
(if (listp flymake-eslint-executable-args)
flymake-eslint-executable-args
(list flymake-eslint-executable-args)))

(defun flymake-eslint--ensure-binary-exists ()
"Ensure that `flymake-eslint-executable-name' exists.
"Ensure that `flymake-eslint-executable' exists and can be invoked with `--version'
Otherwise, throw an error and tell Flymake to disable this
backend if `flymake-eslint-executable-name' can't be found in
variable `exec-path'"
(unless (executable-find flymake-eslint-executable-name)
(let ((option 'flymake-eslint-executable-name))
(error "Can't find \"%s\" in exec-path - try to configure `%s'"
(symbol-value option) option))))
backend."
(with-temp-buffer
(let ((x flymake-eslint-executable))
(unless (= 0 (apply 'call-process `(,(car x) nil t (current-buffer) ,@(cdr x) "--version")))
(error "`eslint' invocation failed. It errored with message: %s" (buffer-string))))))

(defun flymake-eslint--get-position (line column buffer)
"Get the position at LINE and COLUMN for BUFFER."
Expand Down Expand Up @@ -226,14 +225,7 @@ CALLBACK accepts a buffer containing stdout from linter as its
argument."
(when (process-live-p flymake-eslint--process)
(kill-process flymake-eslint--process))
(let ((default-directory
(or
flymake-eslint-project-root
(when (and (featurep 'project)
(project-current))
(project-root (project-current)))
default-directory))
(format-args
(let ((format-args
(if (flymake-eslint--use-json-p)
'("--format" "json")
"")))
Expand All @@ -243,14 +235,13 @@ argument."
:connection-type 'pipe
:noquery t
:buffer (generate-new-buffer " *flymake-eslint*")
:command `(,flymake-eslint-executable-name
:command `(,@flymake-eslint-executable
"--no-color"
"--no-ignore"
,@format-args
"--stdin"
"--stdin-filename"
,(buffer-file-name source-buffer)
,@(flymake-eslint--executable-args))
,(buffer-file-name source-buffer))
:sentinel
(lambda (proc &rest ignored)
(let ((status (process-status proc))
Expand Down

0 comments on commit 64e0779

Please sign in to comment.