STYLE: Nightly Date Stamp
[cmake.git] / Docs / cmake-mode.el
blob0fbecb76dcf34bb74e7c575c44d757ffc0345f62
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 ;------------------------------------------------------------------------------
18 ;;; Commentary:
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))
30 ;; auto-mode-alist))
32 ;------------------------------------------------------------------------------
34 ;;; Code:
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
52 "\\)"))
53 (defconst cmake-regex-indented (concat "^\\("
54 cmake-regex-token
55 "\\|" "[ \t\r\n]"
56 "\\)*"))
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."
69 (if (save-excursion
70 (beginning-of-line)
71 (let ((parse-end (point)))
72 (beginning-of-buffer)
73 (nth 3 (parse-partial-sexp (point) parse-end))
77 nil
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))
84 region)
85 (forward-line -1)
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))))))
91 (forward-line -1)
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."
104 (interactive)
105 (beginning-of-line)
106 (if (cmake-line-starts-inside-string)
108 (if (bobp)
109 (indent-line-to 0)
110 (let ((point-start (point))
111 token cur-indent)
113 (save-excursion
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))
129 (if (and
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.
144 (if (< cur-indent 0)
145 (indent-line-to 0)
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."
160 (interactive)
161 (setq save-point (point))
162 (goto-char (point-min))
163 (while (re-search-forward "^\\([ \t]*\\)\\(\\w+\\)\\([ \t]*(\\)" nil t)
164 (replace-match
165 (concat
166 (match-string 1)
167 (downcase (match-string 2))
168 (match-string 3))
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.
207 (defun cmake-mode ()
208 "Major mode for editing CMake listfiles."
209 (interactive)
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 "#")
235 ; Run user hooks.
236 (run-hooks 'cmake-mode-hook))
238 ; This file provides cmake-mode.
239 (provide 'cmake-mode)
241 ;;; cmake-mode.el ends here