;;; coldc-mode.el --- major mode for editing ColdC code
;; Copyright (C) 1997 Neale Pickett <zephyr@nmt.edu>
;; Modified: 24 February 1998 by Sleeper@LambdaMOO
;; Further hacking to bring it up to date with the latest cc-mode.el.
;;
;; Created: March 15, 1997
;; Version: 1.0
;; Time-stamp: <16 Mar 97 14:05:12 zephyr>
;; Keywords: coldc
;; This program 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 of the
;; License, or (at your option) any later version.
;;
;; This program 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 this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; I pretty much ripped most of this out of the cc-mode.el that came
;; with my XEmacs distribution. It works great for me, your mileage may
;; vary.
;;
;; Feel free to mail me (zephyr@nmt.edu) with comments/suggestions. In
;; particular, I'd like to know if there's a way to fix my grody hack of
;; c-in-literal or a better way to set c-style-alist.
;;
;; To get this mode to work, put this file somewhere in your load-path,
;; and insert the following line in your .emacs:
;;
;; (autoload 'coldc-mode "coldc-mode" "ColdC-mode" t)
;;
;; you might also want to add ("\\.cdc$" . coldc-mode) to your
;; auto-mode-alist, or whatever extension you prefer.
(require 'cc-mode)
(c-initialize-cc-mode)
(defconst c-ColdC-conditional-key
"\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\|catch\\|with\\)\\b[^_]"
"Regexp describing a conditional control for ColdC.")
(defconst coldc-font-lock-keywords
'(("\\(for\\|in\\|if\\|to\\|else\\|while\\|switch\\|catch\\|with\\|var\\|arg\\|break\\|continue\\|return\\|any\\)[ \t\n]"
. 1)
("^@program[ \t]+\\(\\(\\sw\\|[-_.]\\)+\\)"
1 'font-lock-function-name-face)
("^\\(@\\(\\sw\\|[-_]\\)+\\)"
1 'font-lock-preprocessor-face)
("case[ \t]+\\(\\(\\sw\\|\\s_\\)+\\):" . 1)
("\\<\\(default\\):" . 1)))
(defconst c-ColdC-method-key
"^ @program"
"Regexp describing a ColdC method intro.")
(setq coldc-mode-syntax-table nil)
; "Syntax table used in coldc-mode buffers.")
(if coldc-mode-syntax-table
()
(setq coldc-mode-syntax-table (make-syntax-table))
(c-populate-syntax-table coldc-mode-syntax-table)
;; add extra comment syntax
;;; Default now ;(c-setup-dual-comments coldc-mode-syntax-table)
;; symbols
(modify-syntax-entry ?\' "." coldc-mode-syntax-table)
;; comments
(modify-syntax-entry ?/ ". 12" coldc-mode-syntax-table)
(modify-syntax-entry ?\n "> a" coldc-mode-syntax-table)
(modify-syntax-entry ?\^m "> a" coldc-mode-syntax-table)
(modify-syntax-entry ?\* "." coldc-mode-syntax-table)
)
(setq c-style-alist
(append c-style-alist
'(("coldc"
(c-basic-offset . 4)
(c-offsets-alist . ((topmost-intro-cont . +)))
))
))
(defvar coldc-mode-abbrev-table nil
"Abbrev table used in ColdC-mode buffers.")
(define-abbrev-table 'coldc-mode-abbrev-table ())
(defvar coldc-mode-map ()
"Keymap used in ColdC-mode buffers.")
(if coldc-mode-map
nil
(setq coldc-mode-map (c-make-inherited-keymap))
;; add bindings which are only useful for ColdC
)
(easy-menu-define c-coldc-menu coldc-mode-map "ColdC Mode Commands"
(c-mode-menu "ColdC"))
;; This is a nasty, evil, yukky kludge, but I can't find a better way to
;; do it. Perhaps a more experienced elisp programmer can clean up how
;; I do this. I've added an extra condition that checks for lines
;; beginning with "@" or lines containing only ".", which returns 'pound
;; iff we're in coldc-mode.
;;
;; Barf Gag Retch
;;
;; This is for all v19 Emacsen supporting either 1-bit or 8-bit syntax
(defun c-in-literal (&optional lim)
;; Determine if point is in a C++ literal. we cache the last point
;; calculated if the cache is enabled
(if (and (boundp 'c-in-literal-cache)
c-in-literal-cache
(= (point) (aref c-in-literal-cache 0)))
(aref c-in-literal-cache 1)
(let ((rtn (save-excursion
(let* ((lim (or lim (c-point 'bod)))
(here (point))
(state (parse-partial-sexp lim (point))))
(cond
((nth 3 state) 'string)
((nth 4 state) (if (nth 7 state) 'c++ 'c))
((progn
(goto-char here)
(beginning-of-line)
(looking-at "[ \t]*#"))
'pound)
;; \begin{kludge}
((and (eq major-mode 'coldc-mode)
(progn
(goto-char here)
(beginning-of-line)
(looking-at "@\\|\\.\n")))
'pound)
;; \end{kludge}
(t nil))))))
;; cache this result if the cache is enabled
(and (boundp 'c-in-literal-cache)
(setq c-in-literal-cache (vector (point) rtn)))
rtn)))
(defun coldc-mode ()
"Major mode for editing ColdC code.
Nasty hack of cc-mode.
To see what version of cc-mode you are running, enter `\\[c-version]'.
The hook variable `coldc-mode-hook' is run with no args, if that value
is bound and has a non-nil value. Also the common hook
`c-mode-common-hook' is run first.
Key bindings:
\\{coldc-mode-map}"
(interactive)
(c-initialize-cc-mode)
(kill-all-local-variables)
(set-syntax-table coldc-mode-syntax-table)
(setq major-mode 'coldc-mode
mode-name "ColdC"
local-abbrev-table coldc-mode-abbrev-table)
(use-local-map coldc-mode-map)
(c-common-init)
(setq comment-start "// "
comment-end ""
c-conditional-key c-ColdC-conditional-key
c-comment-start-regexp "//"
parse-sexp-ignore-comments nil)
;; (setq comment-start "// "
;; comment-end ""
;; comment-multi-line nil
;; c-conditional-key c-ColdC-conditional-key
;; c-comment-start-regexp c-C++-comment-start-regexp
;; c-class-key c-ColdC-class-key
;; c-method-key c-ColdC-method-key
;; c-double-slash-is-comments-p t
;; c-baseclass-key nil
;; c-access-key c-ColdC-access-key)
(c-set-style "ColdC")
(run-hooks 'c-mode-common-hook)
(run-hooks 'coldc-mode-hook)
(c-update-modeline)
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults '(coldc-font-lock-keywords nil nil))
(turn-on-font-lock))
(provide 'coldc-mode)
;;; coldc-mode.el ends here