1 ;=============================================================================
3 ; Program: CMake - Cross-Platform Makefile Generator
4 ; Module: $RCSfile: cmake-mode.el,v $
6 ; Copyright (c) 2000-$Date: 2008-03-11 14:54:40 $ Kitware, Inc., Insight Consortium. All rights reserved.
7 ; See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
9 ; This software is distributed WITHOUT ANY WARRANTY; without even
10 ; the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 ; PURPOSE. See the above copyright notices for more information.
13 ;=============================================================================
14 ;;; cmake-mode.el --- major-mode for editing CMake sources
16 ;------------------------------------------------------------------------------
20 ;; Provides syntax highlighting and indentation for CMakeLists.txt and
21 ;; *.cmake source files.
23 ;; Add this code to your .emacs file to use the mode:
25 ;; (setq load-path (cons (expand-file-name "/dir/with/cmake-mode") load-path))
26 ;; (require 'cmake-mode)
27 ;; (setq auto-mode-alist
28 ;; (append '(("CMakeLists\\.txt\\'" . cmake-mode)
29 ;; ("\\.cmake\\'" . cmake-mode))
32 ;------------------------------------------------------------------------------
37 ;; Regular expressions used by line indentation function.
39 (defconst cmake-regex-blank
"^[ \t]*$")
40 (defconst cmake-regex-comment
"#.*")
41 (defconst cmake-regex-paren-left
"(")
42 (defconst cmake-regex-paren-right
")")
43 (defconst cmake-regex-argument-quoted
44 "\"\\([^\"\\\\]\\|\\\\\\(.\\|\n\\)\\)*\"")
45 (defconst cmake-regex-argument-unquoted
46 "\\([^ \t\r\n()#\"\\\\]\\|\\\\.\\)\\([^ \t\r\n()#\\\\]\\|\\\\.\\)*")
47 (defconst cmake-regex-token
(concat "\\(" cmake-regex-comment
48 "\\|" cmake-regex-paren-left
49 "\\|" cmake-regex-paren-right
50 "\\|" cmake-regex-argument-unquoted
51 "\\|" cmake-regex-argument-quoted
53 (defconst cmake-regex-indented
(concat "^\\("
57 (defconst cmake-regex-block-open
58 "^\\(IF\\|MACRO\\|FOREACH\\|ELSE\\|ELSEIF\\|WHILE\\|FUNCTION\\)$")
59 (defconst cmake-regex-block-close
60 "^[ \t]*\\(ENDIF\\|ENDFOREACH\\|ENDMACRO\\|ELSE\\|ELSEIF\\|ENDWHILE\\|ENDFUNCTION\\)[ \t]*(")
62 ;------------------------------------------------------------------------------
65 ;; Helper functions for line indentation function.
67 (defun cmake-line-starts-inside-string ()
68 "Determine whether the beginning of the current line is in a string."
71 (let ((parse-end (point)))
73 (nth 3 (parse-partial-sexp (point) parse-end
))
81 (defun cmake-find-last-indented-line ()
82 "Move to the beginning of the last line that has meaningful indentation."
83 (let ((point-start (point))
86 (setq region
(buffer-substring-no-properties (point) point-start
))
87 (while (and (not (bobp))
88 (or (looking-at cmake-regex-blank
)
89 (not (and (string-match cmake-regex-indented region
)
90 (= (length region
) (match-end 0))))))
92 (setq region
(buffer-substring-no-properties (point) point-start
))
97 ;------------------------------------------------------------------------------
100 ;; Line indentation function.
102 (defun cmake-indent ()
103 "Indent current line as CMAKE code."
106 (if (cmake-line-starts-inside-string)
110 (let ((point-start (point))
114 ; Search back for the last indented line.
115 (cmake-find-last-indented-line)
117 ; Start with the indentation on this line.
118 (setq cur-indent
(current-indentation))
120 ; Search forward counting tokens that adjust indentation.
121 (while (re-search-forward cmake-regex-token point-start t
)
122 (setq token
(match-string 0))
123 (if (string-match (concat "^" cmake-regex-paren-left
"$") token
)
124 (setq cur-indent
(+ cur-indent cmake-tab-width
))
126 (if (string-match (concat "^" cmake-regex-paren-right
"$") token
)
127 (setq cur-indent
(- cur-indent cmake-tab-width
))
130 (string-match cmake-regex-block-open token
)
131 (looking-at (concat "[ \t]*" cmake-regex-paren-left
))
133 (setq cur-indent
(+ cur-indent cmake-tab-width
))
138 ; If this is the end of a block, decrease indentation.
139 (if (looking-at cmake-regex-block-close
)
140 (setq cur-indent
(- cur-indent cmake-tab-width
))
143 ; Indent this line by the amount selected.
146 (indent-line-to cur-indent
)
153 ;------------------------------------------------------------------------------
156 ;; Helper functions for buffer
158 (defun unscreamify-cmake-buffer ()
159 "Convert all CMake commands to lowercase in buffer."
161 (setq save-point
(point))
162 (goto-char (point-min))
163 (while (re-search-forward "^\\([ \t]*\\)\\(\\w+\\)\\([ \t]*(\\)" nil t
)
167 (downcase (match-string 2))
170 (goto-char save-point
)
173 ;------------------------------------------------------------------------------
176 ;; Keyword highlighting regex-to-face map.
178 (defconst cmake-font-lock-keywords
179 (list '("^[ \t]*\\(\\w+\\)[ \t]*(" 1 font-lock-function-name-face
))
180 "Highlighting expressions for CMAKE mode."
183 ;------------------------------------------------------------------------------
186 ;; Syntax table for this mode. Initialize to nil so that it is
187 ;; regenerated when the cmake-mode function is called.
189 (defvar cmake-mode-syntax-table nil
"Syntax table for cmake-mode.")
190 (setq cmake-mode-syntax-table nil
)
193 ;; User hook entry point.
195 (defvar cmake-mode-hook nil
)
198 ;; Indentation increment.
200 (defvar cmake-tab-width
2)
202 ;------------------------------------------------------------------------------
205 ;; CMake mode startup function.
208 "Major mode for editing CMake listfiles."
210 (kill-all-local-variables)
211 (setq major-mode
'cmake-mode
)
212 (setq mode-name
"CMAKE")
214 ; Create the syntax table
215 (setq cmake-mode-syntax-table
(make-syntax-table))
216 (set-syntax-table cmake-mode-syntax-table
)
217 (modify-syntax-entry ?_
"w" cmake-mode-syntax-table
)
218 (modify-syntax-entry ?\
( "()" cmake-mode-syntax-table
)
219 (modify-syntax-entry ?\
) ")(" cmake-mode-syntax-table
)
220 (modify-syntax-entry ?
# "<" cmake-mode-syntax-table
)
221 (modify-syntax-entry ?
\n ">" cmake-mode-syntax-table
)
223 ; Setup font-lock mode.
224 (make-local-variable 'font-lock-defaults
)
225 (setq font-lock-defaults
'(cmake-font-lock-keywords))
227 ; Setup indentation function.
228 (make-local-variable 'indent-line-function
)
229 (setq indent-line-function
'cmake-indent
)
231 ; Setup comment syntax.
232 (make-local-variable 'comment-start
)
233 (setq comment-start
"#")
236 (run-hooks 'cmake-mode-hook
))
238 ; This file provides cmake-mode.
239 (provide 'cmake-mode
)
241 ;;; cmake-mode.el ends here