"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/node-gyp/gyp/tools/emacs/gyp.el" (11 Apr 2017, 12178 Bytes) of package /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Lisp source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    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)