diff --git a/cmake/FindQuickLintJSEmacs.cmake b/cmake/FindQuickLintJSEmacs.cmake
new file mode 100644
index 0000000000..181c47e8fa
--- /dev/null
+++ b/cmake/FindQuickLintJSEmacs.cmake
@@ -0,0 +1,49 @@
+# Copyright (C) 2020 Matthew "strager" Glazar
+# See end of file for extended copyright information.
+
+find_program(QUICK_LINT_JS_EMACS "emacs")
+
+if (NOT QUICK_LINT_JS_EMACS)
+ return ()
+endif ()
+
+execute_process(
+ COMMAND
+ ${QUICK_LINT_JS_EMACS}
+ -Q -batch
+ --eval "(princ (format \"%s.%s\" emacs-major-version emacs-minor-version))"
+ RESULT_VARIABLE EMACS_EXIT_CODE
+ OUTPUT_VARIABLE EMACS_VERSION)
+
+if (NOT EMACS_EXIT_CODE EQUAL 0)
+ message(WARNING "Emacs (${QUICK_LINT_JS_EMACS}) found but can't get its version. Skipping...")
+ return ()
+endif()
+
+if (NOT EMACS_VERSION GREATER_EQUAL 24.5)
+ message(WARNING "Emacs found (${QUICK_LINT_JS_EMACS}), but version ${EMACS_VERSION} is not supported. Skipping...")
+ return ()
+endif ()
+
+set(QUICK_LINT_JS_EMACS_FOUND TRUE)
+message(STATUS "Found Emacs ${QUICK_LINT_JS_EMACS} (found suitable version \"${EMACS_VERSION}\" minimum required is \"24.5\")")
+
+mark_as_advanced(QUICK_LINT_JS_EMACS)
+
+# quick-lint-js finds bugs in JavaScript programs.
+# Copyright (C) 2020 Matthew "strager" Glazar
+#
+# This file is part of quick-lint-js.
+#
+# quick-lint-js is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# quick-lint-js is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with quick-lint-js. If not, see .
diff --git a/plugin/emacs/CMakeLists.txt b/plugin/emacs/CMakeLists.txt
index 6ff75d213a..3955c6ef2d 100644
--- a/plugin/emacs/CMakeLists.txt
+++ b/plugin/emacs/CMakeLists.txt
@@ -4,13 +4,82 @@
cmake_minimum_required(VERSION 3.10)
include(GNUInstallDirs)
-install(
- FILES flycheck-quicklintjs.el
- FILES lsp-quicklintjs.el
- FILES eglot-quicklintjs.el
- FILES flymake-quicklintjs.el
- DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/emacs/site-lisp"
-)
+find_package(QuickLintJSEmacs)
+
+macro(emacs_pkg_target NAME FILE)
+ cmake_parse_arguments(
+ ""
+ ""
+ "OUTPUT"
+ ""
+ ${ARGN})
+
+ add_custom_command(
+ OUTPUT ${_OUTPUT}
+ COMMAND
+ ${QUICK_LINT_JS_EMACS}
+ -Q -batch
+ -l package --eval "(package-initialize)"
+ --eval "(add-to-list 'package-directory-list \"${CMAKE_CURRENT_BINARY_DIR}\")"
+ -l ${CMAKE_CURRENT_LIST_DIR}/quicklintjs-make-package.el
+ -f quicklintjs-batch-make-pkg
+ ${FILE}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPENDS
+ ${QUICK_LINT_JS_EMACS}
+ ${CMAKE_CURRENT_LIST_DIR}/quicklintjs-make-package.el
+ ${FILE}
+ VERBATIM)
+
+ add_custom_target(${NAME} ALL DEPENDS ${_OUTPUT})
+endmacro ()
+
+if (QUICK_LINT_JS_EMACS_FOUND)
+ emacs_pkg_target(emacs-plugin-quicklintjs
+ ${CMAKE_CURRENT_LIST_DIR}/quicklintjs.el 0.0.1
+ OUTPUT quicklintjs-0.0.1)
+
+ emacs_pkg_target(emacs-plugin-flycheck-quicklintjs
+ ${CMAKE_CURRENT_LIST_DIR}/flycheck-quicklintjs.el 0.0.1
+ OUTPUT flycheck-quicklintjs-0.0.1)
+
+ emacs_pkg_target(emacs-plugin-flymake-quicklintjs
+ ${CMAKE_CURRENT_LIST_DIR}/flymake-quicklintjs.el 0.0.1
+ OUTPUT flymake-quicklintjs-0.0.1)
+
+ emacs_pkg_target(emacs-plugin-eglot-quicklintjs
+ ${CMAKE_CURRENT_LIST_DIR}/eglot-quicklintjs.el 0.0.1
+ OUTPUT eglot-quicklintjs-0.0.1)
+
+ emacs_pkg_target(emacs-plugin-lsp-quicklintjs
+ ${CMAKE_CURRENT_LIST_DIR}/lsp-quicklintjs.el 0.0.1
+ OUTPUT lsp-quicklintjs-0.0.1)
+
+ add_dependencies(emacs-plugin-flycheck-quicklintjs
+ emacs-plugin-quicklintjs)
+ add_dependencies(emacs-plugin-flymake-quicklintjs
+ emacs-plugin-quicklintjs)
+ add_dependencies(emacs-plugin-eglot-quicklintjs
+ emacs-plugin-quicklintjs)
+ add_dependencies(emacs-plugin-lsp-quicklintjs
+ emacs-plugin-quicklintjs)
+
+ install(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/quicklintjs-0.0.1
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/emacs/site-lisp/elpa)
+ install(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/flycheck-quicklintjs-0.0.1
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/emacs/site-lisp/elpa)
+ install(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/flymake-quicklintjs-0.0.1
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/emacs/site-lisp/elpa)
+ install(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/eglot-quicklintjs-0.0.1
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/emacs/site-lisp/elpa)
+ install(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lsp-quicklintjs-0.0.1
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/emacs/site-lisp/elpa)
+endif ()
# quick-lint-js finds bugs in JavaScript programs.
# Copyright (C) 2020 Matthew "strager" Glazar
diff --git a/plugin/emacs/eglot-quicklintjs.el b/plugin/emacs/eglot-quicklintjs.el
index fbc7249a16..25dec1d245 100644
--- a/plugin/emacs/eglot-quicklintjs.el
+++ b/plugin/emacs/eglot-quicklintjs.el
@@ -1,5 +1,28 @@
;;; eglot-quicklintjs.el --- Eglot support for quick-lint-js -*- lexical-binding: t; -*-
+;; Copyright (C) 2020 Matthew "strager" Glazar
+
+;; Version: 0.0.1
+;; Author: Wagner Riffel
+;; URL: https://quick-lint-js.com
+;; Keywords: languages, tools
+;; Package-Requires: ((quicklintjs "0.0.1") (eglot "1.7") (emacs "26.1"))
+
+;; This file is part of quick-lint-js.
+;;
+;; quick-lint-js is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; quick-lint-js is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with quick-lint-js. If not, see .
+
;;; Commentary:
;; Eglot support for quick-lint-js.
@@ -19,44 +42,13 @@
;;; Code:
(require 'eglot)
+(require 'quicklintjs)
-(defgroup eglot-quicklintjs nil
- "quick-lint-js Eglot integration."
- :group 'eglot-quicklintjs
- :link '(url-link :tag "Website" "https://quick-lint-js.com"))
-
-(defcustom eglot-quicklintjs-program "quick-lint-js"
- "Path to quick-lint-js program to run."
- :group 'eglot-quicklintjs
- :type 'stringp)
-
-(defcustom eglot-quicklintjs-args nil
- "Arguments to quick-lint-js."
- :group 'eglot-quicklintjs
- :type '(repeat string))
-
-(add-to-list 'eglot-server-programs `(js-mode . (,eglot-quicklintjs-program
- "--lsp-server"
- ,@eglot-quicklintjs-args)))
+;;;###autoload
+(with-eval-after-load 'eglot
+ (add-to-list 'eglot-server-programs `(js-mode . ,(quicklintjs-find-program
+ "--lsp-server"))))
(provide 'eglot-quicklintjs)
-;; quick-lint-js finds bugs in JavaScript programs.
-;; Copyright (C) 2020 Matthew Glazar
-;;
-;; This file is part of quick-lint-js.
-;;
-;; quick-lint-js is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; quick-lint-js is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with quick-lint-js. If not, see .
-
;;; eglot-quicklintjs.el ends here
diff --git a/plugin/emacs/flycheck-quicklintjs.el b/plugin/emacs/flycheck-quicklintjs.el
index 37b2081b63..fa33ebe669 100644
--- a/plugin/emacs/flycheck-quicklintjs.el
+++ b/plugin/emacs/flycheck-quicklintjs.el
@@ -1,4 +1,27 @@
-;;; flycheck-quicklintjs --- quick-lint-js Flycheck support -*- lexical-binding: t; -*-
+;;; flycheck-quicklintjs.el --- quick-lint-js Flycheck support -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Matthew "strager" Glazar
+
+;; Version: 0.0.1
+;; Author: Wagner Riffel
+;; URL: https://quick-lint-js.com
+;; Keywords: languages, tools
+;; Package-Requires: ((quicklintjs "0.0.1") (flycheck "32-cvs") (emacs "24.5"))
+
+;; This file is part of quick-lint-js.
+;;
+;; quick-lint-js is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; quick-lint-js is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with quick-lint-js. If not, see .
;;; Commentary:
@@ -35,19 +58,10 @@
;;; Code:
(require 'flycheck)
-
-(defgroup flycheck-quicklintjs nil
- "quick-lint-js Flycheck integration."
- :prefix "flycheck-"
- :group 'flycheck
- :group 'quicklintjs
- :link '(url-link :tag "Website" "https://quick-lint-js.com"))
-
-(flycheck-def-args-var flycheck-quicklintjs-args javascript-quicklintjs)
-(flycheck-def-executable-var javascript-quicklintjs "quick-lint-js")
+(require 'quicklintjs)
(defun flycheck-quicklintjs-parse-errors (output checker buffer)
- "Parse quick-lint-js alist output format from OUTPUT"
+ "Parse CHECKER quick-lint-js alist output format from OUTPUT."
(mapcar (lambda (l)
(let ((region (nth 0 l))
(sev (nth 1 l))
@@ -60,48 +74,31 @@
:id code
:buffer buffer
:checker checker
- :end-pos (cdr region)))) (car (read-from-string output))))
+ :end-pos (cdr region))))
+ (car (read-from-string output))))
-(flycheck-define-checker javascript-quicklintjs
+;;;###autoload
+(flycheck-define-command-checker 'javascript-quicklintjs
"quick-lint-js finds bugs in JavaScript programs.
https://quick-lint-js.com"
- :command ("quick-lint-js"
- "--output-format=emacs-lisp"
- (eval (let ((file (buffer-file-name)))
- (if file
- `("--path-for-config-search" ,file)
- ())))
- "--stdin"
- (eval flycheck-quicklintjs-args))
- :standard-input t
- :error-parser flycheck-quicklintjs-parse-errors
+ :command (quicklintjs-find-program
+ "--output-format=emacs-lisp"
+ (let ((file (buffer-file-name)))
+ (when file (concat "--path-for-config-search=" file)))
+ "--stdin")
+ :standard-input 't
+ :error-parser 'flycheck-quicklintjs-parse-errors
:error-explainer (lambda (err)
(let ((error-code (flycheck-error-id err))
(url "https://quick-lint-js.com/errors/#%s"))
(and error-code `(url . ,(format url error-code)))))
- :modes js-mode)
+ :modes 'js-mode)
-(add-to-list 'flycheck-checkers 'javascript-quicklintjs t)
+;;;###autoload
+(with-eval-after-load 'flycheck
+ (add-to-list 'flycheck-checkers 'javascript-quicklintjs t))
(provide 'flycheck-quicklintjs)
-;; quick-lint-js finds bugs in JavaScript programs.
-;; Copyright (C) 2020 Matthew "strager" Glazar
-;;
-;; This file is part of quick-lint-js.
-;;
-;; quick-lint-js is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; quick-lint-js is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with quick-lint-js. If not, see .
-
;;; flycheck-quicklintjs.el ends here
diff --git a/plugin/emacs/flymake-quicklintjs.el b/plugin/emacs/flymake-quicklintjs.el
index 24cc227380..219cf0d11b 100644
--- a/plugin/emacs/flymake-quicklintjs.el
+++ b/plugin/emacs/flymake-quicklintjs.el
@@ -1,5 +1,28 @@
;;; flymake-quicklintjs.el --- Flymake support for quick-lint-js -*- lexical-binding: t; -*-
+;; Copyright (C) 2020 Matthew "strager" Glazar
+
+;; Version: 0.0.1
+;; Author: Wagner Riffel
+;; URL: https://quick-lint-js.com
+;; Keywords: languages, tools
+;; Package-Requires: ((quicklintjs "0.0.1") (flymake "1.0.9") (emacs "26.1"))
+
+;; This file is part of quick-lint-js.
+;;
+;; quick-lint-js is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; quick-lint-js is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with quick-lint-js. If not, see .
+
;;; Commentary:
;; Flymake support for quick-lint-js.
@@ -14,7 +37,6 @@
;; ;; Enable Flymake
;; (unless (bound-and-true-p flymake-mode)
;; (flymake-mode))
-;; (add-hook 'flymake-diagnostic-functions #'flymake-quicklintjs nil t)
;;
;; ;; Remove the time to wait after last change before automatically checking
;; ;; buffer. The default is 0.5 (500ms)
@@ -24,20 +46,7 @@
;;; Code:
(require 'flymake)
-
-(defgroup flymake-quicklintjs nil
- "Flymake backend for quick-lint-js"
- :link '(url-link :tag "Website" "https://quick-lint-js.com"))
-
-(defcustom flymake-quicklintjs-program "quick-lint-js"
- "Path to quick-lint-js program to run."
- :group 'flymake-quicklintjs
- :type 'stringp)
-
-(defcustom flymake-quicklintjs-args nil
- "Arguments to quick-lint-js."
- :group 'flymake-quicklintjs
- :type '(repeat 'string))
+(require 'quicklintjs)
(defvar-local flymake-quicklintjs--proc nil
"Internal variable for `flymake-quicklintjs'")
@@ -53,70 +62,95 @@ Return a list of Flymake diagnostic objects in source buffer SRC-BUF."
(if (= sev 0) :error :warning) msg)))
quicklintjs-output-alist))
+(defun flymake-quicklintjs--report-with-crash (qljs-stdout-buf
+ qljs-stderr-buf
+ src-buf report-fn)
+ "Similar to `flymake-quicklintjs--report' but try to recover errors in\
+SRC-BUF when quick-lint-js crashes by inspecting QLJS-STDOUT-BUF.
+Whatever is in QLJS-STDERR-BUF is also logged as warning using `flymake-log'."
+ (flymake-log :warning
+ "quick-lint-js exited with a deadly signal.\n\
+Please consider filing a bug at\
+ https://github.com/quick-lint/quick-lint-js/issues/new\n\
+qjls-stderr-buf:\n\
+%s\n"
+ (with-current-buffer qljs-stderr-buf
+ (buffer-substring-no-properties (point-min) (point-max))))
+ (with-current-buffer qljs-stdout-buf
+ (save-excursion
+ ;; a crash without any previous issue, try to fix an empty buffer
+ (when (zerop (buffer-size))
+ (goto-char (point-min))
+ (insert-char ?\())
+ ;; the above left a '(' dangling or quick-lint-js crashed and
+ ;; emacs_lisp_error_reporter::finish() haven't been called yet
+ (goto-char (point-min))
+ (when (eq (char-after 1) ?\()
+ (goto-char (point-max))
+ (insert-char ?\)))))
+ (condition-case nil
+ (flymake-quicklintjs--report qljs-stdout-buf src-buf report-fn)
+ (funcall report-fn '())))
+
+(defun flymake-quicklintjs--report (qljs-stdout-buf src-buf report-fn)
+ "Call REPORT-FN to highlight reports in SRC-BUF reported in QLJS-STDOUT-BUF.
+QLJS-STDOUT-BUF is entirely read and it's expected to be in
+QUICKLINTJS-OUTPUT-ALIST format."
+ (with-current-buffer qljs-stdout-buf
+ (funcall report-fn
+ (flymake-quicklintjs--make-diagnostics
+ src-buf
+ (car (read-from-string
+ (buffer-substring-no-properties (point-min)
+ (point-max))))))))
+
;;;###autoload
(defun flymake-quicklintjs (report-fn &rest _args)
"Flymake backend for quick-lint-js linter.
-This backend uses `flymake-quicklintjs-program' (which see) to launch a
-quick-lint-js process that is passed the current buffer's contents via stdin.
+This backend uses `quicklintjs-find-program' to find and launch a quick-lint-js
+process that is passed the current buffer's contents via stdin.
REPORT-FN is Flymake's callback."
(when (process-live-p flymake-quicklintjs--proc)
(kill-process flymake-quicklintjs--proc))
- (let ((src-buf (current-buffer)))
- (setq flymake-quicklintjs--proc
- (make-process
- :name "flymake-quicklintjs"
- :connection-type 'pipe
- :noquery t
- :buffer (get-buffer-create " *flymake-quicklintjs*")
- :command `(,flymake-quicklintjs-program
- ,@(let ((file (buffer-file-name)))
- (if file
- `("--path-for-config-search" ,file)
- ()))
- "--stdin" "--output-format=emacs-lisp"
- ,@flymake-quicklintjs-args)
- :sentinel
- (lambda (p _ev)
- (unwind-protect
- (when (and (eq 'exit (process-status p))
- (eq p flymake-quicklintjs--proc))
- (with-current-buffer (process-buffer p)
- (let ((diags (flymake-quicklintjs--make-diagnostics
- src-buf
- (car (read-from-string
- (buffer-substring-no-properties
- (point-min) (point-max)))))))
- (if (or diags (zerop (process-exit-status p)))
- (funcall report-fn diags
- :region (cons (point-min) (point-max)))
- (funcall report-fn
- :panic :explanation
- (buffer-substring
- (point-min) (progn (goto-char (point-min))
- (line-end-position))))))))
- (unless (process-live-p p)
- (kill-buffer (process-buffer p)))))))
- (process-send-region flymake-quicklintjs--proc (point-min) (point-max))
- (process-send-eof flymake-quicklintjs--proc)))
+ (let ((src-buf (current-buffer))
+ (stdout-buf (generate-new-buffer " *flymake-quicklintjs-stdout*"))
+ (stderr-buf (generate-new-buffer " *flymake-quicklintjs-stderr*")))
+ (save-restriction
+ (widen)
+ (setq flymake-quicklintjs--proc
+ (make-process
+ :name "flymake-quicklintjs"
+ :connection-type 'pipe
+ :noquery t
+ :buffer stdout-buf
+ :stderr stderr-buf
+ :command (quicklintjs-find-program
+ (let ((file (buffer-file-name)))
+ (when file (concat "--path-for-config-search=" file)))
+ "--stdin" "--output-format=emacs-lisp")
+ :sentinel
+ (lambda (p _ev)
+ (let ((proc-status (process-status p)))
+ (unwind-protect
+ (when (and (or (eq proc-status 'exit)
+ (eq proc-status 'signal))
+ (with-current-buffer src-buf
+ (eq p flymake-quicklintjs--proc)))
+ (if (zerop (process-exit-status p))
+ (flymake-quicklintjs--report stdout-buf
+ src-buf
+ report-fn)
+ (flymake-quicklintjs--report-with-crash
+ stdout-buf stderr-buf src-buf report-fn)))
+ (progn (kill-buffer stdout-buf)
+ (kill-buffer stderr-buf)))))))
+ (process-send-region flymake-quicklintjs--proc (point-min) (point-max))
+ (process-send-eof flymake-quicklintjs--proc))))
-(provide 'flymake-quicklintjs)
+;;;###autoload
+(with-eval-after-load 'flymake
+ (add-hook 'flymake-diagnostic-functions #'flymake-quicklintjs nil t))
-;; quick-lint-js finds bugs in JavaScript programs.
-;; Copyright (C) 2020 Matthew Glazar
-;;
-;; This file is part of quick-lint-js.
-;;
-;; quick-lint-js is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; quick-lint-js is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with quick-lint-js. If not, see .
+(provide 'flymake-quicklintjs)
;;; flymake-quicklintjs.el ends here
diff --git a/plugin/emacs/lsp-quicklintjs.el b/plugin/emacs/lsp-quicklintjs.el
index 48a28b0268..b8ed0fef8e 100644
--- a/plugin/emacs/lsp-quicklintjs.el
+++ b/plugin/emacs/lsp-quicklintjs.el
@@ -1,4 +1,27 @@
-;;; lsp-quicklintjs --- LSP support for quick-lint-js -*- lexical-binding: t; -*-
+;;; lsp-quicklintjs.el --- LSP support for quick-lint-js -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Matthew "strager" Glazar
+
+;; Version: 0.0.1
+;; Author: Wagner Riffel
+;; URL: https://quick-lint-js.com
+;; Keywords: languages, tools
+;; Package-Requires: ((quicklintjs "0.0.1") (lsp-mode "7.0.1") (emacs "26.1"))
+
+;; This file is part of quick-lint-js.
+;;
+;; quick-lint-js is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; quick-lint-js is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with quick-lint-js. If not, see .
;;; Commentary:
@@ -18,46 +41,32 @@
;;; Code:
(require 'lsp-mode)
+(require 'quicklintjs)
-(defgroup lsp-quicklintjs nil
- "quick-lint-js LSP Mode integration."
- :link '(url-link :tag "Website" "https://quick-lint-js.com"))
-
-(defcustom lsp-quicklintjs-program "quick-lint-js"
- "Path to quick-lint-js program to run."
- :group 'lsp-quicklintjs
- :type 'stringp)
+;;;###autoload
+(defun lsp-quicklintjs ()
+ "Like `lsp', but set root folder to `default-directory' to avoid project root\
+prompts."
+ (interactive)
+ ;; Don't mess with user's session state file
+ (set (make-local-variable 'lsp-session-file)
+ (expand-file-name (locate-user-emacs-file
+ ".lsp-quicklintjs-session-v1")))
+ (let* ((session (lsp-session)))
+ (cl-pushnew (expand-file-name default-directory)
+ (lsp-session-folders session) :test 'equal)
+ (lsp--persist-session session))
+ (lsp))
-(defcustom lsp-quicklintjs-args nil
- "Arguments to quick-lint-js."
- :group 'lsp-quicklintjs
- :type '(repeat string))
-
-(lsp-register-client
- (make-lsp-client
- :new-connection (lsp-stdio-connection `(,lsp-quicklintjs-program "--lsp-server"
- ,@lsp-quicklintjs-args))
- :major-modes '(js-mode)
- :server-id 'quick-lint-js))
+;;;###autoload
+(with-eval-after-load 'lsp-mode
+ (lsp-register-client
+ (make-lsp-client
+ :new-connection (lsp-stdio-connection `,(quicklintjs-find-program
+ "--lsp-server"))
+ :major-modes '(js-mode)
+ :server-id 'quick-lint-js)))
(provide 'lsp-quicklintjs)
-;; quick-lint-js finds bugs in JavaScript programs.
-;; Copyright (C) 2020 Matthew Glazar
-;;
-;; This file is part of quick-lint-js.
-;;
-;; quick-lint-js is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; quick-lint-js is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with quick-lint-js. If not, see .
-
;;; lsp-quicklintjs.el ends here
diff --git a/plugin/emacs/quicklintjs-make-package.el b/plugin/emacs/quicklintjs-make-package.el
new file mode 100644
index 0000000000..d4966ab08a
--- /dev/null
+++ b/plugin/emacs/quicklintjs-make-package.el
@@ -0,0 +1,47 @@
+;;; quicklintjs-pkg.el --- Build quick-lint-js Emacs plugins packages -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Matthew "strager" Glazar
+
+;; Version: 0.0.1
+;; Author: Wagner Riffel
+;; URL: https://quick-lint-js.com
+;; Keywords: languages, tools
+;; Package-Requires: ((emacs "24.5"))
+
+;; This file is part of quick-lint-js.
+;;
+;; quick-lint-js is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; quick-lint-js is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with quick-lint-js. If not, see .
+
+;;; Commentary:
+
+;;; Code:
+
+(defun quicklintjs-batch-make-pkg ()
+ (setq package-user-dir nil)
+ (cl-assert (= (length command-line-args-left) 1))
+
+ (let ((file (car command-line-args-left))
+ (inhibit-message 't))
+ (with-temp-buffer
+ (insert-file-contents-literally file)
+ (let* ((pkg-desc (package-buffer-info))
+ (pkg-ver (package-desc-version pkg-desc))
+ (pkg-dir (format "%s-%s.%s"
+ (file-name-sans-extension file)
+ (car pkg-ver)
+ (car (cdr pkg-ver)))))
+ (add-to-list 'package-directory-list pkg-dir)
+ (package-unpack pkg-desc)))))
+
+;;; quicklintjs-pkg.el ends here
diff --git a/plugin/emacs/quicklintjs.el b/plugin/emacs/quicklintjs.el
new file mode 100644
index 0000000000..e7a54d7109
--- /dev/null
+++ b/plugin/emacs/quicklintjs.el
@@ -0,0 +1,77 @@
+;;; quicklintjs.el --- Helper functions for quicklintjs Emacs plugins -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Matthew "strager" Glazar
+
+;; Version: 0.0.1
+;; Author: Wagner Riffel
+;; URL: https://quick-lint-js.com
+;; Keywords: languages, tools
+;; Package-Requires: ((emacs "24.5"))
+
+;; This file is part of quick-lint-js.
+;;
+;; quick-lint-js is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; quick-lint-js is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with quick-lint-js. If not, see .
+
+;;; Commentary:
+
+;; Shared parts of configuration and code among others Emacs plugins.
+
+;;; Code:
+
+(defgroup quicklintjs nil
+ "quick-lint-js finds bugs in JavaScript programs."
+ :prefix "quicklintjs-"
+ :group 'tools
+ :group 'processes
+ :link '(url-link :tag "Website" "https://quick-lint-js.com"))
+
+(defcustom quicklintjs-program-name "quick-lint-js"
+ "Quick-lint-js executable name to search."
+ :group 'quicklintjs
+ :type 'string
+ :safe 'stringp)
+
+(defcustom quicklintjs-program-args nil
+ "Arguments to `quicklintjs-program-name'."
+ :group 'quicklintjs
+ :type '(repeat 'string))
+
+(defcustom quicklintjs-find-program-function #'quicklintjs-executable-find
+ "Function to find quick-lint-js."
+ :group 'quicklintjs
+ :type '(choice (const :tag "Search quick-lint-js in `exec-path'"
+ quicklintjs-executable-find)
+ (const :tag "Search quick-lint-js in node-modules"
+ quicklintjs-node-modules-executable-find)
+ (function :tag "Function to get quick-lint-js path")))
+
+;;;###autoload
+(defun quicklintjs-executable-find ()
+ "Search `quicklintjs-program-name' in variable `exec-path'."
+ (executable-find quicklintjs-program-name))
+
+;;;###autoload
+(defun quicklintjs-find-program (&rest argv)
+ "Make a list of strings by calling `quicklintjs-find-program-function',\
+appending `quicklintjs-program-args' and ARGV.
+Empty strings and nil are ignored."
+ (cl-remove-if-not (lambda (a) (and (stringp a)
+ (> (length a) 0)))
+ (append (list (funcall
+ quicklintjs-find-program-function))
+ quicklintjs-program-args argv)))
+
+(provide 'quicklintjs)
+
+;;; quicklintjs.el ends here
diff --git a/plugin/emacs/test/quicklintjs-test.el b/plugin/emacs/test/quicklintjs-test.el
index d2ba5ae04d..36a40f77db 100644
--- a/plugin/emacs/test/quicklintjs-test.el
+++ b/plugin/emacs/test/quicklintjs-test.el
@@ -2,8 +2,10 @@
;;; Commentary:
;;; Code:
+(require 'cl-lib)
(require 'ert)
(require 'package)
+(require 'quicklintjs)
(defconst cache-dir-name (concat
(expand-file-name default-directory)
@@ -28,10 +30,13 @@
(quicklintjs-install-deps (if (>= emacs-major-version 26)
'(flycheck eglot lsp-mode)
'(flycheck)))
+
+ (set 'quicklintjs-find-program-function (lambda () "quick-lint-js"))
(def-flycheck-tests)
(def-eglot-tests)
(def-lsp-tests)
(def-flymake-tests)
+ (def-quicklintjs-tests)
(ert-run-tests-batch-and-exit))
(defun def-flymake-tests ()
@@ -73,7 +78,7 @@ foobar\")((16 . 22) 2 \"E057\" \"use of undeclared variable: foobar\")(\
(with-current-buffer js-buf
(insert "foobar")
(should (equal (call-process-region (point-min) (point-max)
- flymake-quicklintjs-program nil
+ quicklintjs-program-name nil
out-buf nil "--stdin"
"--output-format=emacs-lisp") 0)))))
@@ -84,7 +89,7 @@ foobar\")((16 . 22) 2 \"E057\" \"use of undeclared variable: foobar\")(\
(insert "function")
(should (equal (call-process-region
(point-min) (point-max)
- flymake-quicklintjs-program nil
+ quicklintjs-program-name nil
out-buf nil "--stdin"
"--output-format=emacs-lisp") 0))))))
@@ -136,6 +141,20 @@ foobar\")((16 . 22) 2 \"E057\" \"use of undeclared variable: foobar\")(\
:id "E059" :checker javascript-quicklintjs
:end-line 1 :end-column 2)))))
+(defun def-quicklintjs-tests ()
+ (ert-deftest quicklintjs-find-program-argv ()
+ (should (cl-every (lambda (a b) (string= a b))
+ (quicklintjs-find-program "foo" "baz")
+ '("quick-lint-js" "foo" "baz"))))
+ (ert-deftest quicklintjs-find-program-removes-nil ()
+ (should (cl-every (lambda (a b) (string= a b))
+ (quicklintjs-find-program "foo" nil "baz")
+ '("quick-lint-js" "foo" "baz"))))
+ (ert-deftest quicklintjs-find-program-removes-empty ()
+ (should (cl-every (lambda (a b) (string= a b))
+ (quicklintjs-find-program "foo" "" "baz")
+ '("quick-lint-js" "foo" "baz")))))
+
;; quick-lint-js finds bugs in JavaScript programs.
;; Copyright (C) 2020 Matthew "strager" Glazar
;;
diff --git a/src/emacs-lisp-error-reporter.cpp b/src/emacs-lisp-error-reporter.cpp
index a0eb7b7562..1f99b845a4 100644
--- a/src/emacs-lisp-error-reporter.cpp
+++ b/src/emacs-lisp-error-reporter.cpp
@@ -82,6 +82,7 @@ void emacs_lisp_error_formatter::write_after_message(severity sev,
return;
}
this->output_ << "\")";
+ this->output_.flush();
}
}