summaryrefslogtreecommitdiffstats
path: root/scripts/kde-emacs
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kde-emacs')
-rw-r--r--scripts/kde-emacs/HACKING7
-rw-r--r--scripts/kde-emacs/dirvars.el200
-rw-r--r--scripts/kde-emacs/kde-emacs-bindings.el185
-rw-r--r--scripts/kde-emacs/kde-emacs-compat.el77
-rw-r--r--scripts/kde-emacs/kde-emacs-core.el3823
-rw-r--r--scripts/kde-emacs/kde-emacs-doc.el322
-rw-r--r--scripts/kde-emacs/kde-emacs-general.el179
-rw-r--r--scripts/kde-emacs/kde-emacs-semantic.el456
-rw-r--r--scripts/kde-emacs/kde-emacs-tips.texi257
-rw-r--r--scripts/kde-emacs/kde-emacs-utils.el894
-rw-r--r--scripts/kde-emacs/kde-emacs-vars.el147
-rw-r--r--scripts/kde-emacs/kde-emacs.el66
-rw-r--r--scripts/kde-emacs/klaralv.el422
13 files changed, 7035 insertions, 0 deletions
diff --git a/scripts/kde-emacs/HACKING b/scripts/kde-emacs/HACKING
new file mode 100644
index 00000000..d3a87f22
--- /dev/null
+++ b/scripts/kde-emacs/HACKING
@@ -0,0 +1,7 @@
+Rules are simple:
+1) Make sure that your functions work both on GNU/Emacs and XEmacs.
+2) Put general variables in kde-emacs-vars.el, file related variables
+inside the related file.
+3) Export general functions to kde-emacs-general.el.
+4) Always provide documentation for both variables and functions that
+you're adding.
diff --git a/scripts/kde-emacs/dirvars.el b/scripts/kde-emacs/dirvars.el
new file mode 100644
index 00000000..5fba18e7
--- /dev/null
+++ b/scripts/kde-emacs/dirvars.el
@@ -0,0 +1,200 @@
+;;; -*- local-enable-local-variables: nil -*-
+;;; dirvars.el --- Local variables that apply to an entire directory
+
+;; Copyright (C) 2002 Matt Armstrong
+
+;; Author: Matt Armstrong <matt@lickey.com>
+;; Location: http://www.lickey.com/env/elisp/dirvars.el
+;; Keywords: files
+;; Version: 1.2
+;; Obscure: matt@squeaker.lickey.com|elisp/dirvars.el|20021213043855|48166
+
+;; This file 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.
+
+;; This file 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., 51 Franklin Steet, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Emacs allows you to specify local variable values for use when
+;; editing a file either in the first line or in a local variables
+;; list.
+;;
+;; This file provides similar functionality, but for an entire
+;; directory tree.
+;;
+;; You simply place an .emacs-dirvars file in the root of your
+;; project's tree, and you can then set emacs variables like you would
+;; in a Local Variables: section at the end of a file. E.g. the
+;; contents of a typical dirvars file might look like this:
+;;
+;; ;; -*- emacs-lisp -*-
+;; ;;
+;; ;; This file is processed by the dirvars emacs package. Each variable
+;; ;; setting below is performed when this dirvars file is loaded.
+;; ;;
+;; indent-tabs-mode: nil
+;; tab-width: 8
+;; show-trailing-whitespace: t
+;; indicate-empty-lines: t
+;;
+;; Much of this code is stolen and modified from the standard Emacs
+;; files.el
+;;
+;; This code refuses to set any symbol that meets any of these
+;; criteria (this criteria is stolen from files.el):
+;;
+;; - the symbol is in the ignored-local-variables list
+;; - the symbol has the risky-local-variable property.
+;; - the symbol name ends in -hook(s), -function(s), -form(s),
+;; -program, -command, or -predicate.
+
+;;; Todo:
+
+;; Implement the following changes to keep in line with elisp coding
+;; conventions: When a package provides a modification of ordinary
+;; Emacs behavior, it is good to include a command to enable and
+;; disable the feature, Provide a command named `WHATEVER-mode' which
+;; turns the feature on or off, and make it autoload (*note
+;; Autoload::). Design the package so that simply loading it has no
+;; visible effect--that should not enable the feature.(2) Users will
+;; request the feature by invoking the command.
+;;
+;; Support customize?
+
+;;; Code:
+
+(defvar dirvars-enable-flag t
+ "*Control use of directory variables in files you visit.
+The meaningful values are nil and non-nil.")
+
+(defun dirvars-find-upwards (file-name)
+ "Find a file in the current directory or one of its parents.
+
+Returns the fully qualified file name, or nil if it isn't found.
+
+The FILE-NAME specifies the file name to search for."
+ ;; Chase links in the source file and search in the dir where it
+ ;; points.
+ (setq dir-name (or (and buffer-file-name
+ (file-name-directory (file-chase-links
+ buffer-file-name)))
+ default-directory))
+ ;; Chase links before visiting the file. This makes it easier to
+ ;; use a single file for several related directories.
+ (setq dir-name (file-chase-links dir-name))
+ (setq dir-name (expand-file-name dir-name))
+ ;; Move up in the dir hierarchy till we find a change log file.
+ (let ((file1 (concat dir-name file-name))
+ parent-dir)
+ (while (and (not (file-exists-p file1))
+ (progn (setq parent-dir
+ (file-name-directory
+ (directory-file-name
+ (file-name-directory file1))))
+ ;; Give up if we are already at the root dir.
+ (not (string= (file-name-directory file1)
+ parent-dir))))
+ ;; Move up to the parent dir and try again.
+ (setq file1 (expand-file-name file-name parent-dir)))
+ ;; If we found the file in a parent dir, use that. Otherwise,
+ ;; return nil
+ (if (or (get-file-buffer file1) (file-exists-p file1))
+ file1
+ nil)))
+
+(defun dirvars-eat-comment ()
+ (while (looking-at "[ \t\n]*;")
+ (let ((begin (point)))
+ (skip-chars-forward " \t\n")
+ (if (looking-at ";")
+ (progn
+ (end-of-line)
+ (delete-region begin (point)))))))
+
+(defun dirvars-hack-local-variables (dirvars-file)
+ (save-excursion
+ (let ((original-buffer (current-buffer))
+ (temp-buffer (get-buffer-create "*dirvars-temp*"))
+ (enable-local-variables (and ;local-enable-local-variables -- doesn't exist!
+ enable-local-variables
+ dirvars-enable-flag))
+ (continue t)
+ (parse-sexp-ignore-comments t)
+ (lisp-mode-hook nil)
+ beg)
+ (set-buffer temp-buffer)
+ (erase-buffer)
+ (lisp-mode)
+ (insert-file dirvars-file)
+ (goto-char (point-min))
+ (catch 'done
+ (while continue
+ (if (null (scan-sexps (point) 1))
+ (throw 'done nil))
+ (goto-char (scan-sexps (point) 1))
+ (goto-char (scan-sexps (point) -1))
+ (if (eobp)
+ (throw 'done nil))
+ (setq beg (point))
+ (skip-chars-forward "^:\n")
+ (if (not (looking-at ":"))
+ (error (format "Missing colon in directory variables entry at %d"
+ (point))))
+ (skip-chars-backward " \t")
+ (let* ((str (buffer-substring beg (point)))
+ (var (read str))
+ val)
+ ;; Read the variable value.
+ (skip-chars-forward "^:")
+ (forward-char 1)
+ (setq val (read (current-buffer)))
+ (save-excursion
+ (set-buffer original-buffer)
+ (dirvars-hack-one-local-variable dirvars-file
+ var val))))))))
+
+(defun dirvars-hack-one-local-variable (dirvars-file var val)
+ "\"Set\" one variable in a local variables spec.
+A few variable names are treated specially."
+ (cond ((memq var ignored-local-variables)
+ nil)
+ ;; Trap risky variables and such. This is the same logic
+ ;; that files.el uses.
+ ((or (get var 'risky-local-variable)
+ (and
+ (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$\\|-predicate$"
+ (symbol-name var))
+ (not (get var 'safe-local-variable))))
+ (message (format "Ignoring %s in %s"
+ (symbol-name var) dirvars-file)))
+ ;;check whether the var should be evaluated
+ ((eq var 'evaluate)
+ (eval val))
+ ;; Ordinary variable, really set it.
+ (t (make-local-variable var)
+ (set var val))))
+
+(defun dirvars-hack-local-variables-before ()
+ (let ((dirvars-file (dirvars-find-upwards ".emacs-dirvars")))
+ (if dirvars-file
+ (dirvars-hack-local-variables dirvars-file))))
+
+(defadvice hack-local-variables
+ (before dirvars-hack-local-variables-before)
+ "Process dirvars before a file's local variables are processed."
+ (dirvars-hack-local-variables-before))
+(ad-activate 'hack-local-variables)
+
+(provide 'dirvars)
+;;; dirvars.el ends here
diff --git a/scripts/kde-emacs/kde-emacs-bindings.el b/scripts/kde-emacs/kde-emacs-bindings.el
new file mode 100644
index 00000000..84202dfb
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-bindings.el
@@ -0,0 +1,185 @@
+;; kde-emacs-bindings.el
+;;
+;; Copyright (C) 2002 KDE Development Team
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2.1 of the License, or (at your option) any later version.
+;;
+;; This library 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
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+
+; currently no binding for header-protection and add-file-to-makefile-am,
+; you need to call them from M-x
+
+; -----------------------------------------------------------------
+; The list below defines the following bindings:
+;
+; F2 : offer a grep command (use C-u F2 if you need to specify options, like -i or -w)
+; Shift-F2 : offer a grep command to search in directories below the current too..
+;
+; F3/Shift-F3/F8/Shift-RMB : different ways to see the list of methods in the current buffer
+;
+; F4 : make
+; Shift-F4 : make clean
+; F5 : make install
+; Shift-F5 : make install-exec
+;
+; Shift-F6 : compile this file [assumes libtool is being used]
+; F6 : Switch from .cpp/.cc to .h and vice-versa
+; F7 : The same, but try to find the current method in the other file
+; F9 : Create a member method in the .cpp, the cursor being on the definition in the .h
+; F10: Place point on a class name, and the respective (Qt) include file will be inserted.
+; This works with all Qt classes but can easily be extended to KDE classes.
+; Shift-F10: Place point on a class name, and "class Blah" will be inserted near the top.
+; Meta-F10: Place point on a class name, and press Meta-F10, and konqueror will load
+; Qt documentation. Customize the location of the Qt documentation with the
+; variable kdab-qt-documentation. XXX will be replace with the class name.
+; Example (setq kdab-qt-location "file:/packages/kde-src/qt-copy/doc/html/XXX.html")
+;
+; M-n: jump to the next error (after compiling) or grep matches
+;
+; Ctrl+Meta+D : insert a kdDebug statement with the name of the current method
+; [the new hide-all-windows shortcut conflicts with that, you may have to
+; change it, or use Ctrl+Meta+Shift+D (!!)]
+;
+; Meta Up/Down : scroll the other window (when window is split)
+
+; Other very useful keybindings to know about:
+; C-x r m to set a named bookmark in the buffer
+; C-x r b to jump to a named bookmark in the buffer
+; To save bookmarks to a file type:
+; M-x bookmark-write
+; and to load bookmarks from a file write:
+; M-x bookmark-load
+
+(require 'kde-emacs-core)
+(require 'kde-emacs-general)
+(require 'kde-emacs-utils)
+(require 'klaralv)
+(require 'kde-emacs-utils)
+(when (featurep 'semantic)
+ (require 'kde-emacs-semantic)
+ (require 'kde-emacs-doc))
+
+;; Wheelmouse support
+(define-key global-map [(button4)] 'scroll-me-down)
+(define-key global-map [(button5)] 'scroll-me-up)
+(define-key global-map [(shift button4)] 'scroll-me-down-a-bit)
+(define-key global-map [(shift button5)] 'scroll-me-up-a-bit)
+
+;; Some example bindings, feel free to customize :)
+(define-key global-map [(meta up)] 'scroll-other-up)
+(define-key global-map [(meta down)] 'scroll-other-down)
+(define-key global-map [(control j)] 'goto-line)
+(global-set-key [(control %)] 'match-paren) ;;for all buffers :)
+
+(if (featurep 'igrep)
+ (progn
+ (setq igrep-find-prune-clause
+ (format "-type d %s -name CVS -o -name .libs -o -name .deps %s"
+ (shell-quote-argument "(")
+ (shell-quote-argument ")")))
+ (setq igrep-find-file-clause
+ (format "-type f %s -name %s %s -name %s %s -name %s %s -name %s" ; -type l
+ (shell-quote-argument "!")
+ (shell-quote-argument "*~") ; Emacs backup
+ (shell-quote-argument "!")
+ (shell-quote-argument "*,v") ; RCS file
+ (shell-quote-argument "!")
+ (shell-quote-argument "s.*") ; SCCS file
+ (shell-quote-argument "!")
+ (shell-quote-argument "*.o") ; compiled object
+ (shell-quote-argument "!")
+ (shell-quote-argument ".#*") ; Emacs temp file
+ )
+ )
+ (define-key global-map [(f2)] 'igrep)
+ (define-key global-map [(shift f2)] 'igrep-find)
+ (define-key global-map [(f12)] 'igrep-find) ; on the console, shift f2 gives f12 for some reason..
+ ;(setq igrep-files-default 'ignore) ; too hard to use *.cc *.h with it, because of the full path
+ )
+ (define-key global-map [(f2)] 'grep))
+(define-key global-map [(shift backspace)] 'kde-delete-backward-ws)
+
+;; FIXME: remember to get these working on Gnu/Emacs (Zack)
+(when (eq kde-emacs-type 'xemacs)
+ (define-key c++-mode-map [(f8)] 'function-menu)
+ (define-key c++-mode-map [(f3)] 'fume-prompt-function-goto)
+ (define-key c++-mode-map [(shift f3)] 'fume-list-functions)
+ )
+
+(define-key global-map [(shift button3)] 'mouse-function-menu)
+(define-key global-map [(shift f4)] 'makeclean)
+(define-key global-map [(f4)] 'make)
+(define-key global-map [(f5)] 'makeinstall)
+(define-key global-map [(shift f5)] 'makeinstallexec)
+(define-key global-map [(shift f6)] 'makethisfile)
+(if kde-emacs-newline-semicolon
+ (define-key c++-mode-map "\;" 'insert-semicolon))
+(define-key c++-mode-map [(f6)] 'kde-switch-cpp-h)
+(define-key c-mode-map [(f6)] 'kde-switch-cpp-h)
+(define-key c++-mode-map [(f7)] 'switch-to-function-def)
+(define-key c++-mode-map [(f9)] 'agulbra-make-member)
+(define-key c-mode-map [(f9)] 'agulbra-make-member)
+(define-key global-map [(meta n)] 'next-error)
+
+; kde-emacs-headers:
+(define-key c++-mode-map [(f10)] 'kdab-insert-header)
+(define-key c++-mode-map [(shift f10)] 'kdab-insert-forward-decl)
+(define-key c++-mode-map [(meta f10)] 'kdab-lookup-qt-documentation)
+(define-key c++-mode-map [(control meta d)] 'insert-kdDebug)
+
+; Standard Qt/KDE shortcuts: Ctrl+Backspace, Ctrl+Delete
+(define-key global-map [(control backspace)] 'backward-kill-word)
+(define-key global-map [(control delete)] 'kill-word)
+
+; Standard Qt/KDE shortcuts: Control Pageup and Pagedown
+(define-key global-map [(control prior)] 'beginning-of-buffer)
+(define-key global-map [(control next)] 'end-of-buffer)
+
+; kde-emacs-semantic :
+; no binding for kde-license-insert; call it via M-x
+(when (featurep 'semantic)
+ (define-key c++-mode-map [(control c)(control k)(d)] 'kde-doc-function-insert)
+ (define-key c++-mode-map [(control c)(control k)(m)] 'kde-doc-multiline-insert)
+ (define-key c++-mode-map [(control c)(control k)(o)] 'kde-doc-oneliner-insert)
+ (define-key c++-mode-map [(control c)(control k)(e)] 'kde-function-expand-at-point)
+ (define-key c++-mode-map [(control c)(control k)(s)] 'kde-create-skeletons))
+
+(modify-frame-parameters (selected-frame) '((menu-bar-lines . 2)))
+(define-key c++-mode-map [menu-bar KDE]
+ (cons "KDE" c++-mode-map))
+(when (featurep 'semantic)
+ (define-key c++-mode-map [menu-bar KDE kde-doc-function-insert]
+ '("kde-doc-function-insert" . kde-doc-function-insert))
+ (define-key c++-mode-map [menu-bar KDE kde-function-expand-at-point]
+ '("kde-function-expand-at-point" . kde-function-expand-at-point))
+ (define-key c++-mode-map [menu-bar KDE kde-create-skeletons]
+ '("kde-create-skeletons" . kde-create-skeletons))
+ (define-key c++-mode-map [menu-bar KDE kde-doc-multiline-insert]
+ '("kde-doc-multiline-insert" . kde-doc-multiline-insert)))
+(define-key c++-mode-map [menu-bar KDE makeclean]
+ '("make clean" . makeclean))
+(define-key c++-mode-map [menu-bar KDE make]
+ '("make" . make))
+(define-key c++-mode-map [menu-bar KDE makeinstall]
+ '("make install" . makeinstall))
+(define-key c++-mode-map [menu-bar KDE makethisfile]
+ '("make this file" . makethisfile))
+(define-key c++-mode-map [menu-bar KDE kdeswitchcpph]
+ '("Switch to .h/.cpp file" . kde-switch-cpp-h))
+(define-key c++-mode-map [menu-bar KDE insert-kdDebug]
+ '("Insert kdDebug" . insert-kdDebug))
+
+
+(provide 'kde-emacs-bindings)
+
diff --git a/scripts/kde-emacs/kde-emacs-compat.el b/scripts/kde-emacs/kde-emacs-compat.el
new file mode 100644
index 00000000..1ff1fe7a
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-compat.el
@@ -0,0 +1,77 @@
+;; kde-emacs-compat.el - contains compatibility functions
+;;
+;; Copyright (C) 2003 Zack Rusin <zack@kde.org>
+;; 2003 KDE Developlment team
+;; 2003 XEmacs developers
+;;
+;; 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; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+(require 'kde-emacs-vars)
+
+;;GNU/Emacs does not have this one
+(if (not (fboundp 'replace-in-string))
+ (defun replace-in-string (str regexp newtext &optional literal)
+ "Replace all matches in STR for REGEXP with NEWTEXT string,
+ and returns the new string.
+Optional LITERAL non-nil means do a literal replacement.
+Otherwise treat `\\' in NEWTEXT as special:
+ `\\&' in NEWTEXT means substitute original matched text.
+ `\\N' means substitute what matched the Nth `\\(...\\)'.
+ If Nth parens didn't match, substitute nothing.
+ `\\\\' means insert one `\\'.
+ `\\u' means upcase the next character.
+ `\\l' means downcase the next character.
+ `\\U' means begin upcasing all following characters.
+ `\\L' means begin downcasing all following characters.
+ `\\E' means terminate the effect of any `\\U' or `\\L'."
+ (if (> (length str) 50)
+ (with-temp-buffer
+ (insert str)
+ (goto-char 1)
+ (while (re-search-forward regexp nil t)
+ (replace-match newtext t literal))
+ (buffer-string))
+ (let ((start 0) newstr)
+ (while (string-match regexp str start)
+ (setq newstr (replace-match newtext t literal str)
+ start (+ (match-end 0) (- (length newstr) (length str)))
+ str newstr))
+ str)))
+
+ )
+
+(if (not (fboundp 'read-shell-command))
+ (progn
+ (defvar read-shell-command-map
+ (let ((map (make-sparse-keymap 'read-shell-command-map)))
+ (if (eq kde-emacs-type 'xemacs)
+ (set-keymap-parents map (list minibuffer-local-map))
+ (set-keymap-parent map minibuffer-local-map))
+ (define-key map "\t" 'comint-dynamic-complete)
+ (define-key map "\M-\t" 'comint-dynamic-complete)
+ (define-key map "\M-?" 'comint-dynamic-list-completions)
+ map)
+ "Minibuffer keymap used by `shell-command' and related commands.")
+ (defun read-shell-command (prompt &optional initial-input history default-value)
+ "Just like read-string, but uses read-shell-command-map:
+\\{read-shell-command-map}"
+ (let ((minibuffer-completion-table nil))
+ (read-from-minibuffer prompt initial-input read-shell-command-map
+ nil (or history 'shell-command-history)
+ nil default-value)))
+ ))
+
+(provide 'kde-emacs-compat)
diff --git a/scripts/kde-emacs/kde-emacs-core.el b/scripts/kde-emacs/kde-emacs-core.el
new file mode 100644
index 00000000..a954dfa0
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-core.el
@@ -0,0 +1,3823 @@
+;; kde-emacs-core.el - core functionality,e.g. syntax & c++-mode-hook
+;;
+;; Copyright (C) 2002 KDE Development Team <www.kde.org>
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2.1 of the License, or (at your option) any later version.
+;;
+;; This library 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
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+
+(require 'kde-emacs-vars)
+;*---------------------------------------------------------------------*/
+;* Variables ... */
+;*---------------------------------------------------------------------*/
+
+(defcustom kde-tab-behavior 'default
+ "Specifies the current tab behavior. default will expand try to complete
+the symbol at point if at the end of something that looks like an indentifier else
+it will indent the current line if the pointer is at the beginning of the line it will
+be moved the the start of the indention. abbrev-indent behaves like default, but the
+cursor isn't moved to the beginning of the indention with tab is pressed when the cursor
+is at the beginning of the line. indent simply indents the line without trying to
+complete the symbol"
+ :group 'kde-devel
+ :version "0.1"
+ :type `(choice (const default) (const abbrev-indent) (const indent)))
+
+;*---------------------------------------------------------------------*/
+;* Functions ... */
+;*---------------------------------------------------------------------*/
+
+
+;; ------- First part, from Arnt's "c++ stuff" - slightly modified for our needs :)
+
+(defun agulbra-c++-tab (arg)
+ "Do the right thing about tabs in c++ mode.
+Try to finish the symbol, or indent the line."
+ (interactive "*P")
+ (cond
+ ((and (not (looking-at "[A-Za-z0-9]"))
+ (save-excursion
+ (forward-char -1)
+ (looking-at "[A-Za-z0-9:>_\\-\\&\\.(){}\\*\\+/]")))
+ (dabbrev-expand arg))
+ (t
+ (if (eq kde-tab-behavior 'default)
+ (c-indent-command)
+ (save-excursion
+ (beginning-of-line)
+ (c-indent-command))))))
+
+(defun agulbra-clean-out-spaces ()
+ "Remove spaces at ends of lines."
+ (interactive)
+ (and (not buffer-read-only)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((count 0)
+ (bmp (buffer-modified-p)))
+ (while (re-search-forward "[ \t]+$" nil t)
+ (setq count (1+ count))
+ (replace-match "" t t))
+ (set-buffer-modified-p bmp)
+ nil
+ ))))
+
+; the above used to contain (untabify (point-min) (point-max)) too
+
+(defun agulbra-c++-clean-out-spaces ()
+ "Remove spaces at ends of lines, only in c++ mode."
+ (interactive)
+ (if (eq major-mode 'c++-mode)
+ (agulbra-clean-out-spaces)
+ )
+ )
+
+(defun agulbra-delete-into-nomenclature (&optional arg)
+ "Delete forward until the end of a nomenclature section or word.
+With arg, do it arg times."
+ (interactive "p")
+ (save-excursion
+ (let ((b (point-marker)))
+ (c-forward-into-nomenclature arg)
+ (delete-region b (point-marker)))))
+
+
+(if (not (fboundp 'font-lock-add-keywords))
+ (defun font-lock-add-keywords (mode keywords &optional append)
+ "XEmacs doesn't have font-lock-add-keywords so we provide it."
+ (font-lock-set-defaults)
+ (if (eq append 'set)
+ (setq font-lock-keywords keywords)
+ ; NOTE: write this function for XEmacs - Zack
+ ;(font-lock-remove-keywords nil keywords) ;to avoid duplicates
+ (let ((old (if (eq (car-safe font-lock-keywords) t)
+ (cdr font-lock-keywords)
+ font-lock-keywords)))
+ (setq font-lock-keywords (if append
+ (append old keywords)
+ (append keywords old))))))
+ )
+
+(c-add-style "kde-c" '("stroustrup"
+ (c-basic-offset . 4)
+ (c-offsets-alist
+ (case-label . 4)
+ (access-label . -)
+ (label . 0)
+ (statement-cont . c-lineup-math)
+ )))
+
+; ( we use Backquote ( '`' ) instead of "'" because we want
+; kde-access-labels to be evaluated... )
+(c-add-style "kde-c++" `("kde-c"
+ ;;FIXME: 1) fume functions not available on GNU/Emacs
+ ;; 2) insert-tab-mode no longer present (free variable)
+ ;; 3) c-hangin-commment-under-p no longer present (free variable)
+ (if (not (eq kde-tab-behavior 'indent))
+ (c-tab-always-indent . nil))
+ ; (insert-tab-mode nil)
+ (indent-tabs-mode . nil)
+ (if (eq kde-emacs-type 'xemacs)
+ (fume-auto-rescan-buffer-p nil))
+ (c-access-key . ,kde-access-labels)
+ (c-opt-access-key . ,kde-access-labels)
+ ; (c-hanging-comment-under-p nil)
+ (c-offsets-alist . ((case-label . 0)
+ (inline-open . 0)))
+ ))
+
+;; KDE C++ mode
+;; Not a "(setq c++-mode-hook ..." because this way we would
+;; prune all other hooks!
+(defun kde-c++-mode-hook ()
+ (font-lock-mode)
+ (c-set-style kde-c++-style)
+ (define-key c++-mode-map "\C-m" 'c-context-line-break)
+ (when (or
+ (eq kde-tab-behavior 'default)
+ (eq kde-tab-behavior 'abbrev-indent))
+ (define-key c++-mode-map "\C-i" 'agulbra-c++-tab))
+ (define-key c++-mode-map "\ef" 'c-forward-into-nomenclature)
+ (define-key c++-mode-map "\ed" 'agulbra-delete-into-nomenclature)
+ (define-key c++-mode-map "\eb" 'c-backward-into-nomenclature)
+ ;; fontify "public|protected|private slots" with one and the same face :)
+ ;; NOTE: write face-at-point function to fontify those just like other
+ ;; access specifiers
+ (font-lock-add-keywords nil '(("\\<\\(\\(public\\|protected\\|private\\) slots\\)\\>"
+ . font-lock-reference-face)))
+ ;; Add (setq magic-keys-mode nil) to your .emacs (before loading this file)
+ ;; to disable the magic keys in C++ mode.
+ (and (boundp 'magic-keys-mode) magic-keys-mode
+ (progn
+ (define-key c++-mode-map "\(" 'insert-parens)
+ (define-key c++-mode-map "\)" 'insert-parens2)
+ (define-key c++-mode-map "\," 'insert-comma)
+ (define-key c++-mode-map "\{" 'insert-curly-brace)
+ ))
+ )
+
+(defun kde-c-mode-hook ()
+ (font-lock-mode)
+ (c-set-style kde-c-style))
+
+;; NOTE : This is a completely new c-guess-basic-syntax, it's faster,
+;; better, meaner, harder, covers more cases, more c++ syntax,
+;; and is in general cooler ;) You have to have the new cc-mode
+;; to use it ( 5.30 at least, check it with "M-x c-version")
+;; If you don't have 5.30 comment out the following c-guess-basic-syntax
+;; and uncomment the one underneath.
+(cond
+ ((string-match "^5\\.30\\." c-version)
+ (defun c-guess-basic-syntax ()
+ "Return the syntactic context of the current line.
+This function does not do any hidden buffer changes."
+ (save-excursion
+ (save-restriction
+ (beginning-of-line)
+ (c-save-buffer-state
+ ((indent-point (point))
+ (case-fold-search nil)
+ (paren-state (c-parse-state))
+ literal containing-sexp char-before-ip char-after-ip lim
+ c-syntactic-context placeholder c-in-literal-cache step-type
+ tmpsymbol keyword injava-inher special-brace-list
+ ;; narrow out any enclosing class or extern "C" block
+ (inclass-p (c-narrow-out-enclosing-class paren-state
+ indent-point))
+ ;; `c-state-cache' is shadowed here so that we don't
+ ;; throw it away due to the narrowing that might be done
+ ;; by the function above. That means we must not do any
+ ;; changes during the execution of this function, since
+ ;; `c-invalidate-state-cache' then would change this local
+ ;; variable and leave a bogus value in the global one.
+ (c-state-cache (if inclass-p
+ (c-whack-state-before (point-min) paren-state)
+ paren-state))
+ (c-state-cache-start (point-min))
+ inenclosing-p macro-start in-macro-expr
+ ;; There's always at most one syntactic element which got
+ ;; a relpos. It's stored in syntactic-relpos.
+ syntactic-relpos
+ (c-stmt-delim-chars c-stmt-delim-chars))
+ ;; Check for meta top-level enclosing constructs such as
+ ;; extern language definitions.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (when (and inclass-p
+ (progn
+ (goto-char (aref inclass-p 0))
+ (looking-at c-other-decl-block-key)))
+ (setq inenclosing-p (match-string 1))
+ (if (string-equal inenclosing-p "extern")
+ ;; Compatibility with legacy choice of name for the
+ ;; extern-lang syntactic symbols.
+ (setq inenclosing-p "extern-lang")))))
+
+ ;; Init some position variables:
+ ;;
+ ;; containing-sexp is the open paren of the closest
+ ;; surrounding sexp or nil if there is none that hasn't been
+ ;; narrowed out.
+ ;;
+ ;; lim is the position after the closest preceding brace sexp
+ ;; (nested sexps are ignored), or the position after
+ ;; containing-sexp if there is none, or (point-min) if
+ ;; containing-sexp is nil.
+ ;;
+ ;; c-state-cache is the state from c-parse-state at
+ ;; indent-point, without any parens outside the region
+ ;; narrowed by c-narrow-out-enclosing-class.
+ ;;
+ ;; paren-state is the state from c-parse-state outside
+ ;; containing-sexp, or at indent-point if containing-sexp is
+ ;; nil. paren-state is not limited to the narrowed region, as
+ ;; opposed to c-state-cache.
+ (if c-state-cache
+ (progn
+ (setq containing-sexp (car paren-state)
+ paren-state (cdr paren-state))
+ (if (consp containing-sexp)
+ (progn
+ (setq lim (cdr containing-sexp))
+ (if (cdr c-state-cache)
+ ;; Ignore balanced paren. The next entry
+ ;; can't be another one.
+ (setq containing-sexp (car (cdr c-state-cache))
+ paren-state (cdr paren-state))
+ ;; If there is no surrounding open paren then
+ ;; put the last balanced pair back on paren-state.
+ (setq paren-state (cons containing-sexp paren-state)
+ containing-sexp nil)))
+ (setq lim (1+ containing-sexp))))
+ (setq lim (point-min)))
+
+ ;; If we're in a parenthesis list then ',' delimits the
+ ;; "statements" rather than being an operator (with the
+ ;; exception of the "for" clause). This difference is
+ ;; typically only noticeable when statements are used in macro
+ ;; arglists.
+ (when (and containing-sexp
+ (eq (char-after containing-sexp) ?\())
+ (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))
+
+ ;; cache char before and after indent point, and move point to
+ ;; the most likely position to perform the majority of tests
+ (goto-char indent-point)
+ (c-backward-syntactic-ws lim)
+ (setq char-before-ip (char-before))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (setq char-after-ip (char-after))
+
+ ;; are we in a literal?
+ (setq literal (c-in-literal lim))
+
+ ;; now figure out syntactic qualities of the current line
+ (cond
+ ;; CASE 1: in a string.
+ ((eq literal 'string)
+ (c-add-syntax 'string (c-point 'bopl)))
+ ;; CASE 2: in a C or C++ style comment.
+ ((and (memq literal '(c c++))
+ ;; This is a kludge for XEmacs where we use
+ ;; `buffer-syntactic-context', which doesn't correctly
+ ;; recognize "\*/" to end a block comment.
+ ;; `parse-partial-sexp' which is used by
+ ;; `c-literal-limits' will however do that in most
+ ;; versions, which results in that we get nil from
+ ;; `c-literal-limits' even when `c-in-literal' claims
+ ;; we're inside a comment.
+ (setq placeholder (c-literal-limits lim)))
+ (c-add-syntax literal (car placeholder)))
+ ;; CASE 3: in a cpp preprocessor macro continuation.
+ ((and (save-excursion
+ (when (c-beginning-of-macro)
+ (setq macro-start (point))))
+ (/= macro-start (c-point 'boi))
+ (progn
+ (setq tmpsymbol 'cpp-macro-cont)
+ (or (not c-syntactic-indentation-in-macros)
+ (save-excursion
+ (goto-char macro-start)
+ ;; If at the beginning of the body of a #define
+ ;; directive then analyze as cpp-define-intro
+ ;; only. Go on with the syntactic analysis
+ ;; otherwise. in-macro-expr is set if we're in a
+ ;; cpp expression, i.e. before the #define body
+ ;; or anywhere in a non-#define directive.
+ (if (c-forward-to-cpp-define-body)
+ (let ((indent-boi (c-point 'boi indent-point)))
+ (setq in-macro-expr (> (point) indent-boi)
+ tmpsymbol 'cpp-define-intro)
+ (= (point) indent-boi))
+ (setq in-macro-expr t)
+ nil)))))
+ (c-add-syntax tmpsymbol macro-start)
+ (setq macro-start nil))
+ ;; CASE 11: an else clause?
+ ((looking-at "else\\>[^_]")
+ (c-beginning-of-statement-1 containing-sexp)
+ (c-add-stmt-syntax 'else-clause nil t nil
+ containing-sexp paren-state))
+ ;; CASE 12: while closure of a do/while construct?
+ ((and (looking-at "while\\>[^_]")
+ (save-excursion
+ (prog1 (eq (c-beginning-of-statement-1 containing-sexp)
+ 'beginning)
+ (setq placeholder (point)))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'do-while-closure nil t nil
+ containing-sexp paren-state))
+ ;; CASE 13: A catch or finally clause? This case is simpler
+ ;; than if-else and do-while, because a block is required
+ ;; after every try, catch and finally.
+ ((save-excursion
+ (and (cond ((c-major-mode-is 'c++-mode)
+ (looking-at "catch\\>[^_]"))
+ ((c-major-mode-is 'java-mode)
+ (looking-at "\\(catch\\|finally\\)\\>[^_]")))
+ (and (c-safe (c-backward-syntactic-ws)
+ (c-backward-sexp)
+ t)
+ (eq (char-after) ?{)
+ (c-safe (c-backward-syntactic-ws)
+ (c-backward-sexp)
+ t)
+ (if (eq (char-after) ?\()
+ (c-safe (c-backward-sexp) t)
+ t))
+ (looking-at "\\(try\\|catch\\)\\>[^_]")
+ (setq placeholder (point))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'catch-clause nil t nil
+ containing-sexp paren-state))
+ ;; CASE 18: A substatement we can recognize by keyword.
+ ((save-excursion
+ (and c-opt-block-stmt-key
+ (if (c-mode-is-new-awk-p)
+ (c-awk-prev-line-incomplete-p containing-sexp) ; ACM 2002/3/29
+ (not (eq char-before-ip ?\;)))
+ (not (memq char-after-ip '(?\) ?\] ?,)))
+ (or (not (eq char-before-ip ?}))
+ (c-looking-at-inexpr-block-backward c-state-cache))
+ (> (point)
+ (progn
+ ;; Ought to cache the result from the
+ ;; c-beginning-of-statement-1 calls here.
+ (setq placeholder (point))
+ (while (eq (setq step-type
+ (c-beginning-of-statement-1 lim))
+ 'label))
+ (if (eq step-type 'previous)
+ (goto-char placeholder)
+ (setq placeholder (point))
+ (if (and (eq step-type 'same)
+ (not (looking-at c-opt-block-stmt-key)))
+ ;; Step up to the containing statement if we
+ ;; stayed in the same one.
+ (let (step)
+ (while (eq
+ (setq step
+ (c-beginning-of-statement-1 lim))
+ 'label))
+ (if (eq step 'up)
+ (setq placeholder (point))
+ ;; There was no containing statement afterall.
+ (goto-char placeholder)))))
+ placeholder))
+ (if (looking-at c-block-stmt-2-key)
+ ;; Require a parenthesis after these keywords.
+ ;; Necessary to catch e.g. synchronized in Java,
+ ;; which can be used both as statement and
+ ;; modifier.
+ (and (zerop (c-forward-token-2 1 nil))
+ (eq (char-after) ?\())
+ (looking-at c-opt-block-stmt-key))))
+ (if (eq step-type 'up)
+ ;; CASE 18A: Simple substatement.
+ (progn
+ (goto-char placeholder)
+ (cond
+ ((eq char-after-ip ?{)
+ (c-add-stmt-syntax 'substatement-open nil nil nil
+ containing-sexp paren-state))
+ ((save-excursion
+ (goto-char indent-point)
+ (back-to-indentation)
+ (looking-at c-label-key))
+ (c-add-stmt-syntax 'substatement-label nil nil nil
+ containing-sexp paren-state))
+ (t
+ (c-add-stmt-syntax 'substatement nil nil nil
+ containing-sexp paren-state))))
+ ;; CASE 18B: Some other substatement. This is shared
+ ;; with case 10.
+ (c-guess-continued-construct indent-point
+ char-after-ip
+ placeholder
+ lim
+ paren-state)))
+ ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and
+ ;; 17E.
+ ((and (or c-opt-inexpr-class-key
+ c-opt-inexpr-block-key
+ c-opt-lambda-key)
+ (setq placeholder (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp paren-state)
+ containing-sexp)))
+ (setq tmpsymbol (assq (car placeholder)
+ '((inexpr-class . class-open)
+ (inexpr-statement . block-open))))
+ (if tmpsymbol
+ ;; It's a statement block or an anonymous class.
+ (setq tmpsymbol (cdr tmpsymbol))
+ ;; It's a Pike lambda. Check whether we are between the
+ ;; lambda keyword and the argument list or at the defun
+ ;; opener.
+ (setq tmpsymbol (if (eq char-after-ip ?{)
+ 'inline-open
+ 'lambda-intro-cont)))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-stmt-syntax tmpsymbol nil t nil
+ (c-most-enclosing-brace c-state-cache (point))
+ (c-whack-state-after (point) paren-state))
+ (unless (eq (point) (cdr placeholder))
+ (c-add-syntax (car placeholder))))
+ ;; CASE 5: Line is at top level.
+ ((null containing-sexp)
+ (cond
+ ;; CASE 5A: we are looking at a defun, brace list, class,
+ ;; or inline-inclass method opening brace
+ ((setq special-brace-list
+ (or (and c-special-brace-lists
+ (c-looking-at-special-brace-list))
+ (eq char-after-ip ?{)))
+ (cond
+ ;; CASE 5A.1: Non-class declaration block open.
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (and (c-safe (c-backward-sexp 2) t)
+ (looking-at c-other-decl-block-key)
+ (setq keyword (match-string 1)
+ placeholder (point))
+ (if (string-equal keyword "extern")
+ ;; Special case for extern-lang-open. The
+ ;; check for a following string is disabled
+ ;; since it doesn't disambiguate anything.
+ (and ;;(progn
+ ;; (c-forward-sexp 1)
+ ;; (c-forward-syntactic-ws)
+ ;; (eq (char-after) ?\"))
+ (setq tmpsymbol 'extern-lang-open))
+ (setq tmpsymbol (intern (concat keyword "-open"))))
+ ))
+ (goto-char placeholder)
+ (c-add-syntax tmpsymbol (c-point 'boi)))
+ ;; CASE 5A.2: we are looking at a class opening brace
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t{")
+ (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
+ (and decl
+ (setq placeholder (aref decl 0)))
+ ))
+ (c-add-syntax 'class-open placeholder))
+ ;; CASE 5A.3: brace list open
+ ((save-excursion
+ (c-beginning-of-decl-1 lim)
+ (while (looking-at c-specifier-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws indent-point))
+ (setq placeholder (c-point 'boi))
+ (or (consp special-brace-list)
+ (and (or (save-excursion
+ (goto-char indent-point)
+ (setq tmpsymbol nil)
+ (while (and (> (point) placeholder)
+ (zerop (c-backward-token-2 1 t))
+ (/= (char-after) ?=))
+ (and c-opt-inexpr-brace-list-key
+ (not tmpsymbol)
+ (looking-at c-opt-inexpr-brace-list-key)
+ (setq tmpsymbol 'topmost-intro-cont)))
+ (eq (char-after) ?=))
+ (looking-at c-brace-list-key))
+ (save-excursion
+ (while (and (< (point) indent-point)
+ (zerop (c-forward-token-2 1 t))
+ (not (memq (char-after) '(?\; ?\()))))
+ (not (memq (char-after) '(?\; ?\()))
+ ))))
+ (if (and (not c-auto-newline-analysis)
+ (c-major-mode-is 'java-mode)
+ (eq tmpsymbol 'topmost-intro-cont))
+ ;; We're in Java and have found that the open brace
+ ;; belongs to a "new Foo[]" initialization list,
+ ;; which means the brace list is part of an
+ ;; expression and not a top level definition. We
+ ;; therefore treat it as any topmost continuation
+ ;; even though the semantically correct symbol still
+ ;; is brace-list-open, on the same grounds as in
+ ;; case B.2.
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
+ (c-add-syntax 'brace-list-open placeholder)))
+ ;; CASE 5A.4: inline defun open
+ ((and inclass-p (not inenclosing-p))
+ (c-add-syntax 'inline-open)
+ (c-add-class-syntax 'inclass inclass-p paren-state))
+ ;; CASE 5A.5: ordinary defun open
+ (t
+ (goto-char placeholder)
+ (if (or inclass-p macro-start)
+ (c-add-syntax 'defun-open (c-point 'boi))
+ ;; Bogus to use bol here, but it's the legacy.
+ (c-add-syntax 'defun-open (c-point 'bol)))
+ )))
+ ;; CASE 5B: first K&R arg decl or member init
+ ((c-just-after-func-arglist-p lim)
+ (cond
+ ;; CASE 5B.1: a member init
+ ((or (eq char-before-ip ?:)
+ (eq char-after-ip ?:))
+ ;; this line should be indented relative to the beginning
+ ;; of indentation for the topmost-intro line that contains
+ ;; the prototype's open paren
+ ;; TBD: is the following redundant?
+ (if (eq char-before-ip ?:)
+ (forward-char -1))
+ (c-backward-syntactic-ws lim)
+ ;; TBD: is the preceding redundant?
+ (if (eq (char-before) ?:)
+ (progn (forward-char -1)
+ (c-backward-syntactic-ws lim)))
+ (if (eq (char-before) ?\))
+ (c-backward-sexp 1))
+ (setq placeholder (point))
+ (save-excursion
+ (and (c-safe (c-backward-sexp 1) t)
+ (looking-at "throw[^_]")
+ (c-safe (c-backward-sexp 1) t)
+ (setq placeholder (point))))
+ (goto-char placeholder)
+ (c-add-syntax 'member-init-intro (c-point 'boi))
+ ;; we don't need to add any class offset since this
+ ;; should be relative to the ctor's indentation
+ )
+ ;; CASE 5B.2: K&R arg decl intro
+ (c-recognize-knr-p
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
+ (if inclass-p
+ (c-add-class-syntax 'inclass inclass-p paren-state)))
+ ;; CASE 5B.3: Inside a member init list.
+ ((c-beginning-of-member-init-list lim)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'member-init-cont (point)))
+ ;; CASE 5B.4: Nether region after a C++ or Java func
+ ;; decl, which could include a `throws' declaration.
+ (t
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'func-decl-cont (c-point 'boi))
+ )))
+ ;; CASE 5C: inheritance line. could be first inheritance
+ ;; line, or continuation of a multiple inheritance
+ ((or (and (c-major-mode-is 'c++-mode)
+ (progn
+ (when (eq char-after-ip ?,)
+ (skip-chars-forward " \t")
+ (forward-char))
+ (looking-at c-opt-postfix-decl-spec-key)))
+ (and (or (eq char-before-ip ?:)
+ ;; watch out for scope operator
+ (save-excursion
+ (and (eq char-after-ip ?:)
+ (c-safe (forward-char 1) t)
+ (not (eq (char-after) ?:))
+ )))
+ (save-excursion
+ (c-backward-syntactic-ws lim)
+ (if (eq char-before-ip ?:)
+ (progn
+ (forward-char -1)
+ (c-backward-syntactic-ws lim)))
+ (back-to-indentation)
+ (looking-at c-class-key)))
+ ;; for Java
+ (and (c-major-mode-is 'java-mode)
+ (let ((fence (save-excursion
+ (c-beginning-of-statement-1 lim)
+ (point)))
+ cont done)
+ (save-excursion
+ (while (not done)
+ (cond ((looking-at c-opt-postfix-decl-spec-key)
+ (setq injava-inher (cons cont (point))
+ done t))
+ ((or (not (c-safe (c-forward-sexp -1) t))
+ (<= (point) fence))
+ (setq done t))
+ )
+ (setq cont t)))
+ injava-inher)
+ (not (c-crosses-statement-barrier-p (cdr injava-inher)
+ (point)))
+ ))
+ (cond
+ ;; CASE 5C.1: non-hanging colon on an inher intro
+ ((eq char-after-ip ?:)
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'inher-intro (c-point 'boi))
+ ;; don't add inclass symbol since relative point already
+ ;; contains any class offset
+ )
+ ;; CASE 5C.2: hanging colon on an inher intro
+ ((eq char-before-ip ?:)
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'inher-intro (c-point 'boi))
+ (if inclass-p
+ (c-add-class-syntax 'inclass inclass-p paren-state)))
+ ;; CASE kde hack:
+ ((and inclass-p
+ c-access-key
+ (looking-at c-access-key))
+ (c-add-syntax 'access-label (c-point 'bonl))
+ (c-add-class-syntax 'inclass inclass-p paren-state)
+ )
+ ;; CASE 5C.3: in a Java implements/extends
+ (injava-inher
+ (let ((where (cdr injava-inher))
+ (cont (car injava-inher)))
+ (goto-char where)
+ (cond ((looking-at "throws\\>[^_]")
+ (c-add-syntax 'func-decl-cont
+ (progn (c-beginning-of-statement-1 lim)
+ (c-point 'boi))))
+ (cont (c-add-syntax 'inher-cont where))
+ (t (c-add-syntax 'inher-intro
+ (progn (goto-char (cdr injava-inher))
+ (c-beginning-of-statement-1 lim)
+ (point))))
+ )))
+ ;; CASE 5C.4: a continued inheritance line
+ (t
+ (c-beginning-of-inheritance-list lim)
+ (c-add-syntax 'inher-cont (point))
+ ;; don't add inclass symbol since relative point already
+ ;; contains any class offset
+ )))
+ ;; CASE 5D: this could be a top-level initialization, a
+ ;; member init list continuation, or a template argument
+ ;; list continuation.
+ ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
+ c++-template-syntax-table
+ (syntax-table))
+ (save-excursion
+ ;; Note: We use the fact that lim is always after any
+ ;; preceding brace sexp.
+ (while (and (zerop (c-backward-token-2 1 t lim))
+ (not (looking-at "[;<,=]"))))
+ (or (memq (char-after) '(?, ?=))
+ (and (c-major-mode-is 'c++-mode)
+ (zerop (c-backward-token-2 1 nil lim))
+ (eq (char-after) ?<)))))
+ (goto-char indent-point)
+ (setq placeholder
+ (c-beginning-of-member-init-list lim))
+ (cond
+ ;; CASE 5D.1: hanging member init colon, but watch out
+ ;; for bogus matches on access specifiers inside classes.
+ ((and placeholder
+ (save-excursion
+ (setq placeholder (point))
+ (c-backward-token-2 1 t lim)
+ (and (eq (char-after) ?:)
+ (not (eq (char-before) ?:))))
+ (save-excursion
+ (goto-char placeholder)
+ (back-to-indentation)
+ (or
+ (/= (car (save-excursion
+ (parse-partial-sexp (point) placeholder)))
+ 0)
+ (and
+ (if c-opt-access-key
+ (not (looking-at c-opt-access-key)) t)
+ (not (looking-at c-class-key))
+ (if c-opt-bitfield-key
+ (not (looking-at c-opt-bitfield-key)) t))
+ )))
+ (goto-char placeholder)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'member-init-cont (point))
+ ;; we do not need to add class offset since relative
+ ;; point is the member init above us
+ )
+ ;; CASE 5D.2: non-hanging member init colon
+ ((progn
+ (c-forward-syntactic-ws indent-point)
+ (eq (char-after) ?:))
+ (skip-chars-forward " \t:")
+ (c-add-syntax 'member-init-cont (point)))
+ ;; CASE 5D.3: perhaps a template list continuation?
+ ((and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (save-restriction
+ (c-with-syntax-table c++-template-syntax-table
+ (goto-char indent-point)
+ (setq placeholder (c-up-list-backward (point)))
+ (and placeholder
+ (eq (char-after placeholder) ?<))))))
+ ;; we can probably indent it just like an arglist-cont
+ (goto-char placeholder)
+ (c-beginning-of-statement-1 lim t)
+ (c-add-syntax 'template-args-cont (c-point 'boi)))
+ ;; CASE 5D.4: perhaps a multiple inheritance line?
+ ((and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (c-beginning-of-statement-1 lim)
+ (setq placeholder (point))
+ (if (looking-at "static\\>[^_]")
+ (c-forward-token-2 1 nil indent-point))
+ (and (looking-at c-class-key)
+ (zerop (c-forward-token-2 2 nil indent-point))
+ (if (eq (char-after) ?<)
+ (c-with-syntax-table c++-template-syntax-table
+ (zerop (c-forward-token-2 1 t indent-point)))
+ t)
+ (eq (char-after) ?:))))
+ (goto-char placeholder)
+ (c-add-syntax 'inher-cont (c-point 'boi)))
+ ;; CASE 5D.5: Continuation of the "expression part" of a
+ ;; top level construct.
+ (t
+ (while (and (eq (car (c-beginning-of-decl-1 containing-sexp))
+ 'same)
+ (save-excursion
+ (c-backward-syntactic-ws)
+ (eq (char-before) ?}))))
+ (c-add-stmt-syntax
+ (if (eq char-before-ip ?,)
+ ;; A preceding comma at the top level means that a
+ ;; new variable declaration starts here. Use
+ ;; topmost-intro-cont for it, for consistency with
+ ;; the first variable declaration. C.f. case 5N.
+ 'topmost-intro-cont
+ 'statement-cont)
+ nil nil nil containing-sexp paren-state))
+ ))
+ ;; CASE 5E: we are looking at a access specifier
+ ((and inclass-p
+ c-opt-access-key
+ (looking-at c-opt-access-key))
+ (setq placeholder (c-add-class-syntax 'inclass inclass-p
+ paren-state))
+ ;; Append access-label with the same anchor point as inclass gets.
+ (c-append-syntax 'access-label placeholder))
+ ;; CASE 5F: Close of a non-class declaration level block.
+ ((and inenclosing-p
+ (eq char-after-ip ?}))
+ (c-add-syntax (intern (concat inenclosing-p "-close"))
+ (aref inclass-p 0)))
+ ;; CASE 5G: we are looking at the brace which closes the
+ ;; enclosing nested class decl
+ ((and inclass-p
+ (eq char-after-ip ?})
+ (save-excursion
+ (save-restriction
+ (widen)
+ (forward-char 1)
+ (and (c-safe (c-backward-sexp 1) t)
+ (= (point) (aref inclass-p 1))
+ ))))
+ (c-add-class-syntax 'class-close inclass-p paren-state))
+ ;; CASE 5H: we could be looking at subsequent knr-argdecls
+ ((and c-recognize-knr-p
+ (not (eq char-before-ip ?}))
+ (save-excursion
+ (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
+ (and placeholder
+ ;; Do an extra check to avoid tripping up on
+ ;; statements that occur in invalid contexts
+ ;; (e.g. in macro bodies where we don't really
+ ;; know the context of what we're looking at).
+ (not (and c-opt-block-stmt-key
+ (looking-at c-opt-block-stmt-key)))))
+ (< placeholder indent-point))
+ (goto-char placeholder)
+ (c-add-syntax 'knr-argdecl (point)))
+ ;; CASE 5I: ObjC method definition.
+ ((and c-opt-method-key
+ (looking-at c-opt-method-key))
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'objc-method-intro (c-point 'boi)))
+ ;; CASE 5P: AWK pattern or function or continuation
+ ;; thereof.
+ ((c-mode-is-new-awk-p)
+ (setq placeholder (point))
+ (c-add-stmt-syntax
+ (if (and (eq (c-beginning-of-statement-1) 'same)
+ (/= (point) placeholder))
+ 'topmost-intro-cont
+ 'topmost-intro)
+ nil nil nil
+ containing-sexp paren-state))
+ ;; CASE 5N: At a variable declaration that follows a class
+ ;; definition or some other block declaration that doesn't
+ ;; end at the closing '}'. C.f. case 5D.5.
+ ((progn
+ (c-backward-syntactic-ws lim)
+ (and (eq (char-before) ?})
+ (save-excursion
+ (let ((start (point)))
+ (if paren-state
+ ;; Speed up the backward search a bit.
+ (goto-char (car (car paren-state))))
+ (c-beginning-of-decl-1 containing-sexp)
+ (setq placeholder (point))
+ (if (= start (point))
+ ;; The '}' is unbalanced.
+ nil
+ (c-end-of-decl-1)
+ (>= (point) indent-point))))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'topmost-intro-cont nil nil nil
+ containing-sexp paren-state))
+ ;; CASE 5J: we are at the topmost level, make
+ ;; sure we skip back past any access specifiers
+ ((progn
+ (while (and inclass-p
+ c-opt-access-key
+ (not (bobp))
+ (save-excursion
+ (c-safe (progn (c-backward-sexp 1) t))
+ (and (looking-at "slots:")
+ (c-backward-sexp 1))
+ (looking-at c-opt-access-key)))
+ (c-backward-sexp 1)
+ (c-backward-syntactic-ws lim))
+ (or (bobp)
+ (if (c-mode-is-new-awk-p)
+ (not (c-awk-prev-line-incomplete-p))
+ (memq (char-before) '(?\; ?})))
+ (and (c-major-mode-is 'objc-mode)
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (eq (char-after) ?@)))))
+ ;; real beginning-of-line could be narrowed out due to
+ ;; enclosure in a class block
+ (save-restriction
+ (widen)
+ (c-add-syntax 'topmost-intro (c-point 'bol))
+ ;; Using bol instead of boi above is highly bogus, and
+ ;; it makes our lives hard to remain compatible. :P
+ (if inclass-p
+ (progn
+ (goto-char (aref inclass-p 1))
+ (or (= (point) (c-point 'boi))
+ (goto-char (aref inclass-p 0)))
+ (if inenclosing-p
+ (c-add-syntax (intern (concat "in" inenclosing-p))
+ (c-point 'boi))
+ (c-add-class-syntax 'inclass inclass-p paren-state))
+ ))
+ (when (and c-syntactic-indentation-in-macros
+ macro-start
+ (/= macro-start (c-point 'boi indent-point)))
+ (c-add-syntax 'cpp-define-intro)
+ (setq macro-start nil))
+ ))
+ ;; CASE 5K: we are at an ObjC method definition
+ ;; continuation line.
+ ((and c-opt-method-key
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (beginning-of-line)
+ (looking-at c-opt-method-key)))
+ (c-add-syntax 'objc-method-args-cont (point)))
+ ;; CASE 5L: we are at the first argument of a template
+ ;; arglist that begins on the previous line.
+ ((eq (char-before) ?<)
+ (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
+ (c-add-syntax 'template-args-cont (c-point 'boi)))
+ ;; CASE 5M: we are at a topmost continuation line
+ (t
+ (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
+ (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
+ ))
+ ;; (CASE 6 has been removed.)
+ ;; CASE 7: line is an expression, not a statement. Most
+ ;; likely we are either in a function prototype or a function
+ ;; call argument list
+ ((not (or (and c-special-brace-lists
+ (save-excursion
+ (goto-char containing-sexp)
+ (c-looking-at-special-brace-list)))
+ (eq (char-after containing-sexp) ?{)))
+ (cond
+ ;; CASE 7A: we are looking at the arglist closing paren.
+ ;; C.f. case 7F.
+ ((memq char-after-ip '(?\) ?\]))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (if (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (progn
+ (forward-char)
+ (skip-chars-forward " \t"))
+ (goto-char placeholder))
+ (c-add-stmt-syntax 'arglist-close (list containing-sexp) t nil
+ (c-most-enclosing-brace paren-state (point))
+ (c-whack-state-after (point) paren-state)))
+ ;; CASE 7B: Looking at the opening brace of an
+ ;; in-expression block or brace list. C.f. cases 4, 16A
+ ;; and 17E.
+ ((and (eq char-after-ip ?{)
+ (progn
+ (setq placeholder (c-inside-bracelist-p (point)
+ c-state-cache))
+ (if placeholder
+ (setq tmpsymbol '(brace-list-open . inexpr-class))
+ (setq tmpsymbol '(block-open . inexpr-statement)
+ placeholder
+ (cdr-safe (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp
+ paren-state)
+ containing-sexp)))
+ ;; placeholder is nil if it's a block directly in
+ ;; a function arglist. That makes us skip out of
+ ;; this case.
+ )))
+ (goto-char placeholder)
+ (back-to-indentation)
+ (c-add-stmt-syntax (car tmpsymbol) nil t nil
+ (c-most-enclosing-brace paren-state (point))
+ (c-whack-state-after (point) paren-state))
+ (if (/= (point) placeholder)
+ (c-add-syntax (cdr tmpsymbol))))
+ ;; CASE 7C: we are looking at the first argument in an empty
+ ;; argument list. Use arglist-close if we're actually
+ ;; looking at a close paren or bracket.
+ ((memq char-before-ip '(?\( ?\[))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-intro placeholder))
+ ;; CASE 7D: we are inside a conditional test clause. treat
+ ;; these things as statements
+ ((progn
+ (goto-char containing-sexp)
+ (and (c-safe (c-forward-sexp -1) t)
+ (looking-at "\\<for\\>[^_]")))
+ (goto-char (1+ containing-sexp))
+ (c-forward-syntactic-ws indent-point)
+ (if (eq char-before-ip ?\;)
+ (c-add-syntax 'statement (point))
+ (c-add-syntax 'statement-cont (point))
+ ))
+ ;; CASE 7E: maybe a continued ObjC method call. This is the
+ ;; case when we are inside a [] bracketed exp, and what
+ ;; precede the opening bracket is not an identifier.
+ ((and c-opt-method-key
+ (eq (char-after containing-sexp) ?\[)
+ (progn
+ (goto-char (1- containing-sexp))
+ (c-backward-syntactic-ws (c-point 'bod))
+ (if (not (looking-at c-symbol-key))
+ (c-add-syntax 'objc-method-call-cont containing-sexp))
+ )))
+ ;; CASE 7F: we are looking at an arglist continuation line,
+ ;; but the preceding argument is on the same line as the
+ ;; opening paren. This case includes multi-line
+ ;; mathematical paren groupings, but we could be on a
+ ;; for-list continuation line. C.f. case 7A.
+ ((progn
+ (goto-char (1+ containing-sexp))
+ (skip-chars-forward " \t")
+ (and (not (eolp))
+ (not (looking-at "\\\\$"))))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (if (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (progn
+ (forward-char)
+ (skip-chars-forward " \t"))
+ (goto-char placeholder))
+ (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp)
+ t nil
+ (c-most-enclosing-brace c-state-cache (point))
+ (c-whack-state-after (point) paren-state)))
+ ;; CASE 7G: we are looking at just a normal arglist
+ ;; continuation line
+ (t (c-forward-syntactic-ws indent-point)
+ (c-add-syntax 'arglist-cont (c-point 'boi)))
+ ))
+ ;; CASE 8: func-local multi-inheritance line
+ ((and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (looking-at c-opt-postfix-decl-spec-key)))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (cond
+ ;; CASE 8A: non-hanging colon on an inher intro
+ ((eq char-after-ip ?:)
+ (c-backward-syntactic-ws lim)
+ (c-add-syntax 'inher-intro (c-point 'boi)))
+ ;; CASE 8B: hanging colon on an inher intro
+ ((eq char-before-ip ?:)
+ (c-add-syntax 'inher-intro (c-point 'boi)))
+ ;; CASE 8C: a continued inheritance line
+ (t
+ (c-beginning-of-inheritance-list lim)
+ (c-add-syntax 'inher-cont (point))
+ )))
+ ;; CASE 9: we are inside a brace-list
+ ((and (not (c-mode-is-new-awk-p)) ; Maybe this isn't needed (ACM, 2002/3/29)
+ (setq special-brace-list
+ (or (and c-special-brace-lists
+ (save-excursion
+ (goto-char containing-sexp)
+ (c-looking-at-special-brace-list)))
+ (c-inside-bracelist-p containing-sexp paren-state))))
+ (cond
+ ;; CASE 9A: In the middle of a special brace list opener.
+ ((and (consp special-brace-list)
+ (save-excursion
+ (goto-char containing-sexp)
+ (eq (char-after) ?\())
+ (eq char-after-ip (car (cdr special-brace-list))))
+ (goto-char (car (car special-brace-list)))
+ (skip-chars-backward " \t")
+ (if (and (bolp)
+ (assoc 'statement-cont
+ (setq placeholder (c-guess-basic-syntax))))
+ (setq c-syntactic-context placeholder)
+ (c-beginning-of-statement-1
+ (c-safe-position (1- containing-sexp) paren-state))
+ (c-forward-token-2 0)
+ (while (looking-at c-specifier-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws))
+ (c-add-syntax 'brace-list-open (c-point 'boi))))
+ ;; CASE 9B: brace-list-close brace
+ ((if (consp special-brace-list)
+ ;; Check special brace list closer.
+ (progn
+ (goto-char (car (car special-brace-list)))
+ (save-excursion
+ (goto-char indent-point)
+ (back-to-indentation)
+ (or
+ ;; We were between the special close char and the `)'.
+ (and (eq (char-after) ?\))
+ (eq (1+ (point)) (cdr (car special-brace-list))))
+ ;; We were before the special close char.
+ (and (eq (char-after) (cdr (cdr special-brace-list)))
+ (zerop (c-forward-token-2))
+ (eq (1+ (point)) (cdr (car special-brace-list)))))))
+ ;; Normal brace list check.
+ (and (eq char-after-ip ?})
+ (c-safe (goto-char (c-up-list-backward (point))) t)
+ (= (point) containing-sexp)))
+ (if (eq (point) (c-point 'boi))
+ (c-add-syntax 'brace-list-close (point))
+ (setq lim (c-most-enclosing-brace c-state-cache (point)))
+ (c-beginning-of-statement-1 lim)
+ (c-add-stmt-syntax 'brace-list-close nil t t lim
+ (c-whack-state-after (point) paren-state))))
+ (t
+ ;; Prepare for the rest of the cases below by going to the
+ ;; token following the opening brace
+ (if (consp special-brace-list)
+ (progn
+ (goto-char (car (car special-brace-list)))
+ (c-forward-token-2 1 nil indent-point))
+ (goto-char containing-sexp))
+ (forward-char)
+ (let ((start (point)))
+ (c-forward-syntactic-ws indent-point)
+ (goto-char (max start (c-point 'bol))))
+ (c-skip-ws-forward indent-point)
+ (cond
+ ;; CASE 9C: we're looking at the first line in a brace-list
+ ((= (point) indent-point)
+ (if (consp special-brace-list)
+ (goto-char (car (car special-brace-list)))
+ (goto-char containing-sexp))
+ (if (eq (point) (c-point 'boi))
+ (c-add-syntax 'brace-list-intro (point))
+ (setq lim (c-most-enclosing-brace c-state-cache (point)))
+ (c-beginning-of-statement-1 lim)
+ (c-add-stmt-syntax 'brace-list-intro nil t t lim
+ (c-whack-state-after (point) paren-state))))
+ ;; CASE 9D: this is just a later brace-list-entry or
+ ;; brace-entry-open
+ (t (if (or (eq char-after-ip ?{)
+ (and c-special-brace-lists
+ (save-excursion
+ (goto-char indent-point)
+ (c-forward-syntactic-ws (c-point 'eol))
+ (c-looking-at-special-brace-list (point)))))
+ (c-add-syntax 'brace-entry-open (point))
+ (c-add-syntax 'brace-list-entry (point))
+ ))
+ ))))
+ ;; CASE 10: A continued statement or top level construct.
+ ((and (if (c-mode-is-new-awk-p)
+ (c-awk-prev-line-incomplete-p containing-sexp) ; ACM 2002/3/29
+ (and (not (memq char-before-ip '(?\; ?:)))
+ (or (not (eq char-before-ip ?}))
+ (c-looking-at-inexpr-block-backward c-state-cache))))
+ (> (point)
+ (save-excursion
+ (c-beginning-of-statement-1 containing-sexp)
+ (setq placeholder (point))))
+ (/= placeholder containing-sexp))
+ ;; This is shared with case 18.
+ (c-guess-continued-construct indent-point
+ char-after-ip
+ placeholder
+ containing-sexp
+ paren-state))
+ ;; CASE 14: A case or default label
+ ((looking-at c-label-kwds-regexp)
+ (goto-char containing-sexp)
+ (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax 'case-label nil t nil
+ lim paren-state))
+ ;; CASE 15: any other label
+ ((looking-at c-label-key)
+ (goto-char containing-sexp)
+ (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
+ (save-excursion
+ (setq tmpsymbol
+ (if (and (eq (c-beginning-of-statement-1 lim) 'up)
+ (looking-at "switch\\>[^_]"))
+ ;; If the surrounding statement is a switch then
+ ;; let's analyze all labels as switch labels, so
+ ;; that they get lined up consistently.
+ 'case-label
+ 'label)))
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax tmpsymbol nil t nil
+ lim paren-state))
+ ;; CASE 16: block close brace, possibly closing the defun or
+ ;; the class
+ ((eq char-after-ip ?})
+ ;; From here on we have the next containing sexp in lim.
+ (setq lim (c-most-enclosing-brace paren-state))
+ (goto-char containing-sexp)
+ (cond
+ ;; CASE 16E: Closing a statement block? This catches
+ ;; cases where it's preceded by a statement keyword,
+ ;; which works even when used in an "invalid" context,
+ ;; e.g. a macro argument.
+ ((c-after-conditional)
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax 'block-close nil t nil
+ lim paren-state))
+ ;; CASE 16A: closing a lambda defun or an in-expression
+ ;; block? C.f. cases 4, 7B and 17E.
+ ((setq placeholder (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp paren-state)
+ nil))
+ (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
+ 'inline-close
+ 'block-close))
+ (goto-char containing-sexp)
+ (back-to-indentation)
+ (if (= containing-sexp (point))
+ (c-add-syntax tmpsymbol (point))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-stmt-syntax tmpsymbol nil t nil
+ (c-most-enclosing-brace paren-state (point))
+ (c-whack-state-after (point) paren-state))
+ (if (/= (point) (cdr placeholder))
+ (c-add-syntax (car placeholder)))))
+ ;; CASE 16B: does this close an inline or a function in
+ ;; a non-class declaration level block?
+ ((setq placeholder (c-search-uplist-for-classkey paren-state))
+ (c-backward-to-decl-anchor lim)
+ (back-to-indentation)
+ (if (save-excursion
+ (goto-char (aref placeholder 0))
+ (looking-at c-other-decl-block-key))
+ (c-add-syntax 'defun-close (point))
+ (c-add-syntax 'inline-close (point))))
+ ;; CASE 16F: Can be a defun-close of a function declared
+ ;; in a statement block, e.g. in Pike or when using gcc
+ ;; extensions. Might also trigger it with some macros
+ ;; followed by blocks, and this gives sane indentation
+ ;; then too. Let it through to be handled below.
+ ;; C.f. cases B.3 and 17G.
+ ((and (not inenclosing-p)
+ lim
+ (save-excursion
+ (and (not (c-looking-at-bos))
+ (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
+ (setq placeholder (point)))))
+ (back-to-indentation)
+ (if (/= (point) containing-sexp)
+ (goto-char placeholder))
+ (c-add-stmt-syntax 'defun-close nil t nil
+ lim paren-state))
+ ;; CASE 16C: if there an enclosing brace that hasn't
+ ;; been narrowed out by a class, then this is a
+ ;; block-close. C.f. case 17H.
+ ((and (not inenclosing-p) lim)
+ ;; If the block is preceded by a case/switch label on
+ ;; the same line, we anchor at the first preceding label
+ ;; at boi. The default handling in c-add-stmt-syntax is
+ ;; really fixes it better, but we do like this to keep
+ ;; the indentation compatible with version 5.28 and
+ ;; earlier.
+ (while (and (/= (setq placeholder (point)) (c-point 'boi))
+ (eq (c-beginning-of-statement-1 lim) 'label)))
+ (goto-char placeholder)
+ (if (looking-at c-label-kwds-regexp)
+ (c-add-syntax 'block-close (point))
+ (goto-char containing-sexp)
+ ;; c-backward-to-block-anchor not necessary here; those
+ ;; situations are handled in case 16E above.
+ (c-add-stmt-syntax 'block-close nil t nil
+ lim paren-state)))
+ ;; CASE 16D: find out whether we're closing a top-level
+ ;; class or a defun
+ (t
+ (save-restriction
+ (narrow-to-region (point-min) indent-point)
+ (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
+ (if decl
+ (c-add-class-syntax 'class-close decl paren-state)
+ (goto-char containing-sexp)
+ (c-backward-to-decl-anchor lim)
+ (back-to-indentation)
+ (c-add-syntax 'defun-close (point)))))
+ )))
+ ;; CASE 17: Statement or defun catchall.
+ (t
+ (goto-char indent-point)
+ ;; Back up statements until we find one that starts at boi.
+ (while (let* ((prev-point (point))
+ (last-step-type (c-beginning-of-statement-1
+ containing-sexp)))
+ (if (= (point) prev-point)
+ (progn
+ (setq step-type (or step-type last-step-type))
+ nil)
+ (setq step-type last-step-type)
+ (/= (point) (c-point 'boi)))))
+ (cond
+ ;; CASE 17B: continued statement
+ ((and (eq step-type 'same)
+ (/= (point) indent-point))
+ (c-add-stmt-syntax 'statement-cont nil nil nil
+ containing-sexp paren-state))
+ ;; CASE 17A: After a case/default label?
+ ((progn
+ (while (and (eq step-type 'label)
+ (not (looking-at c-label-kwds-regexp)))
+ (setq step-type
+ (c-beginning-of-statement-1 containing-sexp)))
+ (eq step-type 'label))
+ (c-add-stmt-syntax (if (eq char-after-ip ?{)
+ 'statement-case-open
+ 'statement-case-intro)
+ nil t nil containing-sexp paren-state))
+ ;; CASE 17D: any old statement
+ ((progn
+ (while (eq step-type 'label)
+ (setq step-type
+ (c-beginning-of-statement-1 containing-sexp)))
+ (eq step-type 'previous))
+ (c-add-stmt-syntax 'statement nil t nil
+ containing-sexp paren-state)
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ;; CASE 17I: Inside a substatement block.
+ ((progn
+ ;; The following tests are all based on containing-sexp.
+ (goto-char containing-sexp)
+ ;; From here on we have the next containing sexp in lim.
+ (setq lim (c-most-enclosing-brace paren-state containing-sexp))
+ (c-after-conditional))
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax 'statement-block-intro nil t nil
+ lim paren-state)
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ;; CASE 17E: first statement in an in-expression block.
+ ;; C.f. cases 4, 7B and 16A.
+ ((setq placeholder (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp paren-state)
+ nil))
+ (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
+ 'defun-block-intro
+ 'statement-block-intro))
+ (back-to-indentation)
+ (if (= containing-sexp (point))
+ (c-add-syntax tmpsymbol (point))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-stmt-syntax tmpsymbol nil t nil
+ (c-most-enclosing-brace c-state-cache (point))
+ (c-whack-state-after (point) paren-state))
+ (if (/= (point) (cdr placeholder))
+ (c-add-syntax (car placeholder))))
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ;; CASE 17F: first statement in an inline, or first
+ ;; statement in a top-level defun. we can tell this is it
+ ;; if there are no enclosing braces that haven't been
+ ;; narrowed out by a class (i.e. don't use bod here).
+ ((save-excursion
+ (save-restriction
+ (widen)
+ (c-narrow-out-enclosing-class paren-state containing-sexp)
+ (not (c-most-enclosing-brace paren-state))))
+ (c-backward-to-decl-anchor lim)
+ (back-to-indentation)
+ (c-add-syntax 'defun-block-intro (point)))
+ ;; CASE 17G: First statement in a function declared inside
+ ;; a normal block. This can occur in Pike and with
+ ;; e.g. the gcc extensions. Might also trigger it with
+ ;; some macros followed by blocks, and this gives sane
+ ;; indentation then too. C.f. cases B.3 and 16F.
+ ((save-excursion
+ (and (not (c-looking-at-bos))
+ (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
+ (setq placeholder (point))))
+ (back-to-indentation)
+ (if (/= (point) containing-sexp)
+ (goto-char placeholder))
+ (c-add-stmt-syntax 'defun-block-intro nil t nil
+ lim paren-state))
+ ;; CASE 17H: First statement in a block. C.f. case 16C.
+ (t
+ ;; If the block is preceded by a case/switch label on the
+ ;; same line, we anchor at the first preceding label at
+ ;; boi. The default handling in c-add-stmt-syntax is
+ ;; really fixes it better, but we do like this to keep the
+ ;; indentation compatible with version 5.28 and earlier.
+ (while (and (/= (setq placeholder (point)) (c-point 'boi))
+ (eq (c-beginning-of-statement-1 lim) 'label)))
+ (goto-char placeholder)
+ (if (looking-at c-label-kwds-regexp)
+ (c-add-syntax 'statement-block-intro (point))
+ (goto-char containing-sexp)
+ ;; c-backward-to-block-anchor not necessary here; those
+ ;; situations are handled in case 17I above.
+ (c-add-stmt-syntax 'statement-block-intro nil t nil
+ lim paren-state))
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ))
+ )
+ ;; now we need to look at any modifiers
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ ;; are we looking at a comment only line?
+ (when (and (looking-at c-comment-start-regexp)
+ (/= (c-forward-token-2 0 nil (c-point 'eol)) 0))
+ (c-append-syntax 'comment-intro))
+ ;; we might want to give additional offset to friends (in C++).
+ (when (and c-opt-friend-key
+ (looking-at c-opt-friend-key))
+ (c-append-syntax 'friend))
+
+ ;; Set syntactic-relpos.
+ (let ((p c-syntactic-context))
+ (while (and p
+ (if (integerp (car-safe (cdr-safe (car p))))
+ (progn
+ (setq syntactic-relpos (car (cdr (car p))))
+ nil)
+ t))
+ (setq p (cdr p))))
+
+ ;; Start of or a continuation of a preprocessor directive?
+ (if (and macro-start
+ (eq macro-start (c-point 'boi))
+ (not (and (c-major-mode-is 'pike-mode)
+ (eq (char-after (1+ macro-start)) ?\"))))
+ (c-append-syntax 'cpp-macro)
+ (when (and c-syntactic-indentation-in-macros macro-start)
+ (if in-macro-expr
+ (when (or
+ (< syntactic-relpos macro-start)
+ (not (or
+ (assq 'arglist-intro c-syntactic-context)
+ (assq 'arglist-cont c-syntactic-context)
+ (assq 'arglist-cont-nonempty c-syntactic-context)
+ (assq 'arglist-close c-syntactic-context))))
+ ;; If inside a cpp expression, i.e. anywhere in a
+ ;; cpp directive except a #define body, we only let
+ ;; through the syntactic analysis that is internal
+ ;; in the expression. That means the arglist
+ ;; elements, if they are anchored inside the cpp
+ ;; expression.
+ (setq c-syntactic-context nil)
+ (c-add-syntax 'cpp-macro-cont macro-start))
+ (when (and (eq macro-start syntactic-relpos)
+ (not (assq 'cpp-define-intro c-syntactic-context))
+ (save-excursion
+ (goto-char macro-start)
+ (or (not (c-forward-to-cpp-define-body))
+ (<= (point) (c-point 'boi indent-point)))))
+ ;; Inside a #define body and the syntactic analysis is
+ ;; anchored on the start of the #define. In this case
+ ;; we add cpp-define-intro to get the extra
+ ;; indentation of the #define body.
+ (c-add-syntax 'cpp-define-intro)))))
+ ;; return the syntax
+ c-syntactic-context)))))
+ ((>= (string-to-number c-version) 5.29)
+ (defun c-guess-basic-syntax ()
+ "Return the syntactic context of the current line."
+ (save-excursion
+ (save-restriction
+ (beginning-of-line)
+ (let* ((indent-point (point))
+ (case-fold-search nil)
+ (paren-state (c-parse-state))
+ literal containing-sexp char-before-ip char-after-ip lim
+ syntax placeholder c-in-literal-cache step-type
+ tmpsymbol keyword injava-inher special-brace-list
+ ;; narrow out any enclosing class or extern "C" block
+ (inclass-p (c-narrow-out-enclosing-class paren-state
+ indent-point))
+ ;; c-state-cache is shadowed here. That means we must
+ ;; not do any changes during the execution of this
+ ;; function, since c-check-state-cache then would change
+ ;; this local variable and leave a bogus value in the
+ ;; global one.
+ (c-state-cache (if inclass-p
+ (c-whack-state-before (point-min) paren-state)
+ paren-state))
+ (c-state-cache-start (point-min))
+ inenclosing-p macro-start in-macro-expr
+ ;; There's always at most one syntactic element which got
+ ;; a relpos. It's stored in syntactic-relpos.
+ syntactic-relpos
+ (c-stmt-delim-chars c-stmt-delim-chars))
+ ;; check for meta top-level enclosing constructs, possible
+ ;; extern language definitions, possibly (in C++) namespace
+ ;; definitions.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (if (and inclass-p
+ (progn
+ (goto-char (aref inclass-p 0))
+ (looking-at c-other-decl-block-key)))
+ (let ((enclosing (match-string 1)))
+ (cond
+ ((string-equal enclosing "extern")
+ (setq inenclosing-p 'extern))
+ ((string-equal enclosing "namespace")
+ (setq inenclosing-p 'namespace))
+ )))))
+
+ ;; Init some position variables:
+ ;;
+ ;; containing-sexp is the open paren of the closest
+ ;; surrounding sexp or nil if there is none that hasn't been
+ ;; narrowed out.
+ ;;
+ ;; lim is the position after the closest preceding brace sexp
+ ;; (nested sexps are ignored), or the position after
+ ;; containing-sexp if there is none, or (point-min) if
+ ;; containing-sexp is nil.
+ ;;
+ ;; c-state-cache is the state from c-parse-state at
+ ;; indent-point, without any parens outside the region
+ ;; narrowed by c-narrow-out-enclosing-class.
+ ;;
+ ;; paren-state is the state from c-parse-state outside
+ ;; containing-sexp, or at indent-point if containing-sexp is
+ ;; nil. paren-state is not limited to the narrowed region, as
+ ;; opposed to c-state-cache.
+ (if c-state-cache
+ (progn
+ (setq containing-sexp (car paren-state)
+ paren-state (cdr paren-state))
+ (if (consp containing-sexp)
+ (progn
+ (setq lim (cdr containing-sexp))
+ (if (cdr c-state-cache)
+ ;; Ignore balanced paren. The next entry
+ ;; can't be another one.
+ (setq containing-sexp (car (cdr c-state-cache))
+ paren-state (cdr paren-state))
+ ;; If there is no surrounding open paren then
+ ;; put the last balanced pair back on paren-state.
+ (setq paren-state (cons containing-sexp paren-state)
+ containing-sexp nil)))
+ (setq lim (1+ containing-sexp))))
+ (setq lim (point-min)))
+
+ ;; If we're in a parenthesis list then ',' delimits the
+ ;; "statements" rather than being an operator (with the
+ ;; exception of the "for" clause). This difference is
+ ;; typically only noticeable when statements are used in macro
+ ;; arglists.
+ (when (and containing-sexp
+ (eq (char-after containing-sexp) ?\())
+ (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))
+
+ ;; cache char before and after indent point, and move point to
+ ;; the most likely position to perform the majority of tests
+ (goto-char indent-point)
+ (c-backward-syntactic-ws lim)
+ (setq char-before-ip (char-before))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (setq char-after-ip (char-after))
+
+ ;; are we in a literal?
+ (setq literal (c-in-literal lim))
+
+ ;; now figure out syntactic qualities of the current line
+ (cond
+ ;; CASE 1: in a string.
+ ((eq literal 'string)
+ (c-add-syntax 'string (c-point 'bopl)))
+ ;; CASE 2: in a C or C++ style comment.
+ ((memq literal '(c c++))
+ (c-add-syntax literal (car (c-literal-limits lim))))
+ ;; CASE 3: in a cpp preprocessor macro continuation.
+ ((and (save-excursion
+ (when (c-beginning-of-macro)
+ (setq macro-start (point))))
+ (/= macro-start (c-point 'boi))
+ (progn
+ (setq tmpsymbol 'cpp-macro-cont)
+ (or (not c-syntactic-indentation-in-macros)
+ (save-excursion
+ (goto-char macro-start)
+ ;; If at the beginning of the body of a #define
+ ;; directive then analyze as cpp-define-intro
+ ;; only. Go on with the syntactic analysis
+ ;; otherwise. in-macro-expr is set if we're in a
+ ;; cpp expression, i.e. before the #define body
+ ;; or anywhere in a non-#define directive.
+ (if (c-forward-to-cpp-define-body)
+ (let ((indent-boi (c-point 'boi indent-point)))
+ (setq in-macro-expr (> (point) indent-boi)
+ tmpsymbol 'cpp-define-intro)
+ (= (point) indent-boi))
+ (setq in-macro-expr t)
+ nil)))))
+ (c-add-syntax tmpsymbol macro-start)
+ (setq macro-start nil))
+ ;; CASE 11: an else clause?
+ ((looking-at "else\\>[^_]")
+ (c-beginning-of-statement-1 containing-sexp)
+ (c-add-stmt-syntax 'else-clause t containing-sexp paren-state))
+ ;; CASE 12: while closure of a do/while construct?
+ ((and (looking-at "while\\>[^_]")
+ (save-excursion
+ (prog1 (eq (c-beginning-of-statement-1 containing-sexp)
+ 'beginning)
+ (setq placeholder (point)))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'do-while-closure t containing-sexp paren-state))
+ ;; CASE 13: A catch or finally clause? This case is simpler
+ ;; than if-else and do-while, because a block is required
+ ;; after every try, catch and finally.
+ ((save-excursion
+ (and (cond ((c-major-mode-is 'c++-mode)
+ (looking-at "catch\\>[^_]"))
+ ((c-major-mode-is 'java-mode)
+ (looking-at "\\(catch\\|finally\\)\\>[^_]")))
+ (and (c-safe (c-backward-syntactic-ws)
+ (c-backward-sexp)
+ t)
+ (eq (char-after) ?{)
+ (c-safe (c-backward-syntactic-ws)
+ (c-backward-sexp)
+ t)
+ (if (eq (char-after) ?\()
+ (c-safe (c-backward-sexp) t)
+ t))
+ (looking-at "\\(try\\|catch\\)\\>[^_]")
+ (setq placeholder (point))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'catch-clause t containing-sexp paren-state))
+ ;; CASE 18: A substatement we can recognize by keyword.
+ ((save-excursion
+ (and c-opt-block-stmt-key
+ (not (eq char-before-ip ?\;))
+ (not (memq char-after-ip '(?\) ?\] ?,)))
+ (or (not (eq char-before-ip ?}))
+ (c-looking-at-inexpr-block-backward c-state-cache))
+ (> (point)
+ (progn
+ ;; Ought to cache the result from the
+ ;; c-beginning-of-statement-1 calls here.
+ (setq placeholder (point))
+ (while (eq (setq step-type
+ (c-beginning-of-statement-1 lim))
+ 'label))
+ (if (eq step-type 'previous)
+ (goto-char placeholder)
+ (setq placeholder (point))
+ (if (and (eq step-type 'same)
+ (not (looking-at c-opt-block-stmt-key)))
+ ;; Step up to the containing statement if we
+ ;; stayed in the same one.
+ (let (step)
+ (while (eq
+ (setq step
+ (c-beginning-of-statement-1 lim))
+ 'label))
+ (if (eq step 'up)
+ (setq placeholder (point))
+ ;; There was no containing statement afterall.
+ (goto-char placeholder)))))
+ placeholder))
+ (if (looking-at c-block-stmt-2-key)
+ ;; Require a parenthesis after these keywords.
+ ;; Necessary to catch e.g. synchronized in Java,
+ ;; which can be used both as statement and
+ ;; modifier.
+ (and (= (c-forward-token-1 1 nil) 0)
+ (eq (char-after) ?\())
+ (looking-at c-opt-block-stmt-key))))
+ (if (eq step-type 'up)
+ ;; CASE 18A: Simple substatement.
+ (progn
+ (goto-char placeholder)
+ (cond
+ ((eq char-after-ip ?{)
+ (c-add-stmt-syntax 'substatement-open nil
+ containing-sexp paren-state))
+ ((save-excursion
+ (goto-char indent-point)
+ (back-to-indentation)
+ (looking-at c-label-key))
+ (c-add-stmt-syntax 'substatement-label nil
+ containing-sexp paren-state))
+ (t
+ (c-add-stmt-syntax 'substatement nil
+ containing-sexp paren-state))))
+ ;; CASE 18B: Some other substatement. This is shared
+ ;; with case 10.
+ (c-guess-continued-construct indent-point
+ char-after-ip
+ placeholder
+ lim
+ paren-state)))
+ ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and
+ ;; 17E.
+ ((and (or c-opt-inexpr-class-key
+ c-opt-inexpr-block-key
+ c-opt-lambda-key)
+ (setq placeholder (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp paren-state)
+ containing-sexp)))
+ (setq tmpsymbol (assq (car placeholder)
+ '((inexpr-class . class-open)
+ (inexpr-statement . block-open))))
+ (if tmpsymbol
+ ;; It's a statement block or an anonymous class.
+ (setq tmpsymbol (cdr tmpsymbol))
+ ;; It's a Pike lambda. Check whether we are between the
+ ;; lambda keyword and the argument list or at the defun
+ ;; opener.
+ (setq tmpsymbol (if (eq char-after-ip ?{)
+ 'inline-open
+ 'lambda-intro-cont)))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-stmt-syntax tmpsymbol t
+ (c-most-enclosing-brace c-state-cache (point))
+ (c-whack-state-after (point) paren-state))
+ (unless (eq (point) (cdr placeholder))
+ (c-add-syntax (car placeholder))))
+ ;; CASE 5: Line is at top level.
+ ((null containing-sexp)
+ (cond
+ ;; CASE 5A: we are looking at a defun, brace list, class,
+ ;; or inline-inclass method opening brace
+ ((setq special-brace-list
+ (or (and c-special-brace-lists
+ (c-looking-at-special-brace-list))
+ (eq char-after-ip ?{)))
+ (cond
+ ;; CASE 5A.1: extern language or namespace construct
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (and (c-safe (progn (c-backward-sexp 2) t))
+ (looking-at c-other-decl-block-key)
+ (setq keyword (match-string 1)
+ placeholder (point))
+ (or (and (string-equal keyword "namespace")
+ (setq tmpsymbol 'namespace-open))
+ (and (string-equal keyword "extern")
+ (progn
+ (c-forward-sexp 1)
+ (c-forward-syntactic-ws)
+ (eq (char-after) ?\"))
+ (setq tmpsymbol 'extern-lang-open)))
+ ))
+ (goto-char placeholder)
+ (c-add-syntax tmpsymbol (c-point 'boi)))
+ ;; CASE 5A.2: we are looking at a class opening brace
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t{")
+ (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
+ (and decl
+ (setq placeholder (aref decl 0)))
+ ))
+ (c-add-syntax 'class-open placeholder))
+ ;; CASE 5A.3: brace list open
+ ((save-excursion
+ (c-beginning-of-decl-1 lim)
+ (if (looking-at "typedef\\>[^_]")
+ (progn (c-forward-sexp 1)
+ (c-forward-syntactic-ws indent-point)))
+ (setq placeholder (c-point 'boi))
+ (or (consp special-brace-list)
+ (and (or (save-excursion
+ (goto-char indent-point)
+ (setq tmpsymbol nil)
+ (while (and (> (point) placeholder)
+ (= (c-backward-token-1 1 t) 0)
+ (/= (char-after) ?=))
+ (if (and (not tmpsymbol)
+ (looking-at "new\\>[^_]"))
+ (setq tmpsymbol 'topmost-intro-cont)))
+ (eq (char-after) ?=))
+ (looking-at "enum\\>[^_]"))
+ (save-excursion
+ (while (and (< (point) indent-point)
+ (= (c-forward-token-1 1 t) 0)
+ (not (memq (char-after) '(?\; ?\()))))
+ (not (memq (char-after) '(?\; ?\()))
+ ))))
+ (if (and (c-major-mode-is 'java-mode)
+ (eq tmpsymbol 'topmost-intro-cont))
+ ;; We're in Java and have found that the open brace
+ ;; belongs to a "new Foo[]" initialization list,
+ ;; which means the brace list is part of an
+ ;; expression and not a top level definition. We
+ ;; therefore treat it as any topmost continuation
+ ;; even though the semantically correct symbol still
+ ;; is brace-list-open, on the same grounds as in
+ ;; case 10B.2.
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
+ (c-add-syntax 'brace-list-open placeholder)))
+ ;; CASE 5A.4: inline defun open
+ ((and inclass-p (not inenclosing-p))
+ (c-add-syntax 'inline-open)
+ (c-add-class-syntax 'inclass inclass-p paren-state))
+ ;; CASE 5A.5: ordinary defun open
+ (t
+ (goto-char placeholder)
+ (if (or inclass-p macro-start)
+ (c-add-syntax 'defun-open (c-point 'boi))
+ ;; Bogus to use bol here, but it's the legacy.
+ (c-add-syntax 'defun-open (c-point 'bol)))
+ )))
+ ;; CASE 5B: first K&R arg decl or member init
+ ((c-just-after-func-arglist-p nil lim)
+ (cond
+ ;; CASE 5B.1: a member init
+ ((or (eq char-before-ip ?:)
+ (eq char-after-ip ?:))
+ ;; this line should be indented relative to the beginning
+ ;; of indentation for the topmost-intro line that contains
+ ;; the prototype's open paren
+ ;; TBD: is the following redundant?
+ (if (eq char-before-ip ?:)
+ (forward-char -1))
+ (c-backward-syntactic-ws lim)
+ ;; TBD: is the preceding redundant?
+ (if (eq (char-before) ?:)
+ (progn (forward-char -1)
+ (c-backward-syntactic-ws lim)))
+ (if (eq (char-before) ?\))
+ (c-backward-sexp 1))
+ (setq placeholder (point))
+ (save-excursion
+ (and (c-safe (c-backward-sexp 1) t)
+ (looking-at "throw[^_]")
+ (c-safe (c-backward-sexp 1) t)
+ (setq placeholder (point))))
+ (goto-char placeholder)
+ (c-add-syntax 'member-init-intro (c-point 'boi))
+ ;; we don't need to add any class offset since this
+ ;; should be relative to the ctor's indentation
+ )
+ ;; CASE 5B.2: K&R arg decl intro
+ (c-recognize-knr-p
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
+ (if inclass-p
+ (c-add-class-syntax 'inclass inclass-p paren-state)))
+ ;; CASE 5B.3: Inside a member init list.
+ ((c-beginning-of-member-init-list lim)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'member-init-cont (point)))
+ ;; CASE 5B.4: Nether region after a C++ or Java func
+ ;; decl, which could include a `throws' declaration.
+ (t
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'func-decl-cont (c-point 'boi))
+ )))
+ ;; CASE 5C: inheritance line. could be first inheritance
+ ;; line, or continuation of a multiple inheritance
+ ((or (and (c-major-mode-is 'c++-mode)
+ (progn
+ (when (eq char-after-ip ?,)
+ (skip-chars-forward " \t")
+ (forward-char))
+ (looking-at c-opt-decl-spec-key)))
+ (and (or (eq char-before-ip ?:)
+ ;; watch out for scope operator
+ (save-excursion
+ (and (eq char-after-ip ?:)
+ (c-safe (progn (forward-char 1) t))
+ (not (eq (char-after) ?:))
+ )))
+ (save-excursion
+ (c-backward-syntactic-ws lim)
+ (if (eq char-before-ip ?:)
+ (progn
+ (forward-char -1)
+ (c-backward-syntactic-ws lim)))
+ (back-to-indentation)
+ (looking-at c-class-key)))
+ ;; for Java
+ (and (c-major-mode-is 'java-mode)
+ (let ((fence (save-excursion
+ (c-beginning-of-statement-1 lim)
+ (point)))
+ cont done)
+ (save-excursion
+ (while (not done)
+ (cond ((looking-at c-opt-decl-spec-key)
+ (setq injava-inher (cons cont (point))
+ done t))
+ ((or (not (c-safe (c-forward-sexp -1) t))
+ (<= (point) fence))
+ (setq done t))
+ )
+ (setq cont t)))
+ injava-inher)
+ (not (c-crosses-statement-barrier-p (cdr injava-inher)
+ (point)))
+ ))
+ (cond
+ ;; CASE 5C.1: non-hanging colon on an inher intro
+ ((eq char-after-ip ?:)
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'inher-intro (c-point 'boi))
+ ;; don't add inclass symbol since relative point already
+ ;; contains any class offset
+ )
+ ;; CASE 5C.2: hanging colon on an inher intro
+ ((eq char-before-ip ?:)
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'inher-intro (c-point 'boi))
+ (if inclass-p
+ (c-add-class-syntax 'inclass inclass-p paren-state)))
+ ;; KDE Hack Start:
+ ((and inclass-p
+ c-access-key
+ (looking-at c-access-key))
+ (c-add-syntax 'access-label (c-point 'bonl))
+ (setq placeholder (c-add-class-syntax 'inclass inclass-p
+ paren-state)))
+ ;;(nconc syntax (list (cons 'access-label placeholder))))
+ ;; KDE Hack End.
+ ;; CASE 5C.3: in a Java implements/extends
+ (injava-inher
+ (let ((where (cdr injava-inher))
+ (cont (car injava-inher)))
+ (goto-char where)
+ (cond ((looking-at "throws\\>[^_]")
+ (c-add-syntax 'func-decl-cont
+ (progn (c-beginning-of-statement-1 lim)
+ (c-point 'boi))))
+ (cont (c-add-syntax 'inher-cont where))
+ (t (c-add-syntax 'inher-intro
+ (progn (goto-char (cdr injava-inher))
+ (c-beginning-of-statement-1 lim)
+ (point))))
+ )))
+ ;; CASE 5C.4: a continued inheritance line
+ (t
+ (c-beginning-of-inheritance-list lim)
+ (c-add-syntax 'inher-cont (point))
+ ;; don't add inclass symbol since relative point already
+ ;; contains any class offset
+ )))
+ ;; CASE 5D: this could be a top-level initialization, a
+ ;; member init list continuation, or a template argument
+ ;; list continuation.
+ ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
+ c++-template-syntax-table
+ (syntax-table))
+ (save-excursion
+ ;; Note: We use the fact that lim is always after any
+ ;; preceding brace sexp.
+ (while (and (= (c-backward-token-1 1 t lim) 0)
+ (not (looking-at "[;<,=]"))))
+ (or (memq (char-after) '(?, ?=))
+ (and (c-major-mode-is 'c++-mode)
+ (= (c-backward-token-1 1 nil lim) 0)
+ (eq (char-after) ?<)))))
+ (goto-char indent-point)
+ (c-beginning-of-member-init-list lim)
+ (cond
+ ;; CASE 5D.1: hanging member init colon, but watch out
+ ;; for bogus matches on access specifiers inside classes.
+ ((and (save-excursion
+ (setq placeholder (point))
+ (c-backward-token-1 1 t lim)
+ (and (eq (char-after) ?:)
+ (not (eq (char-before) ?:))))
+ (save-excursion
+ (goto-char placeholder)
+ (back-to-indentation)
+ (or
+ (/= (car (save-excursion
+ (parse-partial-sexp (point) placeholder)))
+ 0)
+ (and
+ (if c-opt-access-key
+ (not (looking-at c-opt-access-key)) t)
+ (not (looking-at c-class-key))
+ (if c-opt-bitfield-key
+ (not (looking-at c-opt-bitfield-key)) t))
+ )))
+ (goto-char placeholder)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'member-init-cont (point))
+ ;; we do not need to add class offset since relative
+ ;; point is the member init above us
+ )
+ ;; CASE 5D.2: non-hanging member init colon
+ ((progn
+ (c-forward-syntactic-ws indent-point)
+ (eq (char-after) ?:))
+ (skip-chars-forward " \t:")
+ (c-add-syntax 'member-init-cont (point)))
+ ;; CASE 5D.3: perhaps a template list continuation?
+ ((and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (save-restriction
+ (c-with-syntax-table c++-template-syntax-table
+ (goto-char indent-point)
+ (setq placeholder (c-up-list-backward (point)))
+ (and placeholder
+ (eq (char-after placeholder) ?<))))))
+ ;; we can probably indent it just like an arglist-cont
+ (goto-char placeholder)
+ (c-beginning-of-statement-1 lim t)
+ (c-add-syntax 'template-args-cont (c-point 'boi)))
+ ;; CASE 5D.4: perhaps a multiple inheritance line?
+ ((and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (c-beginning-of-statement-1 lim)
+ (setq placeholder (point))
+ (if (looking-at "static\\>[^_]")
+ (c-forward-token-1 1 nil indent-point))
+ (and (looking-at c-class-key)
+ (= (c-forward-token-1 2 nil indent-point) 0)
+ (if (eq (char-after) ?<)
+ (c-with-syntax-table c++-template-syntax-table
+ (= (c-forward-token-1 1 t indent-point) 0))
+ t)
+ (eq (char-after) ?:))))
+ (goto-char placeholder)
+ (c-add-syntax 'inher-cont (c-point 'boi)))
+ ;; CASE 5D.5: Continuation of the "expression part" of a
+ ;; top level construct.
+ (t
+ (while (and (eq (car (c-beginning-of-decl-1 containing-sexp))
+ 'same)
+ (save-excursion
+ (c-backward-syntactic-ws)
+ (eq (char-before) ?}))))
+ (c-add-stmt-syntax
+ (if (eq char-before-ip ?,)
+ ;; A preceding comma at the top level means that a
+ ;; new variable declaration starts here. Use
+ ;; topmost-intro-cont for it, for consistency with
+ ;; the first variable declaration. C.f. case 5N.
+ 'topmost-intro-cont
+ 'statement-cont)
+ nil containing-sexp paren-state))
+ ))
+ ;; CASE 5E: we are looking at a access specifier
+ ((and inclass-p
+ c-opt-access-key
+ (looking-at c-opt-access-key))
+ (setq placeholder (c-add-class-syntax 'inclass inclass-p
+ paren-state))
+ ;; Append access-label with the same anchor point as inclass gets.
+ (nconc syntax (list (cons 'access-label placeholder))))
+ ;; CASE 5F: extern-lang-close or namespace-close?
+ ((and inenclosing-p
+ (eq char-after-ip ?}))
+ (setq tmpsymbol (if (eq inenclosing-p 'extern)
+ 'extern-lang-close
+ 'namespace-close))
+ (c-add-syntax tmpsymbol (aref inclass-p 0)))
+ ;; CASE 5G: we are looking at the brace which closes the
+ ;; enclosing nested class decl
+ ((and inclass-p
+ (eq char-after-ip ?})
+ (save-excursion
+ (save-restriction
+ (widen)
+ (forward-char 1)
+ (and (c-safe (progn (c-backward-sexp 1) t))
+ (= (point) (aref inclass-p 1))
+ ))))
+ (c-add-class-syntax 'class-close inclass-p paren-state))
+ ;; CASE 5H: we could be looking at subsequent knr-argdecls
+ ((and c-recognize-knr-p
+ (not (eq char-before-ip ?}))
+ (save-excursion
+ (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
+ (and placeholder
+ ;; Do an extra check to avoid tripping up on
+ ;; statements that occur in invalid contexts
+ ;; (e.g. in macro bodies where we don't really
+ ;; know the context of what we're looking at).
+ (not (and c-opt-block-stmt-key
+ (looking-at c-opt-block-stmt-key)))))
+ (< placeholder indent-point))
+ (goto-char placeholder)
+ (c-add-syntax 'knr-argdecl (point)))
+ ;; CASE 5I: ObjC method definition.
+ ((and c-opt-method-key
+ (looking-at c-opt-method-key))
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'objc-method-intro (c-point 'boi)))
+ ;; CASE 5N: At a variable declaration that follows a class
+ ;; definition or some other block declaration that doesn't
+ ;; end at the closing '}'. C.f. case 5D.5.
+ ((progn
+ (c-backward-syntactic-ws lim)
+ (and (eq (char-before) ?})
+ (save-excursion
+ (let ((start (point)))
+ (if paren-state
+ ;; Speed up the backward search a bit.
+ (goto-char (car (car paren-state))))
+ (c-beginning-of-decl-1 containing-sexp)
+ (setq placeholder (point))
+ (if (= start (point))
+ ;; The '}' is unbalanced.
+ nil
+ (c-end-of-decl-1)
+ (> (point) indent-point))))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'topmost-intro-cont nil
+ containing-sexp paren-state))
+ ;; CASE 5J: we are at the topmost level, make
+ ;; sure we skip back past any access specifiers
+ ((progn
+ (while (and inclass-p
+ c-opt-access-key
+ (not (bobp))
+ (save-excursion
+ (c-safe (progn (c-backward-sexp 1) t))
+ (and (looking-at "slots:")
+ (c-backward-sexp 1))
+ (looking-at c-opt-access-key)))
+ (c-backward-sexp 1)
+ (c-backward-syntactic-ws lim))
+ (or (bobp)
+ (memq (char-before) '(?\; ?}))
+ (and (c-major-mode-is 'objc-mode)
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (eq (char-after) ?@)))))
+ ;; real beginning-of-line could be narrowed out due to
+ ;; enclosure in a class block
+ (save-restriction
+ (widen)
+ (c-add-syntax 'topmost-intro (c-point 'bol))
+ ;; Using bol instead of boi above is highly bogus, and
+ ;; it makes our lives hard to remain compatible. :P
+ (if inclass-p
+ (progn
+ (goto-char (aref inclass-p 1))
+ (or (= (point) (c-point 'boi))
+ (goto-char (aref inclass-p 0)))
+ (cond
+ ((eq inenclosing-p 'extern)
+ (c-add-syntax 'inextern-lang (c-point 'boi)))
+ ((eq inenclosing-p 'namespace)
+ (c-add-syntax 'innamespace (c-point 'boi)))
+ (t (c-add-class-syntax 'inclass inclass-p paren-state)))
+ ))
+ (when (and c-syntactic-indentation-in-macros
+ macro-start
+ (/= macro-start (c-point 'boi indent-point)))
+ (c-add-syntax 'cpp-define-intro)
+ (setq macro-start nil))
+ ))
+ ;; CASE 5K: we are at an ObjC method definition
+ ;; continuation line.
+ ((and c-opt-method-key
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (beginning-of-line)
+ (looking-at c-opt-method-key)))
+ (c-add-syntax 'objc-method-args-cont (point)))
+ ;; CASE 5L: we are at the first argument of a template
+ ;; arglist that begins on the previous line.
+ ((eq (char-before) ?<)
+ (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
+ (c-add-syntax 'template-args-cont (c-point 'boi)))
+ ;; CASE 5M: we are at a topmost continuation line
+ ;; KDE Hack 2
+ ;; NOTE: is there a way to detect these sooner ?
+ (t
+ (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
+ (if (re-search-forward c-access-key (point-at-eol) t)
+ (progn
+ (c-add-syntax 'topmost-intro (c-point 'bol))
+ (c-add-class-syntax 'inclass inclass-p paren-state)
+ )
+ (progn
+ (c-add-syntax 'topmost-intro-cont (c-point 'boi))
+ ))
+ )
+ ))
+ ;; (CASE 6 has been removed.)
+ ;; CASE 7: line is an expression, not a statement. Most
+ ;; likely we are either in a function prototype or a function
+ ;; call argument list
+ ((not (or (and c-special-brace-lists
+ (save-excursion
+ (goto-char containing-sexp)
+ (c-looking-at-special-brace-list)))
+ (eq (char-after containing-sexp) ?{)))
+ (cond
+ ;; CASE 7A: we are looking at the arglist closing paren
+ ((memq char-after-ip '(?\) ?\]))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-close placeholder))
+ ;; CASE 7B: Looking at the opening brace of an
+ ;; in-expression block or brace list. C.f. cases 4, 16A
+ ;; and 17E.
+ ((and (eq char-after-ip ?{)
+ (progn
+ (setq placeholder (c-inside-bracelist-p (point)
+ c-state-cache))
+ (if placeholder
+ (setq tmpsymbol '(brace-list-open . inexpr-class))
+ (setq tmpsymbol '(block-open . inexpr-statement)
+ placeholder
+ (cdr-safe (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp
+ paren-state)
+ containing-sexp)))
+ ;; placeholder is nil if it's a block directly in
+ ;; a function arglist. That makes us skip out of
+ ;; this case.
+ )))
+ (goto-char placeholder)
+ (back-to-indentation)
+ (c-add-stmt-syntax (car tmpsymbol) t
+ (c-most-enclosing-brace paren-state (point))
+ (c-whack-state-after (point) paren-state))
+ (if (/= (point) placeholder)
+ (c-add-syntax (cdr tmpsymbol))))
+ ;; CASE 7C: we are looking at the first argument in an empty
+ ;; argument list. Use arglist-close if we're actually
+ ;; looking at a close paren or bracket.
+ ((memq char-before-ip '(?\( ?\[))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-intro placeholder))
+ ;; CASE 7D: we are inside a conditional test clause. treat
+ ;; these things as statements
+ ((progn
+ (goto-char containing-sexp)
+ (and (c-safe (progn (c-forward-sexp -1) t))
+ (looking-at "\\<for\\>[^_]")))
+ (goto-char (1+ containing-sexp))
+ (c-forward-syntactic-ws indent-point)
+ (if (eq char-before-ip ?\;)
+ (c-add-syntax 'statement (point))
+ (c-add-syntax 'statement-cont (point))
+ ))
+ ;; CASE 7E: maybe a continued ObjC method call. This is the
+ ;; case when we are inside a [] bracketed exp, and what
+ ;; precede the opening bracket is not an identifier.
+ ((and c-opt-method-key
+ (eq (char-after containing-sexp) ?\[)
+ (progn
+ (goto-char (1- containing-sexp))
+ (c-backward-syntactic-ws (c-point 'bod))
+ (if (not (looking-at c-symbol-key))
+ (c-add-syntax 'objc-method-call-cont containing-sexp))
+ )))
+ ;; CASE 7F: we are looking at an arglist continuation line,
+ ;; but the preceding argument is on the same line as the
+ ;; opening paren. This case includes multi-line
+ ;; mathematical paren groupings, but we could be on a
+ ;; for-list continuation line
+ ((progn
+ (goto-char (1+ containing-sexp))
+ (skip-chars-forward " \t")
+ (and (not (eolp))
+ (not (looking-at "\\\\$"))))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-cont-nonempty placeholder))
+ ;; CASE 7G: we are looking at just a normal arglist
+ ;; continuation line
+ (t (c-forward-syntactic-ws indent-point)
+ (c-add-syntax 'arglist-cont (c-point 'boi)))
+ ))
+ ;; CASE 8: func-local multi-inheritance line
+ ((and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (looking-at c-opt-decl-spec-key)))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (cond
+ ;; CASE 8A: non-hanging colon on an inher intro
+ ((eq char-after-ip ?:)
+ (c-backward-syntactic-ws lim)
+ (c-add-syntax 'inher-intro (c-point 'boi)))
+ ;; CASE 8B: hanging colon on an inher intro
+ ((eq char-before-ip ?:)
+ (c-add-syntax 'inher-intro (c-point 'boi)))
+ ;; CASE 8C: a continued inheritance line
+ (t
+ (c-beginning-of-inheritance-list lim)
+ (c-add-syntax 'inher-cont (point))
+ )))
+ ;; CASE 9: we are inside a brace-list
+ ((setq special-brace-list
+ (or (and c-special-brace-lists
+ (save-excursion
+ (goto-char containing-sexp)
+ (c-looking-at-special-brace-list)))
+ (c-inside-bracelist-p containing-sexp paren-state)))
+ (cond
+ ;; CASE 9A: In the middle of a special brace list opener.
+ ((and (consp special-brace-list)
+ (save-excursion
+ (goto-char containing-sexp)
+ (eq (char-after) ?\())
+ (eq char-after-ip (car (cdr special-brace-list))))
+ (goto-char (car (car special-brace-list)))
+ (skip-chars-backward " \t")
+ (if (and (bolp)
+ (assoc 'statement-cont
+ (setq placeholder (c-guess-basic-syntax))))
+ (setq syntax placeholder)
+ (c-beginning-of-statement-1
+ (c-safe-position (1- containing-sexp) paren-state))
+ (c-forward-token-1 0)
+ (if (looking-at "typedef\\>[^_]") (c-forward-token-1 1))
+ (c-add-syntax 'brace-list-open (c-point 'boi))))
+ ;; CASE 9B: brace-list-close brace
+ ((if (consp special-brace-list)
+ ;; Check special brace list closer.
+ (progn
+ (goto-char (car (car special-brace-list)))
+ (save-excursion
+ (goto-char indent-point)
+ (back-to-indentation)
+ (or
+ ;; We were between the special close char and the `)'.
+ (and (eq (char-after) ?\))
+ (eq (1+ (point)) (cdr (car special-brace-list))))
+ ;; We were before the special close char.
+ (and (eq (char-after) (cdr (cdr special-brace-list)))
+ (= (c-forward-token-1) 0)
+ (eq (1+ (point)) (cdr (car special-brace-list)))))))
+ ;; Normal brace list check.
+ (and (eq char-after-ip ?})
+ (c-safe (progn (goto-char (c-up-list-backward (point)))
+ t))
+ (= (point) containing-sexp)))
+ (if (eq (point) (c-point 'boi))
+ (c-add-syntax 'brace-list-close (point))
+ (setq lim (c-most-enclosing-brace c-state-cache (point)))
+ (c-beginning-of-statement-1 lim)
+ (c-add-stmt-syntax 'brace-list-close t lim
+ (c-whack-state-after (point) paren-state)
+ t)))
+ (t
+ ;; Prepare for the rest of the cases below by going to the
+ ;; token following the opening brace
+ (if (consp special-brace-list)
+ (progn
+ (goto-char (car (car special-brace-list)))
+ (c-forward-token-1 1 nil indent-point))
+ (goto-char containing-sexp))
+ (forward-char)
+ (let ((start (point)))
+ (c-forward-syntactic-ws indent-point)
+ (goto-char (max start (c-point 'bol))))
+ (c-skip-ws-forward indent-point)
+ (cond
+ ;; CASE 9C: we're looking at the first line in a brace-list
+ ((= (point) indent-point)
+ (if (consp special-brace-list)
+ (goto-char (car (car special-brace-list)))
+ (goto-char containing-sexp))
+ (if (eq (point) (c-point 'boi))
+ (c-add-syntax 'brace-list-intro (point))
+ (setq lim (c-most-enclosing-brace c-state-cache (point)))
+ (c-beginning-of-statement-1 lim)
+ (c-add-stmt-syntax 'brace-list-intro t lim
+ (c-whack-state-after (point) paren-state)
+ t)))
+ ;; CASE 9D: this is just a later brace-list-entry or
+ ;; brace-entry-open
+ (t (if (or (eq char-after-ip ?{)
+ (and c-special-brace-lists
+ (save-excursion
+ (goto-char indent-point)
+ (c-forward-syntactic-ws (c-point 'eol))
+ (c-looking-at-special-brace-list (point)))))
+ (c-add-syntax 'brace-entry-open (point))
+ (c-add-syntax 'brace-list-entry (point))
+ ))
+ ))))
+ ;; CASE 10: A continued statement or top level construct.
+ ((and (not (memq char-before-ip '(?\; ?:)))
+ (or (not (eq char-before-ip ?}))
+ (c-looking-at-inexpr-block-backward c-state-cache))
+ (> (point)
+ (save-excursion
+ (c-beginning-of-statement-1 containing-sexp)
+ (setq placeholder (point))))
+ (/= placeholder containing-sexp))
+ ;; This is shared with case 18.
+ (c-guess-continued-construct indent-point
+ char-after-ip
+ placeholder
+ containing-sexp
+ paren-state))
+ ;; CASE 14: A case or default label
+ ((looking-at c-label-kwds-regexp)
+ (goto-char containing-sexp)
+ (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax 'case-label t lim paren-state))
+ ;; CASE 15: any other label
+ ((looking-at c-label-key)
+ (goto-char containing-sexp)
+ (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
+ (save-excursion
+ (setq tmpsymbol
+ (if (and (eq (c-beginning-of-statement-1 lim) 'up)
+ (looking-at "switch\\>[^_]"))
+ ;; If the surrounding statement is a switch then
+ ;; let's analyze all labels as switch labels, so
+ ;; that they get lined up consistently.
+ 'case-label
+ 'label)))
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax tmpsymbol t lim paren-state))
+ ;; CASE 16: block close brace, possibly closing the defun or
+ ;; the class
+ ((eq char-after-ip ?})
+ ;; From here on we have the next containing sexp in lim.
+ (setq lim (c-most-enclosing-brace paren-state))
+ (goto-char containing-sexp)
+ (cond
+ ;; CASE 16E: Closing a statement block? This catches
+ ;; cases where it's preceded by a statement keyword,
+ ;; which works even when used in an "invalid" context,
+ ;; e.g. a macro argument.
+ ((c-after-conditional)
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax 'block-close t lim paren-state))
+ ;; CASE 16A: closing a lambda defun or an in-expression
+ ;; block? C.f. cases 4, 7B and 17E.
+ ((setq placeholder (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp paren-state)
+ nil))
+ (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
+ 'inline-close
+ 'block-close))
+ (goto-char containing-sexp)
+ (back-to-indentation)
+ (if (= containing-sexp (point))
+ (c-add-syntax tmpsymbol (point))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-stmt-syntax tmpsymbol t
+ (c-most-enclosing-brace paren-state (point))
+ (c-whack-state-after (point) paren-state))
+ (if (/= (point) (cdr placeholder))
+ (c-add-syntax (car placeholder)))))
+ ;; CASE 16B: does this close an inline or a function in
+ ;; an extern block or namespace?
+ ((setq placeholder (c-search-uplist-for-classkey paren-state))
+ (c-backward-to-decl-anchor lim)
+ (back-to-indentation)
+ (if (save-excursion
+ (goto-char (aref placeholder 0))
+ (looking-at c-other-decl-block-key))
+ (c-add-syntax 'defun-close (point))
+ (c-add-syntax 'inline-close (point))))
+ ;; CASE 16F: Can be a defun-close of a function declared
+ ;; in a statement block, e.g. in Pike or when using gcc
+ ;; extensions. Might also trigger it with some macros
+ ;; followed by blocks, and this gives sane indentation
+ ;; then too. Let it through to be handled below.
+ ;; C.f. cases B.3 and 17G.
+ ((and (not inenclosing-p)
+ lim
+ (save-excursion
+ (and (not (c-looking-at-bos))
+ (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
+ (setq placeholder (point)))))
+ (back-to-indentation)
+ (if (/= (point) containing-sexp)
+ (goto-char placeholder))
+ (c-add-stmt-syntax 'defun-close t lim paren-state))
+ ;; CASE 16C: if there an enclosing brace that hasn't
+ ;; been narrowed out by a class, then this is a
+ ;; block-close. C.f. case 17H.
+ ((and (not inenclosing-p) lim)
+ ;; If the block is preceded by a case/switch label on
+ ;; the same line, we anchor at the first preceding label
+ ;; at boi. The default handling in c-add-stmt-syntax is
+ ;; really fixes it better, but we do like this to keep
+ ;; the indentation compatible with version 5.28 and
+ ;; earlier.
+ (while (and (/= (setq placeholder (point)) (c-point 'boi))
+ (eq (c-beginning-of-statement-1 lim) 'label)))
+ (goto-char placeholder)
+ (if (looking-at c-label-kwds-regexp)
+ (c-add-syntax 'block-close (point))
+ (goto-char containing-sexp)
+ ;; c-backward-to-block-anchor not necessary here; those
+ ;; situations are handled in case 16E above.
+ (c-add-stmt-syntax 'block-close t lim paren-state)))
+ ;; CASE 16D: find out whether we're closing a top-level
+ ;; class or a defun
+ (t
+ (save-restriction
+ (narrow-to-region (point-min) indent-point)
+ (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
+ (if decl
+ (c-add-class-syntax 'class-close decl paren-state)
+ (goto-char containing-sexp)
+ (c-backward-to-decl-anchor lim)
+ (back-to-indentation)
+ (c-add-syntax 'defun-close (point)))))
+ )))
+ ;; CASE 17: Statement or defun catchall.
+ (t
+ (goto-char indent-point)
+ ;; Back up statements until we find one that starts at boi.
+ (while (let* ((prev-point (point))
+ (last-step-type (c-beginning-of-statement-1
+ containing-sexp)))
+ (if (= (point) prev-point)
+ (progn
+ (setq step-type (or step-type last-step-type))
+ nil)
+ (setq step-type last-step-type)
+ (/= (point) (c-point 'boi)))))
+ (cond
+ ;; CASE 17B: continued statement
+ ((and (eq step-type 'same)
+ (/= (point) indent-point))
+ (c-add-stmt-syntax 'statement-cont nil
+ containing-sexp paren-state))
+ ;; CASE 17A: After a case/default label?
+ ((progn
+ (while (and (eq step-type 'label)
+ (not (looking-at c-label-kwds-regexp)))
+ (setq step-type
+ (c-beginning-of-statement-1 containing-sexp)))
+ (eq step-type 'label))
+ (c-add-stmt-syntax (if (eq char-after-ip ?{)
+ 'statement-case-open
+ 'statement-case-intro)
+ t containing-sexp paren-state))
+ ;; CASE 17D: any old statement
+ ((progn
+ (while (eq step-type 'label)
+ (setq step-type
+ (c-beginning-of-statement-1 containing-sexp)))
+ (eq step-type 'previous))
+ (c-add-stmt-syntax 'statement t containing-sexp paren-state)
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ;; CASE 17I: Inside a substatement block.
+ ((progn
+ ;; The following tests are all based on containing-sexp.
+ (goto-char containing-sexp)
+ ;; From here on we have the next containing sexp in lim.
+ (setq lim (c-most-enclosing-brace paren-state containing-sexp))
+ (c-after-conditional))
+ (c-backward-to-block-anchor lim)
+ (c-add-stmt-syntax 'statement-block-intro t lim paren-state)
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ;; CASE 17E: first statement in an in-expression block.
+ ;; C.f. cases 4, 7B and 16A.
+ ((setq placeholder (c-looking-at-inexpr-block
+ (c-safe-position containing-sexp paren-state)
+ nil))
+ (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
+ 'defun-block-intro
+ 'statement-block-intro))
+ (back-to-indentation)
+ (if (= containing-sexp (point))
+ (c-add-syntax tmpsymbol (point))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-stmt-syntax tmpsymbol t
+ (c-most-enclosing-brace c-state-cache (point))
+ (c-whack-state-after (point) paren-state))
+ (if (/= (point) (cdr placeholder))
+ (c-add-syntax (car placeholder))))
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ;; CASE 17F: first statement in an inline, or first
+ ;; statement in a top-level defun. we can tell this is it
+ ;; if there are no enclosing braces that haven't been
+ ;; narrowed out by a class (i.e. don't use bod here).
+ ;; However, we first check for statements that we can
+ ;; recognize by keywords. That increases the robustness in
+ ;; cases where statements are used on the top level,
+ ;; e.g. in macro definitions.
+ ((save-excursion
+ (save-restriction
+ (widen)
+ (c-narrow-out-enclosing-class paren-state containing-sexp)
+ (not (c-most-enclosing-brace paren-state))))
+ (c-backward-to-decl-anchor lim)
+ (back-to-indentation)
+ (c-add-syntax 'defun-block-intro (point)))
+ ;; CASE 17G: First statement in a function declared inside
+ ;; a normal block. This can occur in Pike and with
+ ;; e.g. the gcc extensions. Might also trigger it with
+ ;; some macros followed by blocks, and this gives sane
+ ;; indentation then too. C.f. cases B.3 and 16F.
+ ((save-excursion
+ (and (not (c-looking-at-bos))
+ (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
+ (setq placeholder (point))))
+ (back-to-indentation)
+ (if (/= (point) containing-sexp)
+ (goto-char placeholder))
+ (c-add-stmt-syntax 'defun-block-intro t lim paren-state))
+ ;; CASE 17H: First statement in a block. C.f. case 16C.
+ (t
+ ;; If the block is preceded by a case/switch label on the
+ ;; same line, we anchor at the first preceding label at
+ ;; boi. The default handling in c-add-stmt-syntax is
+ ;; really fixes it better, but we do like this to keep the
+ ;; indentation compatible with version 5.28 and earlier.
+ (while (and (/= (setq placeholder (point)) (c-point 'boi))
+ (eq (c-beginning-of-statement-1 lim) 'label)))
+ (goto-char placeholder)
+ (if (looking-at c-label-kwds-regexp)
+ (c-add-syntax 'statement-block-intro (point))
+ (goto-char containing-sexp)
+ ;; c-backward-to-block-anchor not necessary here; those
+ ;; situations are handled in case 17I above.
+ (c-add-stmt-syntax 'statement-block-intro t lim paren-state))
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ))
+ )
+ ;; now we need to look at any modifiers
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ ;; are we looking at a comment only line?
+ (when (and (looking-at c-comment-start-regexp)
+ (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
+ (c-add-syntax 'comment-intro))
+ ;; we might want to give additional offset to friends (in C++).
+ (when (and c-opt-friend-key
+ (looking-at c-opt-friend-key))
+ (c-add-syntax 'friend))
+ ;; Start of or a continuation of a preprocessor directive?
+ (if (and macro-start
+ (eq macro-start (c-point 'boi))
+ (not (and (c-major-mode-is 'pike-mode)
+ (eq (char-after (1+ macro-start)) ?\"))))
+ (c-add-syntax 'cpp-macro)
+ (when (and c-syntactic-indentation-in-macros macro-start)
+ (if in-macro-expr
+ (when (or (< syntactic-relpos macro-start)
+ (not (or (assq 'arglist-intro syntax)
+ (assq 'arglist-cont syntax)
+ (assq 'arglist-cont-nonempty syntax)
+ (assq 'arglist-close syntax))))
+ ;; If inside a cpp expression, i.e. anywhere in a
+ ;; cpp directive except a #define body, we only let
+ ;; through the syntactic analysis that is internal
+ ;; in the expression. That means the arglist
+ ;; elements, if they are anchored inside the cpp
+ ;; expression.
+ (setq syntax `((cpp-macro-cont . ,macro-start))))
+ (when (and (eq macro-start syntactic-relpos)
+ (not (assq 'cpp-define-intro syntax))
+ (save-excursion
+ (goto-char macro-start)
+ (or (not (c-forward-to-cpp-define-body))
+ (<= (point) (c-point 'boi indent-point)))))
+ ;; Inside a #define body and the syntactic analysis is
+ ;; anchored on the start of the #define. In this case
+ ;; we add cpp-define-intro to get the extra
+ ;; indentation of the #define body.
+ (c-add-syntax 'cpp-define-intro)))))
+ ;; return the syntax
+ syntax)))))
+ ((defun c-guess-basic-syntax ()
+ (save-excursion
+ (save-restriction
+ (beginning-of-line)
+ (let* ((indent-point (point))
+ (case-fold-search nil)
+ (fullstate (c-parse-state))
+ (state fullstate)
+ literal containing-sexp char-before-ip char-after-ip lim
+ syntax placeholder c-in-literal-cache inswitch-p
+ tmpsymbol keyword injava-inher special-brace-list
+ ;; narrow out any enclosing class or extern "C" block
+ (inclass-p (c-narrow-out-enclosing-class state indent-point))
+ inenclosing-p)
+ ;; check for meta top-level enclosing constructs, possible
+ ;; extern language definitions, possibly (in C++) namespace
+ ;; definitions.
+ (save-excursion
+ (save-restriction
+ (widen)
+ (if (and inclass-p
+ (progn
+ (goto-char (aref inclass-p 0))
+ (looking-at (concat c-extra-toplevel-key "[^_]"))))
+ (let ((enclosing (match-string 1)))
+ (cond
+ ((string-equal enclosing "extern")
+ (setq inenclosing-p 'extern))
+ ((string-equal enclosing "namespace")
+ (setq inenclosing-p 'namespace))
+ )))))
+ ;; get the buffer position of the most nested opening brace,
+ ;; if there is one, and it hasn't been narrowed out
+ (save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t}")
+ (skip-chars-backward " \t")
+ (while (and state
+ (not containing-sexp))
+ (setq containing-sexp (car state)
+ state (cdr state))
+ (if (consp containing-sexp)
+ ;; if cdr == point, then containing sexp is the brace
+ ;; that opens the sexp we close
+ (if (= (cdr containing-sexp) (point))
+ (setq containing-sexp (car containing-sexp))
+ ;; otherwise, ignore this element
+ (setq containing-sexp nil))
+ ;; ignore the bufpos if its been narrowed out by the
+ ;; containing class or does not contain the indent point
+ (if (or (<= containing-sexp (point-min))
+ (>= containing-sexp indent-point))
+ (setq containing-sexp nil)))))
+ ;; (imenu "agulbra-c++-tab")
+ ;; set the limit on the farthest back we need to search
+ (setq lim (or containing-sexp
+ (if (consp (car fullstate))
+ (cdr (car fullstate))
+ nil)
+ (point-min)))
+
+ ;; cache char before and after indent point, and move point to
+ ;; the most likely position to perform the majority of tests
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (setq char-after-ip (char-after))
+ (c-backward-syntactic-ws lim)
+ (setq char-before-ip (char-before))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+
+ ;; are we in a literal?
+ (setq literal (c-in-literal lim))
+
+ ;; now figure out syntactic qualities of the current line
+ (cond
+ ;; CASE 1: in a string.
+ ((memq literal '(string))
+ (c-add-syntax 'string (c-point 'bopl)))
+ ;; CASE 2: in a C or C++ style comment.
+ ((memq literal '(c c++))
+ (c-add-syntax literal (car (c-literal-limits lim))))
+ ;; CASE 3: in a cpp preprocessor macro continuation.
+ ((and (eq literal 'pound)
+ (/= (save-excursion
+ (c-beginning-of-macro lim)
+ (setq placeholder (point)))
+ (c-point 'boi)))
+ (c-add-syntax 'cpp-macro-cont placeholder))
+ ;; CASE 4: In-expression statement.
+ ((and (or c-inexpr-class-key c-inexpr-block-key c-lambda-key)
+ (setq placeholder (c-looking-at-inexpr-block)))
+ (setq tmpsymbol (assq (car placeholder)
+ '((inexpr-class . class-open)
+ (inexpr-statement . block-open))))
+ (if tmpsymbol
+ ;; It's a statement block or an anonymous class.
+ (setq tmpsymbol (cdr tmpsymbol))
+ ;; It's a Pike lambda. Check whether we are between the
+ ;; lambda keyword and the argument list or at the defun
+ ;; opener.
+ (setq tmpsymbol (if (eq char-after-ip ?{)
+ 'inline-open
+ 'lambda-intro-cont)))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-syntax tmpsymbol (point))
+ (unless (eq (point) (cdr placeholder))
+ (c-add-syntax (car placeholder))))
+ ;; CASE 5: Line is at top level.
+ ((null containing-sexp)
+ (cond
+ ;; CASE 5A: we are looking at a defun, brace list, class,
+ ;; or inline-inclass method opening brace
+ ((setq special-brace-list
+ (or (and c-special-brace-lists
+ (c-looking-at-special-brace-list))
+ (eq char-after-ip ?{)))
+ (cond
+ ;; CASE 5A.1: extern language or namespace construct
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (and (c-safe (progn (c-backward-sexp 2) t))
+ (looking-at (concat c-extra-toplevel-key "[^_]"))
+ (setq keyword (match-string 1)
+ placeholder (point))
+ (or (and (string-equal keyword "namespace")
+ (setq tmpsymbol 'namespace-open))
+ (and (string-equal keyword "extern")
+ (progn
+ (c-forward-sexp 1)
+ (c-forward-syntactic-ws)
+ (eq (char-after) ?\"))
+ (setq tmpsymbol 'extern-lang-open)))
+ ))
+ (goto-char placeholder)
+ (c-add-syntax tmpsymbol (c-point 'boi)))
+ ;; CASE 5A.2: we are looking at a class opening brace
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t{")
+ ;; TBD: watch out! there could be a bogus
+ ;; c-state-cache in place when we get here. we have
+ ;; to go through much chicanery to ignore the cache.
+ ;; But of course, there may not be! BLECH! BOGUS!
+ (let ((decl
+ (let ((c-state-cache nil))
+ (c-search-uplist-for-classkey (c-parse-state))
+ )))
+ (and decl
+ (setq placeholder (aref decl 0)))
+ ))
+ (c-add-syntax 'class-open placeholder))
+ ;; CASE 5A.3: brace list open
+ ((save-excursion
+ (c-beginning-of-statement-1 lim)
+ ;; c-b-o-s could have left us at point-min
+ (and (bobp)
+ (c-forward-syntactic-ws indent-point))
+ (if (looking-at "typedef[^_]")
+ (progn (c-forward-sexp 1)
+ (c-forward-syntactic-ws indent-point)))
+ (setq placeholder (c-point 'boi))
+ (or (consp special-brace-list)
+ (and (or (save-excursion
+ (goto-char indent-point)
+ (setq tmpsymbol nil)
+ (while (and (> (point) placeholder)
+ (= (c-backward-token-1 1 t) 0)
+ (/= (char-after) ?=))
+ (if (and (not tmpsymbol)
+ (looking-at "new\\>[^_]"))
+ (setq tmpsymbol 'topmost-intro-cont)))
+ (eq (char-after) ?=))
+ (looking-at "enum[ \t\n]+"))
+ (save-excursion
+ (while (and (< (point) indent-point)
+ (= (c-forward-token-1 1 t) 0)
+ (not (memq (char-after) '(?\; ?\()))))
+ (not (memq (char-after) '(?\; ?\()))
+ ))))
+ (if (and (c-major-mode-is 'java-mode)
+ (eq tmpsymbol 'topmost-intro-cont))
+ ;; We're in Java and have found that the open brace
+ ;; belongs to a "new Foo[]" initialization list,
+ ;; which means the brace list is part of an
+ ;; expression and not a top level definition. We
+ ;; therefore treat it as any topmost continuation
+ ;; even though the semantically correct symbol still
+ ;; is brace-list-open, on the same grounds as in
+ ;; case 10B.2.
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
+ (c-add-syntax 'brace-list-open placeholder)))
+ ;; CASE 5A.4: inline defun open
+ ((and inclass-p (not inenclosing-p))
+ (c-add-syntax 'inline-open)
+ (c-add-class-syntax 'inclass inclass-p))
+ ;; CASE 5A.5: ordinary defun open
+ (t
+ (goto-char placeholder)
+ (if inclass-p
+ (c-add-syntax 'defun-open (c-point 'boi))
+ (c-add-syntax 'defun-open (c-point 'bol)))
+ )))
+ ;; CASE 5B: first K&R arg decl or member init
+ ((c-just-after-func-arglist-p)
+ (cond
+ ;; CASE 5B.1: a member init
+ ((or (eq char-before-ip ?:)
+ (eq char-after-ip ?:))
+ ;; this line should be indented relative to the beginning
+ ;; of indentation for the topmost-intro line that contains
+ ;; the prototype's open paren
+ ;; TBD: is the following redundant?
+ (if (eq char-before-ip ?:)
+ (forward-char -1))
+ (c-backward-syntactic-ws lim)
+ ;; TBD: is the preceding redundant?
+ (if (eq (char-before) ?:)
+ (progn (forward-char -1)
+ (c-backward-syntactic-ws lim)))
+ (if (eq (char-before) ?\))
+ (c-backward-sexp 1))
+ (setq placeholder (point))
+ (save-excursion
+ (and (c-safe (c-backward-sexp 1) t)
+ (looking-at "throw[^_]")
+ (c-safe (c-backward-sexp 1) t)
+ (setq placeholder (point))))
+ (goto-char placeholder)
+ (c-add-syntax 'member-init-intro (c-point 'boi))
+ ;; we don't need to add any class offset since this
+ ;; should be relative to the ctor's indentation
+ )
+ ;; CASE 5B.2: K&R arg decl intro
+ (c-recognize-knr-p
+ (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
+ (if inclass-p (c-add-class-syntax 'inclass inclass-p)))
+ ;; CASE 5B.3: Inside a member init list.
+ ((c-beginning-of-member-init-list lim)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'member-init-cont (point)))
+ ;; CASE 5B.4: Nether region after a C++ or Java func
+ ;; decl, which could include a `throws' declaration.
+ (t
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'func-decl-cont (c-point 'boi))
+ )))
+ ;; CASE 5C: inheritance line. could be first inheritance
+ ;; line, or continuation of a multiple inheritance
+ ((or (and c-baseclass-key
+ (progn
+ (when (eq char-after-ip ?,)
+ (skip-chars-forward " \t")
+ (forward-char))
+ (looking-at c-baseclass-key)))
+ (and (or (eq char-before-ip ?:)
+ ;; watch out for scope operator
+ (save-excursion
+ (and (eq char-after-ip ?:)
+ (c-safe (progn (forward-char 1) t))
+ (not (eq (char-after) ?:))
+ )))
+ (save-excursion
+ (c-backward-syntactic-ws lim)
+ (if (eq char-before-ip ?:)
+ (progn
+ (forward-char -1)
+ (c-backward-syntactic-ws lim)))
+ (back-to-indentation)
+ (looking-at c-class-key)))
+ ;; for Java
+ (and (c-major-mode-is 'java-mode)
+ (let ((fence (save-excursion
+ (c-beginning-of-statement-1 lim)
+ (point)))
+ cont done)
+ (save-excursion
+ (while (not done)
+ (cond ((looking-at c-Java-special-key)
+ (setq injava-inher (cons cont (point))
+ done t))
+ ((or (not (c-safe (c-forward-sexp -1) t))
+ (<= (point) fence))
+ (setq done t))
+ )
+ (setq cont t)))
+ injava-inher)
+ (not (c-crosses-statement-barrier-p (cdr injava-inher)
+ (point)))
+ ))
+ (cond
+ ;; CASE 5C.1: non-hanging colon on an inher intro
+ ((eq char-after-ip ?:)
+ (c-backward-syntactic-ws lim)
+ (c-add-syntax 'inher-intro (c-point 'boi))
+ ;; don't add inclass symbol since relative point already
+ ;; contains any class offset
+ )
+ ;; CASE 5C.2: hanging colon on an inher intro
+ ((eq char-before-ip ?:)
+ (c-add-syntax 'inher-intro (c-point 'boi))
+ (if inclass-p (c-add-class-syntax 'inclass inclass-p)))
+ ;; CASE agulbrahack.1:
+ ((and inclass-p
+ c-access-key
+ (looking-at c-access-key))
+ (c-add-syntax 'access-label (c-point 'bonl))
+ (c-add-class-syntax 'inclass inclass-p)
+ )
+ ;; CASE 5C.3: in a Java implements/extends
+ (injava-inher
+ (let ((where (cdr injava-inher))
+ (cont (car injava-inher)))
+ (goto-char where)
+ (cond ((looking-at "throws[ \t\n]")
+ (c-add-syntax 'func-decl-cont
+ (progn (c-beginning-of-statement-1 lim)
+ (c-point 'boi))))
+ (cont (c-add-syntax 'inher-cont where))
+ (t (c-add-syntax 'inher-intro
+ (progn (goto-char (cdr injava-inher))
+ (c-beginning-of-statement-1 lim)
+ (point))))
+ )))
+ ;; CASE 5C.4: a continued inheritance line
+ (t
+ (c-beginning-of-inheritance-list lim)
+ (c-add-syntax 'inher-cont (point))
+ ;; don't add inclass symbol since relative point already
+ ;; contains any class offset
+ )))
+ ;; CASE 5D: this could be a top-level compound statement, a
+ ;; member init list continuation, or a template argument
+ ;; list continuation.
+ ((c-with-syntax-table (if (c-major-mode-is 'c++-mode)
+ c++-template-syntax-table
+ (syntax-table))
+ (save-excursion
+ (while (and (= (c-backward-token-1 1 t lim) 0)
+ (not (looking-at "[;{<,]"))))
+ (eq (char-after) ?,)))
+ (goto-char indent-point)
+ (c-beginning-of-member-init-list lim)
+ (cond
+ ;; CASE 5D.1: hanging member init colon, but watch out
+ ;; for bogus matches on access specifiers inside classes.
+ ((and (save-excursion
+ (setq plaaceholder (point))
+ (c-backward-token-1 1 t lim)
+ (and (eq (char-after) ?:)
+ (not (eq (char-before) ?:))))
+ (save-excursion
+ (goto-char placeholder)
+ (back-to-indentation)
+ (or
+ (/= (car (save-excursion
+ (parse-partial-sexp (point) placeholder)))
+ 0)
+ (and
+ (if c-access-key (not (looking-at c-access-key)) t)
+ (not (looking-at c-class-key))
+ (if c-bitfield-key (not (looking-at c-bitfield-key)) t))
+ )))
+ (goto-char placeholder)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'member-init-cont (point))
+ ;; we do not need to add class offset since relative
+ ;; point is the member init above us
+ )
+ ;; CASE 5D.2: non-hanging member init colon
+ ((progn
+ (c-forward-syntactic-ws indent-point)
+ (eq (char-after) ?:))
+ (skip-chars-forward " \t:")
+ (c-add-syntax 'member-init-cont (point)))
+ ;; CASE 5D.3: perhaps a multiple inheritance line?
+ ((save-excursion
+ (c-beginning-of-statement-1 lim)
+ (setq placeholder (point))
+ (looking-at c-inher-key))
+ (goto-char placeholder)
+ (c-add-syntax 'inher-cont (c-point 'boi)))
+ ;; CASE 5D.4: perhaps a template list continuation?
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-backward "^<" lim)
+ ;; not sure if this is the right test, but it should
+ ;; be fast and mostly accurate.
+ (setq placeholder (point))
+ (and (eq (char-before) ?<)
+ (not (c-in-literal lim))))
+ ;; we can probably indent it just like an arglist-cont
+ (goto-char placeholder)
+ (c-beginning-of-statement-1 lim)
+ (c-add-syntax 'template-args-cont (c-point 'boi)))
+ ;; CASE 5D.5: perhaps a top-level statement-cont
+ (t
+ (c-beginning-of-statement-1 lim)
+ ;; skip over any access-specifiers
+ (and inclass-p c-access-key
+ (while (looking-at c-access-key)
+ (forward-line 1)))
+ ;; skip over comments, whitespace
+ (c-forward-syntactic-ws indent-point)
+ (c-add-syntax 'statement-cont (c-point 'boi)))
+ ))
+ ;; CASE 5E: we are looking at a access specifier
+ ((and inclass-p
+ c-access-key
+ (looking-at c-access-key))
+ (c-add-syntax 'access-label (c-point 'bonl))
+ (c-add-class-syntax 'inclass inclass-p))
+ ;; CASE 5F: extern-lang-close or namespace-close?
+ ((and inenclosing-p
+ (eq char-after-ip ?}))
+ (setq tmpsymbol (if (eq inenclosing-p 'extern)
+ 'extern-lang-close
+ 'namespace-close))
+ (c-add-syntax tmpsymbol (aref inclass-p 0)))
+ ;; CASE 5G: we are looking at the brace which closes the
+ ;; enclosing nested class decl
+ ((and inclass-p
+ (eq char-after-ip ?})
+ (save-excursion
+ (save-restriction
+ (widen)
+ (forward-char 1)
+ (and (c-safe (progn (c-backward-sexp 1) t))
+ (= (point) (aref inclass-p 1))
+ ))))
+ (c-add-class-syntax 'class-close inclass-p))
+ ;; CASE 5H: we could be looking at subsequent knr-argdecls
+ ((and c-recognize-knr-p
+ ;; here we essentially use the hack that is used in
+ ;; Emacs' c-mode.el to limit how far back we should
+ ;; look. The assumption is made that argdecls are
+ ;; indented at least one space and that function
+ ;; headers are not indented.
+ (let ((limit (save-excursion
+ (re-search-backward "^[^ \^L\t\n#]" nil 'move)
+ (point))))
+ (save-excursion
+ (c-backward-syntactic-ws limit)
+ (setq placeholder (point))
+ (while (and (memq (char-before) '(?\; ?,))
+ (> (point) limit))
+ (beginning-of-line)
+ (setq placeholder (point))
+ (c-backward-syntactic-ws limit))
+ (and (eq (char-before) ?\))
+ (or (not c-method-key)
+ (progn
+ (c-forward-sexp -1)
+ (forward-char -1)
+ (c-backward-syntactic-ws)
+ (not (or (memq (char-before) '(?- ?+))
+ ;; or a class category
+ (progn
+ (c-forward-sexp -2)
+ (looking-at c-class-key))
+ )))))
+ ))
+ (save-excursion
+ (c-beginning-of-statement-1)
+ (not (looking-at "typedef[ \t\n]+"))))
+ (goto-char placeholder)
+ (c-add-syntax 'knr-argdecl (c-point 'boi)))
+ ;; CASE 5I: ObjC method definition.
+ ((and c-method-key
+ (looking-at c-method-key))
+ (c-add-syntax 'objc-method-intro (c-point 'boi)))
+ ;; CASE 5J: we are at the topmost level, make sure we skip
+ ;; back past any access specifiers
+ ((progn
+ (c-backward-syntactic-ws lim)
+ (while (and inclass-p
+ c-access-key
+ (not (bobp))
+ (save-excursion
+ (c-safe (progn (c-backward-sexp 1) t))
+ ;; agulbrahack 2
+ (and (looking-at "slots:")
+ (c-backward-sexp 1))
+ (looking-at c-access-key)))
+ (c-backward-sexp 1)
+ (c-backward-syntactic-ws lim))
+ (or (bobp)
+ (memq (char-before) '(?\; ?\}))))
+ ;; real beginning-of-line could be narrowed out due to
+ ;; enclosure in a class block
+ (save-restriction
+ (widen)
+ (c-add-syntax 'topmost-intro (c-point 'bol))
+ (if inclass-p
+ (progn
+ (goto-char (aref inclass-p 1))
+ (or (= (point) (c-point 'boi))
+ (goto-char (aref inclass-p 0)))
+ (cond
+ ((eq inenclosing-p 'extern)
+ (c-add-syntax 'inextern-lang (c-point 'boi)))
+ ((eq inenclosing-p 'namespace)
+ (c-add-syntax 'innamespace (c-point 'boi)))
+ (t (c-add-class-syntax 'inclass inclass-p)))
+ ))
+ ))
+ ;; CASE 5K: we are at an ObjC or Java method definition
+ ;; continuation line.
+ ((and c-method-key
+ (progn
+ (c-beginning-of-statement-1 lim)
+ (beginning-of-line)
+ (looking-at c-method-key)))
+ (c-add-syntax 'objc-method-args-cont (point)))
+ ;; CASE 5L: we are at the first argument of a template
+ ;; arglist that begins on the previous line.
+ ((eq (char-before) ?<)
+ (c-beginning-of-statement-1 lim)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'template-args-cont (c-point 'boi)))
+ ;; CASE 5M: we are at a topmost continuation line
+ (t
+ (c-beginning-of-statement-1 lim)
+ (c-forward-syntactic-ws)
+ (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
+ )) ; end CASE 5
+ ;; (CASE 6 has been removed.)
+ ;; CASE 7: line is an expression, not a statement. Most
+ ;; likely we are either in a function prototype or a function
+ ;; call argument list
+ ((not (or (and c-special-brace-lists
+ (save-excursion
+ (goto-char containing-sexp)
+ (c-looking-at-special-brace-list)))
+ (eq (char-after containing-sexp) ?{)))
+ (c-backward-syntactic-ws containing-sexp)
+ (cond
+ ;; CASE 7A: we are looking at the arglist closing paren
+ ((and (or (c-major-mode-is 'pike-mode)
+ ;; Don't check this in Pike since it allows a
+ ;; comma after the last arg.
+ (not (eq char-before-ip ?,)))
+ (memq char-after-ip '(?\) ?\])))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-close placeholder))
+ ;; CASE 7B: Looking at the opening brace of an
+ ;; in-expression block or brace list.
+ ((eq char-after-ip ?{)
+ (goto-char indent-point)
+ (setq placeholder (c-point 'boi))
+ (goto-char containing-sexp)
+ (if (c-inside-bracelist-p placeholder
+ (cons containing-sexp state))
+ (progn
+ (c-add-syntax 'brace-list-open (c-point 'boi))
+ (c-add-syntax 'inexpr-class))
+ (c-add-syntax 'block-open (c-point 'boi))
+ (c-add-syntax 'inexpr-statement)))
+ ;; CASE 7C: we are looking at the first argument in an empty
+ ;; argument list. Use arglist-close if we're actually
+ ;; looking at a close paren or bracket.
+ ((memq char-before-ip '(?\( ?\[))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-intro placeholder))
+ ;; CASE 7D: we are inside a conditional test clause. treat
+ ;; these things as statements
+ ((save-excursion
+ (goto-char containing-sexp)
+ (and (c-safe (progn (c-forward-sexp -1) t))
+ (looking-at "\\<for\\>[^_]")))
+ (goto-char (1+ containing-sexp))
+ (c-forward-syntactic-ws indent-point)
+ (c-beginning-of-statement-1 containing-sexp)
+ (if (eq char-before-ip ?\;)
+ (c-add-syntax 'statement (point))
+ (c-add-syntax 'statement-cont (point))
+ ))
+ ;; CASE 7E: maybe a continued method call. This is the case
+ ;; when we are inside a [] bracketed exp, and what precede
+ ;; the opening bracket is not an identifier.
+ ((and c-method-key
+ (eq (char-after containing-sexp) ?\[)
+ (save-excursion
+ (goto-char (1- containing-sexp))
+ (c-backward-syntactic-ws (c-point 'bod))
+ (if (not (looking-at c-symbol-key))
+ (c-add-syntax 'objc-method-call-cont containing-sexp))
+ )))
+ ;; CASE 7F: we are looking at an arglist continuation line,
+ ;; but the preceding argument is on the same line as the
+ ;; opening paren. This case includes multi-line
+ ;; mathematical paren groupings, but we could be on a
+ ;; for-list continuation line
+ ((save-excursion
+ (goto-char (1+ containing-sexp))
+ (skip-chars-forward " \t")
+ (not (eolp)))
+ (goto-char containing-sexp)
+ (setq placeholder (c-point 'boi))
+ (when (and (c-safe (backward-up-list 1) t)
+ (> (point) placeholder))
+ (forward-char)
+ (skip-chars-forward " \t")
+ (setq placeholder (point)))
+ (c-add-syntax 'arglist-cont-nonempty placeholder))
+ ;; CASE 7G: we are looking at just a normal arglist
+ ;; continuation line
+ (t (c-beginning-of-statement-1 containing-sexp)
+ (forward-char 1)
+ (c-forward-syntactic-ws indent-point)
+ (c-add-syntax 'arglist-cont (c-point 'boi)))
+ ))
+ ;; CASE 8: func-local multi-inheritance line
+ ((and c-baseclass-key
+ (save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (looking-at c-baseclass-key)))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (cond
+ ;; CASE 8A: non-hanging colon on an inher intro
+ ((eq char-after-ip ?:)
+ (c-backward-syntactic-ws lim)
+ (c-add-syntax 'inher-intro (c-point 'boi)))
+ ;; CASE 8B: hanging colon on an inher intro
+ ((eq char-before-ip ?:)
+ (c-add-syntax 'inher-intro (c-point 'boi)))
+ ;; CASE 8C: a continued inheritance line
+ (t
+ (c-beginning-of-inheritance-list lim)
+ (c-add-syntax 'inher-cont (point))
+ )))
+ ;; CASE 9: we are inside a brace-list
+ ((setq special-brace-list
+ (or (and c-special-brace-lists
+ (save-excursion
+ (goto-char containing-sexp)
+ (c-looking-at-special-brace-list)))
+ (c-inside-bracelist-p containing-sexp state)))
+ (cond
+ ;; CASE 9A: In the middle of a special brace list opener.
+ ((and (consp special-brace-list)
+ (save-excursion
+ (goto-char containing-sexp)
+ (eq (char-after) ?\())
+ (eq char-after-ip (car (cdr special-brace-list))))
+ (goto-char (car (car special-brace-list)))
+ (skip-chars-backward " \t")
+ (if (and (bolp)
+ (assoc 'statement-cont
+ (setq placeholder (c-guess-basic-syntax))))
+ (setq syntax placeholder)
+ (c-beginning-of-statement-1 lim)
+ (c-forward-token-1 0)
+ (if (looking-at "typedef\\>") (c-forward-token-1 1))
+ (c-add-syntax 'brace-list-open (c-point 'boi))))
+ ;; CASE 9B: brace-list-close brace
+ ((if (consp special-brace-list)
+ ;; Check special brace list closer.
+ (progn
+ (goto-char (car (car special-brace-list)))
+ (save-excursion
+ (goto-char indent-point)
+ (back-to-indentation)
+ (or
+ ;; We were between the special close char and the `)'.
+ (and (eq (char-after) ?\))
+ (eq (1+ (point)) (cdr (car special-brace-list))))
+ ;; We were before the special close char.
+ (and (eq (char-after) (cdr (cdr special-brace-list)))
+ (= (c-forward-token-1) 0)
+ (eq (1+ (point)) (cdr (car special-brace-list)))))))
+ ;; Normal brace list check.
+ (and (eq char-after-ip ?})
+ (c-safe (progn (forward-char 1)
+ (c-backward-sexp 1)
+ t))
+ (= (point) containing-sexp)))
+ (c-add-syntax 'brace-list-close (c-point 'boi)))
+ (t
+ ;; Prepare for the rest of the cases below by going to the
+ ;; token following the opening brace
+ (if (consp special-brace-list)
+ (progn
+ (goto-char (car (car special-brace-list)))
+ (c-forward-token-1 1 nil indent-point))
+ (goto-char containing-sexp))
+ (forward-char)
+ (let ((start (point)))
+ (c-forward-syntactic-ws indent-point)
+ (goto-char (max start (c-point 'bol))))
+ (skip-chars-forward " \t\n\r" indent-point)
+ (cond
+ ;; CASE 9C: we're looking at the first line in a brace-list
+ ((= (point) indent-point)
+ (goto-char containing-sexp)
+ (c-add-syntax 'brace-list-intro (c-point 'boi))
+ ) ; end CASE 9C
+ ;; CASE 9D: this is just a later brace-list-entry or
+ ;; brace-entry-open
+ (t (if (or (eq char-after-ip ?{)
+ (and c-special-brace-lists
+ (save-excursion
+ (goto-char indent-point)
+ (c-forward-syntactic-ws (c-point 'eol))
+ (c-looking-at-special-brace-list (point)))))
+ (c-add-syntax 'brace-entry-open (point))
+ (c-add-syntax 'brace-list-entry (point))
+ )) ; end CASE 9D
+ )))) ; end CASE 9
+ ;; CASE 10: A continued statement
+ ((and (not (memq char-before-ip '(?\; ?:)))
+ (or (not (eq char-before-ip ?}))
+ (c-looking-at-inexpr-block-backward containing-sexp))
+ (> (point)
+ (save-excursion
+ (c-beginning-of-statement-1 containing-sexp)
+ (c-forward-syntactic-ws)
+ (setq placeholder (point))))
+ (/= placeholder containing-sexp))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (let ((after-cond-placeholder
+ (save-excursion
+ (goto-char placeholder)
+ (if (and c-conditional-key (looking-at c-conditional-key))
+ (progn
+ (c-safe (c-skip-conditional))
+ (c-forward-syntactic-ws)
+ (if (eq (char-after) ?\;)
+ (progn
+ (forward-char 1)
+ (c-forward-syntactic-ws)))
+ (point))
+ nil))))
+ (cond
+ ;; CASE 10A: substatement
+ ((and after-cond-placeholder
+ (>= after-cond-placeholder indent-point))
+ (goto-char placeholder)
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'substatement-open (c-point 'boi))
+ (c-add-syntax 'substatement (c-point 'boi))))
+ ;; CASE 10B: open braces for class or brace-lists
+ ((setq special-brace-list
+ (or (and c-special-brace-lists
+ (c-looking-at-special-brace-list))
+ (eq char-after-ip ?{)))
+ (cond
+ ;; CASE 10B.1: class-open
+ ((save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t{")
+ (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
+ (and decl
+ (setq placeholder (aref decl 0)))
+ ))
+ (c-add-syntax 'class-open placeholder))
+ ;; CASE 10B.2: brace-list-open
+ ((or (consp special-brace-list)
+ (save-excursion
+ (goto-char placeholder)
+ (looking-at "\\<enum\\>"))
+ (save-excursion
+ (goto-char indent-point)
+ (while (and (> (point) placeholder)
+ (= (c-backward-token-1 1 t) 0)
+ (/= (char-after) ?=)))
+ (eq (char-after) ?=)))
+ ;; The most semantically accurate symbol here is
+ ;; brace-list-open, but we report it simply as a
+ ;; statement-cont. The reason is that one normally
+ ;; adjusts brace-list-open for brace lists as
+ ;; top-level constructs, and brace lists inside
+ ;; statements is a completely different context.
+ (goto-char indent-point)
+ (c-beginning-of-closest-statement)
+ (c-add-syntax 'statement-cont (c-point 'boi)))
+ ;; CASE 10B.3: The body of a function declared inside a
+ ;; normal block. This can only occur in Pike.
+ ((and (c-major-mode-is 'pike-mode)
+ (progn
+ (goto-char indent-point)
+ (not (c-looking-at-bos))))
+ (c-beginning-of-closest-statement)
+ (c-add-syntax 'defun-open (c-point 'boi)))
+ ;; CASE 10B.4: catch-all for unknown construct.
+ (t
+ ;; Can and should I add an extensibility hook here?
+ ;; Something like c-recognize-hook so support for
+ ;; unknown constructs could be added. It's probably a
+ ;; losing proposition, so I dunno.
+ (goto-char placeholder)
+ (c-add-syntax 'statement-cont (c-point 'boi))
+ (c-add-syntax 'block-open))
+ ))
+ ;; CASE 10C: iostream insertion or extraction operator
+ ((looking-at "<<\\|>>")
+ (goto-char placeholder)
+ (and after-cond-placeholder
+ (goto-char after-cond-placeholder))
+ (while (and (re-search-forward "<<\\|>>" indent-point 'move)
+ (c-in-literal placeholder)))
+ ;; if we ended up at indent-point, then the first
+ ;; streamop is on a separate line. Indent the line like
+ ;; a statement-cont instead
+ (if (/= (point) indent-point)
+ (c-add-syntax 'stream-op (c-point 'boi))
+ (c-backward-syntactic-ws lim)
+ (c-add-syntax 'statement-cont (c-point 'boi))))
+ ;; CASE 10D: continued statement. find the accurate
+ ;; beginning of statement or substatement
+ (t
+ (c-beginning-of-statement-1 after-cond-placeholder)
+ ;; KLUDGE ALERT! c-beginning-of-statement-1 can leave
+ ;; us before the lim we're passing in. It should be
+ ;; fixed, but I'm worried about side-effects at this
+ ;; late date. Fix for v5.
+ (goto-char (or (and after-cond-placeholder
+ (max after-cond-placeholder (point)))
+ (point)))
+ (c-add-syntax 'statement-cont (point)))
+ )))
+ ;; CASE 11: an else clause?
+ ((looking-at "\\<else\\>[^_]")
+ (c-backward-to-start-of-if containing-sexp)
+ (c-add-syntax 'else-clause (c-point 'boi)))
+ ;; CASE 12: Statement. But what kind? Lets see if its a
+ ;; while closure of a do/while construct
+ ((progn
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (and (looking-at "while\\b[^_]")
+ (save-excursion
+ (c-backward-to-start-of-do containing-sexp)
+ (setq placeholder (point))
+ (looking-at "do\\b[^_]"))
+ ))
+ (goto-char placeholder)
+ (c-add-syntax 'do-while-closure (c-point 'boi)))
+ ;; CASE 13: A catch or finally clause? This case is simpler
+ ;; than if-else and do-while, because a block is required
+ ;; after every try, catch and finally.
+ ((save-excursion
+ (and (cond ((c-major-mode-is 'c++-mode)
+ (looking-at "\\<catch\\>[^_]"))
+ ((c-major-mode-is 'java-mode)
+ (looking-at "\\<\\(catch\\|finally\\)\\>[^_]")))
+ (c-safe (c-backward-sexp) t)
+ (eq (char-after) ?{)
+ (c-safe (c-backward-sexp) t)
+ (if (eq (char-after) ?\()
+ (c-safe (c-backward-sexp) t)
+ t)
+ (looking-at "\\<\\(try\\|catch\\)\\>[^_]")
+ (setq placeholder (c-point 'boi))))
+ (c-add-syntax 'catch-clause placeholder))
+ ;; CASE 14: A case or default label
+ ((looking-at c-switch-label-key)
+ (goto-char containing-sexp)
+ ;; check for hanging braces
+ (if (/= (point) (c-point 'boi))
+ (c-forward-sexp -1))
+ (c-add-syntax 'case-label (c-point 'boi)))
+ ;; CASE 15: any other label
+ ((looking-at c-label-key)
+ (goto-char containing-sexp)
+ ;; check for hanging braces
+ (if (/= (point) (c-point 'boi))
+ (c-forward-sexp -1))
+ (c-add-syntax 'label (c-point 'boi)))
+ ;; CASE 16: block close brace, possibly closing the defun or
+ ;; the class
+ ((eq char-after-ip ?})
+ (let* ((lim (c-safe-position containing-sexp fullstate))
+ (relpos (save-excursion
+ (goto-char containing-sexp)
+ (if (/= (point) (c-point 'boi))
+ (c-beginning-of-statement-1 lim))
+ (c-point 'boi))))
+ (cond
+ ;; CASE 16A: closing a lambda defun or an in-expression
+ ;; block?
+ ((save-excursion
+ (goto-char containing-sexp)
+ (setq placeholder (c-looking-at-inexpr-block)))
+ (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
+ 'inline-close
+ 'block-close))
+ (goto-char containing-sexp)
+ (back-to-indentation)
+ (if (= containing-sexp (point))
+ (c-add-syntax tmpsymbol (point))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-syntax tmpsymbol (point))
+ (if (/= (point) (cdr placeholder))
+ (c-add-syntax (car placeholder)))))
+ ;; CASE 16B: does this close an inline or a function in
+ ;; an extern block or namespace?
+ ((progn
+ (goto-char containing-sexp)
+ (setq placeholder (c-search-uplist-for-classkey state)))
+ (goto-char (aref placeholder 0))
+ (if (looking-at (concat c-extra-toplevel-key "[^_]"))
+ (c-add-syntax 'defun-close relpos)
+ (c-add-syntax 'inline-close relpos)))
+ ;; CASE 16C: if there an enclosing brace that hasn't
+ ;; been narrowed out by a class, then this is a
+ ;; block-close
+ ((and (not inenclosing-p)
+ (c-most-enclosing-brace state)
+ (or (not (c-major-mode-is 'pike-mode))
+ ;; In Pike it can be a defun-close of a
+ ;; function declared in a statement block. Let
+ ;; it through to be handled below.
+ (or (c-looking-at-bos)
+ (progn
+ (c-beginning-of-statement-1)
+ (looking-at c-conditional-key)))))
+ (c-add-syntax 'block-close relpos))
+ ;; CASE 16D: find out whether we're closing a top-level
+ ;; class or a defun
+ (t
+ (save-restriction
+ (narrow-to-region (point-min) indent-point)
+ (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
+ (if decl
+ (c-add-class-syntax 'class-close decl)
+ (c-add-syntax 'defun-close relpos)))))
+ )))
+ ;; CASE 17: statement catchall
+ (t
+ ;; we know its a statement, but we need to find out if it is
+ ;; the first statement in a block
+ (goto-char containing-sexp)
+ (forward-char 1)
+ (c-forward-syntactic-ws indent-point)
+ ;; now skip forward past any case/default clauses we might find.
+ (while (or (c-skip-case-statement-forward fullstate indent-point)
+ (and (looking-at c-switch-label-key)
+ (not inswitch-p)))
+ (setq inswitch-p t))
+ ;; we want to ignore non-case labels when skipping forward
+ (while (and (looking-at c-label-key)
+ (goto-char (match-end 0)))
+ (c-forward-syntactic-ws indent-point))
+ (cond
+ ;; CASE 17A: we are inside a case/default clause inside a
+ ;; switch statement. find out if we are at the statement
+ ;; just after the case/default label.
+ ((and inswitch-p
+ (progn
+ (goto-char indent-point)
+ (c-beginning-of-statement-1 containing-sexp)
+ (setq placeholder (point))
+ (beginning-of-line)
+ (when (re-search-forward c-switch-label-key
+ (max placeholder (c-point 'eol)) t)
+ (setq placeholder (match-beginning 0)))))
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (if (eq (char-after) ?{)
+ (c-add-syntax 'statement-case-open placeholder)
+ (c-add-syntax 'statement-case-intro placeholder)))
+ ;; CASE 17B: continued statement
+ ((eq char-before-ip ?,)
+ (goto-char indent-point)
+ (c-beginning-of-closest-statement)
+ (c-add-syntax 'statement-cont (c-point 'boi)))
+ ;; CASE 17C: a question/colon construct? But make sure
+ ;; what came before was not a label, and what comes after
+ ;; is not a globally scoped function call!
+ ((or (and (memq char-before-ip '(?: ??))
+ (save-excursion
+ (goto-char indent-point)
+ (c-backward-syntactic-ws lim)
+ (back-to-indentation)
+ (not (looking-at c-label-key))))
+ (and (memq char-after-ip '(?: ??))
+ (save-excursion
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ ;; watch out for scope operator
+ (not (looking-at "::")))))
+ (goto-char indent-point)
+ (c-beginning-of-closest-statement)
+ (c-add-syntax 'statement-cont (c-point 'boi)))
+ ;; CASE 17D: any old statement
+ ((< (point) indent-point)
+ (let ((safepos (c-most-enclosing-brace fullstate))
+ relpos done)
+ (goto-char indent-point)
+ (c-beginning-of-statement-1 safepos)
+ ;; It is possible we're on the brace that opens a nested
+ ;; function.
+ (if (and (eq (char-after) ?{)
+ (save-excursion
+ (c-backward-syntactic-ws safepos)
+ (not (eq (char-before) ?\;))))
+ (c-beginning-of-statement-1 safepos))
+ (if (and inswitch-p
+ (looking-at c-switch-label-key))
+ (progn
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws)))
+ (setq relpos (c-point 'boi))
+ (while (and (not done)
+ (<= safepos (point))
+ (/= relpos (point)))
+ (c-beginning-of-statement-1 safepos)
+ (if (= relpos (c-point 'boi))
+ (setq done t))
+ (setq relpos (c-point 'boi)))
+ (c-add-syntax 'statement relpos)
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open))))
+ ;; CASE 17E: first statement in an in-expression block
+ ((setq placeholder
+ (save-excursion
+ (goto-char containing-sexp)
+ (c-looking-at-inexpr-block)))
+ (goto-char containing-sexp)
+ (back-to-indentation)
+ (let ((block-intro (if (eq (car placeholder) 'inlambda)
+ 'defun-block-intro
+ 'statement-block-intro)))
+ (if (= containing-sexp (point))
+ (c-add-syntax block-intro (point))
+ (goto-char (cdr placeholder))
+ (back-to-indentation)
+ (c-add-syntax block-intro (point))
+ (if (/= (point) (cdr placeholder))
+ (c-add-syntax (car placeholder)))))
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ;; CASE 17F: first statement in an inline, or first
+ ;; statement in a top-level defun. we can tell this is it
+ ;; if there are no enclosing braces that haven't been
+ ;; narrowed out by a class (i.e. don't use bod here!)
+ ((save-excursion
+ (save-restriction
+ (widen)
+ (goto-char containing-sexp)
+ (c-narrow-out-enclosing-class state containing-sexp)
+ (not (c-most-enclosing-brace state))))
+ (goto-char containing-sexp)
+ ;; if not at boi, then defun-opening braces are hung on
+ ;; right side, so we need a different relpos
+ (if (/= (point) (c-point 'boi))
+ (progn
+ (c-backward-syntactic-ws)
+ (c-safe (c-forward-sexp (if (eq (char-before) ?\))
+ -1 -2)))
+ ;; looking at a Java throws clause following a
+ ;; method's parameter list
+ (c-beginning-of-statement-1)
+ ))
+ (c-add-syntax 'defun-block-intro (c-point 'boi)))
+ ;; CASE 17G: First statement in a function declared inside
+ ;; a normal block. This can only occur in Pike.
+ ((and (c-major-mode-is 'pike-mode)
+ (progn
+ (goto-char containing-sexp)
+ (and (not (c-looking-at-bos))
+ (progn
+ (c-beginning-of-statement-1)
+ (not (looking-at c-conditional-key))))))
+ (c-add-syntax 'defun-block-intro (c-point 'boi)))
+ ;; CASE 17H: first statement in a block
+ (t (goto-char containing-sexp)
+ (if (/= (point) (c-point 'boi))
+ (c-beginning-of-statement-1
+ (if (= (point) lim)
+ (c-safe-position (point) state) lim)))
+ (c-add-syntax 'statement-block-intro (c-point 'boi))
+ (if (eq char-after-ip ?{)
+ (c-add-syntax 'block-open)))
+ ))
+ )
+ ;; now we need to look at any modifiers
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (cond
+ ;; are we looking at a comment only line?
+ ((and (looking-at c-comment-start-regexp)
+ (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
+ (c-add-syntax 'comment-intro))
+ ;; we might want to give additional offset to friends (in C++).
+ ((and (c-major-mode-is 'c++-mode)
+ (looking-at c-C++-friend-key))
+ (c-add-syntax 'friend))
+ ;; Start of a preprocessor directive?
+ ((and (eq literal 'pound)
+ (= (save-excursion
+ (c-beginning-of-macro lim)
+ (setq placeholder (point)))
+ (c-point 'boi))
+ (not (and (c-major-mode-is 'pike-mode)
+ (eq (char-after (1+ placeholder)) ?\"))))
+ (c-add-syntax 'cpp-macro)))
+ ;; return the syntax
+ syntax))))))
+
+(add-hook 'find-file-hooks 'agulbra-c++-clean-out-spaces)
+(add-hook 'write-file-hooks 'agulbra-c++-clean-out-spaces)
+
+(add-hook 'c++-mode-hook 'kde-c++-mode-hook)
+(add-hook 'c-mode-hook 'kde-c-mode-hook)
+; always end a file with a newline
+(setq-default require-final-newline t)
+; 'next-line won't be adding newlines
+(setq-default next-line-add-newlines nil)
+(setq compilation-error-regexp-systems-list '(gnu of comma 4bsd)
+ compilation-ask-about-save nil)
+
+(provide 'kde-emacs-core)
diff --git a/scripts/kde-emacs/kde-emacs-doc.el b/scripts/kde-emacs/kde-emacs-doc.el
new file mode 100644
index 00000000..5fca1361
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-doc.el
@@ -0,0 +1,322 @@
+;; kde-emacs-doc.el
+;;
+;; Copyright (C) 2002 Zack Rusin <zack@kde.org>
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2.1 of the License, or (at your option) any later version.
+;;
+;; This library 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
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+;;
+;;
+;;; Documentation :
+;; Interactive functions:
+;; kde-license-insert - inserts the chosen license header in the current
+;; buffer,
+;; kde-doc-function-insert - insert documentation skeleton for the function
+;; at the current location
+;; kde-doc-multiline-insert - inserts blank mutliline comment skeleton
+;; kde-doc-oneliner-insert - inserts blank one line comment skeleton
+;;
+;;; TODO :
+;; - add interactive functions to insert file, class, brief,
+;; and group comments,
+;; - change the way commenting works after license insertion,
+;; - add syntax higlighting for doxygen/kdoc keywords
+;; - add more license headers
+
+
+(require 'kde-emacs-core)
+(require 'kde-emacs-semantic)
+
+;*---------------------------------------------------------------------*/
+;* Licenses ... */
+;*---------------------------------------------------------------------*/
+
+(defvar LGPL "This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+02110-1301 USA"
+ "GNU LGPL license header.")
+
+(defvar GPL "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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+02110-1301, USA."
+ "GNU GPL license header.")
+
+(defvar FDL "Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1
+or any later version published by the Free Software Foundation;
+with the Invariant Sections being LIST THEIR TITLES, with the
+Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+A copy of the license is included in the section entitled \"GNU
+Free Documentation License\"."
+ "GNU FDL license header.")
+
+(defvar BSD "Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ "BSD license header.")
+
+
+;;----------------
+;; Variables |
+;;----------------
+
+(defconst kde-doc-styles
+ '(
+ (javadoc .
+ ((start . "/**")
+ (end . "*/")
+ (separator . "\n*")
+ (oneliner . "///")
+ (element . "/**< */")
+ (param . "@param %s")
+ (return . "@return")
+ (seealso . "@see")
+ (class . "")
+ (brief . "@brief")
+ (file . "@file %s")
+ ))
+ (qt .
+ ((start . "/*!")
+ (end . "*/")
+ (separator . "\n")
+ (oneliner . "//!")
+ (element . "/*!< */")
+ (param . "\\param %s")
+ (return . "\\return")
+ (seealso . "\\sa")
+ (class . "\\class")
+ (brief . "\\brief")
+ (file . "\\file %s")
+ ))
+ )
+ "Documentation styles used by KDE.")
+
+(defcustom kde-doc-style 'javadoc
+ "Current documentation style. This variable is buffer local."
+ :group 'kde-devel
+ :version "0.1"
+ :type (if (boundp 'kde-doc-styles)
+ `(choice ,@(mapcar (lambda (s) `(const ,(car s))) kde-doc-styles))
+ 'symbol))
+(make-variable-buffer-local 'kde-doc-style)
+
+(defcustom kde-license-comment-style 'box
+ "Style to be used for `kde-license-insert'.
+See `comment-styles' for a list of available styles."
+ :group 'kde-devel
+ :version "0.1"
+ :type (if (boundp 'comment-styles)
+ `(choice ,@(mapcar (lambda (s) `(const ,(car s))) comment-styles))
+ 'symbol))
+
+;*---------------------------------------------------------------------*/
+;* Functions ... */
+;*---------------------------------------------------------------------*/
+
+(defun kde-license-header ()
+ (let ((ret (file-name-nondirectory (buffer-file-name))))
+ (setq ret (concat ret " \n\n"))
+ (setq ret (concat ret "Copyright (C) " (format-time-string "%Y ")
+ kde-full-name " <"kde-email">\n\n"))
+ ))
+
+(defun kde-license-insert (license)
+ "Inserts the chosen license header at the top of the current
+buffer."
+ (interactive (list (completing-read
+ "Which license do you want to use? "
+ '(("GNU GPL" 1) ("GNU LGPL" 2) ("GNU FDL" 3) ("BSD" 4))
+ nil t nil)))
+ (save-excursion
+ (let ((start (point-min))
+ (end)
+ )
+ (setq comment-style kde-license-comment-style)
+ (goto-char start)
+ (if license
+ (progn
+ (cond ((string= license "GNU GPL")
+ (insert (kde-license-header))
+ (insert GPL)
+ )
+ ((string= license "GNU LGPL")
+ (insert (kde-license-header))
+ (insert LGPL)
+ )
+ ((string= license "GNU FDL")
+ (insert (kde-license-header))
+ (insert FDL)
+ )
+ ((string= license "BSD")
+ (insert (kde-license-header))
+ (insert BSD)
+ )
+ )
+ (insert "\n")
+ (setq end (point))
+ (comment-region start end)
+ )
+ )
+ )
+ ))
+
+(defmacro kde-doc-type-string (arg)
+ "Maps doc element from kde-doc-style to string."
+ `(cdr (assoc ,arg (assoc kde-doc-style kde-doc-styles)))
+ )
+
+(defun kde-doc-param-string (ARG)
+ "Substitues %s in the param string with ARG."
+ (let ((par (kde-doc-type-string 'param)))
+ (if (string-match "\%s" par)
+ (replace-match ARG t t par)
+ par))
+ )
+
+(defun kde-function-documentation (function)
+ (let ((ret "") (rettype (semantic-token-type function)))
+ (setq ret (kde-doc-type-string 'start))
+ (setq ret (concat ret (kde-doc-type-string 'separator)))
+ (dolist (elt (semantic-token-function-args function) ret)
+ (setq ret (concat ret (kde-doc-type-string 'separator) " "
+ (kde-doc-param-string (semantic-token-name elt))))
+ )
+ (if (not (or
+ (kde-is-constructor function)
+ (semantic-token-function-destructor function)))
+ (progn
+ (if (listp rettype)
+ (setq rettype (car rettype)))
+ (if (not (string= rettype "void"))
+ (setq ret (concat ret (kde-doc-type-string 'separator) " " (kde-doc-type-string 'return)))
+ )
+ )
+ )
+ (setq ret (concat ret "\n" (kde-doc-type-string 'end) ))
+ ))
+
+(defun kde-doc-function-insert ()
+ "Inserts skeleton function documentation for a function
+at the current location."
+ (interactive)
+ (save-excursion
+ (let* ((pt (point))
+ (token (kde-function-at-point pt))
+ (ret "")
+ (start) (end)
+ )
+ (if (not token)
+ (error "There's no function at %d." pt)
+ (progn
+ (setq ret (kde-function-documentation token))
+ (goto-char (semantic-token-start token))
+ (previous-line)
+ (goto-char (point-at-eol))
+ (setq start (point))
+ (insert "\n " ret)
+ (setq end (semantic-token-end token))
+ (indent-region start end nil)
+ )
+ )
+ )))
+
+(defun kde-doc-oneliner-insert ()
+ "Insert oneliner comment at the current point. If the line is not empty newline is inserted."
+ (interactive)
+ (let ((thisblank)(pt))
+ (save-excursion
+ (beginning-of-line)
+ (setq pt (point))
+ (setq thisblank (looking-at "[ \t]*$"))
+ (if (not thisblank)
+ (progn
+ (newline)
+ (goto-char pt)
+ ))
+ (insert (kde-doc-type-string 'oneliner))
+ (setq pt (point-at-eol))
+ (end-of-line)
+ )
+ (goto-char pt)
+ ))
+
+(defun kde-doc-multiline-insert ()
+ "Inserts blank multiline comment at point. If the current line isn't blank
+the functions inserts a newline."
+ (interactive)
+ (let ((thisblank)(start) (end))
+ (save-excursion
+ (beginning-of-line)
+ (setq start (point))
+ (setq thisblank (looking-at "[ \t]*$"))
+ (if (not thisblank)
+ (progn
+ (newline)
+ (goto-char start)
+ ))
+ ;; The blank to fix sometimes occuring
+ ;; weird behavior in indent-region
+ (insert " "
+ (kde-doc-type-string 'start)
+ (kde-doc-type-string 'separator) "\n"
+ (kde-doc-type-string 'end)
+ )
+ (setq end (point))
+ (indent-region start end nil)
+ )
+ (goto-char start)
+ (end-of-line)
+ ))
+
+
+(provide 'kde-emacs-doc)
diff --git a/scripts/kde-emacs/kde-emacs-general.el b/scripts/kde-emacs/kde-emacs-general.el
new file mode 100644
index 00000000..be34047c
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-general.el
@@ -0,0 +1,179 @@
+;; kde-emacs-general.el
+;;
+;; Copyright (C) 2002 KDE Development Team <www.kde.org>
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2.1 of the License, or (at your option) any later version.
+;;
+;; This library 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
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'kde-emacs-vars)
+
+;*---------------------------------------------------------------------*/
+;* Functions ... */
+;*---------------------------------------------------------------------*/
+
+;; Helper for kde-file-get-cpp-h
+(defun kde-find-file (filename basedir)
+ "Looks for \"filename\" under \"basedir\""
+ (if basedir
+ (let ((path (concat basedir "/" filename)))
+ (if (file-readable-p path)
+ path))
+ )
+)
+
+(defun kde-file-get-cpp-h ()
+ "Function returns a corresponding source or header file. The returned
+variable is a list of the form (FILENAME IS_READABLE) e.g. when being in
+test.h file and having test.cpp file readable in the same directory it will
+return (\"test.cpp\" t)."
+ (interactive)
+ (let* ((name (buffer-file-name))
+ (nname (file-name-sans-extension name))
+ (ext (file-name-extension name))
+ (path nil)
+ (ret nil)
+ (listit nil))
+ (cond
+ ((member ext kde-header-files)
+ (setq listit kde-source-files)
+ (while (and listit (not ret)) ; loop over the list but stop once ret is set
+ (setq path (concat nname "." (car listit)))
+ (if (file-readable-p path)
+ (setq ret (cons path t))
+ )
+ (if (not ret)
+ (if (string-match "_p$" nname)
+ (progn
+ (setq path (concat (substring nname 0 (string-match "_p$" nname)) "." (car listit)))
+ (if (file-readable-p path)
+ (setq ret (cons path t))
+ )))
+ )
+ (if (not ret)
+ (progn ; look in kde-source-directory
+ (setq path (kde-find-file (file-name-nondirectory path) kde-source-directory))
+ (if (and
+ path
+ (file-readable-p path))
+ (setq ret (cons path t))
+ ))
+ )
+ (setq listit (cdr listit)) ; ++listit
+ )
+ ; not found, will create one
+ (if (not ret)
+ (setq ret (cons (concat nname "." kde-prefered-source-extension) nil ))
+ ))
+
+ ((member ext kde-source-files)
+ (setq listit kde-header-files)
+ (while (and listit (not ret)) ; loop over the list but stop once ret is set
+ (setq path (concat nname "." (car listit)))
+ ; look in current dir
+ (if (file-readable-p path)
+ (setq ret (cons path t)))
+ (if (not ret) ;check for header_p.h files
+ (progn (setq path (concat nname "_p." (car listit)))
+ (if (file-readable-p path)
+ (setq ret (cons path t)))))
+ (if (not (file-readable-p path))
+ (progn ; look in kde-include-directory
+ (setq path (kde-find-file (file-name-nondirectory path) kde-include-directory))
+ (if (and
+ path
+ (file-readable-p path))
+ (setq ret (cons path t))
+ ))
+ )
+ (setq listit (cdr listit)) ; ++listit
+ )
+ ; not found, will create one
+ (if (not ret)
+ (setq ret (cons (concat nname "." (car kde-header-files)) nil ))
+ ))
+ )
+ ret
+ ))
+
+(defun kde-switch-cpp-h ()
+ "Switches between the source and the header file
+(both directions)."
+ (interactive)
+ (let ((file (kde-file-get-cpp-h)))
+ (if (car file)
+ (find-file (car file))
+ (error "Corresponding source file doesn't exist.")
+ )
+ ))
+
+(defun kde-delete-backward-ws ()
+ "Function deletes all preceding whitespace characters."
+ (interactive)
+ (let ((start (point))
+ end)
+ (save-excursion
+ (setq end (re-search-backward "[^ \t]" (point-at-bol) t))
+ (if (not end)
+ (setq end (point-at-bol))
+ (setq end (1+ end))))
+ (delete-backward-char (- start end))))
+
+(defun kde-skip-blank-lines ()
+ "Skips backwards past blank lines, stopping
+at a first non-blank line"
+ (let* ((start (point-at-bol))
+ (end (point-at-eol))
+ (mstring (buffer-substring start end))
+ (ret 0))
+ (while (or
+ (string-match "^[ \t\r\n]+$" mstring)
+ (and (string= mstring "")
+ (= ret 0)))
+ (setq ret (forward-line -1)) ; if ret != 0, we stop, since we're at the first line...
+ (setq start (point-at-bol)
+ end (point-at-eol))
+ (setq mstring (buffer-substring start end))
+ )
+ ))
+
+(defun kde-comments-begin ()
+ "Skip back from current point past any preceding C-based comments at the beginning of lines.
+Presumes no \"/*\" strings are nested within multi-line comments."
+ (let ((opoint))
+ (while (progn (setq opoint (point))
+ ;; To previous line
+ (if (zerop (forward-line -1))
+ (cond
+ ;; If begins with "//" or ends with "*/", then is a
+ ;; comment.
+ ((looking-at "[ \t]*\\(//\\|$\\)"))
+ ((looking-at ".*\\*/[ \t]*$")
+ (progn (end-of-line)
+ ;; Avoid //*** single line comments here.
+ (if (re-search-backward "\\(^\\|[^/]\\)/\\*" nil t)
+ (progn (beginning-of-line)
+ (looking-at "[ \t]*/\\*")))))
+ (t nil)))))
+ (goto-char opoint)
+ ;; Skip past whitespace
+ (skip-chars-forward " \t\n\r\f")
+ (beginning-of-line)))
+
+(provide 'kde-emacs-general)
diff --git a/scripts/kde-emacs/kde-emacs-semantic.el b/scripts/kde-emacs/kde-emacs-semantic.el
new file mode 100644
index 00000000..1753520b
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-semantic.el
@@ -0,0 +1,456 @@
+;; kde-emacs-semantic.el
+;;
+;; Copyright (C) 2002 Zack Rusin <zack@kde.org>
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2.1 of the License, or (at your option) any later version.
+;;
+;; This library 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
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+
+;;; Commentary:
+;; Package provides four interactive functions:
+;; - kde-function-doc-insert - creates a skeleton doxygen
+;; documentation for function at point.
+;; Customize it with kde-func-doc variables.
+;;
+;; - kde-function-expanded-at-point - returns t if function at point
+;; has already been expanded.
+;;
+;; - kde-function-expand-at-point - expand (creates a stub) for function
+;; at point (as long as function is a prototype
+;; and haven't been expanded).
+;;
+;; - kde-create-skeletons - creates stubs for all methods in the current
+;; header file.
+;;
+;; Package is very flexible, look at defcustom variables for things
+;; you can customize.
+
+;;; Problems:
+;; Most problems relate to C++ syntax which isn't handled correctly
+;; by the Semantic package. For now templates aren't supported, I
+;; have a temporary solution for other problems (e.g. const functions,
+;; QT/KDE specific access specifiers)
+
+;;; Code:
+(require 'kde-emacs-vars)
+(require 'kde-emacs-general)
+
+;*---------------------------------------------------------------------*/
+;* User configuration ... */
+;*---------------------------------------------------------------------*/
+;;Not yet, not yet
+;(defcustom kde-summary-function 'semantic-uml-prototype-nonterminal
+; "*Function to use when showing info about the token"
+; :group 'kde-devel
+; :type semantic-token->text-custom-list
+; )
+
+(defcustom kde-generate-docs-with-stubs nil
+ "*Should function documentation be generated with the stubs."
+ :group 'kde-devel
+ :type 'boolean)
+
+(defcustom kde-expand-arg-start "( "
+ "*A string which specifies how the function arguments format should start.
+e.g. \"( \" would start function arguments list like : \"func( int arg\".
+and \" (\" will format the begining of the function argument list as
+follows : \"func (int arg\"."
+ :group 'kde-devel
+ :version "0.1"
+ :type 'string)
+
+(defcustom kde-expand-arg-end " )"
+ "*Just like kde-expand-arg-start but specifies how the list should end."
+ :group 'kde-devel
+ :version "0.1"
+ :type 'string)
+
+(defcustom kde-expand-arg-break ", "
+ "*Specifies how the arguments should be separated."
+ :group 'kde-devel
+ :version "0.1"
+ :type 'string)
+
+
+;*---------------------------------------------------------------------*/
+;* Functions ... */
+;*---------------------------------------------------------------------*/
+;; FIXME : semantic doesn't handle QT access specifiers
+;(setq-default global-semantic-show-unmatched-syntax-mode nil)
+;(setq-default global-semantic-show-dirty-mode nil)
+
+(defun kde-format-func-arg (arg)
+ "Formats one argument (from token to string)."
+ (let ((ret ""))
+ (if (semantic-token-variable-extra-spec arg 'const)
+ (setq ret "const "))
+ (setq ret (concat ret (car (semantic-token-type arg))))
+ (if (semantic-token-variable-extra-spec arg 'pointer)
+ (dotimes (idx (semantic-token-variable-extra-spec arg 'pointer))
+ (setq ret (concat ret "*"))
+ )
+ )
+ (if (semantic-token-variable-extra-spec arg 'reference)
+ (setq ret (concat ret "&"))
+ )
+ (setq ret (concat ret " " (semantic-token-name arg)))
+ ret
+ ))
+
+(defun kde-format-args (token)
+ "Formats all arguments from token to string.
+Token has to be the function variable list e.g.
+from semantic-token-function-args"
+ (let ((res kde-expand-arg-start) (idx 1))
+ (dolist (elt token res)
+ (setq res (concat res (kde-format-func-arg elt)))
+ (when (< idx (length token))
+ (setq res (concat res kde-expand-arg-break)))
+ (setq idx (1+ idx))
+ )
+ (setq res (concat res kde-expand-arg-end))
+ ;; if it's something like "( )" replace it with "()"
+ (when (string= res (concat kde-expand-arg-start kde-expand-arg-end))
+ (setq res (replace-regexp-in-string "([ \t]+)" "()" res)))
+ res
+ ))
+
+(defun kde-function-in-tokens (FUNC TOKENS)
+ "Search for function in tokens. FUNC has to be a function
+token and TOKENS have to be a list of functions from buffer."
+ (let ((ret)(elt))
+ (while (and TOKENS (not ret))
+ (setq elt (car TOKENS))
+ (setq TOKENS (cdr TOKENS))
+ (if (and (string= (semantic-token-name FUNC)
+ (semantic-token-name elt))
+ (equal (semantic-token-type FUNC)
+ (semantic-token-type elt))
+ ;; FIXME (semantic) : Functions in some classes don't have the
+ ;; 'parent property set !!!
+ ;;(string= (semantic-token-function-parent FUNC1)
+ ;; (semantic-token-function-parent FUNC2))
+ (string= (kde-format-args (semantic-token-function-args FUNC))
+ (kde-format-args (semantic-token-function-args elt))))
+ (setq ret t))
+ )
+ ret
+ ))
+
+(defmacro kde-label-signals (pt)
+ "Returns none-nil if the current access label == \"signals\""
+ `(save-excursion
+ (goto-char ,pt)
+ (if (looking-at ":")
+ (re-search-backward "signals" (point-at-bol) t)
+ )
+ ))
+
+(defun kde-label-namespace (pt)
+ "Return the namespace to which the variable/function at point PT belongs to."
+ (save-excursion
+ (goto-char pt)
+ (if (looking-at "::")
+ (let ((start) (end))
+ (re-search-backward "\\b\\w+" (point-at-bol) t)
+ (setq start (match-beginning 0))
+ (setq end (match-end 0))
+ (buffer-substring-no-properties start end)
+ )
+ )
+ ))
+
+(defmacro kde-label-slots (pt)
+ "Return none-nil if at PT there's slots access specifier."
+ `(save-excursion
+ (goto-char ,pt)
+ (if (looking-at ":")
+ ;; export this regex to a kde-emacs-vars defvar
+ (re-search-backward "\\(public\\|protected\\|private\\)[ \t]+slots" (point-at-bol) t))
+ ))
+
+(defmacro kde-is-constructor (function)
+ "Returns t if the FUNCTION is a constructor."
+ `(semantic-token-function-extra-spec ,function 'constructor)
+ )
+
+(defun kde-function-const (function)
+ "Returns t if the FUNCTION has been declared as const, e.g.
+if given a token representing \"int getInt() const\" this functions
+would return t"
+ (save-excursion
+ (let ((start (semantic-token-start function))
+ (end (semantic-token-end function)))
+ (goto-char end)
+ (if (re-search-backward "const\b*;" start t)
+ t
+ nil)
+ )
+ ))
+
+(defun kde-is-prototype (function)
+ "Returns t if the FUNCTION is only a prototype."
+ (cond
+ ((semantic-token-function-extra-spec function 'prototype)
+ t)
+ (t
+ (kde-function-const function))
+ ))
+
+
+
+(defun kde-function-at-point (pt)
+ "Return function at pt as a token."
+ (save-excursion
+ (let ((token)
+ (what (semantic-find-nonterminal-by-position pt (current-buffer)))
+ (ctx))
+ (goto-char pt)
+ (if (eq (semantic-token-token what) 'function)
+ what
+ (semantic-find-nonterminal-by-position pt (semantic-token-type-parts what)))
+ )
+ ))
+
+(defun kde-function-construct (token pclass)
+ "Constructs a function string from the TOKEN, with the parent class PCLASS."
+ (let ((fname (semantic-token-name token)))
+ (if (semantic-token-function-destructor token)
+ (setq fname (concat "~" fname))
+ )
+ (if pclass
+ (setq fname (concat pclass "::" fname))
+ )
+ (if (and
+ (not (kde-is-constructor token))
+ (not (semantic-token-function-destructor token)))
+ (progn
+ (cond
+ ((stringp (semantic-token-type token))
+ (setq fname (concat (semantic-token-type token) "\n" fname))
+ )
+ (t
+ (setq fname (concat (car (semantic-token-type token)) "\n" fname)))
+ )
+ (if (semantic-token-function-extra-spec token 'const)
+ (setq fname (concat "const " fname))
+ )
+ )
+ )
+ (setq fname (concat fname (kde-format-args (semantic-token-function-args token))))
+ (if (kde-function-const token)
+ (setq fname (concat fname " const" ))
+ )
+ (setq fname (concat fname "\n{" "\n}"))
+ fname
+ )
+ )
+
+(defun kde-class-expand (class-token)
+ "Returns stubs for member functions as a string.
+class-token has to be a token representing either a class or a struct."
+ (let ((ret "")
+ (name (semantic-token-name class-token))
+ (parents (semantic-token-type-parent class-token))
+ (parts (semantic-token-type-parts class-token))
+ (cur-token)
+ (cur-token-name)
+ (asignal)
+ (aslot)
+ (namespace)
+ )
+ (dolist (elt parts ret)
+ (setq cur-token (semantic-token-token elt))
+ (setq cur-token-name (semantic-token-name elt))
+ (cond
+ ((and
+ (eq cur-token 'type)
+ (stringp cur-token-name))
+ (cond
+ ((string= cur-token-name "class")
+ (kde-class-expand elt)
+ )
+ ((string= cur-token-name "enum")
+ ;;skip enums
+ )
+ ((string= cur-token-name "struct")
+ (kde-class-expand elt)
+ )
+ )
+ )
+ ((and
+ (eq cur-token 'function)
+ (stringp cur-token-name))
+ ;;FUNCTION - generate a skeleton for it
+ (if (and (kde-is-prototype elt)
+ (not asignal))
+ (setq ret (concat ret (kde-function-construct elt name) "\n\n"))
+ )
+ ;(insert (kde-function-documentation elt) "\n")
+ )
+ ((and
+ (eq cur-token 'label)
+ (stringp cur-token-name))
+ (setq aslot nil
+ asignal nil)
+ ;;LABEL - unsets both signals and slots
+ )
+ ((and
+ (eq cur-token 'variable)
+ cur-token-name)
+ ;;VARIABLE - doesn't handle static variables correctly right now
+ )
+ ((not (stringp cur-token-name))
+ (cond
+ ((kde-label-signals (car (semantic-token-extent elt)))
+ ;;SIGNALS - next prototypes belong to signals and we don't want to
+ ;; expand those
+ (setq asignal t
+ aslot nil)
+ )
+ ((kde-label-namespace (car (semantic-token-extent elt)))
+ ;;NAMESPACE - semantic doesn't handle things like Qt::ButtonState correctly
+ ;; so we do ;)
+ (setq namespace (kde-label-namespace (car (semantic-token-extent elt))))
+ )
+ ((kde-label-slots (car (semantic-token-extent elt)))
+ ;;SLOTS - for now just unset signals
+ (setq aslot t
+ asignal nil)
+ )
+ (t
+ (insert "something else at " (number-to-string (car (semantic-token-extent elt))) "\n"))
+ ))
+ (t
+ (insert "Unknown type :: " (prin1-to-string elt) " >>" (prin1-to-string cur-token) "\n"))
+ )
+ )
+ ret
+ )
+ )
+
+(defun kde-expand-tokens (tokens)
+ "Expands smenatic tokens to strings."
+ (let ((ret ""))
+ (dolist (elt tokens ret)
+ (cond
+ ((eq (semantic-token-token elt) 'type)
+ (setq ret (concat ret (kde-class-expand elt)))
+ )
+ ((eq (semantic-token-token elt) 'function)
+ (if (kde-is-prototype elt)
+ (setq ret (concat ret (kde-function-construct elt nil) "\n\n"))
+ )
+ )
+ ((eq (semantic-token-token elt) 'variable)
+ ;; skip
+ ;;(kde-extract-variable elt)
+ )
+ ((eq (semantic-token-token elt) 'include)
+ ;;ignore includes for now
+ )
+ (t (insert "Unknown type : " (prin1-to-string (semantic-token-type elt)) "\n"))
+ )
+ )
+ )
+ )
+
+
+(defun kde-tokens-in-file (FILENAME)
+ "Returns all tokens from a file with the FILENAME."
+ (let ((exists (file-readable-p FILENAME))
+ (buf (current-buffer))
+ (tokens))
+ (if exists
+ (progn
+ (find-file FILENAME)
+ (setq tokens (semantic-bovinate-toplevel t))
+ (switch-to-buffer buf)
+ tokens)
+ nil)
+ ))
+
+(defun kde-function-in-file (FUNC FILENAME)
+ "Returns non-nil if FUNC is in a file named FILENAME"
+ (let ((tokens (kde-tokens-in-file FILENAME)))
+ (if tokens
+ (kde-function-in-tokens FUNC tokens)
+ nil
+ )
+ ))
+
+(defun kde-function-is-expanded (FUNC)
+ "Returns t if the function FUNC has been expanded."
+ (let ((file (kde-file-get-cpp-h)))
+ (if (cdr file)
+ (if (kde-function-in-file FUNC (car file))
+ t
+ nil
+ )
+ nil)
+ ))
+
+(defun kde-function-expanded-at-point (PT)
+ "Returns non-nil if the function at point PT has already been expanded."
+ (interactive "d")
+ (let ((func (kde-function-at-point PT)))
+ (kde-function-is-expanded func)
+ )
+ )
+
+(defun kde-create-skeletons ()
+ "Creates functions stubs in the source file, for all functions
+in the current header file."
+ (interactive)
+ (let* ((all-tokens (semantic-bovinate-toplevel t))
+ (filename (buffer-name))
+ (cppfile (car (kde-file-get-cpp-h)))
+ (funcs (kde-expand-tokens all-tokens)))
+ (find-file cppfile)
+ (save-excursion
+ (insert "#include \"" filename "\"\n\n")
+ (insert funcs)
+ )
+ )
+ )
+
+(defun kde-function-expand-at-point (PT)
+ "Expand function at point PT."
+ (interactive "d")
+ (let ((object (semantic-find-nonterminal-by-position PT (current-buffer)))
+ (func (kde-function-at-point PT))
+ (file)
+ (buf)
+ (parent))
+ (if (and object (equal (semantic-token-type object) "class"))
+ (setq parent (semantic-token-name object)))
+ (if (and (not (kde-function-expanded-at-point PT))
+ (kde-is-prototype func))
+ (progn
+ (setq func (kde-function-construct func parent))
+ (setq file (car (kde-file-get-cpp-h)))
+ (setq buf (current-buffer))
+ (find-file file)
+ (save-excursion
+ (goto-char (point-max))
+ (insert "\n" func "\n")
+ )
+ (switch-to-buffer buf)
+ )
+ (error "Function already expanded or defined!")
+ )
+ )
+ )
+
+(provide 'kde-emacs-semantic)
diff --git a/scripts/kde-emacs/kde-emacs-tips.texi b/scripts/kde-emacs/kde-emacs-tips.texi
new file mode 100644
index 00000000..ee7c0f19
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-tips.texi
@@ -0,0 +1,257 @@
+\input texinfo @c -*-texinfo-*-
+
+@finalout
+
+@c %**start of header
+@setfilename kde-emacs-tips
+@settitle KDE Emacs usefull programming tips
+@footnotestyle end
+@c @setchapternewpage odd !! we don't want blank pages
+@c %**end of header
+
+@dircategory Emacs
+@direntry
+* KDE Emacs: (kde-emacs). Emacs mode for editing KDE/QT C++/C code.
+@end direntry
+
+@ifnottex
+Copyright @copyright{} 2002 Zack Rusin and KDE Development Team
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``The GNU Manifesto'', ``Distribution'' and
+``GNU GENERAL PUBLIC LICENSE'', with the Front-Cover texts being ``A GNU
+Manual'', and with the Back-Cover Texts as in (a) below. A copy of the
+license is included in the section entitled ``GNU Free Documentation
+License'' in the Emacs manual.
+
+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+this GNU Manual, like GNU software. Copies published by the Free
+Software Foundation raise funds for GNU development.''
+
+This document is part of a collection distributed under the GNU Free
+Documentation License. If you want to distribute this document
+separately from the collection, you can do so by adding a copy of the
+license to the document, as described in section 6 of the license.
+@end ifnottex
+
+@titlepage
+@sp 10
+
+@center @titlefont{KDE Emacs Package}
+@sp 2
+@center @subtitlefont{KDE Emacs package documentation and programming tips.}
+@sp 2
+@author Zack Rusin
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 2002 Zack Rusin & KDE Development Team
+@sp 1
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``The GNU Manifesto'', ``Distribution'' and
+``GNU GENERAL PUBLIC LICENSE'', with the Front-Cover texts being ``A GNU
+Manual'', and with the Back-Cover Texts as in (a) below. A copy of the
+license is included in the section entitled ``GNU Free Documentation
+License'' in the Emacs manual.
+
+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
+this GNU Manual, like GNU software. Copies published by the Free
+Software Foundation raise funds for GNU development.''
+
+This document is part of a collection distributed under the GNU Free
+Documentation License. If you want to distribute this document
+separately from the collection, you can do so by adding a copy of the
+license to the document, as described in section 6 of the license.
+@end titlepage
+
+@node Top, Introduction, (dir), (dir)
+@comment node-name, next, previous, up
+
+@macro kdeemacs
+KDE Emacs
+@end macro
+
+@ifinfo
+@top @kdeemacs{}
+
+@kdeemacs{} is an Emacs package with tons of useful features
+which ease KDE development process.
+KDE Emacs usefull programming tips.
+
+@end ifinfo
+
+@menu
+* Introduction::
+* Getting Connected::
+* Generating stubs::
+* Tips::
+@end menu
+
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+@node Introduction, Getting Connected, Top, Top
+@comment node-name, next, previous, up
+@chapter Introduction
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+@node Getting Connected, Generating stubs, Introduction, Top
+@comment node-name, next, previous, up
+@chapter Getting Connected
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+@menu
+* Sect. 2.1:: Installation
+* Sect. 2.2:: Files
+* Sect. 2.3:: Keybindings
+@end menu
+
+@node Sect. 2.1, Sect. 2.2, Chapter 2, Chapter 2
+@section @code{Installation}
+@comment node-name, next, previous, up
+
+@node Sect. 2.2, Sect. 2.3, Sect. 2.1, Chapter 2
+@section @code{Files}
+@comment node-name, next, previous, up
+
+@node Sect. 2.3, , Sect 2.2, Chapter 2
+@section @code{Keybindings}
+@comment node-name, next, previous, up
+
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+@node Generating stubs , Tips, Getting Connected, Top
+@comment node-name, next, previous, up
+@chapter Generating stubs
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+@node Tips, Top, Generating stubs, Top
+@comment node-name, next, previous, up
+@chapter Tips
+@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+@sp 1
+@strong{Q.} @emph{How do I hide #ifdef's in source files without
+actually changing them?}
+
+@strong{A.} Use @code{hide-ifdef-mode} which supports hiding of ifdef
+blocks without actually changing the file. In this mode @kbd{C-c @@
+C-d} hides ifdef block and @kbd{C-c @@ C-s} shows it again.
+
+@sp 1
+@strong{Q.} @emph{How do I get more informations about the keybindings
+of the currently active modes?}
+
+@strong{A.} Type @kbd{M-x describe-mode}.
+
+@sp 1
+@strong{Q.} @emph{How do I get automatic syntax higlighting of my
+custom types?}
+
+@strong{A.} Use a package named @file{ctypes.el} which does exactly
+that.
+
+@sp 1
+@strong{Q.} @emph{Is it possible to highlight dangerous syntax, just
+like Borland JBuilder does it?}
+
+@strong{A.} Yes, use the @file{cwarn.el} package.
+
+@sp 1
+@strong{Q.} @emph{How do I easily customize Emacs faces/colors?}
+
+@strong{A.} Use the @file{color-theme.el} package.
+
+@sp 1
+@strong{Q.} @emph{How do I set the taskbar Emacs identification string?}
+
+@strong{A.} To your @file{.emacs} add a line like:
+@example
+(setq frame-title-format "%b (%m)")
+@end example
+which will display ``filename (mode)'' type of string in the
+taskbar. Type @kbd{C-h v frame-title-format} to get more info.
+
+@sp 1
+@strong{Q.} @emph{Can I make Emacs jump to the matching parenthesis
+with @kbd{%} just like vi?}
+
+@strong{A.} Yes, just add to your @file{.emacs} something like:
+@example
+;; Make the % key jump to the matching {}[]() if on another, like VI
+(global-set-key "%" 'match-paren)
+
+(defun match-paren (arg)
+ "Go to the matching parenthesis if on parenthesis otherwise insert %."
+ (interactive "p")
+ (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
+ ((looking-at "\\s\)") (forward-char 1) (backward-list 1))
+ (t (self-insert-command (or arg 1)))))
+@end example
+
+@sp 1
+@strong{Q.} @emph{Can I have words like FIXME, TODO, HACK or NOTE
+higlighted in documentation strings?}
+
+@strong{A.} Yes, either use @file{code-keywords.el} package or wait
+till I'll add it to @kdeemacs{}.
+
+@sp 1
+@strong{Q.} @emph{I really, really hate identifiersNamedLikeThis. I'd
+like to change them to identifiers_named_like_this but the
+maintainer of the application/library that I'm hacking on doesn't
+agree with me. What can I do? }
+
+@strong{A.} Use the @file{glasses.el} package which changes
+identifiersNamedLikeThis to identifiers_named_like_this in the
+buffers you're editing and switches them back to their original form
+once you save those buffers.
+
+@sp 1
+@strong{Q.} @emph{Is it possible to get function completion or
+signature display in Emacs? Will it ever be done?}
+
+@strong{A.} Yes and yes. I've been planning on doing this for quite a
+while and hopefully will have this finished pretty soon (no dates
+though :) ) The first thing that should be done is writing a few
+fixes for the Semantic package (@file{c.bnf} to be more exact),
+because Semantic doesn't handle templates, member function declared
+as const or KDE access specifiers, once this is done all that will be
+left is using semanticdb package which efficiently stores and retrieves
+large amounts of tokens and then displaying tokens belonging to types at
+point which match current context.
+
+@sp 1
+@strong{Q.} @emph{Is there a package that would highlight changes that
+I made to a certain file?}
+
+@strong{A.} I wouldn't be writing this if there wouldn't - try
+@kbd{M-x highlight-changes-mode}.
+
+@sp 1
+@strong{Q.} @emph{How to get a diff between the stuff I have in my
+local buffer and the file on disk?}
+
+@strong{A.} Use ibuffer package. After @kbd{M-x ibuffer} typing
+@kbd{=} over a file will display a diff between the buffer and the
+file on the disk.
+
+@sp 1
+@strong{Q.} @emph{I want to temporarily highlight certain variable in
+a file, how to do it?}
+
+@strong{A.} Type @kbd{M-x hi-lock-mode}, now @kbd{C-x w h
+@emph{regexp} @key{RET} @emph{face} @key{RET}} highlights regexp with
+face in the current file and @kbd{C-x w r @emph{regexp} @key{RET}}
+unhighlights it.
+
+@node Concept Index, , Variables Index, Top
+@c node-name, next, previous, up
+@unnumbered Concept Index
+
+@printindex cp
+
+@contents
+@bye
diff --git a/scripts/kde-emacs/kde-emacs-utils.el b/scripts/kde-emacs/kde-emacs-utils.el
new file mode 100644
index 00000000..c6904539
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-utils.el
@@ -0,0 +1,894 @@
+;; kde-emacs-utils.el
+;;
+;; Copyright (C) 2002-2005 KDE Development Team <www.kde.org>
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2.1 of the License, or (at your option) any later version.
+;;
+;; This library 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
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+
+
+(require 'kde-emacs-vars)
+(require 'kde-emacs-general)
+(require 'kde-emacs-compat)
+
+(if (eq kde-emacs-type 'xemacs)
+ (progn
+ (require 'func-menu)
+ (add-hook 'find-file-hooks 'fume-add-menubar-entry))
+ (require 'imenu))
+
+(defmacro c-safe-scan-lists (from count depth)
+ "Like `scan-lists' but returns nil instead of signalling errors.
+This function does not do any hidden buffer changes."
+ (if (featurep 'xemacs)
+ `(scan-lists ,from ,count ,depth nil t)
+ `(c-safe (scan-lists ,from ,count ,depth))))
+
+;; returns non-nil if the given file has a using declaration
+;; with the passed namespace
+(defun kde-file-has-using (namespace)
+ (let (found)
+ (save-excursion
+ (beginning-of-buffer)
+ (setq found (re-search-forward "^using" nil 1))
+ (if found
+ (setq found (search-forward namespace (line-end-position) 1))
+ )
+ )
+ found)
+ )
+
+;; returns non-nill if the given file has a "namespace SomeNM" declaration
+;; where SomeNM is passed via the namespace argument
+(defun kde-file-is-in-namespace (namespace)
+ (let (found)
+ (save-excursion
+ (beginning-of-buffer)
+ (setq found (re-search-forward "^namespace" nil 1))
+ (if found
+ (setq found (search-forward namespace (line-end-position) 1))
+ )
+ )
+ found)
+ )
+
+; Helper function for parsing our current position in a C++ header file
+; returns (namespace (class function)) where (a b) is a cons.
+(defun method-under-point ()
+ (let ((class nil)
+ (namespace "") ; will contain A::B::
+ (function nil))
+ (save-excursion
+ (backward-char) ; in case we're after the ';'
+ (search-forward ";" nil t) ; look for the ';'
+ (backward-char)
+ (save-excursion
+ ; Go up a level, skipping entire classes etc.
+ ; This is a modified version of (backward-up-list) which doesn't
+ ; throw an error when not found.
+ (let ((pos (c-safe-scan-lists (point) -1 1)))
+ ; +1 added here so that the regexp in the while matches the { too.
+ (goto-char (if pos (+ pos 1) (point-min))))
+ (while (re-search-backward "^[ ]*\\(class\\|namespace\\|struct\\)[ \t][^};]*{" nil t)
+ (save-excursion
+ (forward-word 1)
+ (when (looking-at "[ \t]*[A-Z_]*_EXPORT[A-Z_]*[ \t]")
+ (forward-word 1)
+ (re-search-forward "[ \t]" nil t))
+ (while (looking-at "[ \t]")
+ (forward-char 1))
+ (setq start (point))
+ ; Parse class name ("Foo" or "Foo::Bar::Blah").
+ ; Beware of "Foo:"
+ (while (or (looking-at "[A-Za-z0-9_]") (looking-at "::"))
+ (while (looking-at "[A-Za-z0-9_]")
+ (forward-char 1))
+ (while (looking-at "::")
+ (forward-char 2))
+ )
+ (cond
+ (class ; class found already, so the rest goes into the namespace
+ (setq namespace (concat (buffer-substring start (point)) "::" namespace)))
+ (t ; class==nil
+ (setq class (buffer-substring start (point)))))
+ )
+ ; Go up one level again
+ (let ((pos (c-safe-scan-lists (point) -1 1)))
+ (goto-char (if pos (+ pos 1) (point-min))))
+ ))
+
+ ; Back to where we were, parse function name
+ (let ((end (point))) ; remember where the function decl ends
+ (search-backward ")" nil t) ; look back for the end of the argument list
+ (forward-char)
+ (backward-sexp) ; brings us back to the '('
+ (backward-word 1)
+ (when (looking-at "throw[ \t]") ; exception specification, look for () again
+ (search-backward ")" nil t)
+ (forward-char)
+ (backward-sexp))
+ ; now that we moved back enough, go to beginning of line.
+ ; (we assume that the return type, function name, and '(' are on the same line)
+ (re-search-backward "^[ \t]*")
+ (while (looking-at "[ \t]")
+ (forward-char 1))
+ (setq function (buffer-substring (point) end))
+ )
+ ) ; end of global save-excursion
+ (cons namespace (cons class function)) ; the returned value
+ )
+ )
+
+; get rid of virtual, static, multiple spaces, default values.
+(defun canonical-function-sig (function)
+ (and (string-match "[ \t]*\\<virtual\\>[ \t]*" function)
+ (setq function (replace-match " " t t function)))
+ (and (string-match "^\\(virtual\\>\\)?[ \t]*" function)
+ (setq function (replace-match "" t t function)))
+ (and (string-match "^\\(explicit\\>\\)?[ \t]*" function)
+ (setq function (replace-match "" t t function)))
+ (and (string-match "^\\(static\\>\\)?[ \t]*" function)
+ (setq function (replace-match "" t t function)))
+ (while (string-match " +" function) ; simplifyWhiteSpace
+ (setq function (replace-match " " t t function)))
+ (while (string-match "\t+" function)
+ (setq function (replace-match " " t t function)))
+ (while (string-match "^ " function) ; remove leading whitespace
+ (setq function (replace-match "" t t function)))
+ (let ((startargs (string-match "(" function)))
+ (while (string-match " ?=[^,)]+" function startargs) ; remove default values
+ (setq function (replace-match " " t t function))))
+ (while (string-match " +," function) ; remove space before commas
+ (setq function (replace-match "," t t function)))
+ function ; the return value
+)
+
+; Helper method which turns the function as seen in the header
+; into the signature for its implementation
+; Returns the fully-qualified signature of the function implementation
+(defun kde-function-impl-sig (namespace class _function)
+ (let (
+ (function (canonical-function-sig _function))
+ (insertion-string nil))
+ (and (stringp class)
+ (cond
+ ((string-match (concat "^ *" class "[ \\t]*(") function) ; constructor
+ (setq insertion-string
+ (replace-match
+ (concat namespace class "::" class "(")
+ t t function)
+ ))
+ ((string-match (concat "^ *~" class "[ \\t]*(") function) ; destructor
+ (setq insertion-string
+ (replace-match
+ (concat namespace class "::~" class "(")
+ t t function)
+ ))
+ )) ; end of "class required"
+ (if (not (stringp insertion-string)) ; no ctor nor dtor
+ (if (or (string-match " *\\([a-zA-Z0-9_]+\\)[ \\t]*(" function) ; normal method
+ (string-match " *\\(operator[^ \\t]+\\)[ \\t]*(" function)) ; operator
+ (setq insertion-string
+ (replace-match
+ (if class
+ (concat " " namespace class "::" "\\1(") ; c++ method
+ (concat " " "\\1(")) ; c function
+ t nil function)
+ )
+ ; else
+ (error (concat "Can't parse declaration ``"
+ function "'' in class ``" class
+ "'', aborting"))))
+ insertion-string ; the return value
+ )
+ )
+
+;; Switch between the declaration of a class member in .cc/.cpp/.C, and its definition in the .h file
+;; Written by David and Reggie after much hair tearing
+;; Found since, might be worth looking at: http://www.hendawi.com/emacs/sourcepair.el
+(defun switch-to-function-def ()
+ (interactive)
+ (let ((n (buffer-file-name))
+ (namespace "")
+ (class "")
+ (function "")
+ found
+ )
+ (if (or (string-match "\\.cc$" n)
+ (string-match "\\.cpp$" n)
+ (string-match "\\.C$" n))
+ ; TODO replace fume-function-before-point, needed for emacs,
+ ; and for better namespace support.
+ ;(progn
+ ; (let ((pos (kde-scan-lists (point) -1 1 nil t))) ; Go up a level
+ ; (goto-char (if pos (+ pos 1) (point-min))))
+ (let ((a (fume-function-before-point)))
+ (and (string-match "^\\(.*\\)::\\(.*\\)$" a)
+ (progn
+ (setq class (match-string 1 a))
+ (setq function (match-string 2 a))
+ (kde-switch-cpp-h)
+ (goto-char 0)
+ ; Look for beginning of class ("\\s-+" means whitespace including newlines)
+ (re-search-forward
+ (concat "\\(class\\|struct\\|namespace\\)\\s-+"
+ "\\([A-Z_]+_EXPORT[A-Z_]*\\)?\\s-+" ; allow for optional EXPORT macro
+ class "\\b" ; the classname - with word separator
+ "[^;]+{" ; the optional inheritance and the '{'
+ ) nil t)
+ ;; TODO keep looking, until we find a match that's not inside a comment
+ (re-search-forward (concat "\\b" (kde-function-regexp-quote function) "[ \t]*(") nil t)))))
+ (if (string-match "\\.h$" n)
+ (progn
+ (let ((mup (method-under-point))
+ (sig "")
+ (pos 0))
+ (setq namespace (car mup))
+ (setq class (car (cdr mup)))
+ (setq function (cdr (cdr mup)))
+ (kde-switch-cpp-h)
+
+ ;; First search with namespace prefixed
+ (goto-char 0)
+ (setq sig (kde-remove-newline (kde-function-impl-sig namespace class function)))
+ (if (string-match "(.*" sig) ; remove args
+ (setq sig (replace-match "" nil t sig)))
+ (setq found (re-search-forward (concat "^[^()]*" (kde-function-regexp-quote sig) "[ \t]*(") nil t) )
+
+ (if (not found)
+ (progn
+ ; Now search without name space prefix
+
+ (goto-char 0)
+ (setq sig (kde-remove-newline (kde-function-impl-sig "" class function)))
+
+ (if (string-match "(.*" sig) ; remove args
+ (setq sig (replace-match "" nil t sig)))
+ (re-search-forward (concat "^[^()]*" (kde-function-regexp-quote sig) "[ \t]*(") nil t) ) )
+ )))))
+
+(defun kde-remove-newline (str)
+ (replace-in-string str "\n" " "))
+; quote for use as regexp, but replace spaces with "any whitespace"
+(defun kde-function-regexp-quote (str)
+ (replace-in-string (regexp-quote str) "[ \n\t]" "[ \n\t]"))
+
+; Initial implementation by Arnt Gulbransen
+; Current maintainer: David Faure
+(defun agulbra-make-member ()
+ "make a skeleton member function in the .cpp or .cc file"
+ (interactive)
+ (let* (
+ (mup (method-under-point))
+ (namespace (car mup)) ; will contain A::B::
+ (class (car (cdr mup)))
+ (function (cdr (cdr mup)))
+ (file (buffer-file-name))
+ (insertion-string (kde-function-impl-sig namespace class function))
+ (msubstr nil)
+ (start nil)
+ (newcppfile nil)
+ )
+ (setq insertion-string
+ (concat insertion-string "\n{\n"
+ (replace-in-string kde-make-member-default-impl "FUNCTION"
+ ; the function name and args, without newlines
+ (replace-in-string insertion-string "\n" " " t)
+ t)
+ "}\n"))
+ ; move to next method, to be ready for next call
+ (backward-char) ; in case we're after the ';'
+ (re-search-forward ";" nil t) ; end of this method decl
+ (let ((moveToNext t))
+ (while moveToNext
+ (re-search-forward ";" nil t) ; end of next method decl
+ (save-excursion
+ (forward-char -2) ; -1 goes to ';' itself, so go before that
+ (while (looking-at "[ \t0=]")
+ (forward-char -1))
+ (forward-char 1)
+ ; move to next method again if we're at a pure virtual method
+ (setq moveToNext (looking-at "[ \t]*=[ \t]*0;"))
+ )
+ )
+ )
+
+ (setq newcppfile (not (cdr (kde-file-get-cpp-h))))
+ (if (string-match "\\.h$" file)
+ (kde-switch-cpp-h)
+ )
+ (goto-char (point-max))
+ (kde-comments-begin)
+ (kde-skip-blank-lines)
+ (setq msubstr (buffer-substring (point-at-bol) (point-at-eol)))
+ (if (string-match "^#include.*moc.*" msubstr)
+ (progn
+ (forward-line -1)
+ (end-of-line)
+ (insert "\n")))
+ (if (string-match "}" msubstr)
+ (progn
+ (end-of-line)
+ (insert "\n")
+ (forward-line 1)
+ ))
+ (when newcppfile
+ (insert "\n"))
+ (insert insertion-string)
+ (forward-char -3)
+ (c-indent-defun)
+ (save-excursion
+ (and (string-match ".*/" file)
+ (setq file (replace-match "" t nil file)))
+ (and (string-match "\\.h$" file)
+ (functionp 'kdab-insert-include-file)
+ (kdab-insert-include-file file 't nil)))
+ (when (featurep 'fume-rescan-buffer)
+ (fume-rescan-buffer))
+ ))
+
+(defun add-file-to-buildsystem ()
+ "Add the current (C++) file to either Makefile.am or a .pro file, whichever exists."
+ ; Author: David
+ (interactive)
+ (if (file-readable-p "Makefile.am")
+ (add-file-to-makefile-am)
+ ; else: find a .pro file and add it there
+ (let* ((files (directory-files "." nil ".pro$" nil t))
+ (projfile (car files)))
+ (if projfile
+ (add-file-to-project projfile "^SOURCES[ \t]*") ; could be SOURCES= or SOURCES+=
+ ; else: error
+ (error "No build system file found")
+ )))
+ )
+
+; internal helper for add-file-to-*
+(defun add-file-to-project (makefile searchString)
+ (let ((file (buffer-name)))
+ (if (not (file-readable-p makefile))
+ (error (concat makefile " not found!"))
+ )
+ (find-file makefile)
+ (goto-char (point-min))
+ (if (re-search-forward searchString nil t)
+ (progn
+ (end-of-line)
+ ; check if line ends with '\' [had to read make-mode.el to find this one!]
+ (while (= (char-before) ?\\)
+ (end-of-line 2)) ; moves to end of next line
+ (insert " ")
+ (insert file)
+ )
+ (error (concat searchString " not found"))
+ ))
+ )
+
+(defun add-file-to-makefile-am ()
+ "Add the current file to the first _SOURCES line in the Makefile.am"
+ ; Author: David
+ (interactive)
+ (add-file-to-project "Makefile.am" "_SOURCES")
+ )
+
+
+; Inserts a kdDebug statement showing the name of the current method.
+; You need to create the empty line first.
+(defun insert-kdDebug ()
+ (interactive)
+ (insert "kdDebug() << ")
+ ;; no unnecessary fume-* functions which aren't available on GNU/Emacs
+ (insert "k_funcinfo")
+ (insert " << endl;")
+ )
+
+; finds a string to be used in the header-protection function ( see below )
+(defun kde-header-protection-definable-string ()
+ (let* ((definablestring "")
+ (f (buffer-file-name))
+ (parts (nreverse (split-string f "/")))
+ (i)
+ (first-iter t)
+ (iters (min (length parts) kde-header-protection-parts-to-show)))
+ (dotimes (i iters)
+ (let ((part (pop parts)))
+ (setq definablestring
+ (concat
+ (upcase (replace-in-string part "[\\.-]" "_"))
+ (if (not first-iter) "_" "")
+ definablestring
+ )
+ )
+ (setq first-iter nil)
+ )
+ )
+ definablestring
+ )
+ )
+
+; Creates the ifndef/define/endif statements necessary for a header file
+(defun header-protection ()
+ (interactive)
+ (let ((s (kde-header-protection-definable-string)))
+ (save-excursion
+ (goto-char (point-min))
+ (insert "#ifndef " s "\n#define " s "\n\n")
+ (goto-char (point-max))
+ (insert "\n#endif\n")
+ )
+ )
+ )
+
+; Makes '(' insert '(' or ' ( ' where appropiate
+(defun insert-parens (arg) (interactive "*P")
+ (if (not (c-in-literal))
+ (let ((n nil) (except nil))
+ (save-excursion
+ (setq n (or (progn (forward-char -2) (looking-at "if"))
+ (progn (forward-char -1) (looking-at "for"))
+ (progn (forward-char -1) (looking-at "case"))
+ (progn (forward-char -1) (looking-at "while"))
+ )
+ )
+ (setq except (or (progn (forward-char -2) (looking-at "kdDebug"))
+ (looking-at "kdError")
+ (progn (forward-char -2) (looking-at "kdWarning"))
+ )
+ )
+ )
+ (cond
+ (n (progn
+ (insert " ")
+ (self-insert-command (prefix-numeric-value arg))
+ (insert kde-emacs-after-parent-string)
+ ))
+ (t ;else
+ (self-insert-command (prefix-numeric-value arg))
+ (cond ((not except) (insert kde-emacs-after-parent-string)))
+ )))
+ (self-insert-command (prefix-numeric-value arg)))
+ )
+
+(defun insert-parens2 (arg) (interactive "*P")
+ (if (not (c-in-literal))
+ (let ((remv nil) (nospac nil))
+ (forward-char -2)
+ (setq remv (looking-at "( ")) ; () -> we'll have to remove that space
+ (forward-char 1)
+ (setq nospac ; no space to be added
+ (or (looking-at " ")
+ (looking-at "(")
+ (save-excursion ; check for kdDebug(123
+ (while (looking-at "[0-9]")
+ (forward-char -1))
+ (forward-char -7)
+ (or (looking-at "kdDebug(")
+ (looking-at "kdError(")
+ (progn (forward-char -2) (looking-at "kdWarning("))
+ )
+ )
+ )
+ )
+ (forward-char 1)
+ (cond
+ (remv (progn
+ (delete-backward-char 1)
+ (self-insert-command (prefix-numeric-value arg)))) ; the () case
+ (nospac (self-insert-command (prefix-numeric-value arg))) ; no space to be added
+ (t ;else
+ (if abbrev-mode ; XEmacs
+ (expand-abbrev))
+ (insert kde-emacs-after-parent-string)
+ (self-insert-command (prefix-numeric-value arg))
+ ))) ; normal case, prepend a space
+ ;;(blink-matching-open) ; show the matching parens
+ (self-insert-command (prefix-numeric-value arg)))
+ )
+
+; Makes ',' insert ', '
+(defun insert-comma (arg)
+ (interactive "*P")
+ (let* ((ch (char-after))
+ (spacep (not (or (eq ch ? )
+ (c-in-literal)
+ arg))))
+ (self-insert-command (prefix-numeric-value arg))
+ (if spacep
+ (insert " "))))
+
+(defun insert-semicolon (arg)
+ (interactive "*P")
+ (self-insert-command (prefix-numeric-value arg))
+ (newline-and-indent))
+
+(defun insert-curly-brace (arg) (interactive "*P")
+ (if (not (c-in-literal))
+ (let ((n nil) (o nil)
+ (spacep nil) (c nil)
+ (oneliner nil))
+ (save-excursion
+ (save-excursion
+ (if (re-search-forward "[a-zA-Z]" (point-at-eol) t)
+ (setq oneliner t)))
+ (forward-char -1) ; These three lines are for the situation where
+ (if (not (looking-at " ")) ; the user already have inserted a space after
+ (forward-char 1) ; the closing parenthesis
+ (setq spacep t))
+ (forward-char -2)
+ (setq o (looking-at "()"))
+ (forward-char 1)
+ (setq n (looking-at ")"))
+ (if (and
+ (not oneliner)
+ (not (eq
+ (count-lines (point-min) (point))
+ (count-lines (point-min) (point-max)))))
+ (progn
+ (next-line 1)
+ (beginning-of-line)
+ (if (re-search-forward "[a-zA-Z]" (point-at-eol) t)
+ (setq c (eq (car (car (c-guess-basic-syntax))) 'substatement)))
+ )
+ )
+ )
+ (cond
+ (n (progn
+ (if (not spacep) (insert " "))
+ (self-insert-command (prefix-numeric-value arg))
+ (if (not c) (newline-and-indent))
+ (if oneliner (end-of-line))
+ (save-excursion
+ (if c
+ (progn
+ (next-line 1)
+ (end-of-line)
+ ))
+ (newline-and-indent)
+ (insert "}")(c-indent-line))
+ (c-indent-line)
+ ))
+ (o (progn
+ (newline)
+ (self-insert-command (prefix-numeric-value arg))
+ (newline-and-indent)))
+ (t (progn ;else
+ (self-insert-command (prefix-numeric-value arg))
+ (save-excursion
+ (beginning-of-line)
+ (c-indent-command))))
+ ))
+ (self-insert-command (prefix-numeric-value arg))
+ )
+)
+
+;; have PelDel mode work
+(put 'insert-parens 'pending-delete t)
+(put 'insert-parens2 'pending-delete t)
+(put 'insert-comma 'pending-delete t)
+(put 'insert-curly-brace 'pending-delete t)
+(put 'newline-and-indent 'pending-delete t)
+
+; A wheel mouse that doesn't beep, unlike mwheel-install
+(defun scroll-me-up () (interactive) (scroll-up 4))
+(defun scroll-me-down () (interactive) (scroll-down 4))
+(defun scroll-me-up-a-bit () (interactive) (scroll-up 1))
+(defun scroll-me-down-a-bit () (interactive) (scroll-down 1))
+
+; Compilation
+(defun makeclean ()
+ "Executes a \"make clean\" in the current directory"
+ (interactive)
+ (compile (concat kde-emacs-make " clean"))
+ )
+
+(defun make ()
+ "Executes a \"make\" in the current directory"
+ (interactive)
+ (compile (concat kde-emacs-make " -k"))
+ )
+
+(defun makeinstall ()
+ "Executes a \"make install\" in the current directory"
+ (interactive)
+ (compile (concat kde-emacs-make " -k install"))
+ )
+
+(defun makeinstallexec ()
+ "Executes a \"make install-exec\" in the current directory"
+ (interactive)
+ (compile (concat kde-emacs-make " -k install-exec"))
+ )
+
+(defun makethisfile ()
+ "Try to compile the currently opened file"
+ (interactive)
+ (let ((f (file-name-nondirectory (buffer-file-name)))
+ (objext nil))
+
+ (if (file-readable-p "Makefile.am")
+ (setq objext "\.lo")
+ (setq objext "\.o"))
+ (if (string-match "\.cpp$" f) (setq f (replace-match objext t t f)))
+ (if (string-match "\.cc$" f) (setq f (replace-match objext t t f)))
+ (compile (concat kde-emacs-make " " f)))
+ )
+
+;; pc-like textmarking
+(when kde-use-pc-select
+ (progn
+ (load "pc-select")
+ (if (eq kde-emacs-type 'xemacs)
+ (funcall 'pc-select-mode)
+ (funcall 'pc-selection-mode))))
+
+
+; Move in other window
+(defun scroll-other-up () (interactive) (scroll-other-window-down 1)) ; hehe :)
+(defun scroll-other-down () (interactive) (scroll-other-window 1))
+
+(defun match-paren (arg)
+ "Go to the matching parenthesis if on parenthesis otherwise insert %."
+ (interactive "p")
+ (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
+ ((looking-at "\\s\)") (forward-char 1) (backward-list 1))
+ (t (self-insert-command (or arg 1)))))
+
+(defun kde-start-c++-header ()
+ "Start a new C++ header by inserting include guards ( see \
+ header-protection function ), inserting a license statement \
+ and putting (point) at the correct position"
+ (interactive)
+ (header-protection)
+ (insert "\n")
+ (beginning-of-buffer)
+ (kde-license-insert "GNU GPL")
+ (next-line 1)
+ (kill-line)
+ (end-of-buffer)
+ (next-line -3)
+ (insert "\n")
+)
+
+(defun kde-year-range-parse-years-string (string)
+ "parses something like \"2000, 2008-2010\" into a list of the form \
+ ((2008 . 2010)(2000 . 2000))"
+ (let ((pos -1)
+ (oldpos)
+ (l (length string))
+ (currange "")
+ (startyear)
+ (endyear)
+ (ret)
+ )
+ (while (< pos l)
+ (setq oldpos (+ pos 1))
+ (setq pos (string-match "[,]" string (+ pos 1)))
+ (unless pos (setq pos l))
+ (setq currange (substring string oldpos pos))
+ (string-match "[0-9]+" currange)
+ (setq startyear (string-to-int (match-string 0 currange)))
+ (setq endyear
+ (if (string-match "-" currange)
+ (string-to-int (substring currange (match-end 0)))
+ startyear))
+ (setq ret (cons (cons startyear endyear) ret))
+ )
+ ret
+ )
+ )
+
+(defun kde-year-range-contains-year (ranges year)
+ "checks whether year is in ranges.. ( ranges is a list as \
+ kde-year-range-parse-years-string returns.. "
+ (let ((ret))
+ (dolist (range ranges ret)
+ (when (and (>= year (car range)) (<= year (cdr range)))
+ (setq ret t))
+ )))
+
+(defun kde-year-range-to-string (ranges)
+ "converts ranges to a string.."
+ (let ((ret ""))
+ (dolist (range ranges)
+ (setq ret
+ (concat
+ (int-to-string (car range))
+ (if (/= (cdr range) (car range))
+ (concat "-" (int-to-string (cdr range)))
+ "")
+ ", "
+ ret)
+ )
+ )
+ ; remove extraneous ", "
+ (setq ret (substring ret 0 (- (length ret) 2)))
+ )
+ )
+
+; merges adjacent year ranges into one..
+(defun kde-year-range-cleanup (range)
+ (let ((origrange range))
+ (while (and range (cdr range))
+ (let ((years (car range)) (nyears (cadr range)))
+ (when (>= (+ (cdr nyears) 1) (car nyears))
+ (setcar range (cons (car nyears) (cdr years)))
+ (setcdr range (cddr range)))
+ )
+ (setq range (cdr range))
+ )
+ origrange
+ )
+ )
+
+; adds year to range..
+(defun kde-year-range-add-year (range year)
+ (while range
+ (let ((years (car range)))
+ (cond
+ ((and (>= year (car years)) (<= year (cdr years))
+ ; year is already in the range..
+ (setq range nil)))
+ ((= year (+ (cdr years) 1))
+ (setcdr years year)
+ (setq range nil))
+ ((= year (- (car years) 1))
+ (setcar years year)
+ (setq range nil))
+ )
+ )
+ (setq range (cdr range))
+ )
+ (kde-year-range-cleanup range)
+ )
+
+(defun kde-add-copyright () (interactive)
+ "Tries to add your kde-full-name and kde-email to the Copyright \
+ statements at the top of a file... It tries to figure out \
+ if it's already there, and if so, updates the line to include the \
+ current year.. ( well, replaces it by a new one, anyway :) )"
+ (let ((wascomment ""))
+ (save-excursion
+ (beginning-of-buffer)
+ (if (re-search-forward (concat "Copyright ([Cc]) \\([0-9 ,-]*\\) " (regexp-quote kde-full-name)) nil t)
+ (progn
+ (beginning-of-line)
+ (let ((years (kde-year-range-cleanup (kde-year-range-parse-years-string (match-string 1))))
+ (new-copyright-string "Copyright (C) ")
+ (this-year (string-to-int (format-time-string "%Y"))))
+ (when (not (kde-year-range-contains-year years this-year))
+ (kde-year-range-add-year years this-year))
+ (setq new-copyright-string
+ (concat new-copyright-string (kde-year-range-to-string years)))
+ ; finish new-copyright-string
+ (setq new-copyright-string
+ (concat new-copyright-string " " kde-full-name " <" kde-email ">"))
+ (beginning-of-line)
+ (re-search-forward "Copyright ([Cc])")
+ (beginning-of-line)
+ (setq wascomment
+ (buffer-substring (point)
+ (match-beginning 0)
+ ))
+ (kill-line nil)
+ (insert new-copyright-string)
+ )
+ )
+ (beginning-of-buffer)
+ (let ((first-copyright-str (re-search-forward "Copyright ([Cc])" nil t)))
+ (if first-copyright-str
+ (progn
+ (goto-char first-copyright-str)
+ (beginning-of-line)
+ (setq wascomment (buffer-substring (point) (match-beginning 0)))
+ (forward-line 1)
+ )
+ (goto-line 2))
+ )
+ (beginning-of-line)
+ (insert "Copyright (C) " (format-time-string "%Y") " "
+ kde-full-name " <" kde-email ">\n")
+ (forward-line -1)
+ )
+ (end-of-line)
+ (let ((end (point)))
+ (beginning-of-line)
+ (insert wascomment)
+ )
+ )
+ )
+ )
+
+(defun kde-emacs-file-style-update ()
+ "Updates the style header of this file"
+ (interactive)
+ (if (or (eq major-mode 'c++-mode)
+ (eq major-mode 'c-mode))
+ (let ((startpoint) (endpoint)
+ (firstline) (strings)
+ (str) (m) (m2) (var) (value)
+ (final))
+ (save-excursion
+ (beginning-of-buffer)
+ (setq startpoint (point))
+ (setq endpoint (point-at-eol)))
+ (setq firstline (buffer-substring startpoint endpoint))
+ (if (string-match "-\*-\\([A-Za-z0-9\-\+\:\; ]+\\)-\*-" firstline)
+ (delete-region startpoint endpoint))
+ (setq final (concat "-*- "
+ "Mode: " mode-name "; "
+ "c-basic-offset: " (prin1-to-string c-basic-offset) "; "
+ "indent-tabs-mode: " (prin1-to-string indent-tabs-mode) "; "
+ "tab-width: " (prin1-to-string tab-width) "; "
+ "-*-"))
+ (save-excursion
+ (beginning-of-buffer)
+ (insert final)
+ (comment-region (point-at-bol) (point-at-eol))
+ (newline)))))
+
+; Helper for qt-open-header, for Qt 4. Opens a file if it says #include "../foo/bar.h",
+; close it and open that file instead; recursively until finding a real file.
+(defun qt-follow-includes (file)
+ (let ((line "")
+ (begin nil)
+ (buffer nil))
+ (find-file file)
+ (goto-char 0)
+ (if (looking-at "#include \"")
+ (progn
+ (forward-char 10)
+ (setq begin (point))
+ (re-search-forward "\"" nil t)
+ (backward-char 1)
+ (setq file (buffer-substring begin (point)))
+ (setq buffer (current-buffer))
+ (qt-follow-includes file)
+ (kill-buffer buffer)
+ )
+ ; else: this is the right file, skip the comments and go to the class
+ (progn
+ (re-search-forward "^class" nil t)
+ (beginning-of-line))
+ )))
+
+(defun qt-open-header ()
+ "Open the Qt header file for the class under point"
+ (interactive)
+ (let* ((qtinc (concat (getenv "QTDIR") "/include/"))
+ (class (thing-at-point 'word))
+ (f nil)
+ (file nil)
+ (files nil)
+ )
+ (save-excursion
+ ; The Qt3 case: the includes are directly in $QTDIR/include/, lowercased
+ (setq f (concat qtinc (downcase class) ".h" ))
+ (if (file-readable-p f)
+ (setq file f)
+ ; For some Qt3/e classes: add _qws
+ (setq f (concat qtinc (downcase class) "_qws.h" ))
+ (if (file-readable-p f)
+ (setq file f)
+ ; The Qt4 case: the includes are in $QTDIR/include/QSomething/, in original case
+ (setq files (directory-files qtinc t nil "dirsonly"))
+ (dolist (f files nil)
+ (if (file-readable-p (concat f "/" class) )
+ (setq file (concat f "/" class))))
+ ))
+ (and file
+ (qt-follow-includes file))
+ )
+ ))
+
+(provide 'kde-emacs-utils)
diff --git a/scripts/kde-emacs/kde-emacs-vars.el b/scripts/kde-emacs/kde-emacs-vars.el
new file mode 100644
index 00000000..216e64f5
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs-vars.el
@@ -0,0 +1,147 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; kde-emacs-vars.el ;;
+;; ;;
+;; Copyright (C) 2002 Zack Rusin <zack@kde.org> ;;
+;; ;;
+;; 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; if not, write to the Free Software ;;
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA ;;
+;; 02110-1301, USA. ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst kde-emacs-version "0.2"
+ "KDE Emacs package version number.")
+(defun kde-emacs-version ()
+ "Returns the version of KDE Emacs package."
+ (interactive)
+ (message "KDE Emacs version : %s" kde-emacs-version))
+
+
+(defvar kde-emacs-type
+ (eval-when-compile
+ (if (string-match "XEmacs" (emacs-version))
+ 'xemacs
+ 'emacs))
+ "The type of Emacs we are running on.")
+
+;*---------------------------------------------------------------------*/
+;* Constants ... */
+;*---------------------------------------------------------------------*/
+
+(defconst kde-access-labels
+ "\\<\\(signals\\|k_dcop\\|\\(public\\|protected\\|private\\)\\([ ]+slots\\)?\\)\\>:"
+ "KDE specific access labels regexp.")
+
+(defconst kde-source-files '("cpp" "cc" "cxx" "CC" "C" "c")
+ "List of source-file extensions.")
+
+(defconst kde-header-files '("h" "H" "hh" "hxx" "hpp")
+ "List of header-file extensions.")
+
+;*---------------------------------------------------------------------*/
+;* Group ... */
+;*---------------------------------------------------------------------*/
+(defgroup kde-devel nil
+ "Development utilities."
+ :tag "KDE devel"
+ :prefix "kdedevel-"
+ :group 'programming)
+
+(defcustom kde-full-name (or user-full-name
+ (getenv "USER")
+ "Your Name")
+ "*Name used by kde-emacs."
+ :group 'kde-devel
+ :version "0.1"
+ :type 'string)
+
+(defcustom kde-email (or user-mail-address
+ (concat (getenv "LOGNAME") "@" (getenv "HOSTNAME"))
+ "Your Email")
+ "*Email address used by kde-emacs."
+ :group 'kde-devel
+ :version "0.1"
+ :type 'string)
+
+(defcustom kde-cvs-root (concat (getenv "HOME") "/cvs/kde")
+ "*Root Directory of KDE CVS Respiratory"
+ :group 'kde-devel
+ :type 'string)
+
+(defcustom magic-keys-mode 't
+ "Set this variable to true to have some special keybindings. E.g. bind '(' to a function which inserts '( ' when appropriate..."
+ :group 'kde-devel
+ :type 'boolean)
+
+(defcustom kde-emacs-make "make"
+ "Specifies the make command which KDE Emacs will use"
+ :group 'kde-devel
+ :type 'string)
+
+;;Make styles a list of the format (radio (const kde-c++) (const kde-c) style)
+;;and assign it to type.
+(defcustom kde-c++-style "kde-c++"
+ "Set this variable to the CC Mode style you would like loaded when you open a C++ KDE source code file..."
+ :group 'kde-devel
+ :type 'string)
+
+(defcustom kde-c-style "kde-c"
+ "Set this variable to the CC Mode style you would like loaded when you open a C KDE source code file..."
+ :group 'kde-devel
+ :type 'string)
+
+(defcustom kde-use-pc-select 't
+ "Set this to nil if you really hate PC Select Mode..."
+ :group 'kde-devel
+ :type 'boolean)
+
+(defcustom kde-emacs-newline-semicolon nil
+ "Set this to true to have typing \";\" automatically insert
+a newline."
+ :group 'kde-devel
+ :type 'boolean)
+
+(defcustom kde-header-protection-parts-to-show 1
+ "Set this variable to the number of parts from the file name you want to be used for the defined word in the
+header-protection function.. E.g. setting this to 3 makes header-protection define KIG_MISC_NEWTYPE_H for a
+file named /home/domi/src/kdenonbeta/kig/misc/newtype.h"
+ :group 'kde-devel
+ :type 'integer)
+
+(defcustom kde-emacs-after-parent-string " "
+ "Set this to whatever you want to have inserted after the first parenthesis. Works only if
+magic-keys-mode is set to true. "
+ :group 'kde-devel
+ :type 'string)
+
+(defcustom kde-include-directory nil
+ "Set this to the directory holding the includes for the current module/project/whatever."
+ :group 'kde-devel
+ :type 'string)
+
+(defcustom kde-source-directory nil
+ "Set this to the directory holding the sources for the current module/project/whatever."
+ :group 'kde-devel
+ :type 'string)
+
+(defcustom kde-make-member-default-impl " \n"
+ "Default implementation added by agulbra-make-member. FUNCTION gets replaced by the full signature of the function/method."
+ :group 'kde-devel
+ :type 'string)
+
+; a grep in the part of kde-source I have gives:
+; 5579 files uses .cpp, 1402 uses .cc, 10 uses .cxx, and 1 uses .C
+(defconst kde-prefered-source-extension "cpp"
+ "Source extension which kde-* functions should use for creating new files.")
+
+(provide 'kde-emacs-vars)
diff --git a/scripts/kde-emacs/kde-emacs.el b/scripts/kde-emacs/kde-emacs.el
new file mode 100644
index 00000000..b2865c53
--- /dev/null
+++ b/scripts/kde-emacs/kde-emacs.el
@@ -0,0 +1,66 @@
+;; kde-emacs.el
+;; Time-stamp: <2002-06-26 00:49:48 zack>
+;;
+;; Copyright (C) 2002 Zack Rusin <zackrat@att.net>
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2.1 of the License, or (at your option) any later version.
+;;
+;; This library 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
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+
+;;; Installation:
+;;
+;; Put the following lines in your ".emacs":
+;; (add-to-list 'load-path "~/path-to-kde-emacs")
+;; (require 'kde-emacs)
+;;
+;; I also strongly recommend to add the following two lines to
+;; .emacs file:
+;; (setq kde-full-name "Your Name")
+;; (setq kde-email "Your Email")
+;;
+;; You may want to byte-compile the package to speed it up
+;; a bit. To do it in the *scratch* buffer type in the following
+;; line:
+;; (byte-recompile-directory "~/kde-emacs" t)
+;; place the cursor after the closing paren and hit "Ctrl-x Ctrl-e",
+;; that's it.
+;;
+;; All keybindings are in kde-emacs-bindings.el, look at/customize
+;; this file before byte-compiling the package!
+;; If you want to see things you can customize type:
+;; M-x customize-group
+;; and type in "kde-devel" group.
+;;
+;; TODO:
+;; - in (if kde-emacs-type... change direct function calls
+;; to funcall's
+;;
+
+(require 'cc-mode) ;; needed by kde-emacs-core's test on c-version
+
+(require 'kde-emacs-compat)
+(require 'kde-emacs-core)
+(require 'kde-emacs-general)
+(require 'klaralv)
+(require 'kde-emacs-utils)
+(require 'dirvars)
+
+;; load this only if semantic package is present
+(when (featurep 'semantic)
+ (require 'kde-emacs-semantic)
+ (require 'kde-emacs-doc))
+
+(require 'kde-emacs-bindings)
+
+(provide 'kde-emacs)
diff --git a/scripts/kde-emacs/klaralv.el b/scripts/kde-emacs/klaralv.el
new file mode 100644
index 00000000..df29ff78
--- /dev/null
+++ b/scripts/kde-emacs/klaralv.el
@@ -0,0 +1,422 @@
+;; ------------------------------ COPYRIGHT NOTICE ------------------------------
+;; klaralv.el version 1.3
+;; Copyright Klaralvdalens Datakonsult AB.
+;;
+;; 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. If you did not, write to the Free Software Foundation,
+;; Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
+
+
+;; ------------------------------ INSTALLATION ------------------------------
+;; To use this file, add the current directory to your load path.
+;; you do this by inserting something like the following to your .emacs:
+;; (setq load-path (cons "/home/blackie/Emacs/" load-path))
+;;
+;; Next insert the following line into your .emacs
+;; (require 'klaralv)
+;; (global-set-key [(f5)] 'kdab-insert-header)
+;; (global-set-key [(shift f5)] 'kdab-insert-forward-decl)
+;; (setq kdab-qt-documentation "file://usr/local/qt/html/doc/XXX.html")
+;; (global-set-key [(control f5)] 'kdab-lookup-qt-documentation)
+;;
+;; If you use QTopia, and do not want include files to be prefixed with qpe/,
+;; as in qpe/qpeapplication, then insert the following code in your setup
+;; (setq kdab-prefix-qpe nil)
+
+;; ------------------------------ CONFIGURATION ------------------------------
+(defvar kdab-qt-documentation
+ "http://doc.trolltech.com/3.0/XXX.html"
+ "URL for Qt documentation. XXX must be in the string.
+ Example: file://packages/kde-src/qt-copy/doc/html/XXX.html")
+
+(defvar kdab-qpe-documentation
+ "file://opt/qtopia/doc/XXX.html"
+ "URL for QTopia documentatin. XXX must be in the string.
+ Example: file:/opt/qtopia/doc/XXX.html")
+
+
+(defvar kdab-prefix-qpe 't
+ "set this to nil if you do not want QPE header files prefixed with qpe/")
+
+;; special case for include files
+;; Please notify blackie@klaralvdalens-datakonsult.se with any modification to this variable!
+(defvar kdab-special-includes
+ '(
+ (qlayout.h QHBoxLayout QVBoxLayout QGridLayout QBoxLayout)
+ (qlistview.h QListViewItem QCheckListItem QListViewItemIterator)
+ (qiconview.h QIconViewItem QIconDragItem QIconDrag)
+ (qdragobject.h QTextDrag QStoredDrag QUriDag QColorDrag QImageDrag QDragManager)
+ (qmime.h QMimeSource QMimeSourceFactory QWindowsMime)
+ (qptrlist.h QPtrListIterator)
+ (qevent.h QTimerEvent QMouseEvent QWheelEvent QTabletEvent QKeyEvent
+ QFocusEvent QPaintEvent QMoveEvent QResizeEvent QCloseEvent
+ QShowEvent QHideEvent QContextMenuEvent QIMEvent QDropEvent
+ QDragMoveEvent QDragEnterEvent QDragResponseEvent QDragLeaveEvent
+ QChildEvent QCustomEvent)
+ (qdatetime.h QTime QDateTime QDate)
+ (qdatetimeedit.h QTimeEdit QDateTimeEditBase QDateEdit QDateTimeEdit)
+ (qcstring.h QByteArray)
+ (qobjectlist.h QObjectListIt QObjectListIterator)
+ (qwidgetlist.h QWidgetListIt)
+ (qtabbar.h QTab)
+ (qpalette.h QColorGroup)
+ (qaction.h QActionGroup)
+ (qvalidator.h QIntValidator QDoubleValidator QRegExpValidator)
+ (qlistbox.h QListBoxItem QListBoxText QListBoxPixmap)
+ (qstring.h QChar QCharRef QConstString)
+ (qcanvas.h QCanvasSprite QCanvasPolygonalItem QCanvasRectangle
+ QCanvasPolygon QCanvasEllipse QCanvasText QCanvasLine
+ QCanvasChunk QCanvas QCanvasItem QCanvasView QCanvasPixmap)
+ (qgl.h QGLFormat QGL QGLContext QGLWidget QGLColormap)
+ (qtable.h QTableSelection QTableItem QComboTableItem QCheckTableItem)
+ (qsqlfield.h QSqlField QSqlFieldInfo)
+ (qsqlrecord.h QSqlRecord QSqlRecordInfo)
+
+ ; Qt/Embedded
+ (qcopchannel_qws.h QCopChannel)
+ (qdirectpainter_qws.h QDirectPainter)
+ (qfontfactorybdf_qws.h QFontFactoryBDF)
+ (qfontfactoryttf_qws.h QFontFactoryFT)
+ (qfontmanager_qws.h QGlyphMetrics QGlyph QRenderedFont QDiskFont QFontManager QFontFactory)
+ (qgfx_qws.h QScreenCursor QPoolEntry QScreen QGfx)
+ (qgfxlinuxfb_qws.h QLinuxFbScreen)
+ (qgfxmatroxdefs_qws.h QQnxFbGfx QQnxScreen)
+ (qgfxraster_qws.h QGfxRasterBase QGfxRaster)
+ (qgfxvnc_qws.h QRfbRect QRfbPixelFormat QRfbServerInit QRfbSetEncodings
+ QRfbFrameBufferUpdateRequest QRfbKeyEvent QRfbPointerEvent QRfbClientCutText QVNCServer)
+ (qkeyboard_qws.h QWSKeyboardHandler)
+ (qlock_qws.h QLock QLockHolder)
+ (qmemorymanager_qws.h QMemoryManagerPixmap QMemoryManager)
+ (qsoundqss_qws.h QWSSoundServer QWSSoundClient QWSSoundServerClient QWSSoundServerSocket)
+ (qwindowsystem_qws.h QWSInternalWindowInfo QWSScreenSaver QWSWindow QWSSoundServer
+ QWSServer QWSServer KeyboardFilter QWSClient)
+ (qwsbeosdecoration_qws.h QWSBeOSDecoration)
+ (qwscursor_qws.h QWSCursor)
+ (qwsdecoration_qws.h QWSDecoration)
+ (qwsdefaultdecoration_qws.h QWSDefaultDecoration)
+ (qwsdisplay_qws.h QWSWindowInfo QWSDisplay)
+ (qwshydrodecoration_qws.h QWSHydroDecoration)
+ (qwskde2decoration_qws.h QWSKDE2Decoration)
+ (qwskdedecoration_qws.h QWSKDEDecoration)
+ (qwsmanager_qws.h QWSManager QWSButton)
+ (qwsmouse_qws.h QWSPointerCalibrationData QWSMouseHandler QCalibratedMouseHandler
+ QAutoMouseHandlerPrivate QWSMouseHandlerPrivate QVrTPanelHandlerPrivate
+ QTPanelHandlerPrivate QYopyTPanelHandlerPrivate QCustomTPanelHandlerPrivate
+ QVFbMouseHandlerPrivate)
+ (qwsproperty_qws.h QWSPropertyManager)
+ (qwsregionmanager_qws.h QWSRegionManager)
+ (qwssocket_qws.h QWSSocket QWSServerSocket)
+ (qwswindowsdecoration_qws.h QWSWindowsDecoration)
+ (qstatusbar.h statusBar())
+
+ ; KDE
+ (kdebug.h kdDebug kdWarning kdError kdFatal kdBacktrace)
+ (kconfig.h KConfigGroup)
+ (kiconloader.h BarIcon SmallIcon DesktopIcon KIcon)
+ (kicondialog.h KIconCanvas KIconButton)
+ (knuminput.h KDoubleNumInput KIntNumInput)
+
+ ; KDGear - http://www.klaralvdalens-datakonsult.se
+ (KDCheckableGroupBox.h KDCheckableGroupBox)
+ (KDCheckableHGroupBox.h KDCheckableHGroupBox)
+ (KDCheckableVGroupBox.h KDCheckableVGroupBox)
+ (KDCloseableWidget.h KDCloseableWidget)
+ (KDConfigDialog.h KDConfigDialog)
+ (KDConfigWidget.h KDConfigWidget)
+ (KDDateWidget.h KDDateWidget KDDateTimeWidget)
+ (KDDirMonitor.h KDDirMonitor)
+ (KDGridWidget.h KDGridWidget)
+ (KDListBoxPair.h KDListBoxPair)
+ (KDMinimizeSplitter.h KDMinimizeSplitter)
+ (KDSearchableListBox.h KDSearchableListBox)
+ (KDSemiSizingControl.h KDSemiSizingControl)
+ (KDShowHideTableControl.h KDShowHideTableControl)
+ (KDSimpleSizingControl.h KDSimpleSizingControl)
+ (KDSizingControl.h KDSizingControl)
+ (KDStream.h KDStream)
+ (KDTimeWidget.h KDTimeWidget)
+
+ ; KDChart - http://www.klaralvdalens-datakonsult.se
+ (KDChart.h KDChart)
+ (KDChartAxisParams.h KDChartAxisParams)
+ (KDChartBaseSeries.h KDChartBaseSeries)
+ (KDChartCustomBox.h KDChartCustomBox)
+ (KDChartData.h KDChartData)
+ (KDChartEnums.h KDChartEnums)
+ (KDChartListTable.h KDChartListTableData KDChartListTablePrivate)
+ (KDChartNotEnoughSpaceException.h KDChartNotEnoughSpaceException)
+ (KDChartPainter.h KDChartPainter)
+ (KDChartParams.h KDChartFrameSettings KDChartParams ModeAndChart)
+ (KDChartPlaneSeries.h KDChartPlaneSeries)
+ (KDChartPropertySet.h KDChartPropertySet)
+ (KDChartSeriesCollection.h KDChartSeriesCollection)
+ (KDChartTable.h KDChartTableData)
+ (KDChartTableBase.h KDChartTableDataBase)
+ (KDChartTextPiece.h KDChartTextPiece)
+ (KDChartUnknownTypeException.h KDChartUnknownTypeException)
+ (KDChartVectorSeries.h KDChartVectorSeries)
+ (KDChartVectorTable.h KDChartVectorTableData KDChartVectorTablePrivate)
+ (KDChartWidget.h KDChartWidget)
+ (KDFrame.h KDFrame KDFrameCorner)
+ (KDFrameProfileSection.h KDFrameProfileSection)
+
+
+ ; Useful fake entries
+ (qapplication.h qApp)
+ (kapplication.h kapp)
+ (klocale.h i18n I18N_NOOP)
+ (kstandarddirs.h locate locateLocal)
+ (stdlib.h getenv)
+ (unistd.h unlink sleep usleep)
+ (iostream cout cerr)
+ (ctype.h isalnum isalpha isascii isblank iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit)
+ (qeventloop.h eventloop)
+
+ )
+ "List of special include files which do not follow the normal scheme")
+
+(defvar kdab-qpe-includes
+ '(
+ (alarmserver.h AlarmServer)
+ (applnk.h AppLnk DocLnk AppLnkSet DocLnkSet)
+ (calendar.h Calendar)
+ (categories.h CategoryGroup CategoryGroup Categories CheckedListView)
+ (categorymenu.h CategoryMenu)
+ (categoryselect.h CategoryCombo CategorySelect CategoryEdit CategoryWidget)
+ (config.h Config)
+ (contact.h Contact)
+ (database.h QWSDatabase DatabaseDefaultView Database DatabaseView DatabaseDefaultView)
+ (datebookdb.h DateBookDB)
+ (datebookmonth.h DateBookMonthHeader DayItemMonth DateBookMonthTable DateBookMonth DateButton)
+ (event.h Event EffectiveEvent EffectiveEventSizeSorter EffectiveEventTimeSorter)
+ (filemanager.h FileManager)
+ (fileselector.h FileSelectorItem FileSelector)
+ (finddialog.h FindDialog)
+ (fontdatabase.h FontDatabase)
+ (fontmanager.h FontManager)
+ (global.h Global)
+ (imageedit.h ImageEdit)
+ (inputmethodinterface.h InputMethodInterface)
+ (ir.h Ir)
+ (lightstyle.h LightStyle)
+ (lnkproperties.h LnkProperties)
+ (mediaplayerplugininterface.h MediaPlayerDecoder)
+ (menubutton.h MenuButton)
+ (mimetype.h MimeType)
+ (network.h Network)
+ (palmtoprecord.h Record)
+ (palmtopuidgen.h UidGen)
+ (password.h Password)
+ (power.h PowerStatus PowerStatusManager )
+ (process.h Process)
+ (qcopenvelope_qws.h QCopEnvelope)
+ (qdawg.h QDawg)
+ (qlibrary.h QLibrary)
+ (qpeapplication.h QPEApplication)
+ (qpedecoration_qws.h QPEDecoration QPEManager)
+ (qpedialog.h QPEDialogListener)
+ (qpemenubar.h QPEMenuToolFocusManager QPEMenuBar)
+ (qpemessagebox.h QPEMessageBox)
+ (qpestyle.h QPEStyle : public QWindowsStyle)
+ (qpetoolbar.h QPEToolBar)
+ (record.h Record)
+ (resource.h Resource)
+ (sound.h Sound)
+ (storage.h StorageInfo FileSystem)
+ (task.h Task)
+ (timeconversion.h TimeConversion)
+ (timestring.h DateFormat TimeString)
+ (tzselect.h TZCombo TimeZoneSelector)
+ ))
+
+;; ------------------------------ SOURCE CODE ------------------------------
+
+;; Merge in qpe classes
+(defun kdab-get-special-include-list ()
+ (let (elm header classes (list kdab-qpe-includes) filename (result kdab-special-includes))
+ (while list
+ (setq elm (car list))
+ (setq list (cdr list))
+ (setq filename (concat (if kdab-prefix-qpe "qpe/" "") (symbol-name (car elm))))
+ (setq result (cons (cons (intern filename) (cdr elm)) result)))
+ result))
+
+;; Lookup class `cls' in kdab-special-includes and return the associate include file name
+(defun kdab-map-special (cls)
+ (let ((list (kdab-get-special-include-list))
+ (found nil))
+ (while (and list (not found))
+ (let* ( (elm (car list))
+ (include-file (car elm))
+ (classes (cdr elm)))
+ ( while (and classes (not found))
+ (if (string= (downcase cls) (downcase (symbol-name (car classes))))
+ (setq found include-file)
+ (setq classes (cdr classes)))))
+ (setq list (cdr list)))
+ (if found
+ (symbol-name found)
+ nil) ; return value
+ ))
+
+
+
+;--------------------------------------------------------------------------------
+; Insert include file for Qt program.
+; Place point anywhere on a Qt class, and invoke this function. A result of
+; this is that an include line is added (if it does not already exists) for
+; the given class.
+;--------------------------------------------------------------------------------
+(defun kdab-insert-header ( prefix )
+ "Insert include file for class at point"
+ (interactive "P")
+ (save-excursion
+ (let* ((word-at-point (if prefix
+ (read-from-minibuffer "Class: ")
+ (current-word))))
+ (kdab-insert-header-non-interactive word-at-point))))
+
+;--------------------------------------------------------------------------------
+; insert include file for `word-with-case' non-interactively.
+; for an interactive version see kdab-insert-header
+;--------------------------------------------------------------------------------
+(defun kdab-insert-header-non-interactive (word-with-case)
+ (save-excursion
+ (let* ((word (downcase word-with-case))
+ (special-header (cond
+ ((kdab-map-special word) (kdab-map-special word))
+ ((string-match "^qdom" word) "qdom.h")
+ ((string-match "^qxml" word) "qxml.h")
+ (t (concat word ".h"))))
+ header is-local)
+
+
+ ;; decide on the header file.
+ (if (file-exists-p (concat word-with-case ".h"))
+ (progn ; file exists in given case in pwd.
+ (setq header (concat word-with-case ".h"))
+ (setq is-local 't))
+ (if (file-exists-p (concat word ".h")) ; file exists in lowercase in pwd
+ (progn
+ (setq header (concat word ".h"))
+ (setq is-local 't))
+ (progn ; header in <..> path
+ (setq header special-header)
+ (setq is-local nil))))
+
+ (kdab-insert-include-file header is-local t))))
+
+;--------------------------------------------------------------------------------
+; Insert header file for header. If is-local insert it with ""
+; otherwise insert it with <>
+;--------------------------------------------------------------------------------
+(defun kdab-insert-include-file (header is-local show-message)
+ (let ((include-file (if is-local
+ (concat "#include \"" header "\"")
+ (concat "#include <" header ">"))))
+
+ (beginning-of-buffer)
+ (if (re-search-forward (concat "^ *// *\\(#include *[<\"][ \t]*" header "[ \t]*[>\"]\\)") nil t)
+ (progn
+ (replace-match "\\1")
+ (when show-message
+ (message (concat "commented in #include for " header))))
+
+ (if (not (re-search-forward (concat "#include *[\"<][ \t]*" header "[ \t]*[\">]") nil t))
+ (progn
+ ; No include existed
+ (goto-char (point-max)) ; Using end-of-buffer makes point move, despite save-excursion
+ (if (not (re-search-backward "^#include *[\"<][^\">]+\.h *[\">]" nil t))
+ (beginning-of-buffer)
+ (progn (end-of-line) (forward-char 1)))
+
+ ;; Now insert the header
+ (insert (concat include-file "\n"))
+ (when show-message
+ (message (concat "inserted " include-file))))
+ (when show-message
+ (message (concat "header file \"" header "\" is already included")))))))
+
+
+
+;----------------------------------------------------------------------------
+; Insert a forward declaration for a Qt class.
+; Place point anywhere on a Qt class, and invoke this function. A
+; result of this is that a forward declaration line is added (if it does
+; not already exist) for the given class.
+;----------------------------------------------------------------------------
+(defun kdab-insert-forward-decl ( prefix )
+ (interactive "P")
+ (save-excursion
+ (let* ((word (if prefix (read-from-minibuffer "Class: ")
+ (current-word))))
+ (beginning-of-buffer)
+ (if (re-search-forward (concat "^ *// *\\(class *" word ";\\)") nil t)
+ (progn
+ (replace-match "\\1")
+ (message (concat "commented in forward declaration for " word)))
+
+ (if (not (re-search-forward (concat "class *" word ";") nil t))
+ (progn
+ ; No forward decl existed
+ ; Look for other forward declarations and insert this one before them
+ ; (this avoids finding class Private; inside a class, or other stuff in the middle of the file)
+ (if (re-search-forward "^[ \t]*class .*;" nil t)
+ (progn
+ ; Exit namespace foo { class bar; } if necessary
+ ; This is a modified version of (backward-up-list) which doesn't
+ ; throw an error when not found.
+ (goto-char (or (scan-lists (point) -1 1 nil t) (point))) ; ### do multiple times if necessary
+ (re-search-backward "^[ \t]*namespace " nil t) ; in case of namespace foo\n{
+ (beginning-of-line))
+ ; No forward declarations found, lets search for include lines.
+ ; For those we start from the end, because we want to leave file.h first.
+ (progn (goto-char (point-max))
+ (if (re-search-backward "#include" nil t)
+ (progn (end-of-line) (forward-char 1))
+ (beginning-of-buffer))))
+
+ (progn
+ (insert "class " word ";\n")
+ (message (concat "inserted class " word ";"))))
+ (message (concat "forward decl for \"" word "\" already exists")))))))
+
+
+(defun is-qpe-class (class)
+ (let ((list kdab-qpe-includes) classes (found nil))
+ (while (and (not found) list)
+ (setq classes (cdr (car list)))
+ (while classes
+ (if (string= (downcase (symbol-name (car classes))) (downcase class))
+ (setq found 't))
+ (setq classes (cdr classes)))
+ (setq list (cdr list)))
+ found))
+
+;--------------------------------------------------------------------------------
+; Start konqueror with documentation for the class under point.
+; set `kdab-qt-documentation' and `kdab-qpe-documentation'
+; to specify the replacement for the documentation
+;--------------------------------------------------------------------------------
+(defun kdab-lookup-qt-documentation ()
+ (interactive "")
+ (save-excursion
+ (let* ((word (downcase (current-word)))
+ (doc (if (is-qpe-class word) kdab-qpe-documentation kdab-qt-documentation))
+ (url (if (not (string-match "XXX" doc))
+ (error "didn't find three X's in kdab-qt-documentation or kdab-qpe-documentation")
+ (replace-match word t t doc))))
+ (start-process "qt documentation" nil "kfmclient" "openURL" url)
+ (message (concat "Loading " url)))))
+
+(provide 'klaralv)