home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / may94 / util / edit / jade.lha / Jade / lisp / c-mode.jl < prev    next >
Lisp/Scheme  |  1994-04-18  |  4KB  |  139 lines

  1. ;;;; c-mode.jl -- Primitive mode for editing C source
  2. ;;;  Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4. ;;; This file is part of Jade.
  5.  
  6. ;;; Jade is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 2, or (at your option)
  9. ;;; any later version.
  10.  
  11. ;;; Jade is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ;;; GNU General Public License for more details.
  15.  
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with Jade; see the file COPYING.  If not, write to
  18. ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. (provide 'c-mode)
  21.  
  22. (defvar c-mode-tab 4
  23.   "Size of indentation for c-mode")
  24. (defvar c-mode-auto-indent nil
  25.   "When t cursor is automatically indented when <return> is pressed in
  26. c-mode.")
  27.  
  28. (setq c-mode-keymap (make-keylist))
  29. (bind-keys c-mode-keymap
  30.   "return" 'c-return
  31.   "shift-return" 'split-line
  32.   "{" 'c-open-brace
  33.   "}" 'c-close-brace
  34.   ":" 'c-colon
  35.   "tab" 'c-indent-cursor
  36.   "meta-tab" 'goto-next-tab)
  37.  
  38. (defun c-mode ()
  39.   "(c-mode)
  40. Simple mode for editing C source code."
  41.   (eval-hook 'c-mode-hook)
  42.   (setq
  43.     mode-name "c-mode"
  44.     major-mode-kill 'c-mode-kill
  45.     screen-tab c-mode-tab
  46. ;   word-regexp "[a-zA-Z0-9_]"
  47. ;   word-not-regexp "[^a-zA-Z0-9_]"
  48. ;   paragraph-regexp "^{"
  49.     keymap-path (cons c-mode-keymap keymap-path)))
  50.  
  51. (defun c-mode-kill ()
  52.   (setq
  53.     mode-name nil
  54.     keymap-path (delq c-mode-keymap keymap-path)))
  55.  
  56. (defun c-return ()
  57.   (split-line)
  58.   (when c-mode-auto-indent
  59.     (if (empty-line-p)
  60.     (goto (c-indent-pos-empty))
  61.       (set-indent-pos (c-indent-pos)))))
  62.  
  63. (defun c-open-brace ()
  64.   (insert "{")
  65.   (set-indent-pos (c-indent-pos)))
  66.  
  67. (defun c-close-brace ()
  68.   (insert "}")
  69.   (set-indent-pos (c-indent-pos)))
  70.  
  71. (defun c-colon ()
  72.   (insert ":")
  73.   (set-indent-pos (c-indent-pos)))
  74.  
  75. (defun c-indent-pos (&optional line-pos)
  76.   "(c-indent-pos [LINE-POS])
  77. *Attempts* to guess the correct indentation for this line. Returns the
  78. position for the first non-space in the line."
  79.   (setq line-pos (line-start line-pos))
  80.   (let*
  81.       ((ind-pos (c-indent-pos-empty line-pos)))
  82.     (when (not (empty-line-p line-pos))
  83.       (cond
  84.     ((regexp-match-line "^ *({|}|case .*:|default *:)" line-pos)
  85.       (prev-tab 1 ind-pos))
  86.     ((regexp-match-line "^ *([a-zA-Z0-9_]*:|#)" line-pos)
  87.       (set-pos-col ind-pos 1))))
  88.     ind-pos))
  89.  
  90. (defun c-indent-pos-empty (&optional line-pos)
  91.   "(c-indent-pos-empty [LINE-POS])
  92. Returns the position for the first non-space in the line. Bases its guess
  93. upon the assumption that the line is empty.
  94. All positions depend on the indentation of the previous line(s)."
  95.   (setq line-pos (line-start line-pos))
  96.   (let*
  97.       ((p-line-pos (prev-line 1 (dup-pos line-pos))))
  98.     (while (or (empty-line-p p-line-pos) (regexp-match-line "^([a-zA-Z0-9_]+:|#)" p-line-pos))
  99.       (unless (prev-line 1 p-line-pos)
  100.     (return)))
  101.     (let*
  102.     ((ind-pos (indent-pos p-line-pos)))
  103.       (set-pos-line ind-pos (pos-line line-pos))
  104.       (cond
  105.     ((regexp-match-line "{|case .*:|default *:|do($| )|else|(if|for|while|switch) *\\(.*\\)" p-line-pos)
  106.       (next-tab 1 ind-pos))
  107.     ((regexp-match-line ";" p-line-pos)
  108.       (prev-line 1 p-line-pos)
  109.       (while (or (empty-line-p p-line-pos) (regexp-match-line "^([a-zA-Z0-9_]+:|#)" p-line-pos))
  110.         (unless (prev-line 1 p-line-pos)
  111.           (return)))
  112.       (when (and (regexp-match-line "do($| )|else|(if|for|while|switch) *\\(.*\\)" p-line-pos)
  113.              (not (regexp-match-line " { *(/\\*.*\\*/|) *$" p-line-pos)))
  114.         (prev-tab 1 ind-pos)))
  115.     ((regexp-match-line "^ */\\*" p-line-pos)
  116.       (unless (regexp-match-line "\\*/" p-line-pos)
  117.         (right-char 3 ind-pos)))
  118.     ((regexp-match-line "^ *\\*/ *$" p-line-pos)
  119.       (left-char 1 ind-pos))
  120.     ((regexp-match-line "\\*/" p-line-pos)
  121.       (left-char 3 ind-pos)))
  122.       ind-pos)))
  123.  
  124. (defun c-indent-lines (start-pos end-pos)
  125.   (setq start-pos (line-start start-pos))
  126.   (while (< start-pos end-pos)
  127.     (set-indent-pos (c-indent-pos start-pos))
  128.     (next-line 1 start-pos)))
  129.  
  130. (defun c-indent-cursor (&aux tmp)
  131.   (if (empty-line-p)
  132.       (goto (c-indent-pos-empty (cursor-pos)))
  133.     (setq tmp (set-indent-pos (c-indent-pos (cursor-pos))))
  134.     (cond
  135.       ((> tmp (cursor-pos))
  136.     (goto tmp))
  137.       ((> (cursor-pos) (line-end))
  138.     (goto (line-end))))))
  139.