diff lisp/cc-mode/cc-lobotomy.el @ 165:5a88923fcbfe r20-3b9

Import from CVS: tag r20-3b9
author cvs
date Mon, 13 Aug 2007 09:44:42 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/cc-mode/cc-lobotomy.el	Mon Aug 13 09:44:42 2007 +0200
@@ -0,0 +1,200 @@
+;;; cc-lobotomy.el --- excise portions of cc-mode's brain... for speed
+
+;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
+
+;; Author:     1995 Barry A. Warsaw
+;; Maintainer: Unmaintained
+;; Created:    March 1995, split from cc-mode.el
+;; Version:    5.11
+;; Keywords:   c languages oop
+
+;; This file is not part of GNU Emacs.
+
+;; 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 GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Every effort has been made to improve the performance of
+;; cc-mode. However, due to the nature of the C, C++, and Objective-C
+;; language definitions, a trade-off is often required between
+;; accuracy of construct recognition and speed. I believe it is always
+;; best to be correct, and that the mode is currently fast enough for
+;; most normal usage.  Others disagree.  I have no intention of
+;; including these hacks in the main distribution.  When cc-mode
+;; version 5 comes out, it will include a rewritten indentation engine
+;; so that performance will be greatly improved automatically.  This
+;; was not included in this release of version 4 so that Emacs 18
+;; could still be supported.  Note that this implies that cc-mode
+;; version 5 will *not* work on Emacs 18!
+;;
+;; To use, see the variable cc-lobotomy-pith-list and the function
+;; cc-lobotomize.   The variable contains a good explanation of the
+;; speed/accuracy trade-offs for each option.  Set it to what you'd
+;; like, and call cc-lobotomy in your c-mode-hook.
+;;
+;; This will redefine certain cc-mode functions and affect all cc-mode
+;; buffers globally.
+;;
+;; This file is completely unsupported!  I have no idea whether this
+;; will work with such things as cc-mode-18.el.
+
+
+;;; Code:
+(require 'cc-mode)
+
+(defvar cc-lobotomy-pith-list ()
+  "*List of things to dumb-ify to speed up cc-mode.  Note that each
+incurs a penalty in correct identification of certain code constructs.
+Possible values to put on this list:
+
+  'literal -- `c-in-literal' is lobotomized.  This will significantly
+              speed up parsing over large lists of cpp macros, as seen
+	      for instance in header files.  The penalty is that you
+	      cannot put the `#' character as the first non-whitespace
+	      character on a line inside other multi-line literals
+	      (i.e. comments or strings)
+
+  'class   -- `c-narrow-out-enclosing-class' and `c-search-uplist for
+              classkey' are lobotomized.  This speeds up some
+	      indenting inside and around class and struct
+	      definitions.  The penalty is that elements inside of
+	      classes and structs may not indent correctly.
+
+  'lists   -- `c-inside-bracelist-p' is lobotomized.  This speeds up
+              indenting inside and around brace lists (e.g. aggregate
+	      initializers, enum lists, etc.).  The penalty is that
+	      elements inside these lists may not indent correctly.")
+
+(defun cc-lobotomize ()
+  "Perform lobotomies on cc-mode as described in `cc-lobotomy-pith-list'."
+  (let (pithedp)
+    (if (memq 'literal cc-lobotomy-pith-list)
+	(progn
+	  (fset 'c-in-literal 'cc-in-literal-lobotomized)
+	  (setq pithedp t)))
+    (if (memq 'class cc-lobotomy-pith-list)
+	(progn
+	  (fset 'c-narrow-out-enclosing-class
+		'cc-narrow-out-enclosing-class-lobotomized)
+	  (fset 'c-search-uplist-for-classkey
+		'cc-search-uplist-for-classkey-lobotomized)
+	  (setq pithedp t)))
+    (if (memq 'lists cc-lobotomy-pith-list)
+	(progn
+	  (fset 'c-inside-bracelist-p 'cc-inside-bracelist-p-lobotomized)
+	  (setq pithedp t)))
+    (if pithedp
+	(fset 'c-submit-bug-report 'cc-submit-bug-report-lobotomized))
+    ))
+
+
+;; This is a faster version of c-in-literal.  It trades speed for one
+;; approximation, namely that within other literals, the `#' character
+;; cannot be the first non-whitespace on a line.
+(defun cc-in-literal-lobotomized (&optional lim)
+  ;; first check the cache
+  (if (and (boundp 'c-in-literal-cache)
+	   c-in-literal-cache
+	   (= (point) (aref c-in-literal-cache 0)))
+      (aref c-in-literal-cache 1)
+    ;; quickly check for cpp macro. this breaks if the `#' character
+    ;; appears as the first non-whitespace on a line inside another
+    ;; literal.
+    (let* (state
+	   (char-at-boi (char-after (c-point 'boi)))
+	   (rtn (cond
+		 ((and char-at-boi (= char-at-boi ?#))
+		  'pound)
+		 ((nth 3 (setq state (save-excursion
+				       (parse-partial-sexp
+					(or lim (c-point 'bod))
+					(point)))))
+		  'string)
+		 ((nth 4 state) (if (nth 7 state) 'c++ 'c))
+		 (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 cc-narrow-out-enclosing-class-lobotomized (dummy1 dummy2) nil)
+
+(defun cc-search-uplist-for-classkey-lobotomized (dummy) nil)
+
+(defun cc-inside-bracelist-p-lobotomized (dummy1 dummy2) nil)
+
+(defun cc-submit-bug-report-lobotomized ()
+  "Submit via mail a bug report on cc-mode."
+  (interactive)
+  ;; load in reporter
+  (let ((reporter-prompt-for-summary-p t)
+	(reporter-dont-compact-list '(c-offsets-alist)))
+    (and
+     (y-or-n-p "Do you want to submit a report on cc-mode? ")
+     (require 'reporter)
+     (reporter-submit-bug-report
+      c-mode-help-address
+      (concat "cc-mode " c-version " ("
+	      (cond ((eq major-mode 'c++-mode)  "C++")
+		    ((eq major-mode 'c-mode)    "C")
+		    ((eq major-mode 'objc-mode) "ObjC"))
+	      ")")
+      (let ((vars (list
+		   ;; report only the vars that affect indentation
+		   'c-basic-offset
+		   'c-offsets-alist
+		   'c-block-comments-indent-p
+		   'c-cleanup-list
+		   'c-comment-only-line-offset
+		   'c-backslash-column
+		   'c-delete-function
+		   'c-electric-pound-behavior
+		   'c-hanging-braces-alist
+		   'c-hanging-colons-alist
+		   'c-hanging-comment-ender-p
+		   'c-tab-always-indent
+		   'c-recognize-knr-p
+		   'defun-prompt-regexp
+		   'tab-width
+		   )))
+	(if (not (boundp 'defun-prompt-regexp))
+	    (delq 'defun-prompt-regexp vars)
+	  vars))
+      (function
+       (lambda ()
+	 (insert
+	  (if c-special-indent-hook
+	      (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
+		      "c-special-indent-hook is set to '"
+		      (format "%s" c-special-indent-hook)
+		      ".\nPerhaps this is your problem?\n"
+		      "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
+	    "\n")
+	  (format "c-emacs-features: %s\n" c-emacs-features)
+	  )))
+      (function
+       (lambda ()
+	 (insert
+	  "You are using cc-lobotomy.el.  You realize that by doing\n"
+	  "so you have already made the decision to trade off accuracy\n"
+	  "for speed?  Don't set your hopes too high that your problem\n"
+	  "will be fixed.\n\n"
+	  )))
+      "Dear Barry,"
+      ))))
+
+(provide 'cc-lobotomy)
+;;; cc-lobotomy.el ends here