Skip to content

Commit db508bd

Browse files
Daemon support (#91)
* Surface errors from prettier daemons * Add test for daemon error reporting * Add note about executable dependencies * Document how to run Prettier as a daemon * Try to fix "Permission denied" error on Windows * Add a test for error display using the normal prettier executable
1 parent 40f3822 commit db508bd

File tree

5 files changed

+102
-5
lines changed

5 files changed

+102
-5
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ jobs:
5151
with:
5252
node-version: '22.x'
5353

54-
- name: Install prettier
55-
run: npm install -g prettier
54+
- name: Install prettier executables
55+
run: npm install -g prettier @fsouza/prettierd
5656

5757
- name: Build
5858
run: |

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ And then hook into `web-mode` like this:
130130
'("\\.jsx?\\'" . prettier-js-mode))))
131131
```
132132

133+
### Usage with prettierd
134+
135+
If you want to mostly eliminate the overhead of running the `prettier` command on every file save (improving performance slightly), you could try using [`prettierd`](https://github.com/fsouza/prettierd) to run Prettier as a daemon.
136+
137+
```elisp
138+
(setq prettier-js-command "prettierd")
139+
```
140+
141+
Note that this may come at the expense of a bit more complexity in terms of configuring/managing the daemon.
142+
133143
## Customization
134144

135145
This package is customizable via Emacs' easy customization interface:

fixtures/syntax-error.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// This file contains a JavaScript syntax error
2+
function brokenFunction(a, b { // Missing closing parenthesis
3+
return a + b;
4+
}

prettier-js-test.el

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
;;; Commentary:
66
;; Tests for prettier-js.el
77

8+
;; These tests will fail unless node/npm are installed, as well as prettier and
9+
;; prettierd. Run the following command to install those latter dependencies:
10+
11+
;; npm install -g prettier @fsouza/prettierd
12+
813
;;; Code:
914

1015
(require 'ert)
@@ -241,5 +246,77 @@
241246
(when (file-exists-p temp-file)
242247
(delete-file temp-file)))))
243248

249+
(ert-deftest prettier-js-test-error-display ()
250+
"Test that errors from prettier are displayed in the error buffer."
251+
(let* ((syntax-error-file (expand-file-name "fixtures/syntax-error.js"))
252+
(temp-dir (make-temp-file "prettier-test-dir-" t))
253+
(temp-file (expand-file-name "syntax-error.js" temp-dir))
254+
(prettier-js-command "prettier")
255+
(prettier-js-show-errors 'buffer)
256+
(default-directory temp-dir))
257+
(unwind-protect
258+
(progn
259+
;; Copy syntax error file to temp directory
260+
(copy-file syntax-error-file temp-file t)
261+
262+
;; Visit the temp file
263+
(with-current-buffer (find-file-noselect temp-file)
264+
;; Run prettier-js which should display the error
265+
(prettier-js)
266+
267+
;; Check that the error buffer exists and contains the error message
268+
(let ((error-buffer (get-buffer "*prettier errors*")))
269+
(should error-buffer)
270+
(with-current-buffer error-buffer
271+
(should (string-match-p "SyntaxError: Unexpected token" (buffer-string)))))
272+
273+
(kill-buffer)
274+
;; Clean up error buffer
275+
(when-let ((buf (get-buffer "*prettier errors*")))
276+
(kill-buffer buf))))
277+
278+
;; Clean up temp directory
279+
(when (file-exists-p temp-dir)
280+
(delete-directory temp-dir t)))))
281+
282+
(ert-deftest prettier-js-test-prettierd-error-display ()
283+
"Test that errors from prettierd are displayed in the error buffer."
284+
(let* ((syntax-error-file (expand-file-name "fixtures/syntax-error.js"))
285+
(temp-dir (make-temp-file "prettier-test-dir-" t))
286+
(temp-file (expand-file-name "syntax-error.js" temp-dir))
287+
(prettier-js-command "prettierd")
288+
(prettier-js-show-errors 'buffer)
289+
(default-directory temp-dir))
290+
(unwind-protect
291+
(progn
292+
;; Copy syntax error file to temp directory
293+
(copy-file syntax-error-file temp-file t)
294+
295+
;; Visit the temp file
296+
(with-current-buffer (find-file-noselect temp-file)
297+
;; Run prettier-js which should display the error
298+
(prettier-js)
299+
300+
;; Check that the error buffer exists and contains the error message
301+
(let ((error-buffer (get-buffer "*prettier errors*")))
302+
(should error-buffer)
303+
(with-current-buffer error-buffer
304+
(should (string-match-p "SyntaxError: Unexpected token" (buffer-string)))))
305+
306+
(kill-buffer)
307+
;; Clean up error buffer
308+
(when-let ((buf (get-buffer "*prettier errors*")))
309+
(kill-buffer buf))))
310+
311+
;; Stop prettierd daemon to ensure the temp directory can be deleted on
312+
;; Windows; I think prettierd "locks" the directory where it's started
313+
(when (executable-find "prettierd")
314+
(message "Stopping prettierd daemon...")
315+
(call-process "prettierd" nil nil nil "stop"))
316+
317+
;; Clean up temp directory
318+
(when (file-exists-p temp-dir)
319+
(delete-directory temp-dir t)))))
320+
244321
(provide 'prettier-js-test)
245322
;;; prettier-js-test.el ends here

prettier-js.el

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ a `before-save-hook'."
9191
(const :tag "None" nil))
9292
:group 'prettier-js)
9393

94+
(defvar prettier-js-daemon-commands '("prettier_d" "prettierd")
95+
"List of prettier daemon commands that put errors in stdout rather than stderr.")
96+
9497
(defvar-local prettier-js-error-state nil
9598
"Indicates if there's an error with the prettier executable.
9699
When non-nil, contains the error message to display.")
@@ -264,6 +267,10 @@ PATCHBUF is the buffer where the diff output will be written."
264267
(bufferfile (make-temp-file "prettier" nil ext))
265268
(outputfile (make-temp-file "prettier" nil ext))
266269
(errorfile (make-temp-file "prettier" nil ext))
270+
;; Some prettier daemons put errors in stdout rather than stderr
271+
(program-errorfile (if (member prettier-js-command prettier-js-daemon-commands)
272+
outputfile
273+
errorfile))
267274
(errbuf (if prettier-js-show-errors (get-buffer-create "*prettier errors*")))
268275
(patchbuf (get-buffer-create "*prettier patch*"))
269276
(coding-system-for-read 'utf-8)
@@ -295,9 +302,8 @@ PATCHBUF is the buffer where the diff output will be written."
295302
(setq prettier-js-error-state "Diff command had an issue")
296303
(user-error "Error calling diff; is GNU diff on your path?")))
297304
(message "Could not apply prettier")
298-
(if errbuf
299-
(prettier-js--process-errors file-path errorfile errbuf))
300-
))
305+
(when errbuf
306+
(prettier-js--process-errors file-path program-errorfile errbuf))))
301307
(kill-buffer patchbuf)
302308
(delete-file errorfile)
303309
(delete-file bufferfile)

0 commit comments

Comments
 (0)