make.el 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. ;;; semantic/bovine/make.el --- Makefile parsing rules.
  2. ;; Copyright (C) 2000-2004, 2008-2012 Free Software Foundation, Inc.
  3. ;; Author: Eric M. Ludlam <zappo@gnu.org>
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is free software: you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;;
  17. ;; Use the Semantic Bovinator to parse Makefiles.
  18. ;; Concocted as an experiment for nonstandard languages.
  19. (require 'make-mode)
  20. (require 'semantic)
  21. (require 'semantic/bovine/make-by)
  22. (require 'semantic/analyze)
  23. (require 'semantic/dep)
  24. (declare-function semantic-analyze-possible-completions-default
  25. "semantic/analyze/complete")
  26. ;;; Code:
  27. (define-lex-analyzer semantic-lex-make-backslash-no-newline
  28. "Detect and create a beginning of line token (BOL)."
  29. (and (looking-at "\\(\\\\\n\\s-*\\)")
  30. ;; We have a \ at eol. Push it as whitespace, but pretend
  31. ;; it never happened so we can skip the BOL tokenizer.
  32. (semantic-lex-push-token (semantic-lex-token 'whitespace
  33. (match-beginning 1)
  34. (match-end 1)))
  35. (goto-char (match-end 1))
  36. nil) ;; CONTINUE
  37. ;; We want to skip BOL, so move to the next condition.
  38. nil)
  39. (define-lex-regex-analyzer semantic-lex-make-command
  40. "A command in a Makefile consists of a line starting with TAB, and ending at the newline."
  41. "^\\(\t\\)"
  42. (let ((start (match-end 0)))
  43. (while (progn (end-of-line)
  44. (save-excursion (forward-char -1) (looking-at "\\\\")))
  45. (forward-char 1))
  46. (semantic-lex-push-token
  47. (semantic-lex-token 'shell-command start (point)))))
  48. (define-lex-regex-analyzer semantic-lex-make-ignore-automake-conditional
  49. "An automake conditional seems to really bog down the parser.
  50. Ignore them."
  51. "^@\\(\\w\\|\\s_\\)+@"
  52. (setq semantic-lex-end-point (match-end 0)))
  53. (define-lex semantic-make-lexer
  54. "Lexical analyzer for Makefiles."
  55. semantic-lex-beginning-of-line
  56. semantic-lex-make-ignore-automake-conditional
  57. semantic-lex-make-command
  58. semantic-lex-make-backslash-no-newline
  59. semantic-lex-whitespace
  60. semantic-lex-newline
  61. semantic-lex-symbol-or-keyword
  62. semantic-lex-charquote
  63. semantic-lex-paren-or-list
  64. semantic-lex-close-paren
  65. semantic-lex-string
  66. semantic-lex-ignore-comments
  67. semantic-lex-punctuation
  68. semantic-lex-default-action)
  69. (defun semantic-make-expand-tag (tag)
  70. "Expand TAG into a list of equivalent tags, or nil."
  71. (let ((name (semantic-tag-name tag))
  72. xpand)
  73. ;(message "Expanding %S" name)
  74. ;(goto-char (semantic-tag-start tag))
  75. ;(sit-for 0)
  76. (if (and (consp name)
  77. (memq (semantic-tag-class tag) '(function include))
  78. (> (length name) 1))
  79. (while name
  80. (setq xpand (cons (semantic-tag-clone tag (car name)) xpand)
  81. name (cdr name)))
  82. ;; Else, only a single name.
  83. (when (consp name)
  84. (setcar tag (car name)))
  85. (setq xpand (list tag)))
  86. xpand))
  87. (define-mode-local-override semantic-get-local-variables
  88. makefile-mode (&optional point)
  89. "Override `semantic-get-local-variables' so it does not throw an error.
  90. We never have local variables in Makefiles."
  91. nil)
  92. (define-mode-local-override semantic-ctxt-current-class-list
  93. makefile-mode (&optional point)
  94. "List of classes that are valid to place at point."
  95. (let ((tag (semantic-current-tag)))
  96. (when tag
  97. (cond ((condition-case nil
  98. (save-excursion
  99. (condition-case nil (forward-sexp -1)
  100. (error nil))
  101. (forward-char -2)
  102. (looking-at "\\$\\s("))
  103. (error nil))
  104. ;; We are in a variable reference
  105. '(variable))
  106. ((semantic-tag-of-class-p tag 'function)
  107. ;; Note: variables are handled above.
  108. '(function filename))
  109. ((semantic-tag-of-class-p tag 'variable)
  110. '(function filename))
  111. ))))
  112. (define-mode-local-override semantic-format-tag-abbreviate
  113. makefile-mode (tag &optional parent color)
  114. "Return an abbreviated string describing tag for Makefiles."
  115. (let ((class (semantic-tag-class tag))
  116. (name (semantic-format-tag-name tag parent color))
  117. )
  118. (cond ((eq class 'function)
  119. (concat name ":"))
  120. ((eq class 'filename)
  121. (concat "./" name))
  122. (t
  123. (semantic-format-tag-abbreviate-default tag parent color)))))
  124. (defvar-mode-local makefile-mode semantic-function-argument-separator
  125. " "
  126. "Separator used between dependencies to rules.")
  127. (define-mode-local-override semantic-format-tag-prototype
  128. makefile-mode (tag &optional parent color)
  129. "Return a prototype string describing tag for Makefiles."
  130. (let* ((class (semantic-tag-class tag))
  131. (name (semantic-format-tag-name tag parent color))
  132. )
  133. (cond ((eq class 'function)
  134. (concat name ": "
  135. (semantic--format-tag-arguments
  136. (semantic-tag-function-arguments tag)
  137. #'semantic-format-tag-prototype
  138. color)))
  139. ((eq class 'filename)
  140. (concat "./" name))
  141. (t
  142. (semantic-format-tag-prototype-default tag parent color)))))
  143. (define-mode-local-override semantic-format-tag-concise-prototype
  144. makefile-mode (tag &optional parent color)
  145. "Return a concise prototype string describing tag for Makefiles.
  146. This is the same as a regular prototype."
  147. (semantic-format-tag-prototype tag parent color))
  148. (define-mode-local-override semantic-format-tag-uml-prototype
  149. makefile-mode (tag &optional parent color)
  150. "Return a UML prototype string describing tag for Makefiles.
  151. This is the same as a regular prototype."
  152. (semantic-format-tag-prototype tag parent color))
  153. (define-mode-local-override semantic-analyze-possible-completions
  154. makefile-mode (context)
  155. "Return a list of possible completions in a Makefile.
  156. Uses default implementation, and also gets a list of filenames."
  157. (save-excursion
  158. (require 'semantic/analyze/complete)
  159. (set-buffer (oref context buffer))
  160. (let* ((normal (semantic-analyze-possible-completions-default context))
  161. (classes (oref context :prefixclass))
  162. (filetags nil))
  163. (when (memq 'filename classes)
  164. (let* ((prefix (car (oref context :prefix)))
  165. (completetext (cond ((semantic-tag-p prefix)
  166. (semantic-tag-name prefix))
  167. ((stringp prefix)
  168. prefix)
  169. ((stringp (car prefix))
  170. (car prefix))))
  171. (files (directory-files default-directory nil
  172. (concat "^" completetext))))
  173. (setq filetags (mapcar (lambda (f) (semantic-tag f 'filename))
  174. files))))
  175. ;; Return the normal completions found, plus any filenames
  176. ;; that match.
  177. (append normal filetags)
  178. )))
  179. (defcustom-mode-local-semantic-dependency-system-include-path
  180. makefile-mode semantic-makefile-dependency-system-include-path
  181. nil
  182. "The system include path used by Makefiles language.")
  183. ;;;###autoload
  184. (defun semantic-default-make-setup ()
  185. "Set up a Makefile buffer for parsing with semantic."
  186. (semantic-make-by--install-parser)
  187. (setq semantic-symbol->name-assoc-list '((variable . "Variables")
  188. (function . "Rules")
  189. (include . "Dependencies")
  190. ;; File is a meta-type created
  191. ;; to represent completions
  192. ;; but not actually parsed.
  193. (file . "File"))
  194. semantic-case-fold t
  195. semantic-tag-expand-function 'semantic-make-expand-tag
  196. semantic-lex-syntax-modifications '((?. "_")
  197. (?= ".")
  198. (?/ "_")
  199. (?$ ".")
  200. (?+ ".")
  201. (?\\ ".")
  202. )
  203. imenu-create-index-function 'semantic-create-imenu-index
  204. )
  205. (setq semantic-lex-analyzer #'semantic-make-lexer)
  206. )
  207. (provide 'semantic/bovine/make)
  208. ;; Local variables:
  209. ;; generated-autoload-file: "../loaddefs.el"
  210. ;; generated-autoload-load-name: "semantic/bovine/make"
  211. ;; End:
  212. ;;; semantic/bovine/make.el ends here