@@ -40,47 +40,89 @@ Return a list of Flymake diagnostic objects in source buffer SRC-BUF."
40
40
(if (= sev 0 ) :error :warning ) msg)))
41
41
quicklintjs-output-alist))
42
42
43
+ (defun flymake-quicklintjs--report-with-crash (qljs-stdout-buf
44
+ qljs-stderr-buf
45
+ src-buf report-fn )
46
+ " Similar to `flymake-quicklintjs--report' but tries to recover errors from
47
+ quick-lint-js crashes and logs whatever is in QLJS-STDERR-BUF"
48
+ (flymake-log :warning
49
+ " quick-lint-js exited with a deadly signal.\n \
50
+ Please consider filing a bug at\
51
+ https://github.com/quick-lint/quick-lint-js/issues/new\n \
52
+ qjls-stderr-buf:\n \
53
+ %s\n "
54
+ (with-current-buffer qljs-stderr-buf
55
+ (buffer-substring-no-properties (point-min ) (point-max ))))
56
+ (with-current-buffer qljs-stdout-buf
57
+ (save-excursion
58
+ ; ; a crash without any previous issue, try to fix an empty buffer
59
+ (when (zerop (buffer-size ))
60
+ (goto-char (point-min ))
61
+ (insert-char ?\( ))
62
+ ; ; the above left a '(' danlging or crashed and
63
+ ; ; emacs_lisp_error_reporter::finish() haven't been called yet
64
+ (goto-char (point-min ))
65
+ (when (eq (char-after 1 ) ?\( )
66
+ (goto-char (point-max ))
67
+ (insert-char ?\) ))))
68
+ (condition-case nil
69
+ (flymake-quicklintjs--report qljs-stdout-buf src-buf report-fn)
70
+ (funcall report-fn '())))
71
+
72
+ (defun flymake-quicklintjs--report (qljs-stdout-buf src-buf report-fn )
73
+ " Call REPORT-FN to highlight reports in SRC_BUF reported in QLJS-STDOUT-BUF.
74
+ QLJS-STDOUT-BUF is entirely read and it's expected to be in
75
+ QUICKLINTJS-OUTPUT-ALIST format."
76
+ (with-current-buffer qljs-stdout-buf
77
+ (funcall report-fn
78
+ (flymake-quicklintjs--make-diagnostics
79
+ src-buf
80
+ (car (read-from-string
81
+ (buffer-substring-no-properties (point-min )
82
+ (point-max ))))))))
83
+
43
84
;;;### autoload
44
85
(defun flymake-quicklintjs (report-fn &rest _args )
45
86
" Flymake backend for quick-lint-js linter.
46
- This backend uses `flymake- quicklintjs-program' (which see) to launch a
47
- quick-lint-js process that is passed the current buffer's contents via stdin.
87
+ This backend uses `quicklintjs-find- program' to find and launch a quick-lint-js
88
+ process that is passed the current buffer's contents via stdin.
48
89
REPORT-FN is Flymake's callback."
49
90
(when (process-live-p flymake-quicklintjs--proc)
50
91
(kill-process flymake-quicklintjs--proc))
51
- (let ((src-buf (current-buffer )))
52
- (setq flymake-quicklintjs--proc
53
- (make-process
54
- :name " flymake-quicklintjs"
55
- :connection-type 'pipe
56
- :noquery t
57
- :buffer (get-buffer-create " *flymake-quicklintjs*" )
58
- :command (quicklintjs-find-program
59
- (let ((file (buffer-file-name )))
60
- (when file (concat " --path-for-config-search=" file)))
61
- " --stdin" " --output-format=emacs-lisp" )
62
- :sentinel
63
- (lambda (p _ev )
64
- (unwind-protect
65
- (when (and (eq 'exit (process-status p))
66
- (eq p flymake-quicklintjs--proc))
67
- (with-current-buffer (process-buffer p)
68
- (let ((diags (flymake-quicklintjs--make-diagnostics
69
- src-buf
70
- (car (read-from-string
71
- (buffer-substring-no-properties
72
- (point-min ) (point-max )))))))
73
- (if (or diags (zerop (process-exit-status p)))
74
- (funcall report-fn diags)
75
- (funcall report-fn
76
- :panic :explanation
77
- (buffer-substring
78
- (point-min ) (progn (goto-char (point-min ))
79
- (line-end-position ))))))))
80
- (unless (process-live-p p)
81
- (kill-buffer (process-buffer p)))))))
82
- (process-send-region flymake-quicklintjs--proc (point-min ) (point-max ))
83
- (process-send-eof flymake-quicklintjs--proc)))
92
+ (let ((src-buf (current-buffer ))
93
+ (stdout-buf (generate-new-buffer " *flymake-quicklintjs-stdout*" ))
94
+ (stderr-buf (generate-new-buffer " *flymake-quicklintjs-stderr*" )))
95
+ (save-restriction
96
+ (widen )
97
+ (setq flymake-quicklintjs--proc
98
+ (make-process
99
+ :name " flymake-quicklintjs"
100
+ :connection-type 'pipe
101
+ :noquery t
102
+ :buffer stdout-buf
103
+ :stderr stderr-buf
104
+ :command (quicklintjs-find-program
105
+ (let ((file (buffer-file-name )))
106
+ (when file (concat " --path-for-config-search=" file)))
107
+ " --stdin" " --output-format=emacs-lisp" )
108
+ :sentinel
109
+ (lambda (p _ev )
110
+ (let ((proc-status (process-status p)))
111
+ (unwind-protect
112
+ (when (and (or (eq proc-status 'exit )
113
+ (eq proc-status 'signal ))
114
+ (with-current-buffer src-buf
115
+ (eq p flymake-quicklintjs--proc)))
116
+ (if (zerop (process-exit-status p))
117
+ (flymake-quicklintjs--report stdout-buf
118
+ src-buf
119
+ report-fn)
120
+ (flymake-quicklintjs--report-with-crash
121
+ stdout-buf stderr-buf src-buf report-fn)))
122
+ (progn (kill-buffer stdout-buf)
123
+ (kill-buffer stderr-buf)))))))
124
+ (process-send-region flymake-quicklintjs--proc (point-min ) (point-max ))
125
+ (process-send-eof flymake-quicklintjs--proc))))
84
126
85
127
(provide 'flymake-quicklintjs )
86
128
0 commit comments