1*1b3f573fSAndroid Build Coastguard Worker;;; protobuf-mode.el --- major mode for editing protocol buffers. -*- lexical-binding: t; -*- 2*1b3f573fSAndroid Build Coastguard Worker 3*1b3f573fSAndroid Build Coastguard Worker;; Author: Alexandre Vassalotti <[email protected]> 4*1b3f573fSAndroid Build Coastguard Worker;; Created: 23-Apr-2009 5*1b3f573fSAndroid Build Coastguard Worker;; Version: 0.3 6*1b3f573fSAndroid Build Coastguard Worker;; Keywords: google protobuf languages 7*1b3f573fSAndroid Build Coastguard Worker 8*1b3f573fSAndroid Build Coastguard Worker;; Redistribution and use in source and binary forms, with or without 9*1b3f573fSAndroid Build Coastguard Worker;; modification, are permitted provided that the following conditions are 10*1b3f573fSAndroid Build Coastguard Worker;; met: 11*1b3f573fSAndroid Build Coastguard Worker;; 12*1b3f573fSAndroid Build Coastguard Worker;; * Redistributions of source code must retain the above copyright 13*1b3f573fSAndroid Build Coastguard Worker;; notice, this list of conditions and the following disclaimer. 14*1b3f573fSAndroid Build Coastguard Worker;; * Redistributions in binary form must reproduce the above 15*1b3f573fSAndroid Build Coastguard Worker;; copyright notice, this list of conditions and the following disclaimer 16*1b3f573fSAndroid Build Coastguard Worker;; in the documentation and/or other materials provided with the 17*1b3f573fSAndroid Build Coastguard Worker;; distribution. 18*1b3f573fSAndroid Build Coastguard Worker;; * Neither the name of Google Inc. nor the names of its 19*1b3f573fSAndroid Build Coastguard Worker;; contributors may be used to endorse or promote products derived from 20*1b3f573fSAndroid Build Coastguard Worker;; this software without specific prior written permission. 21*1b3f573fSAndroid Build Coastguard Worker;; 22*1b3f573fSAndroid Build Coastguard Worker;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23*1b3f573fSAndroid Build Coastguard Worker;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24*1b3f573fSAndroid Build Coastguard Worker;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25*1b3f573fSAndroid Build Coastguard Worker;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26*1b3f573fSAndroid Build Coastguard Worker;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27*1b3f573fSAndroid Build Coastguard Worker;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28*1b3f573fSAndroid Build Coastguard Worker;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29*1b3f573fSAndroid Build Coastguard Worker;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30*1b3f573fSAndroid Build Coastguard Worker;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31*1b3f573fSAndroid Build Coastguard Worker;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32*1b3f573fSAndroid Build Coastguard Worker;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33*1b3f573fSAndroid Build Coastguard Worker 34*1b3f573fSAndroid Build Coastguard Worker;;; Commentary: 35*1b3f573fSAndroid Build Coastguard Worker 36*1b3f573fSAndroid Build Coastguard Worker;; Installation: 37*1b3f573fSAndroid Build Coastguard Worker;; - Put `protobuf-mode.el' in your Emacs load-path. 38*1b3f573fSAndroid Build Coastguard Worker;; - Add this line to your .emacs file: 39*1b3f573fSAndroid Build Coastguard Worker;; (require 'protobuf-mode) 40*1b3f573fSAndroid Build Coastguard Worker;; 41*1b3f573fSAndroid Build Coastguard Worker;; You can customize this mode just like any mode derived from CC Mode. If 42*1b3f573fSAndroid Build Coastguard Worker;; you want to add customizations specific to protobuf-mode, you can use the 43*1b3f573fSAndroid Build Coastguard Worker;; `protobuf-mode-hook'. For example, the following would make protocol-mode 44*1b3f573fSAndroid Build Coastguard Worker;; use 2-space indentation: 45*1b3f573fSAndroid Build Coastguard Worker;; 46*1b3f573fSAndroid Build Coastguard Worker;; (defconst my-protobuf-style 47*1b3f573fSAndroid Build Coastguard Worker;; '((c-basic-offset . 2) 48*1b3f573fSAndroid Build Coastguard Worker;; (indent-tabs-mode . nil))) 49*1b3f573fSAndroid Build Coastguard Worker;; 50*1b3f573fSAndroid Build Coastguard Worker;; (add-hook 'protobuf-mode-hook 51*1b3f573fSAndroid Build Coastguard Worker;; (lambda () (c-add-style "my-style" my-protobuf-style t))) 52*1b3f573fSAndroid Build Coastguard Worker;; 53*1b3f573fSAndroid Build Coastguard Worker;; Refer to the documentation of CC Mode for more information about 54*1b3f573fSAndroid Build Coastguard Worker;; customization details and how to use this mode. 55*1b3f573fSAndroid Build Coastguard Worker;; 56*1b3f573fSAndroid Build Coastguard Worker;; TODO: 57*1b3f573fSAndroid Build Coastguard Worker;; - Make highlighting for enum values work properly. 58*1b3f573fSAndroid Build Coastguard Worker;; - Fix the parser to recognize extensions as identifiers and not 59*1b3f573fSAndroid Build Coastguard Worker;; as casts. 60*1b3f573fSAndroid Build Coastguard Worker;; - Improve the parsing of option assignment lists. For example: 61*1b3f573fSAndroid Build Coastguard Worker;; optional int32 foo = 1 [(my_field_option) = 4.5]; 62*1b3f573fSAndroid Build Coastguard Worker;; - Add support for fully-qualified identifiers (e.g., with a leading "."). 63*1b3f573fSAndroid Build Coastguard Worker 64*1b3f573fSAndroid Build Coastguard Worker;;; Code: 65*1b3f573fSAndroid Build Coastguard Worker 66*1b3f573fSAndroid Build Coastguard Worker(require 'cc-mode) 67*1b3f573fSAndroid Build Coastguard Worker 68*1b3f573fSAndroid Build Coastguard Worker(eval-when-compile 69*1b3f573fSAndroid Build Coastguard Worker (and (= emacs-major-version 24) 70*1b3f573fSAndroid Build Coastguard Worker (>= emacs-minor-version 4) 71*1b3f573fSAndroid Build Coastguard Worker (require 'cl-lib)) 72*1b3f573fSAndroid Build Coastguard Worker (require 'cc-langs) 73*1b3f573fSAndroid Build Coastguard Worker (require 'cc-fonts)) 74*1b3f573fSAndroid Build Coastguard Worker 75*1b3f573fSAndroid Build Coastguard Worker;; This mode does not inherit properties from other modes. So, we do not use 76*1b3f573fSAndroid Build Coastguard Worker;; the usual `c-add-language' function. 77*1b3f573fSAndroid Build Coastguard Worker(eval-and-compile 78*1b3f573fSAndroid Build Coastguard Worker (put 'protobuf-mode 'c-mode-prefix "protobuf-")) 79*1b3f573fSAndroid Build Coastguard Worker 80*1b3f573fSAndroid Build Coastguard Worker;; The following code uses of the `c-lang-defconst' macro define syntactic 81*1b3f573fSAndroid Build Coastguard Worker;; features of protocol buffer language. Refer to the documentation in the 82*1b3f573fSAndroid Build Coastguard Worker;; cc-langs.el file for information about the meaning of the -kwds variables. 83*1b3f573fSAndroid Build Coastguard Worker 84*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-primitive-type-kwds 85*1b3f573fSAndroid Build Coastguard Worker protobuf '("double" "float" "int32" "int64" "uint32" "uint64" "sint32" 86*1b3f573fSAndroid Build Coastguard Worker "sint64" "fixed32" "fixed64" "sfixed32" "sfixed64" "bool" 87*1b3f573fSAndroid Build Coastguard Worker "string" "bytes" "group")) 88*1b3f573fSAndroid Build Coastguard Worker 89*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-modifier-kwds 90*1b3f573fSAndroid Build Coastguard Worker protobuf '("required" "optional" "repeated")) 91*1b3f573fSAndroid Build Coastguard Worker 92*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-class-decl-kwds 93*1b3f573fSAndroid Build Coastguard Worker protobuf '("message" "enum" "service")) 94*1b3f573fSAndroid Build Coastguard Worker 95*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-constant-kwds 96*1b3f573fSAndroid Build Coastguard Worker protobuf '("true" "false")) 97*1b3f573fSAndroid Build Coastguard Worker 98*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-other-decl-kwds 99*1b3f573fSAndroid Build Coastguard Worker protobuf '("package" "import")) 100*1b3f573fSAndroid Build Coastguard Worker 101*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-other-kwds 102*1b3f573fSAndroid Build Coastguard Worker protobuf '("default" "max")) 103*1b3f573fSAndroid Build Coastguard Worker 104*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-identifier-ops 105*1b3f573fSAndroid Build Coastguard Worker ;; Handle extended identifiers like google.protobuf.MessageOptions 106*1b3f573fSAndroid Build Coastguard Worker protobuf '((left-assoc "."))) 107*1b3f573fSAndroid Build Coastguard Worker 108*1b3f573fSAndroid Build Coastguard Worker;; The following keywords do not fit well in keyword classes defined by 109*1b3f573fSAndroid Build Coastguard Worker;; cc-mode. So, we approximate as best we can. 110*1b3f573fSAndroid Build Coastguard Worker 111*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-type-list-kwds 112*1b3f573fSAndroid Build Coastguard Worker protobuf '("extensions" "to" "reserved")) 113*1b3f573fSAndroid Build Coastguard Worker 114*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-typeless-decl-kwds 115*1b3f573fSAndroid Build Coastguard Worker protobuf '("extend" "rpc" "option" "returns")) 116*1b3f573fSAndroid Build Coastguard Worker 117*1b3f573fSAndroid Build Coastguard Worker 118*1b3f573fSAndroid Build Coastguard Worker;; Here we remove default syntax for loops, if-statements and other C 119*1b3f573fSAndroid Build Coastguard Worker;; syntactic features that are not supported by the protocol buffer language. 120*1b3f573fSAndroid Build Coastguard Worker 121*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-brace-list-decl-kwds 122*1b3f573fSAndroid Build Coastguard Worker ;; Remove syntax for C-style enumerations. 123*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 124*1b3f573fSAndroid Build Coastguard Worker 125*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-block-stmt-1-kwds 126*1b3f573fSAndroid Build Coastguard Worker ;; Remove syntax for "do" and "else" keywords. 127*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 128*1b3f573fSAndroid Build Coastguard Worker 129*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-block-stmt-2-kwds 130*1b3f573fSAndroid Build Coastguard Worker ;; Remove syntax for "for", "if", "switch" and "while" keywords. 131*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 132*1b3f573fSAndroid Build Coastguard Worker 133*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-simple-stmt-kwds 134*1b3f573fSAndroid Build Coastguard Worker ;; Remove syntax for "break", "continue", "goto" and "return" keywords. 135*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 136*1b3f573fSAndroid Build Coastguard Worker 137*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-paren-stmt-kwds 138*1b3f573fSAndroid Build Coastguard Worker ;; Remove special case for the "(;;)" in for-loops. 139*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 140*1b3f573fSAndroid Build Coastguard Worker 141*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-label-kwds 142*1b3f573fSAndroid Build Coastguard Worker ;; Remove case label syntax for the "case" and "default" keywords. 143*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 144*1b3f573fSAndroid Build Coastguard Worker 145*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-before-label-kwds 146*1b3f573fSAndroid Build Coastguard Worker ;; Remove special case for the label in a goto statement. 147*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 148*1b3f573fSAndroid Build Coastguard Worker 149*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-cpp-matchers 150*1b3f573fSAndroid Build Coastguard Worker ;; Disable all the C preprocessor syntax. 151*1b3f573fSAndroid Build Coastguard Worker protobuf nil) 152*1b3f573fSAndroid Build Coastguard Worker 153*1b3f573fSAndroid Build Coastguard Worker(c-lang-defconst c-decl-prefix-re 154*1b3f573fSAndroid Build Coastguard Worker ;; Same as for C, except it does not match "(". This is needed for disabling 155*1b3f573fSAndroid Build Coastguard Worker ;; the syntax for casts. 156*1b3f573fSAndroid Build Coastguard Worker protobuf "\\([\{\};,]+\\)") 157*1b3f573fSAndroid Build Coastguard Worker 158*1b3f573fSAndroid Build Coastguard Worker 159*1b3f573fSAndroid Build Coastguard Worker;; Add support for variable levels of syntax highlighting. 160*1b3f573fSAndroid Build Coastguard Worker 161*1b3f573fSAndroid Build Coastguard Worker(defconst protobuf-font-lock-keywords-1 (c-lang-const c-matchers-1 protobuf) 162*1b3f573fSAndroid Build Coastguard Worker "Minimal highlighting for protobuf-mode.") 163*1b3f573fSAndroid Build Coastguard Worker 164*1b3f573fSAndroid Build Coastguard Worker(defconst protobuf-font-lock-keywords-2 (c-lang-const c-matchers-2 protobuf) 165*1b3f573fSAndroid Build Coastguard Worker "Fast normal highlighting for protobuf-mode.") 166*1b3f573fSAndroid Build Coastguard Worker 167*1b3f573fSAndroid Build Coastguard Worker(defconst protobuf-font-lock-keywords-3 (c-lang-const c-matchers-3 protobuf) 168*1b3f573fSAndroid Build Coastguard Worker "Accurate normal highlighting for protobuf-mode.") 169*1b3f573fSAndroid Build Coastguard Worker 170*1b3f573fSAndroid Build Coastguard Worker(defvar protobuf-font-lock-keywords protobuf-font-lock-keywords-3 171*1b3f573fSAndroid Build Coastguard Worker "Default expressions to highlight in protobuf-mode.") 172*1b3f573fSAndroid Build Coastguard Worker 173*1b3f573fSAndroid Build Coastguard Worker;; Our syntax table is auto-generated from the keyword classes we defined 174*1b3f573fSAndroid Build Coastguard Worker;; previously with the `c-lang-const' macro. 175*1b3f573fSAndroid Build Coastguard Worker(defvar protobuf-mode-syntax-table nil 176*1b3f573fSAndroid Build Coastguard Worker "Syntax table used in protobuf-mode buffers.") 177*1b3f573fSAndroid Build Coastguard Worker(or protobuf-mode-syntax-table 178*1b3f573fSAndroid Build Coastguard Worker (setq protobuf-mode-syntax-table 179*1b3f573fSAndroid Build Coastguard Worker (funcall (c-lang-const c-make-mode-syntax-table protobuf)))) 180*1b3f573fSAndroid Build Coastguard Worker 181*1b3f573fSAndroid Build Coastguard Worker(defvar protobuf-mode-abbrev-table nil 182*1b3f573fSAndroid Build Coastguard Worker "Abbreviation table used in protobuf-mode buffers.") 183*1b3f573fSAndroid Build Coastguard Worker 184*1b3f573fSAndroid Build Coastguard Worker(defvar protobuf-mode-map nil 185*1b3f573fSAndroid Build Coastguard Worker "Keymap used in protobuf-mode buffers.") 186*1b3f573fSAndroid Build Coastguard Worker(or protobuf-mode-map 187*1b3f573fSAndroid Build Coastguard Worker (setq protobuf-mode-map (c-make-inherited-keymap))) 188*1b3f573fSAndroid Build Coastguard Worker 189*1b3f573fSAndroid Build Coastguard Worker(easy-menu-define protobuf-menu protobuf-mode-map 190*1b3f573fSAndroid Build Coastguard Worker "Protocol Buffers Mode Commands" 191*1b3f573fSAndroid Build Coastguard Worker (cons "Protocol Buffers" (c-lang-const c-mode-menu protobuf))) 192*1b3f573fSAndroid Build Coastguard Worker 193*1b3f573fSAndroid Build Coastguard Worker;;;###autoload (add-to-list 'auto-mode-alist '("\\.proto\\'" . protobuf-mode)) 194*1b3f573fSAndroid Build Coastguard Worker 195*1b3f573fSAndroid Build Coastguard Worker;;;###autoload 196*1b3f573fSAndroid Build Coastguard Worker(define-derived-mode protobuf-mode prog-mode "Protocol-Buffers" 197*1b3f573fSAndroid Build Coastguard Worker "Major mode for editing Protocol Buffers description language. 198*1b3f573fSAndroid Build Coastguard Worker 199*1b3f573fSAndroid Build Coastguard WorkerThe hook `c-mode-common-hook' is run with no argument at mode 200*1b3f573fSAndroid Build Coastguard Workerinitialization, then `protobuf-mode-hook'. 201*1b3f573fSAndroid Build Coastguard Worker 202*1b3f573fSAndroid Build Coastguard WorkerKey bindings: 203*1b3f573fSAndroid Build Coastguard Worker\\{protobuf-mode-map}" 204*1b3f573fSAndroid Build Coastguard Worker :after-hook (c-update-modeline) 205*1b3f573fSAndroid Build Coastguard Worker (setq abbrev-mode t) 206*1b3f573fSAndroid Build Coastguard Worker (c-initialize-cc-mode t) 207*1b3f573fSAndroid Build Coastguard Worker (c-init-language-vars protobuf-mode) 208*1b3f573fSAndroid Build Coastguard Worker (c-common-init 'protobuf-mode) 209*1b3f573fSAndroid Build Coastguard Worker (easy-menu-add protobuf-menu) 210*1b3f573fSAndroid Build Coastguard Worker (setq imenu-generic-expression 211*1b3f573fSAndroid Build Coastguard Worker '(("Message" "^[[:space:]]*message[[:space:]]+\\([[:alnum:]]+\\)" 1) 212*1b3f573fSAndroid Build Coastguard Worker ("Enum" "^[[:space:]]*enum[[:space:]]+\\([[:alnum:]]+\\)" 1) 213*1b3f573fSAndroid Build Coastguard Worker ("Service" "^[[:space:]]*service[[:space:]]+\\([[:alnum:]]+\\)" 1))) 214*1b3f573fSAndroid Build Coastguard Worker (c-run-mode-hooks 'c-mode-common-hook)) 215*1b3f573fSAndroid Build Coastguard Worker 216*1b3f573fSAndroid Build Coastguard Worker(provide 'protobuf-mode) 217*1b3f573fSAndroid Build Coastguard Worker 218*1b3f573fSAndroid Build Coastguard Worker;;; protobuf-mode.el ends here 219