1 ;;; gn.el - A major mode for editing gn files.
3 ;; Copyright 2015 The Chromium Authors. All rights reserved.
4 ;; Use of this source code is governed by a BSD-style license that can be
5 ;; found in the LICENSE file.
7 ;; Put this somewhere in your load-path and
10 ;; TODO(erg): There's a lot of general improvements that could be made here:
12 ;; - We syntax highlight builtin actions, but don't highlight instantiations of
13 ;; templates. Should we?
14 ;; - `fill-paragraph' works for comments, but when pointed at code, breaks
16 ;; - Might want to support `imenu' users. Even if it's just a list of toplevel
19 (eval-when-compile (require 'cl
)) ;For the `case' macro.
22 (defvar gn-font-lock-target-declaration-keywords
23 '("action" "action_foreach" "copy" "executable" "group"
24 "shared_library" "source_set" "static_library" "if" "else"))
26 (defvar gn-font-lock-buildfile-fun-keywords
27 '("assert" "config" "declare_args" "defined" "exec_script" "foreach"
28 "get_label_info" "get_path_info" "get_target_outputs" "getenv" "import"
29 "print" "process_file_template" "read_file" "rebase_path"
30 "set_default_toolchain" "set_defaults" "set_sources_assignment_filter"
31 "template" "tool" "toolchain" "toolchain_args" "write_file"))
33 (defvar gn-font-lock-predefined-var-keywords
34 '("current_cpu" "current_os" "current_toolchain" "default_toolchain"
35 "host_cpu" "host_os" "python_path" "root_build_dir" "root_gen_dir"
36 "root_out_dir" "target_cpu" "target_gen_dir" "target_os" "target_out_dir"))
38 (defvar gn-font-lock-var-keywords
39 '("all_dependent_configs" "allow_circular_includes_from" "args" "cflags"
40 "cflags_c" "cflags_cc" "cflags_objc" "cflags_objcc" "check_includes"
41 "complete_static_lib" "configs" "data" "data_deps" "defines" "depfile"
42 "deps" "forward_dependent_configs_from" "include_dirs" "inputs"
43 "ldflags" "lib_dirs" "libs" "output_extension" "output_name" "outputs"
44 "public" "public_configs" "public_deps" "script" "sources" "testonly"
47 (defconst gn-font-lock-keywords
48 `((,(regexp-opt gn-font-lock-target-declaration-keywords
'words
) .
49 font-lock-keyword-face
)
50 (,(regexp-opt gn-font-lock-buildfile-fun-keywords
'words
) .
51 font-lock-function-name-face
)
52 (,(regexp-opt gn-font-lock-predefined-var-keywords
'words
) .
53 font-lock-constant-face
)
54 (,(regexp-opt gn-font-lock-var-keywords
'words
) .
55 font-lock-variable-name-face
)))
57 (defvar gn-indent-basic
2)
59 (defun gn-smie-rules (kind token
)
60 "These are slightly modified indentation rules from the SMIE
61 Indentation Example info page. This changes the :before rule
62 and adds a :list-intro to handle our x = [ ] syntax."
63 (pcase (cons kind token
)
64 (`(:elem . basic
) gn-indent-basic
)
65 (`(,_ .
",") (smie-rule-separator kind
))
66 (`(:list-intro .
"") gn-indent-basic
)
67 (`(:before .
,(or `"[" `"(" `"{"))
68 (if (smie-rule-hanging-p) (smie-rule-parent)))
70 (and (not (smie-rule-bolp)) (smie-rule-prev-p "else")
71 (smie-rule-parent)))))
74 (define-derived-mode gn-mode prog-mode
"GN"
75 "Major mode for editing gn (Generate Ninja)."
77 (setq-local font-lock-defaults
'(gn-font-lock-keywords))
79 (setq-local comment-use-syntax t
)
80 (setq-local comment-start
"#")
81 (setq-local comment-end
"")
83 (smie-setup nil
#'gn-smie-rules
)
84 (setq-local smie-indent-basic gn-indent-basic
)
86 ;; python style comment: “# …”
87 (modify-syntax-entry ?
# "< b" gn-mode-syntax-table
)
88 (modify-syntax-entry ?
\n "> b" gn-mode-syntax-table
)
89 (modify-syntax-entry ?_
"w" gn-mode-syntax-table
))
92 (add-to-list 'auto-mode-alist
'("\\.gni?\\'" . gn-mode
))