Emacs

There are a variety of settings that you can put into your .emacs configuration file that will make life easier when working with BRL-CAD sources. Additionally, installing cmake-mode.el into your ~/.emacs.d/ directory will help with editing of build system files.

; indent case statements ala BSD KNF / K&R style regardless of mode
(c-set-offset 'case-label '+)
(c-set-offset 'statement-case-open '+)
(c-set-offset 'innamespace 0)
(c-set-offset 'inline-open 0)

;; Support font-locking large files
(set-variable 'font-lock-maximum-size 18024000)
(global-font-lock-mode t)
(transient-mark-mode t)
(turn-on-font-lock)

; quell initialization warnings due to Local Variable block bug
(setq inhibit-startup-message t)

; Stop at the end of the file, not just add lines
(setq next-line-add-newlines nil)

; make sure goto labels can be placed on column 0
(setq c-label-minimum-indentation 0)

; display column numbers in addition to line numbers
(set-variable 'column-number-mode t)

; to not read-only lock other people's cvs files (and not go into vc-mode)
(set-variable 'vc-handle-cvs nil)

;;;;;;;;;;;;;;;;
; key bindings ;
;;;;;;;;;;;;;;;;

; so that M-TAB inserts a real tab while editing code
(global-set-key "�  " (quote self-insert-command "  "))

; bind "C-x g" to be M-x goto-line
(global-set-key "\C-xg" 'goto-line)

;;;;;;;;;;;;;
; functions ;
;;;;;;;;;;;;;

(defun dos-unix ()
  "Convert DOS CR-LF to UNIX NL"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (search-forward "\r" nil t) (replace-match ""))))

(defun unix-dos ()
  "Convert UNIX NL to DOS CR-LF"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (search-forward "\n" nil t) (replace-match "\r\n"))))

(defun ws ()
  "Make sure there is a space after every comma"
  (interactive)
  (save-excursion
    (set-variable 'case-fold-search nil)
    (goto-char (point-min))
    (while (re-search-forward "\\([,(]\\)\\([^[:space:]\n,]\\)" nil t) (replace-match "\\1 \\2"))
    (goto-char (point-min))
    (while (re-search-forward "COMMA ', '" nil t) (replace-match "COMMA ','"))
    (goto-char (point-min))
    (while (re-search-forward "([   ]+" nil t) (replace-match "("))
    (goto-char (point-min))
    (while (re-search-forward "[    ]+)" nil t) (replace-match ")"))
    (goto-char (point-min))
    (while (re-search-forward ")[   ]+\\([a-zA-Z]\\)" nil t) (replace-match ") \\1"))
    (goto-char (point-min))
    (while (re-search-forward "}[   ]*else[     ]*{" nil t) (replace-match "} else {"))
    (goto-char (point-min))
    (while (search-forward "if[     ]*(" nil t) (replace-match "if ("))
    (goto-char (point-min))
    (while (search-forward "for[    ]*(" nil t) (replace-match "for ("))
    (goto-char (point-min))
    (while (search-forward "while[  ]*(" nil t) (replace-match "while ("))
    (goto-char (point-min))
    (while (search-forward ")[  ]*{" nil t) (replace-match ") {"))
    (goto-char (point-min))
    (while (re-search-forward ")[[:space:|:space:]]*{" nil t) (replace-match ") {"))
    (goto-char (point-min))
    (while (re-search-forward "
\\(};?\\)[  ]*
[
    ]+" nil t) (replace-match "
\\1


"))
    (goto-char (point-min))
    (while (re-search-forward "
[   ]*
[
]+
" nil t) (replace-match "


"))
    (c-set-offset 'case-label '+)
    (c-set-offset 'statement-case-open '+)
    (c-set-offset 'innamespace 0)
    (c-set-offset 'inline-open 0)
    (indent-region (point-min) (point-max) nil)
    ))

(defun ws2 ()
  "Removes embedded white space (particularly tabs)"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (query-replace-regexp "\\([[:alnum:]_*(\[{@<>+#!\"'-]\\)[    ]*  [   ]*\\([[:alnum:]_*(\[{@<>+#!\"'-][[:alnum:]_*(\[{@<>+#!\"'-]?\\)[     ]+" "\\1 \\2 "))
    (goto-char (point-min))
    (while (query-replace-regexp "\\([[:alnum:]_*(\[{@<>+#!\"'-]\\)[    ]*  [   ]*\\([[:alnum:]_*(\[{@<>+#!\"'-]\\)" "\\1 \\2"))
    (goto-char (point-min))
    (while (query-replace-regexp "\\([[:alnum:]_*(\[{@<>+#!\"'-]\\)[    ]+ +[   ]*\\([[:alnum:]_*(\[{@<>+#!\"'-]\\)" "\\1 \\2"))
    ))

(defun ws3 ()
  "collapses multiple empty lines and ensures two after every global block"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (query-replace-regexp "
\\(};?\\)[  ]*
[
    ]+" "
\\1


"))
    (goto-char (point-min))
    (while (query-replace-regexp "
[   ]*
[
]+
" "


"))
    ))

(defun embrace ()
  "fix else statements and braces to be K&R style"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (query-replace-regexp "}[[:space:|:space:]]*
[[:space:|:space:]]+else" "} else"))
    (goto-char (point-min))
    (while (query-replace-regexp "[[:space:|:space:]]*
[[:space:|:space:]]+{" " {"))
    (goto-char (point-min))
    (while (query-replace-regexp "[[:space:|:space:]]*\\(/\\*.*\\*/\\)[[:space:|:space:]]*{
\\([[:space:|:space:]]+\\)" " {
\\2\\1
\\2"))
    (goto-char (point-min))
    (while (query-replace-regexp "[[:space:|:space:]]*\\(/\\*.*\\*/\\)[[:space:|:space:]]*
\\([[:space:|:space:]]+\\){" " {
\\2\\1"))
    (goto-char (point-min))
    (while (query-replace-regexp "[[:space:|:space:]]*{[[:space:|:space:]]*\\(/\\*.*\\*/\\)[[:space:|:space:]]*
\\([[:space:|:space:]]+\\)" " {
\\2\\1
\\2"))
    ))

; custom bindings to support our style idiosyncrasies
(global-set-key "\M-0" 'ws)
(global-set-key "\M-9" 'ws2)
(global-set-key "\M-8" 'embrace)
(global-set-key "\M-7" 'ws3)

If you install the aforementioned cmake-mode, you’ll need these extra lines in your .emacs file in order to enable the mode:

(add-to-list 'load-path "~/.emacs.d")

(require 'cmake-mode)
(setq auto-mode-alist
      (append '(("CMakeLists\\.txt\\'" . cmake-mode)
                ("\\.cmake\\'" . cmake-mode))
              auto-mode-alist))