xref: /aosp_15_r20/external/google-java-format/core/src/main/scripts/google-java-format.el (revision 10816b529e1d7005ca788e7b4c5efd1c72957e26)
1;;; google-java-format.el --- Format code with google-java-format -*- lexical-binding: t; -*-
2;;
3;; Copyright 2015 Google, Inc. All Rights Reserved.
4;;
5;; Package-Requires: ((emacs "24"))
6;;
7;; Licensed under the Apache License, Version 2.0 (the "License");
8;; you may not use this file except in compliance with the License.
9;; You may obtain a copy of the License at
10;;
11;;      http://www.apache.org/licenses/LICENSE-2.0
12;;
13;; Unless required `by applicable law or agreed to in writing, software
14;; distributed under the License is distributed on an "AS-IS" BASIS,
15;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16;; See the License for the specific language governing permissions and
17;; limitations under the License.
18
19;; Keywords: tools, Java
20
21;;; Commentary:
22
23;; This package allows a user to filter code through
24;; google-java-format, fixing its formatting.
25
26;; To use it, ensure the directory of this file is in your `load-path'
27;; and add
28;;
29;;   (require 'google-java-format)
30;;
31;; to your .emacs configuration.
32
33;; You may also want to bind `google-java-format-region' to a key:
34;;
35;;   (global-set-key [C-M-tab] #'google-java-format-region)
36
37;;; Code:
38
39(defgroup google-java-format nil
40  "Format code using google-java-format."
41  :group 'tools)
42
43(defcustom google-java-format-executable
44  "/usr/bin/google-java-format"
45  "Location of the google-java-format executable.
46
47A string containing the name or the full path of the executable."
48  :group 'google-java-format
49  :type '(file :must-match t :match (lambda (widget file) (file-executable-p file)))
50  :risky t)
51
52;;;###autoload
53(defun google-java-format-region (start end)
54  "Use google-java-format to format the code between START and END.
55If called interactively, uses the region, if there is one.  If
56there is no region, then formats the current line."
57  (interactive
58   (if (use-region-p)
59       (list (region-beginning) (region-end))
60     (list (point) (1+ (point)))))
61  (let ((cursor (point))
62        (temp-buffer (generate-new-buffer " *google-java-format-temp*"))
63        (stderr-file (make-temp-file "google-java-format")))
64    (unwind-protect
65        (let ((status (call-process-region
66                       ;; Note that emacs character positions are 1-indexed,
67                       ;; and google-java-format is 0-indexed, so we have to
68                       ;; subtract 1 from START to line it up correctly.
69                       (point-min) (point-max)
70                       google-java-format-executable
71                       nil (list temp-buffer stderr-file) t
72                       "--offset" (number-to-string (1- start))
73                       "--length" (number-to-string (- end start))
74                       "-"))
75              (stderr
76               (with-temp-buffer
77                 (insert-file-contents stderr-file)
78                 (when (> (point-max) (point-min))
79                   (insert ": "))
80                 (buffer-substring-no-properties
81                  (point-min) (line-end-position)))))
82          (cond
83           ((stringp status)
84            (error "google-java-format killed by signal %s%s" status stderr))
85           ((not (zerop status))
86            (error "google-java-format failed with code %d%s" status stderr))
87           (t (message "google-java-format succeeded%s" stderr)
88              (delete-region (point-min) (point-max))
89              (insert-buffer-substring temp-buffer)
90              (goto-char cursor))))
91      (delete-file stderr-file)
92      (when (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
93
94;;;###autoload
95(defun google-java-format-buffer ()
96  "Use google-java-format to format the current buffer."
97  (interactive)
98  (google-java-format-region (point-min) (point-max)))
99
100;;;###autoload
101(defalias 'google-java-format 'google-java-format-region)
102
103(provide 'google-java-format)
104
105;;; google-java-format.el ends here
106