Skip to content

Instantly share code, notes, and snippets.

@mkmik
Created May 3, 2014 20:59
Show Gist options
  • Save mkmik/11505749 to your computer and use it in GitHub Desktop.
Save mkmik/11505749 to your computer and use it in GitHub Desktop.
(defcustom jsfmt-command "jsfmt"
"The 'jsfmt' command"
:type 'string
:group 'go)
(defun jsfmt ()
"Formats the current buffer according to the jsfmt tool."
(interactive)
(let ((tmpfile (make-temp-file "jsfmt" nil ".js"))
(patchbuf (get-buffer-create "*Jsfmt patch*"))
(errbuf (get-buffer-create "*Jsfmt Errors*"))
(coding-system-for-read 'utf-8)
(coding-system-for-write 'utf-8))
(with-current-buffer errbuf
(setq buffer-read-only nil)
(erase-buffer))
(with-current-buffer patchbuf
(erase-buffer))
(write-region nil nil tmpfile)
;; We're using errbuf for the mixed stdout and stderr output. This
;; is not an issue because jsfmt -w does not produce any stdout
;; output in case of success.
(if (zerop (call-process jsfmt-command nil errbuf nil "-f" "-w" tmpfile))
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
(progn
(kill-buffer errbuf)
(message "Buffer is already jsfmted"))
(go--apply-rcs-patch patchbuf)
(kill-buffer errbuf)
(message "Applied jsfmt"))
(message "Could not apply jsfmt. Check errors for details")
(jsfmt--process-errors (buffer-file-name) tmpfile errbuf))
(kill-buffer patchbuf)
(delete-file tmpfile)))
(defun jsfmt--process-errors (filename tmpfile errbuf)
;; Convert the jsfmt stderr to something understood by the compilation mode.
(with-current-buffer errbuf
(goto-char (point-min))
(insert "jsfmt errors:\n")
(while (search-forward-regexp (concat "^\\(" (regexp-quote tmpfile) "\\):") nil t)
(replace-match (file-name-nondirectory filename) t t nil 1))
(compilation-mode)
(display-buffer errbuf)))
(defun jsfmt-before-save ()
"Add this to .emacs to run jsfmt on the current buffer when saving:
(add-hook 'before-save-hook 'jsfmt-before-save).
Note that this will cause js2-mode to get loaded the first time
you save any file, kind of defeating the point of autoloading."
(interactive)
(when (eq major-mode 'js2-mode) (jsfmt)))
@mkmik
Copy link
Author

mkmik commented May 3, 2014

I shamelessly adapted the gofmt elisp code.
Meant to be used with https://github.com/rdio/jsfmt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment