source: trip-planner-front/node_modules/node-gyp/gyp/tools/emacs/gyp.el

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 11.9 KB
RevLine 
[6a3a178]1;;; gyp.el - font-lock-mode support for gyp files.
2
3;; Copyright (c) 2012 Google Inc. 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.
6
7;; Put this somewhere in your load-path and
8;; (require 'gyp)
9
10(require 'python)
11(require 'cl)
12
13(when (string-match "python-mode.el" (symbol-file 'python-mode 'defun))
14 (error (concat "python-mode must be loaded from python.el (bundled with "
15 "recent emacsen), not from the older and less maintained "
16 "python-mode.el")))
17
18(defadvice python-indent-calculate-levels (after gyp-outdent-closing-parens
19 activate)
20 "De-indent closing parens, braces, and brackets in gyp-mode."
21 (when (and (eq major-mode 'gyp-mode)
22 (string-match "^ *[])}][],)}]* *$"
23 (buffer-substring-no-properties
24 (line-beginning-position) (line-end-position))))
25 (setf (first python-indent-levels)
26 (- (first python-indent-levels) python-continuation-offset))))
27
28(defadvice python-indent-guess-indent-offset (around
29 gyp-indent-guess-indent-offset
30 activate)
31 "Guess correct indent offset in gyp-mode."
32 (or (and (not (eq major-mode 'gyp-mode))
33 ad-do-it)
34 (save-excursion
35 (save-restriction
36 (widen)
37 (goto-char (point-min))
38 ;; Find first line ending with an opening brace that is not a comment.
39 (or (and (re-search-forward "\\(^[[{]$\\|^.*[^#].*[[{]$\\)")
40 (forward-line)
41 (/= (current-indentation) 0)
42 (set (make-local-variable 'python-indent-offset)
43 (current-indentation))
44 (set (make-local-variable 'python-continuation-offset)
45 (current-indentation)))
46 (message "Can't guess gyp indent offset, using default: %s"
47 python-continuation-offset))))))
48
49(define-derived-mode gyp-mode python-mode "Gyp"
50 "Major mode for editing .gyp files. See http://code.google.com/p/gyp/"
51 ;; gyp-parse-history is a stack of (POSITION . PARSE-STATE) tuples,
52 ;; with greater positions at the top of the stack. PARSE-STATE
53 ;; is a list of section symbols (see gyp-section-name and gyp-parse-to)
54 ;; with most nested section symbol at the front of the list.
55 (set (make-local-variable 'gyp-parse-history) '((1 . (list))))
56 (gyp-add-font-lock-keywords))
57
58(defun gyp-set-indentation ()
59 "Hook function to configure python indentation to suit gyp mode."
60 (set (make-local-variable 'python-indent-offset) 2)
61 (set (make-local-variable 'python-continuation-offset) 2)
62 (set (make-local-variable 'python-indent-guess-indent-offset) t)
63 (python-indent-guess-indent-offset))
64
65(add-hook 'gyp-mode-hook 'gyp-set-indentation)
66
67(add-to-list 'auto-mode-alist '("\\.gyp\\'" . gyp-mode))
68(add-to-list 'auto-mode-alist '("\\.gypi\\'" . gyp-mode))
69(add-to-list 'auto-mode-alist '("/\\.gclient\\'" . gyp-mode))
70
71;;; Font-lock support
72
73(defconst gyp-dependencies-regexp
74 (regexp-opt (list "dependencies" "export_dependent_settings"))
75 "Regular expression to introduce 'dependencies' section")
76
77(defconst gyp-sources-regexp
78 (regexp-opt (list "action" "files" "include_dirs" "includes" "inputs"
79 "libraries" "outputs" "sources"))
80 "Regular expression to introduce 'sources' sections")
81
82(defconst gyp-conditions-regexp
83 (regexp-opt (list "conditions" "target_conditions"))
84 "Regular expression to introduce conditions sections")
85
86(defconst gyp-variables-regexp
87 "^variables"
88 "Regular expression to introduce variables sections")
89
90(defconst gyp-defines-regexp
91 "^defines"
92 "Regular expression to introduce 'defines' sections")
93
94(defconst gyp-targets-regexp
95 "^targets"
96 "Regular expression to introduce 'targets' sections")
97
98(defun gyp-section-name (section)
99 "Map the sections we are interested in from SECTION to symbol.
100
101 SECTION is a string from the buffer that introduces a section. The result is
102 a symbol representing the kind of section.
103
104 This allows us to treat (for the purposes of font-lock) several different
105 section names as the same kind of section. For example, a 'sources section
106 can be introduced by the 'sources', 'inputs', 'outputs' keyword.
107
108 'other is the default section kind when a more specific match is not made."
109 (cond ((string-match-p gyp-dependencies-regexp section) 'dependencies)
110 ((string-match-p gyp-sources-regexp section) 'sources)
111 ((string-match-p gyp-variables-regexp section) 'variables)
112 ((string-match-p gyp-conditions-regexp section) 'conditions)
113 ((string-match-p gyp-targets-regexp section) 'targets)
114 ((string-match-p gyp-defines-regexp section) 'defines)
115 (t 'other)))
116
117(defun gyp-invalidate-parse-states-after (target-point)
118 "Erase any parse information after target-point."
119 (while (> (caar gyp-parse-history) target-point)
120 (setq gyp-parse-history (cdr gyp-parse-history))))
121
122(defun gyp-parse-point ()
123 "The point of the last parse state added by gyp-parse-to."
124 (caar gyp-parse-history))
125
126(defun gyp-parse-sections ()
127 "A list of section symbols holding at the last parse state point."
128 (cdar gyp-parse-history))
129
130(defun gyp-inside-dictionary-p ()
131 "Predicate returning true if the parser is inside a dictionary."
132 (not (eq (cadar gyp-parse-history) 'list)))
133
134(defun gyp-add-parse-history (point sections)
135 "Add parse state SECTIONS to the parse history at POINT so that parsing can be
136 resumed instantly."
137 (while (>= (caar gyp-parse-history) point)
138 (setq gyp-parse-history (cdr gyp-parse-history)))
139 (setq gyp-parse-history (cons (cons point sections) gyp-parse-history)))
140
141(defun gyp-parse-to (target-point)
142 "Parses from (point) to TARGET-POINT adding the parse state information to
143 gyp-parse-state-history. Parsing stops if TARGET-POINT is reached or if a
144 string literal has been parsed. Returns nil if no further parsing can be
145 done, otherwise returns the position of the start of a parsed string, leaving
146 the point at the end of the string."
147 (let ((parsing t)
148 string-start)
149 (while parsing
150 (setq string-start nil)
151 ;; Parse up to a character that starts a sexp, or if the nesting
152 ;; level decreases.
153 (let ((state (parse-partial-sexp (gyp-parse-point)
154 target-point
155 -1
156 t))
157 (sections (gyp-parse-sections)))
158 (if (= (nth 0 state) -1)
159 (setq sections (cdr sections)) ; pop out a level
160 (cond ((looking-at-p "['\"]") ; a string
161 (setq string-start (point))
162 (goto-char (scan-sexps (point) 1))
163 (if (gyp-inside-dictionary-p)
164 ;; Look for sections inside a dictionary
165 (let ((section (gyp-section-name
166 (buffer-substring-no-properties
167 (+ 1 string-start)
168 (- (point) 1)))))
169 (setq sections (cons section (cdr sections)))))
170 ;; Stop after the string so it can be fontified.
171 (setq target-point (point)))
172 ((looking-at-p "{")
173 ;; Inside a dictionary. Increase nesting.
174 (forward-char 1)
175 (setq sections (cons 'unknown sections)))
176 ((looking-at-p "\\[")
177 ;; Inside a list. Increase nesting
178 (forward-char 1)
179 (setq sections (cons 'list sections)))
180 ((not (eobp))
181 ;; other
182 (forward-char 1))))
183 (gyp-add-parse-history (point) sections)
184 (setq parsing (< (point) target-point))))
185 string-start))
186
187(defun gyp-section-at-point ()
188 "Transform the last parse state, which is a list of nested sections and return
189 the section symbol that should be used to determine font-lock information for
190 the string. Can return nil indicating the string should not have any attached
191 section."
192 (let ((sections (gyp-parse-sections)))
193 (cond
194 ((eq (car sections) 'conditions)
195 ;; conditions can occur in a variables section, but we still want to
196 ;; highlight it as a keyword.
197 nil)
198 ((and (eq (car sections) 'list)
199 (eq (cadr sections) 'list))
200 ;; conditions and sources can have items in [[ ]]
201 (caddr sections))
202 (t (cadr sections)))))
203
204(defun gyp-section-match (limit)
205 "Parse from (point) to LIMIT returning by means of match data what was
206 matched. The group of the match indicates what style font-lock should apply.
207 See also `gyp-add-font-lock-keywords'."
208 (gyp-invalidate-parse-states-after (point))
209 (let ((group nil)
210 (string-start t))
211 (while (and (< (point) limit)
212 (not group)
213 string-start)
214 (setq string-start (gyp-parse-to limit))
215 (if string-start
216 (setq group (case (gyp-section-at-point)
217 ('dependencies 1)
218 ('variables 2)
219 ('conditions 2)
220 ('sources 3)
221 ('defines 4)
222 (nil nil)))))
223 (if group
224 (progn
225 ;; Set the match data to indicate to the font-lock mechanism the
226 ;; highlighting to be performed.
227 (set-match-data (append (list string-start (point))
228 (make-list (* (1- group) 2) nil)
229 (list (1+ string-start) (1- (point)))))
230 t))))
231
232;;; Please see http://code.google.com/p/gyp/wiki/GypLanguageSpecification for
233;;; canonical list of keywords.
234(defun gyp-add-font-lock-keywords ()
235 "Add gyp-mode keywords to font-lock mechanism."
236 ;; TODO(jknotten): Move all the keyword highlighting into gyp-section-match
237 ;; so that we can do the font-locking in a single font-lock pass.
238 (font-lock-add-keywords
239 nil
240 (list
241 ;; Top-level keywords
242 (list (concat "['\"]\\("
243 (regexp-opt (list "action" "action_name" "actions" "cflags"
244 "cflags_cc" "conditions" "configurations"
245 "copies" "defines" "dependencies" "destination"
246 "direct_dependent_settings"
247 "export_dependent_settings" "extension" "files"
248 "include_dirs" "includes" "inputs" "ldflags" "libraries"
249 "link_settings" "mac_bundle" "message"
250 "msvs_external_rule" "outputs" "product_name"
251 "process_outputs_as_sources" "rules" "rule_name"
252 "sources" "suppress_wildcard"
253 "target_conditions" "target_defaults"
254 "target_defines" "target_name" "toolsets"
255 "targets" "type" "variables" "xcode_settings"))
256 "[!/+=]?\\)") 1 'font-lock-keyword-face t)
257 ;; Type of target
258 (list (concat "['\"]\\("
259 (regexp-opt (list "loadable_module" "static_library"
260 "shared_library" "executable" "none"))
261 "\\)") 1 'font-lock-type-face t)
262 (list "\\(?:target\\|action\\)_name['\"]\\s-*:\\s-*['\"]\\([^ '\"]*\\)" 1
263 'font-lock-function-name-face t)
264 (list 'gyp-section-match
265 (list 1 'font-lock-function-name-face t t) ; dependencies
266 (list 2 'font-lock-variable-name-face t t) ; variables, conditions
267 (list 3 'font-lock-constant-face t t) ; sources
268 (list 4 'font-lock-preprocessor-face t t)) ; preprocessor
269 ;; Variable expansion
270 (list "<@?(\\([^\n )]+\\))" 1 'font-lock-variable-name-face t)
271 ;; Command expansion
272 (list "<!@?(\\([^\n )]+\\))" 1 'font-lock-variable-name-face t)
273 )))
274
275(provide 'gyp)
Note: See TracBrowser for help on using the repository browser.