196 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
| ;;; web-beautify.el --- Format HTML, CSS and JavaScript/JSON
 | |
| 
 | |
| ;; Copyright (C) 2013-2016 Yasuyuki Oka and web-beautify contributors
 | |
| 
 | |
| ;; Author: Yasuyuki Oka <yasuyk@gmail.com>
 | |
| ;; Version: 0.3.2
 | |
| ;; URL: https://github.com/yasuyk/web-beautify
 | |
| 
 | |
| ;; This program 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.
 | |
| 
 | |
| ;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| ;;; Commentary:
 | |
| 
 | |
| ;; Add the following to your Emacs init file.
 | |
| 
 | |
| ;;     (require 'web-beautify) ;; Not necessary if using ELPA package
 | |
| ;;     (eval-after-load 'js2-mode
 | |
| ;;       '(define-key js2-mode-map (kbd "C-c b") 'web-beautify-js))
 | |
| ;;     (eval-after-load 'json-mode
 | |
| ;;       '(define-key json-mode-map (kbd "C-c b") 'web-beautify-js))
 | |
| ;;     (eval-after-load 'sgml-mode
 | |
| ;;       '(define-key html-mode-map (kbd "C-c b") 'web-beautify-html))
 | |
| ;;     (eval-after-load 'css-mode
 | |
| ;;       '(define-key css-mode-map (kbd "C-c b") 'web-beautify-css))
 | |
| 
 | |
| ;; If you want to automatically format before saving a file,
 | |
| ;; add the following hook to your Emacs configuration:
 | |
| 
 | |
| ;;     (eval-after-load 'js2-mode
 | |
| ;;       '(add-hook 'js2-mode-hook
 | |
| ;;                  (lambda ()
 | |
| ;;                    (add-hook 'before-save-hook 'web-beautify-js-buffer t t))))
 | |
| 
 | |
| ;;     (eval-after-load 'json-mode
 | |
| ;;       '(add-hook 'json-mode-hook
 | |
| ;;                  (lambda ()
 | |
| ;;                    (add-hook 'before-save-hook 'web-beautify-js-buffer t t))))
 | |
| 
 | |
| ;;     (eval-after-load 'sgml-mode
 | |
| ;;       '(add-hook 'html-mode-hook
 | |
| ;;                  (lambda ()
 | |
| ;;                    (add-hook 'before-save-hook 'web-beautify-html-buffer t t))))
 | |
| 
 | |
| ;;     (eval-after-load 'css-mode
 | |
| ;;       '(add-hook 'css-mode-hook
 | |
| ;;                  (lambda ()
 | |
| ;;                    (add-hook 'before-save-hook 'web-beautify-css-buffer t t))))
 | |
| 
 | |
| ;; For more information, See URL https://github.com/yasuyk/web-beautify.
 | |
| 
 | |
| 
 | |
| ;;; Code:
 | |
| 
 | |
| (defvar web-beautify-html-program "html-beautify"
 | |
|   "The executable to use for formatting HTML.")
 | |
| 
 | |
| (defvar web-beautify-css-program "css-beautify"
 | |
|   "The executable to use for formatting CSS.")
 | |
| 
 | |
| (defvar web-beautify-js-program "js-beautify"
 | |
|   "The executable to use for formatting JavaScript and JSON.")
 | |
| 
 | |
| (defconst web-beautify-args '("-f" "-"))
 | |
| 
 | |
| (defun web-beautify-command-not-found-message (program)
 | |
|   "Construct a message about PROGRAM not found."
 | |
|   (format
 | |
|    "%s not found. Install it with `npm -g install js-beautify`."
 | |
|    program))
 | |
| 
 | |
| (defun web-beautify-format-error-message (buffer-name)
 | |
|   "Construct a format error message with BUFFER-NAME."
 | |
|   (format
 | |
|    "Could not apply web-beautify. See %s to for details."
 | |
|    buffer-name))
 | |
| 
 | |
| (defun web-beautify-get-shell-command (program)
 | |
|   "Join PROGRAM with the constant js-beautify args."
 | |
|   (mapconcat 'identity (append (list program) web-beautify-args) " "))
 | |
| 
 | |
| (declare-function web-mode-reload "ext:web-mode")
 | |
| (declare-function js2-mode "ext:js2-mode")
 | |
| 
 | |
| (defun web-beautify-reload ()
 | |
|   "Reload mode to activate faces."
 | |
|   (deactivate-mark)
 | |
|   (cond ((eq major-mode 'web-mode)
 | |
|          (web-mode-reload))
 | |
|         ((eq major-mode 'js2-mode)
 | |
|          (js2-mode))))
 | |
| 
 | |
| (defun web-beautify-format-region (program beginning end)
 | |
|   "By PROGRAM, format each line in the BEGINNING .. END region."
 | |
|   ;; Check that js-beautify is installed.
 | |
|   (if (executable-find program)
 | |
|       (let* ((output-buffer-name "*Web Beautify Errors*")
 | |
|              (output-buffer (get-buffer-create output-buffer-name))
 | |
|              ;; Stash the previous point/window positions so they can be
 | |
|              ;; reclaimed after the buffer is replaced. Otherwise there is a
 | |
|              ;; disturbing "jump" to vertically-center point after being
 | |
|              ;; momentarily bounced to the top of the file.
 | |
|              (previous-point (point))
 | |
|              (previous-window-start (window-start))
 | |
|              (shell-command (web-beautify-get-shell-command program)))
 | |
|         ;; Run the command.
 | |
|         (if (zerop (shell-command-on-region beginning end shell-command (current-buffer) t output-buffer t))
 | |
|             (progn
 | |
|               ;; Reclaim position for a smooth transition.
 | |
|               (goto-char previous-point)
 | |
|               (set-window-start nil previous-window-start)
 | |
|               (message "Applied web-beautify.")
 | |
|               (web-beautify-reload)
 | |
|               (kill-buffer output-buffer))
 | |
|           ;; Unfortunately an error causes the buffer to be replaced with
 | |
|           ;; emptiness... so undo that. Kind of an ugly hack. But a
 | |
|           ;; properly-configured web-beautify shouldn't encounter this much, if
 | |
|           ;; ever.
 | |
|           (undo)
 | |
|           (message (web-beautify-format-error-message output-buffer-name))))
 | |
|     (message (web-beautify-command-not-found-message program))))
 | |
| 
 | |
| (defun web-beautify-format-buffer (program)
 | |
|   "By PROGRAM, format current buffer with EXTENSTION."
 | |
|   (web-beautify-format-region program (point-min) (point-max)))
 | |
| 
 | |
| ;;;###autoload
 | |
| (defun web-beautify-html ()
 | |
|   "Format region if active, otherwise the current buffer.
 | |
| 
 | |
| Formatting is done according to the html-beautify command."
 | |
|   (interactive)
 | |
|   (if (use-region-p)
 | |
|       (web-beautify-format-region
 | |
|        web-beautify-html-program
 | |
|        (region-beginning) (region-end))
 | |
|     (web-beautify-html-buffer)))
 | |
| 
 | |
| ;;;###autoload
 | |
| (defun web-beautify-html-buffer ()
 | |
|   "Format the current buffer according to the html-beautify command."
 | |
|   (web-beautify-format-buffer web-beautify-html-program))
 | |
| 
 | |
| ;;;###autoload
 | |
| (defun web-beautify-css ()
 | |
|   "Format region if active, otherwise the current buffer.
 | |
| 
 | |
| Formatting is done according to the css-beautify command."
 | |
|   (interactive)
 | |
|   (if (use-region-p)
 | |
|       (web-beautify-format-region
 | |
|        web-beautify-css-program
 | |
|        (region-beginning) (region-end))
 | |
|     (web-beautify-css-buffer)))
 | |
| 
 | |
| ;;;###autoload
 | |
| (defun web-beautify-css-buffer ()
 | |
|   "Format the current buffer according to the css-beautify command."
 | |
|   (web-beautify-format-buffer web-beautify-css-program))
 | |
| 
 | |
| ;;;###autoload
 | |
| (defun web-beautify-js ()
 | |
|   "Format region if active, otherwise the current buffer.
 | |
| 
 | |
| Formatting is done according to the js-beautify command."
 | |
|   (interactive)
 | |
|   (if (use-region-p)
 | |
|       (web-beautify-format-region
 | |
|        web-beautify-js-program
 | |
|        (region-beginning) (region-end))
 | |
|     (web-beautify-js-buffer)))
 | |
| 
 | |
| ;;;###autoload
 | |
| (defun web-beautify-js-buffer ()
 | |
|   "Format the current buffer according to the js-beautify command."
 | |
|   (web-beautify-format-buffer web-beautify-js-program))
 | |
| 
 | |
| 
 | |
| (provide 'web-beautify)
 | |
| 
 | |
| ;; Local Variables:
 | |
| ;; coding: utf-8
 | |
| ;; eval: (checkdoc-minor-mode 1)
 | |
| ;; End:
 | |
| 
 | |
| ;;; web-beautify.el ends here
 |