home *** CD-ROM | disk | FTP | other *** search
- ;;;; c-mode.jl -- Primitive mode for editing C source
- ;;; Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
-
- ;;; This file is part of Jade.
-
- ;;; Jade is free software; you can redistribute it and/or modify it
- ;;; under the terms of the GNU General Public License as published by
- ;;; the Free Software Foundation; either version 2, or (at your option)
- ;;; any later version.
-
- ;;; Jade is distributed in the hope that it will be useful, but
- ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;; GNU General Public License for more details.
-
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with Jade; see the file COPYING. If not, write to
- ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- (provide 'c-mode)
-
- (defvar c-mode-tab 4
- "Size of indentation for c-mode")
- (defvar c-mode-auto-indent nil
- "When t cursor is automatically indented when <return> is pressed in
- c-mode.")
-
- (setq c-mode-keymap (make-keylist))
- (bind-keys c-mode-keymap
- "return" 'c-return
- "shift-return" 'split-line
- "{" 'c-open-brace
- "}" 'c-close-brace
- ":" 'c-colon
- "tab" 'c-indent-cursor
- "meta-tab" 'goto-next-tab)
-
- (defun c-mode ()
- "(c-mode)
- Simple mode for editing C source code."
- (eval-hook 'c-mode-hook)
- (setq
- mode-name "c-mode"
- major-mode-kill 'c-mode-kill
- screen-tab c-mode-tab
- ; word-regexp "[a-zA-Z0-9_]"
- ; word-not-regexp "[^a-zA-Z0-9_]"
- ; paragraph-regexp "^{"
- keymap-path (cons c-mode-keymap keymap-path)))
-
- (defun c-mode-kill ()
- (setq
- mode-name nil
- keymap-path (delq c-mode-keymap keymap-path)))
-
- (defun c-return ()
- (split-line)
- (when c-mode-auto-indent
- (if (empty-line-p)
- (goto (c-indent-pos-empty))
- (set-indent-pos (c-indent-pos)))))
-
- (defun c-open-brace ()
- (insert "{")
- (set-indent-pos (c-indent-pos)))
-
- (defun c-close-brace ()
- (insert "}")
- (set-indent-pos (c-indent-pos)))
-
- (defun c-colon ()
- (insert ":")
- (set-indent-pos (c-indent-pos)))
-
- (defun c-indent-pos (&optional line-pos)
- "(c-indent-pos [LINE-POS])
- *Attempts* to guess the correct indentation for this line. Returns the
- position for the first non-space in the line."
- (setq line-pos (line-start line-pos))
- (let*
- ((ind-pos (c-indent-pos-empty line-pos)))
- (when (not (empty-line-p line-pos))
- (cond
- ((regexp-match-line "^ *({|}|case .*:|default *:)" line-pos)
- (prev-tab 1 ind-pos))
- ((regexp-match-line "^ *([a-zA-Z0-9_]*:|#)" line-pos)
- (set-pos-col ind-pos 1))))
- ind-pos))
-
- (defun c-indent-pos-empty (&optional line-pos)
- "(c-indent-pos-empty [LINE-POS])
- Returns the position for the first non-space in the line. Bases its guess
- upon the assumption that the line is empty.
- All positions depend on the indentation of the previous line(s)."
- (setq line-pos (line-start line-pos))
- (let*
- ((p-line-pos (prev-line 1 (dup-pos line-pos))))
- (while (or (empty-line-p p-line-pos) (regexp-match-line "^([a-zA-Z0-9_]+:|#)" p-line-pos))
- (unless (prev-line 1 p-line-pos)
- (return)))
- (let*
- ((ind-pos (indent-pos p-line-pos)))
- (set-pos-line ind-pos (pos-line line-pos))
- (cond
- ((regexp-match-line "{|case .*:|default *:|do($| )|else|(if|for|while|switch) *\\(.*\\)" p-line-pos)
- (next-tab 1 ind-pos))
- ((regexp-match-line ";" p-line-pos)
- (prev-line 1 p-line-pos)
- (while (or (empty-line-p p-line-pos) (regexp-match-line "^([a-zA-Z0-9_]+:|#)" p-line-pos))
- (unless (prev-line 1 p-line-pos)
- (return)))
- (when (and (regexp-match-line "do($| )|else|(if|for|while|switch) *\\(.*\\)" p-line-pos)
- (not (regexp-match-line " { *(/\\*.*\\*/|) *$" p-line-pos)))
- (prev-tab 1 ind-pos)))
- ((regexp-match-line "^ */\\*" p-line-pos)
- (unless (regexp-match-line "\\*/" p-line-pos)
- (right-char 3 ind-pos)))
- ((regexp-match-line "^ *\\*/ *$" p-line-pos)
- (left-char 1 ind-pos))
- ((regexp-match-line "\\*/" p-line-pos)
- (left-char 3 ind-pos)))
- ind-pos)))
-
- (defun c-indent-lines (start-pos end-pos)
- (setq start-pos (line-start start-pos))
- (while (< start-pos end-pos)
- (set-indent-pos (c-indent-pos start-pos))
- (next-line 1 start-pos)))
-
- (defun c-indent-cursor (&aux tmp)
- (if (empty-line-p)
- (goto (c-indent-pos-empty (cursor-pos)))
- (setq tmp (set-indent-pos (c-indent-pos (cursor-pos))))
- (cond
- ((> tmp (cursor-pos))
- (goto tmp))
- ((> (cursor-pos) (line-end))
- (goto (line-end))))))
-