[Cmake] (X)Emacs mode

Ken Martin ken . martin at kitware . com
Tue, 29 Apr 2003 08:57:44 -0400


This is a multi-part message in MIME format.

------=_NextPart_000_00A7_01C30E2D.6676E150
Content-Type: text/plain;
	charset="us-ascii"
Content-Transfer-Encoding: 7bit

> Hello, brave CMake hackers,
> 
> does someone have a usable emacs mode for editing CMake scripts?
> 
> I saw in the archive that Ken Martin posted one in 2001. Did you
enhance
> it
> meanwhile, and could you be so kind to repost it?
> 
> Thanks,
> Stefan

I just hacked up tcl-mode.el and mainly changed the key words regexp. I
think the emacs mode is in the archive message as well. I haven't
modified it from that date since my lisp skills are rather rusty. I have
attached the basic mode setting code for your .emacs (or _emacs) file
but you probably already have that.

;; setup automode list for specific file types
(setq auto-mode-alist (append '(("\\.c$" . c++-mode)
                                ... (etc etc) ...
                                ("CMakeLists.txt" . cmake-mode)
                                ("Makefile" . makefile-mode))
                              auto-mode-alist))





------=_NextPart_000_00A7_01C30E2D.6676E150
Content-Type: application/octet-stream;
	name="cmake-mode.el"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="cmake-mode.el"

;;; tcl-mode.el --- a major-mode for editing cmake/tk scripts=0A=
=0A=
;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.=0A=
=0A=
;; Author: Gregor Schmid <schmid at fb3-s7 . math . tu-berlin . de>=0A=
;; Keywords: languages, processes, tools=0A=
=0A=
;; This file is part of GNU Emacs.=0A=
=0A=
;; GNU Emacs is free software; you can redistribute it and/or modify=0A=
;; it under the terms of the GNU General Public License as published by=0A=
;; the Free Software Foundation; either version 2, or (at your option)=0A=
;; any later version.=0A=
=0A=
;; GNU Emacs is distributed in the hope that it will be useful,=0A=
;; but WITHOUT ANY WARRANTY; without even the implied warranty of=0A=
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the=0A=
;; GNU General Public License for more details.=0A=
=0A=
;; You should have received a copy of the GNU General Public License=0A=
;; along with GNU Emacs; see the file COPYING.  If not, write to the=0A=
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,=0A=
;; Boston, MA 02111-1307, USA.=0A=
=0A=
;;; Commentary:=0A=
=0A=
;; Special Thanks to Simon Marshall <simonm at mail . esrin . esa . it> for=0A=
;; font-lock patches.=0A=
=0A=
;; This file was written with emacs using Jamie Lokier's folding mode=0A=
;; That's what the funny ;;willow marks are there for=0A=
=0A=
;;willow Usage=0A=
=0A=
;; Cmake3-mode supports c-mode style formatting and sending of=0A=
;; lines/regions/files to a cmake interpreter. An interpreter (see=0A=
;; variable `cmake-default-application') will be started if you try to=0A=
;; send some code and none is running. You can use the process-buffer=0A=
;; (named after the application you chose) as if it were an=0A=
;; interactive shell. See the documentation for `comint.el' for=0A=
;; details.=0A=
=0A=
;;bongo=0A=
;;willow Key-bindings=0A=
=0A=
;; To see all the keybindings for folding mode, look at =
`cmake-setup-keymap'=0A=
;; or start `cmake-mode' and type `\C-h m'.=0A=
;; The keybindings may seem strange, since I prefer to use them with=0A=
;; cmake-prefix-key set to nil, but since those keybindings are already =
used=0A=
;; the default for `cmake-prefix-key' is `\C-c', which is the =
conventional=0A=
;; prefix for major-mode commands.=0A=
=0A=
;; You can customise the keybindings either by setting `cmake-prefix-key'=0A=
;; or by putting the following in your .emacs=0A=
;; 	(setq cmake-mode-map (make-sparse-keymap))=0A=
;; and=0A=
;; 	(define-key cmake-mode-map <your-key> <function>)=0A=
;; for all the functions you need.=0A=
=0A=
;;bongo=0A=
;;willow Variables=0A=
=0A=
;; You may want to customize the following variables:=0A=
;; 	cmake-indent-level=0A=
;; 	cmake-always-show=0A=
;;	cmake-mode-map=0A=
;;	cmake-prefix-key=0A=
;;	cmake-mode-hook=0A=
=0A=
;;bongo=0A=
=0A=
;;; Code:=0A=
=0A=
;; We need that !=0A=
(require 'comint)=0A=
=0A=
;;willow variables=0A=
=0A=
(defgroup cmake nil=0A=
  "Major mode for editing cmake/tk code."=0A=
  :prefix "cmake-"=0A=
  :group 'languages)=0A=
=0A=
(defvar cmake-mode-map nil=0A=
  "Keymap used with cmake mode.")=0A=
=0A=
(defvar cmake-prefix-key "\C-c"=0A=
  "Prefix for all cmake-mode commands.")=0A=
=0A=
(defcustom cmake-mode-hook nil=0A=
  "Hooks called when cmake mode fires up."=0A=
  :type 'hook=0A=
  :group 'cmake)=0A=
=0A=
(defvar cmake-region-start (make-marker)=0A=
  "Start of special region for cmake communication.")=0A=
=0A=
(defvar cmake-region-end (make-marker)=0A=
  "End of special region for cmake communication.")=0A=
=0A=
(defcustom cmake-indent-level 4=0A=
  "Amount by which cmake subexpressions are indented."=0A=
  :type 'integer=0A=
  :group 'cmake)=0A=
=0A=
(defcustom cmake-default-eval "eval"=0A=
  "Default command used when sending regions."=0A=
  :type 'string=0A=
  :group 'cmake)=0A=
=0A=
(defvar cmake-mode-menu (make-sparse-keymap "Cmake3-Mode")=0A=
  "Keymap for cmake-mode's menu.")=0A=
=0A=
(defvar cmake-font-lock-keywords=0A=
  (eval-when-compile=0A=
    (list=0A=
     ;;=0A=
     ;; Function name declarations.=0A=
     '("\\<\\(icmake_class\\|class\\|method\\|proc\\|body\\)\\>[ =
\t]*\\(\\sw+\\)?"=0A=
       (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))=0A=
     ;;=0A=
     ;; Keywords.=0A=
     (concat "\\<\\("=0A=
"A\\(BSTRACT_FILES\\|DD_\\(CUSTOM_COMMAND\\|DE\\(FINITIONS\\|PENDENCIES\\=
)\\|EXECUTABLE\\|LIBRARY\\|TEST\\)\\|UX_SOURCE_DIRECTORY\\)\\|BUILD_\\(CO=
MMAND\\|NAME\\)\\|C\\(ABLE_\\(CLASS_SET\\|WRAP_TCL\\)\\|ONFIGURE_\\(FILE\=
\|GCCXML\\)\\)\\|E\\(LSE\\|N\\(ABLE_TESTING\\|D\\(FOREACH\\|IF\\)\\)\\)\\=
|F\\(IND_\\(FILE\\|LIBRARY\\|P\\(ATH\\|ROGRAM\\)\\)\\|LTK_WRAP_UI\\|OREAC=
H\\)\\|GET_FILENAME_COMPONENT\\|I\\(F\\|N\\(CLUDE\\(\\|_\\(DIRECTORIES\\|=
EXTERNAL_MSPROJECT\\|REGULAR_EXPRESSION\\)\\)\\|STALL_\\(FILES\\|PROGRAMS=
\\|TARGETS\\)\\)\\)\\|L\\(I\\(BRARY\\|NK_\\(DIRECTORIES\\|LIBRARIES\\)\\)=
\\|OAD_CACHE\\)\\|M\\(A\\(KE_DIRECTORY\\|RK_AS_ADVANCED\\)\\|ESSAGE\\)\\|=
O\\(PTION\\|UTPUT_REQUIRED_FILES\\)\\|PROJECT\\|QT_WRAP_\\(CPP\\|UI\\)\\|=
S\\(ET\\|ITE_NAME\\|OURCE_\\(FILES\\(\\|_REMOVE\\)\\|GROUP\\)\\|UBDIR\\(S=
\\|_DEPENDS\\)\\)\\|TARGET_LINK_LIBRARIES\\|U\\(SE_MANGLED_MESA\\|TILITY_=
SOURCE\\)\\|V\\(ARIABLE_REQUIRES\\|TK_WRAP_\\(JAVA\\|PYTHON\\|TCL\\)\\)\\=
|WRAP_EXCLUDE_FILES"=0A=
	     "\\)\\>")=0A=
     ;;=0A=
     ;; Types.=0A=
;   (make-regexp '("global" "upvar" "variable" "inherit" "public"=0A=
;		   "private" "protected" "common"))=0A=
     (cons (concat "\\<\\("=0A=
		   "common\\|global\\|inherit\\|p\\(r\\(ivate\\|otected\\)\\|ublic\\)"=0A=
		   "\\|upvar\\|variable"=0A=
		   "\\)\\>")=0A=
	   'font-lock-type-face)=0A=
     ))=0A=
  "Default expressions to highlight in CMAKE3 modes.")=0A=
=0A=
(defvar cmake-imenu-generic-expression=0A=
  '(=0A=
    (nil "^\\s-*\\(proc\\|body\\)\\s-+\\(\\(\\s_\\|\\sw\\)+\\)" 2)=0A=
    ("Classes" "^\\s-*class\\s-+\\(\\(\\s_\\|\\sw\\)+\\)" 1))=0A=
  =0A=
  "Imenu generic expression for cmake-mode.  See =
`imenu-generic-expression'.")=0A=
=0A=
=0A=
;;bongo=0A=
;;willow cmake-mode=0A=
=0A=
;;;###autoload=0A=
(defun cmake-mode ()=0A=
  "Major mode for editing cmake scripts.=0A=
The following keys are bound:=0A=
\\{cmake-mode-map}=0A=
"=0A=
  (interactive)=0A=
  (let ((switches nil)=0A=
	s)=0A=
    (kill-all-local-variables)=0A=
    (setq major-mode 'cmake-mode)=0A=
    (setq mode-name "CMAKE3")=0A=
    (set (make-local-variable 'indent-line-function) 'cmake-indent-line)=0A=
    (set (make-local-variable 'comment-start) "# ")=0A=
    (set (make-local-variable 'comment-start-skip) "# *")=0A=
    (set (make-local-variable 'font-lock-defaults)=0A=
	 '(cmake-font-lock-keywords nil nil ((?_ . "w") (?: . "w"))))=0A=
    (set (make-local-variable 'imenu-generic-expression)=0A=
	 cmake-imenu-generic-expression)=0A=
    (setq imenu-case-fold-search nil)=0A=
    (make-local-variable 'cmake-default-eval)=0A=
    (or cmake-mode-map=0A=
	(cmake-setup-keymap))=0A=
    (use-local-map cmake-mode-map)=0A=
    (set-syntax-table (copy-syntax-table))=0A=
    (modify-syntax-entry ?# "<")=0A=
    (modify-syntax-entry ?\n ">")=0A=
    (run-hooks 'cmake-mode-hook)))=0A=
=0A=
;;bongo=0A=
;;willow cmake-setup-keymap=0A=
=0A=
(defun cmake-setup-keymap ()=0A=
  "Set up keymap for cmake mode.=0A=
If the variable `cmake-prefix-key' is nil, the bindings go directly=0A=
to `cmake-mode-map', otherwise they are prefixed with =
`cmake-prefix-key'."=0A=
  (setq cmake-mode-map (make-sparse-keymap))=0A=
  (define-key cmake-mode-map [menu-bar cmake-mode]=0A=
    (cons "Cmake3-Mode" cmake-mode-menu))=0A=
  (let ((map (if cmake-prefix-key=0A=
		 (make-sparse-keymap)=0A=
	       cmake-mode-map)))=0A=
  ;; indentation=0A=
  (define-key cmake-mode-map [?\)] 'cmake-electric-brace)=0A=
  ;; communication=0A=
  (define-key map "\C-\M-s" 'cmake-set-cmake-region-start)=0A=
  (define-key map "\C-\M-e" 'cmake-set-cmake-region-end)=0A=
  (define-key map "\C-\M-r" 'cmake-send-cmake-region)=0A=
  (if cmake-prefix-key=0A=
      (define-key cmake-mode-map cmake-prefix-key map))=0A=
  ))=0A=
=0A=
;;bongo=0A=
;;willow indentation=0A=
=0A=
(defun cmake-electric-brace (arg)=0A=
  "Insert `)' and indent line for cmake."=0A=
  (interactive "P")=0A=
  (insert-char ?\) (prefix-numeric-value arg))=0A=
  (cmake-indent-line)=0A=
  (blink-matching-open))=0A=
=0A=
;;willow cmake-indent-line=0A=
=0A=
(defun cmake-indent-line ()=0A=
  "Indent current line as cmake code.=0A=
Return the amount the indentation changed by."=0A=
  (let ((indent (cmake-calculate-indentation nil))=0A=
	beg shift-amt=0A=
	(case-fold-search nil)=0A=
	(pos (- (point-max) (point))))=0A=
    (beginning-of-line)=0A=
    (setq beg (point))=0A=
    (skip-chars-forward " \t")=0A=
    (save-excursion=0A=
      (while (eq (following-char) ?\))=0A=
	(setq indent (max (- indent cmake-indent-level) 0))=0A=
	(forward-char 1)=0A=
	(if (looking-at "\\([ \t]*\\)\)")=0A=
	    (progn=0A=
	      (delete-region (match-beginning 1) (match-end 1))=0A=
	      (insert-char ?  (1- cmake-indent-level))))))=0A=
    (setq shift-amt (- indent (current-column)))=0A=
    (if (zerop shift-amt)=0A=
	(if (> (- (point-max) pos) (point))=0A=
	    (goto-char (- (point-max) pos)))=0A=
      (delete-region beg (point))=0A=
      (indent-to indent)=0A=
      ;; If initial point was within line's indentation,=0A=
      ;; position after the indentation.  Else stay at same point in =
text.=0A=
      (if (> (- (point-max) pos) (point))=0A=
	  (goto-char (- (point-max) pos))))=0A=
    shift-amt))=0A=
=0A=
;;bongo=0A=
;;willow cmake-calculate-indentation=0A=
=0A=
(defun cmake-calculate-indentation (&optional parse-start)=0A=
  "Return appropriate indentation for current line as cmake code.=0A=
In usual case returns an integer: the column to indent to."=0A=
  (let ((pos (point)))=0A=
    (save-excursion=0A=
      (if parse-start=0A=
	  (setq pos (goto-char parse-start)))=0A=
      (beginning-of-line)=0A=
      (if (bobp)=0A=
	  (current-indentation)=0A=
	(forward-char -1)=0A=
	(if (eq (preceding-char) ?\\)=0A=
	    (+ (current-indentation)=0A=
	       (progn=0A=
		 (beginning-of-line)=0A=
		 (if (bobp)=0A=
		     (* 2 cmake-indent-level)=0A=
		   (forward-char -1)=0A=
		   (if (not (eq (preceding-char) ?\\))=0A=
		       (* 2 cmake-indent-level)=0A=
		     0))))=0A=
	  (forward-char 1)=0A=
	  (if (re-search-backward=0A=
	       "\\(^[^ \t\n\r#]\\)\\|\\(\([^\)]*[#\n]\\)\\|\\(\)\\s *\n\\)"=0A=
	       nil  t)=0A=
	      (+ (- (current-indentation)=0A=
		    (if (save-excursion=0A=
			  (beginning-of-line)=0A=
			  (and (not (bobp))=0A=
			       (progn=0A=
				 (forward-char -1)=0A=
				 (eq (preceding-char) ?\\))))=0A=
			(* 2 cmake-indent-level)=0A=
		      0))=0A=
		 (if (eq (following-char) ?\()=0A=
		     cmake-indent-level=0A=
		   0))=0A=
	    (goto-char pos)=0A=
	    (beginning-of-line)=0A=
	    (forward-line -1)=0A=
	    (current-indentation)))))))=0A=
=0A=
;;bongo=0A=
=0A=
;;bongo=0A=
;;willow searching=0A=
=0A=
=0A=
(provide 'cmake-mode)=0A=
=0A=
=0C=0A=
;;willow Emacs local variables=0A=
=0A=
;; Local Variables:=0A=
;; folded-file: t=0A=
;; End:=0A=
=0A=
;;bongo=0A=
=0A=
;;; cmake-mode.el ends here=0A=

------=_NextPart_000_00A7_01C30E2D.6676E150--