update
[configs.git] / .emacs.d / lisp / flatbuffers / flatbuffers-mode.el
1 ;;; flatbuffers-mode.el --- Major mode for editing flatbuffers  -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2019-2020 Asal Mirzaieva
4
5 ;; Author: Asal Mirzaieva <asalle.kim@gmail.com>
6 ;; Created: 12-Nov-2019
7 ;; Version: 0.2
8 ;; Keywords: flatbuffers languages
9 ;; Homepage: https://github.com/Asalle/flatbuffers-mode
10 ;; Package-Requires: ((emacs "24.3"))
11
12 ;; This file is not part of GNU Emacs.
13
14 ;; This program is free software: you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation, either version 3 of the License, or
17 ;; (at your option) any later version.
18 ;;
19 ;; This program is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 ;; GNU General Public License for more details.
23 ;;
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
26
27 ;;; Commentary:
28
29 ;; FlatBuffers is an efficient cross platform serialization library for C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift. It was originally created at Google for game development and other performance-critical applications.
30 ;; https://google.github.io/flatbuffers/
31
32 ;; Installation:
33 ;;   - Put `flatbuffers-mode.el' in your Emacs load-path.
34 ;;   - Add this line to your .emacs file:
35 ;;       (require 'flatbuffers-mode)
36 ;;
37 ;;; Code:
38
39 ;; Font-locking definitions and helpers
40 (defconst flatbuffers-mode-keywords
41   '("namespace" "root_type" "struct" "table" "enum" "union" "required" "include" "attribute" "rpc_service" "file_extension" "file_identifier"))
42
43 (defconst flatbuffers-special-types
44   '("double" "bool" "uint" "ulong"))
45
46 (defconst flatbuffers-comment-start "//")
47
48 (defconst flatbuffers-re-ident "[[:word:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
49
50 (defconst flatbuffers-re-generic
51   (concat "<[[:space:]]*'" flatbuffers-re-ident "[[:space:]]*>"))
52
53 (defun flatbuffers-re-word (inner) "Generate word regex. INNER is the word to enclose." (concat "\\<" inner "\\>"))
54 (defun flatbuffers-re-grab (inner) "Generate grab regex. INNER is the expression to enclose." (concat "\\(" inner "\\)"))
55 (defun flatbuffers-re-shy (inner) "Generate shy regex. INNER is the expression to enclose." (concat "\\(?:" inner "\\)"))
56
57 (defun flatbuffers-re-item-def (itype)
58   "Highlight the keywords. ITYPE is the type of the keyword."
59   (concat (flatbuffers-re-word itype)
60           (flatbuffers-re-shy flatbuffers-re-generic) "?"
61           "[[:space:]]+" (flatbuffers-re-grab flatbuffers-re-ident)))
62
63 (defvar flatbuffers-mode-font-lock-keywords
64   (append
65    `(
66      ;; Keywords
67      (,(regexp-opt flatbuffers-mode-keywords 'symbols) . font-lock-keyword-face)
68
69      ;; Special types
70      (,(regexp-opt flatbuffers-special-types 'symbols) . font-lock-type-face)
71
72      (,(concat (flatbuffers-re-grab flatbuffers-re-ident) "[[:space:]]*:[^:]") 1 font-lock-variable-name-face)
73
74      ;; Ensure we highlight `Foo' in a:Foo
75      (,(concat ":[[:space:]]*" (flatbuffers-re-grab flatbuffers-re-ident)) 1 font-lock-type-face))
76
77     ;; Ensure we highlight `Foo` in `struct Foo` as a type.
78     (mapcar (lambda (x)
79                 (list (flatbuffers-re-item-def (car x))
80                       1 (cdr x)))
81             '(("enum" . font-lock-type-face)
82               ("struct" . font-lock-type-face)
83               ("union" . font-lock-type-face)
84               ("root_type" . font-lock-type-face)
85               ("table" . font-lock-type-face)))))
86
87 (defvar flatbuffers-mode-syntax-table
88   (let ((table (make-syntax-table)))
89     (modify-syntax-entry ?/ ". 14")
90     table))
91
92 ;;;###autoload
93 (define-derived-mode flatbuffers-mode prog-mode "Flatbuffers"
94   "Major mode for Flatbuffers code.
95
96 \\{flatbuffers-mode-map}"
97   :group 'flatbuffers-mode
98   :syntax-table flatbuffers-mode-syntax-table
99
100   ;; Fonts
101   (setq-local font-lock-defaults '(flatbuffers-mode-font-lock-keywords
102                                    nil nil nil nil
103                                    (font-lock-syntactic-face-function . flatbuffers-mode-syntactic-face-function)))
104   (font-lock-add-keywords nil `((,(concat flatbuffers-comment-start ".*") 0 font-lock-comment-face t))))
105
106 ;;;###autoload
107 (add-to-list 'auto-mode-alist '("\\.fbs\\'" . flatbuffers-mode))
108
109 (defun flatbuffers-mode-reload ()
110   "Reload the flatbuffers mode in current buffer."
111   (interactive)
112   (unload-feature 'flatbuffers-mode)
113   (require 'flatbuffers-mode)
114   (flatbuffers-mode))
115
116 (provide 'flatbuffers-mode)
117
118 ;;; flatbuffers-mode.el ends here