diff --git a/site-lisp/google-java-format.el b/site-lisp/google-java-format.el new file mode 100644 index 0000000..f9e8d2a --- /dev/null +++ b/site-lisp/google-java-format.el @@ -0,0 +1,105 @@ +;;; google-java-format.el --- Format code with google-java-format -*- lexical-binding: t; -*- +;; +;; Copyright 2015 Google, Inc. All Rights Reserved. +;; +;; Package-Requires: ((emacs "24")) +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); +;; you may not use this file except in compliance with the License. +;; You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses/LICENSE-2.0 +;; +;; Unless required `by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS-IS" BASIS, +;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;; See the License for the specific language governing permissions and +;; limitations under the License. + +;; Keywords: tools, Java + +;;; Commentary: + +;; This package allows a user to filter code through +;; google-java-format, fixing its formatting. + +;; To use it, ensure the directory of this file is in your `load-path' +;; and add +;; +;; (require 'google-java-format) +;; +;; to your .emacs configuration. + +;; You may also want to bind `google-java-format-region' to a key: +;; +;; (global-set-key [C-M-tab] #'google-java-format-region) + +;;; Code: + +(defgroup google-java-format nil + "Format code using google-java-format." + :group 'tools) + +(defcustom google-java-format-executable + "/usr/bin/google-java-format" + "Location of the google-java-format executable. + +A string containing the name or the full path of the executable." + :group 'google-java-format + :type '(file :must-match t :match #'file-executable-p) + :risky t) + +;;;###autoload +(defun google-java-format-region (start end) + "Use google-java-format to format the code between START and END. +If called interactively, uses the region, if there is one. If +there is no region, then formats the current line." + (interactive + (if (use-region-p) + (list (region-beginning) (region-end)) + (list (point) (1+ (point))))) + (let ((cursor (point)) + (temp-buffer (generate-new-buffer " *google-java-format-temp*")) + (stderr-file (make-temp-file "google-java-format"))) + (unwind-protect + (let ((status (call-process-region + ;; Note that emacs character positions are 1-indexed, + ;; and google-java-format is 0-indexed, so we have to + ;; subtract 1 from START to line it up correctly. + (point-min) (point-max) + google-java-format-executable + nil (list temp-buffer stderr-file) t + "--offset" (number-to-string (1- start)) + "--length" (number-to-string (- end start)) + "-")) + (stderr + (with-temp-buffer + (insert-file-contents stderr-file) + (when (> (point-max) (point-min)) + (insert ": ")) + (buffer-substring-no-properties + (point-min) (line-end-position))))) + (cond + ((stringp status) + (error "google-java-format killed by signal %s%s" status stderr)) + ((not (zerop status)) + (error "google-java-format failed with code %d%s" status stderr)) + (t (message "google-java-format succeeded%s" stderr) + (delete-region (point-min) (point-max)) + (insert-buffer-substring temp-buffer) + (goto-char cursor)))) + (delete-file stderr-file) + (when (buffer-name temp-buffer) (kill-buffer temp-buffer))))) + +;;;###autoload +(defun google-java-format-buffer () + "Use google-java-format to format the current buffer." + (interactive) + (google-java-format-region (point-min) (point-max))) + +;;;###autoload +(defalias 'google-java-format 'google-java-format-region) + +(provide 'google-java-format) + +;;; google-java-format.el ends here