Skip to content

Commit ef642df

Browse files
wgrrstrager
authored andcommitted
plugin: Add Emacs integration with Flycheck
Most of Emacs users uses Flycheck their main error reporting tool, this patch provide Emacs support with Flycheck. There's room for many improvements, notability :errors-explainer and :standard-input, add them when their blocks are fixed. Signed-off-by: wagner riffel <[email protected]>
1 parent 3af523e commit ef642df

File tree

11 files changed

+396
-0
lines changed

11 files changed

+396
-0
lines changed

.github/docker/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ RUN \
2929
coreutils \
3030
debhelper \
3131
dpkg-dev \
32+
emacs-nox \
3233
fakeroot \
3334
g++-8 \
3435
g++-9 \
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright (C) 2020 Matthew Glazar
2+
# See end of file for extended copyright information.
3+
4+
name: test Emacs plugin
5+
on:
6+
push:
7+
pull_request:
8+
types: [opened, synchronize]
9+
10+
jobs:
11+
build:
12+
name: Emacs
13+
runs-on: ubuntu-latest
14+
container: ghcr.io/quick-lint/quick-lint-js-github-builder:v2
15+
steps:
16+
- name: checkout
17+
if: ${{ github.event_name == 'push' }}
18+
uses: actions/checkout@v2
19+
- name: checkout
20+
if: ${{ github.event_name == 'pull_request' }}
21+
uses: actions/checkout@v2
22+
with:
23+
ref: ${{ github.event.pull_request.head.sha }}
24+
25+
- name: configure
26+
run: cmake -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8 -DBUILD_TESTING=OFF -S . -B .
27+
- name: build
28+
run: cmake --build . --config Debug
29+
- name: install
30+
run: sudo cmake --install . --config Debug
31+
32+
- name: version
33+
run: emacs --version
34+
- name: test
35+
run: ./plugin/emacs/test-emacs.sh
36+
37+
# quick-lint-js finds bugs in JavaScript programs.
38+
# Copyright (C) 2020 Matthew Glazar
39+
#
40+
# This file is part of quick-lint-js.
41+
#
42+
# quick-lint-js is free software: you can redistribute it and/or modify
43+
# it under the terms of the GNU General Public License as published by
44+
# the Free Software Foundation, either version 3 of the License, or
45+
# (at your option) any later version.
46+
#
47+
# quick-lint-js is distributed in the hope that it will be useful,
48+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
49+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50+
# GNU General Public License for more details.
51+
#
52+
# You should have received a copy of the GNU General Public License
53+
# along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>.

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ add_subdirectory(docs)
3333
add_subdirectory(fuzz)
3434
add_subdirectory(plugin/vim)
3535
add_subdirectory(plugin/vscode)
36+
add_subdirectory(plugin/emacs)
3637
add_subdirectory(src)
3738
add_subdirectory(tools)
3839
add_subdirectory(website/demo)

plugin/emacs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.melpa-cache/

plugin/emacs/CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (C) 2020 Matthew Glazar
2+
# See end of file for extended copyright information.
3+
4+
cmake_minimum_required(VERSION 3.10)
5+
include(GNUInstallDirs)
6+
7+
install(
8+
FILES flycheck-quicklintjs.el
9+
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/emacs/site-lisp"
10+
)
11+
12+
# quick-lint-js finds bugs in JavaScript programs.
13+
# Copyright (C) 2020 Matthew Glazar
14+
#
15+
# This file is part of quick-lint-js.
16+
#
17+
# quick-lint-js is free software: you can redistribute it and/or modify
18+
# it under the terms of the GNU General Public License as published by
19+
# the Free Software Foundation, either version 3 of the License, or
20+
# (at your option) any later version.
21+
#
22+
# quick-lint-js is distributed in the hope that it will be useful,
23+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
24+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25+
# GNU General Public License for more details.
26+
#
27+
# You should have received a copy of the GNU General Public License
28+
# along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>.

plugin/emacs/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# flycheck-quicklintjs Emacs plugin
2+
3+
This directory contains a plugin for the [Emacs text editor][Emacs].
4+
5+
This plugin integrates with other Emacs plugins to show lint rules when editing
6+
files in Emacs.
7+
8+
**Important**: Installing this Emacs plugin will not also install quick-lint-js
9+
itself. You must separately install quick-lint-js in order for this plugin to
10+
work.
11+
12+
Flycheck plugin must be installed and configured in order for this plugin to
13+
work:
14+
15+
* [Flycheck] - On the fly syntax checking for GNU Emacs 31 or newer
16+
17+
## Installation
18+
19+
### Manually
20+
21+
You need to copy flycheck-quicklintjs.el inside a folder present in Emacs
22+
load-path, a default one that is looked up by Emacs is
23+
`/usr/local/share/emacs/site-lisp` but requires root privileges, alternatively
24+
you may append a custom folder of your preference containing the
25+
`flycheck-quicklintjs.el` file to Emacs load-path variable, for example:
26+
27+
```lisp
28+
(add-to-list 'load-path "~/.emacs/quicklintjs")
29+
```
30+
31+
A less convenient way also possible is appending to `load-path` with Emacs
32+
command line argument `-L folder`
33+
34+
### Initialization
35+
36+
When Emacs is able to find the quick-lint-js library, you need to load it,
37+
your [Emacs Initialization] file is a good place:
38+
39+
```lisp
40+
(require 'flycheck)
41+
(require 'flycheck-quicklintjs)
42+
```
43+
44+
At this point quick-lint-js should be registered as a checker, which you can
45+
verify with `M-x flycheck-verify-setup`, optionally we suggest that you add
46+
this hook to `js-mode`, which will remove the delay after you type that
47+
Flycheck waits before running the checker, also registers `quick-lint-js`
48+
as the selected checker by default, instead of `eslint`.
49+
50+
```lisp
51+
(defun my-flycheck-quicklintjs-setup ()
52+
"Configure flycheck-quicklintjs for better experience."
53+
54+
;; Enable Flycheck
55+
(unless (bound-and-true-p flycheck-mode)
56+
(flycheck-mode))
57+
58+
;; Use quick-lint-js by default when in 'js-mode`
59+
(flycheck-select-checker 'javascript-quicklintjs)
60+
61+
;; Remove any delay after a change in buffer to run checkers.
62+
;; The default is 0.5 (500ms)
63+
(setq-local flycheck-idle-change-delay 0)
64+
65+
;; Run quick-lint-js program when the buffer is changed and when 'js-mode` is
66+
;; loaded
67+
(setq-local flycheck-check-syntax-automatically '(mode-enabled idle-change)))
68+
(add-hook 'js-mode-hook #'my-flycheck-quicklintjs-setup)
69+
```
70+
71+
[Flycheck]: https://www.flycheck.org/
72+
[Emacs]: https://www.gnu.org/software/emacs/
73+
[Emacs Initialization]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html

plugin/emacs/flycheck-quicklintjs.el

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
;;; flycheck-quicklintjs --- quick-lint-js flycheck support -*- lexical-binding: t; -*-
2+
3+
;;; Commentary:
4+
5+
;; This flycheck exetension configures flycheck to run quick-lint-js
6+
;; to run as a checker.
7+
;;
8+
;; Example usage in your init.el:
9+
;;
10+
;; (require 'flycheck-quicklintjs)
11+
;;
12+
;; ;; Optionally you can setup Flycheck with the expected
13+
;; ;; quick-lint-js experience:
14+
;; (defun my-flycheck-quicklintjs-setup ()
15+
;; "Configure flycheck-quicklintjs for better experience."
16+
;;
17+
;; ;; Enable Flycheck
18+
;; (unless (bound-and-true-p flycheck-mode)
19+
;; (flycheck-mode))
20+
;;
21+
;; ;; Use quick-lint-js by default when in 'js-mode`
22+
;; (flycheck-select-checker 'javascript-quicklintjs)
23+
;;
24+
;; ;; Remove any delay after a change in buffer to run checkers.
25+
;; ;; The default is 0.5 (500ms)
26+
;; (setq-local flycheck-idle-change-delay 0)
27+
;;
28+
;; ;; Run quick-lint-js program when the buffer is changed and when 'js-mode` is
29+
;; ;; loaded
30+
;; (setq-local flycheck-check-syntax-automatically '(mode-enabled idle-change)))
31+
;; (add-hook 'js-mode-hook #'my-flycheck-quicklintjs-setup)
32+
;;
33+
34+
;;; Code:
35+
36+
(require 'flycheck)
37+
38+
(defgroup flycheck-quicklintjs nil
39+
"quick-lint-js Flycheck integration."
40+
:prefix "flycheck-"
41+
:group 'flycheck
42+
:group 'quicklintjs
43+
:link '(url-link :tag "Website" "https://quick-lint-js.com"))
44+
45+
(flycheck-def-args-var flycheck-quicklintjs-args javascript-quicklintjs)
46+
(flycheck-def-executable-var javascript-quicklintjs "quick-lint-js")
47+
48+
(flycheck-define-checker javascript-quicklintjs
49+
"quick-lint-js finds bugs in JavaScript programs.
50+
51+
https://quick-lint-js.com"
52+
:command ("quick-lint-js"
53+
"--output-format=gnu-like"
54+
(eval flycheck-quicklintjs-args)
55+
source)
56+
:standard-input 't
57+
:error-patterns ((error
58+
line-start (file-name) ":" line ":" column ":"
59+
(zero-or-more whitespace) "error:" (zero-or-more whitespace)
60+
(message) line-end)
61+
(warning
62+
line-start (file-name) ":" line ":" column ":"
63+
(zero-or-more whitespace) "warning:" (zero-or-more whitespace)
64+
(message) line-end))
65+
:modes js-mode)
66+
67+
(add-to-list 'flycheck-checkers 'javascript-quicklintjs t)
68+
69+
(provide 'flycheck-quicklintjs)
70+
71+
;; quick-lint-js finds bugs in JavaScript programs.
72+
;; Copyright (C) 2020 Matthew Glazar
73+
;;
74+
;; This file is part of quick-lint-js.
75+
;;
76+
;; quick-lint-js is free software: you can redistribute it and/or modify
77+
;; it under the terms of the GNU General Public License as published by
78+
;; the Free Software Foundation, either version 3 of the License, or
79+
;; (at your option) any later version.
80+
;;
81+
;; quick-lint-js is distributed in the hope that it will be useful,
82+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
83+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84+
;; GNU General Public License for more details.
85+
;;
86+
;; You should have received a copy of the GNU General Public License
87+
;; along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>.
88+
89+
;;; flycheck-quicklintjs.el ends here

plugin/emacs/test-emacs.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/sh
2+
3+
# Copyright (C) 2020 Matthew Glazar
4+
# See end of file for extended copyright information.
5+
6+
set -e
7+
set -u
8+
9+
cd "$(dirname "${0}")"
10+
11+
emacs \
12+
-Q \
13+
--batch \
14+
-L . \
15+
-l test/quicklintjs-test.el \
16+
-f quicklintjs-test-main
17+
18+
# quick-lint-js finds bugs in JavaScript programs.
19+
# Copyright (C) 2020 Matthew Glazar
20+
#
21+
# This file is part of quick-lint-js.
22+
#
23+
# quick-lint-js is free software: you can redistribute it and/or modify
24+
# it under the terms of the GNU General Public License as published by
25+
# the Free Software Foundation, either version 3 of the License, or
26+
# (at your option) any later version.
27+
#
28+
# quick-lint-js is distributed in the hope that it will be useful,
29+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
30+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31+
# GNU General Public License for more details.
32+
#
33+
# You should have received a copy of the GNU General Public License
34+
# along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>.

plugin/emacs/test/error.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function() {
2+
let var x = 1
3+
4+
// quick-lint-js finds bugs in JavaScript programs.
5+
// Copyright (C) 2020 Matthew Glazar
6+
//
7+
// This file is part of quick-lint-js.
8+
//
9+
// quick-lint-js is free software: you can redistribute it and/or modify
10+
// it under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 3 of the License, or
12+
// (at your option) any later version.
13+
//
14+
// quick-lint-js is distributed in the hope that it will be useful,
15+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>.

plugin/emacs/test/quicklintjs-test.el

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
;;; quicklintjs-test.el --- quick-lint-js test suite -*- lexical-binding: t; -*-
2+
;;; Commentary:
3+
4+
;;; Code:
5+
(require 'ert)
6+
(require 'package)
7+
8+
(defconst cache-dir-name (concat
9+
(expand-file-name default-directory)
10+
".melpa-cache/"))
11+
12+
(defun quicklintjs-test-main ()
13+
(setq package-user-dir cache-dir-name
14+
package-check-signature nil)
15+
(add-to-list 'package-archives
16+
'("MELPA" . "https://stable.melpa.org/packages/"))
17+
(package-initialize)
18+
19+
(unless package-archive-contents
20+
(package-refresh-contents))
21+
22+
(unless (package-installed-p 'flycheck)
23+
;; the DONT-SELECT argument is only available and make sense
24+
;; in emacs 25 and above.
25+
(if (> emacs-major-version 24)
26+
(package-install 'flycheck t)
27+
(package-install 'flycheck)))
28+
29+
(require 'flycheck)
30+
(require 'flycheck-ert)
31+
(require 'flycheck-quicklintjs)
32+
(def-flycheck-tests)
33+
(ert-run-tests-batch-and-exit))
34+
35+
(ert-deftest quicklintjs-is-in-checkers ()
36+
(should (member 'javascript-quicklintjs flycheck-checkers)))
37+
38+
(defun def-flycheck-tests ()
39+
(flycheck-ert-def-checker-test javascript-quicklintjs javascript error
40+
(let ((flycheck-checker 'javascript-quicklintjs)
41+
(inhibit-message t))
42+
(flycheck-ert-should-syntax-check
43+
"test/error.js" '(js-mode)
44+
'(1 1 error "missing name in function statement [E061]"
45+
:checker javascript-quicklintjs)
46+
'(1 12 error "unclosed code block; expected '}' by end of file [E134]"
47+
:checker javascript-quicklintjs)
48+
'(2 7 error "unexpected token in variable declaration; expected variable name [E114]"
49+
:checker javascript-quicklintjs))))
50+
51+
(flycheck-ert-def-checker-test javascript-quicklintjs javascript warning
52+
(let ((flycheck-checker 'javascript-quicklintjs)
53+
(inhibit-message t))
54+
(flycheck-ert-should-syntax-check
55+
"test/warning.js" '(js-mode)
56+
'(1 1 warning "assignment to undeclared variable [E059]"
57+
:checker javascript-quicklintjs)))))
58+
59+
;; quick-lint-js finds bugs in JavaScript programs.
60+
;; Copyright (C) 2020 Matthew Glazar
61+
;;
62+
;; This file is part of quick-lint-js.
63+
;;
64+
;; quick-lint-js is free software: you can redistribute it and/or modify
65+
;; it under the terms of the GNU General Public License as published by
66+
;; the Free Software Foundation, either version 3 of the License, or
67+
;; (at your option) any later version.
68+
;;
69+
;; quick-lint-js is distributed in the hope that it will be useful,
70+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
71+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72+
;; GNU General Public License for more details.
73+
;;
74+
;; You should have received a copy of the GNU General Public License
75+
;; along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>.
76+
77+
;;; quicklintjs-test.el ends here

0 commit comments

Comments
 (0)