]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/pascal.el
(c-defun-name): Make it work for "struct foo bar [] = { ...".
[gnu-emacs] / lisp / progmodes / pascal.el
index 3212107b20de78716e3c87c129a2e61168507209..a21fd1f9e30bce63ae50109ed7e42cbe6c7dcfe3 100644 (file)
@@ -1,16 +1,17 @@
 ;;; pascal.el --- major mode for editing pascal source in Emacs
 
-;; Copyright (C) 1993, 94, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+;;               2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
 
 ;; Author: Espen Skoglund <esk@gnu.org>
 ;; Keywords: languages
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs 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.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,9 +19,7 @@
 ;; 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 Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 
 (defgroup pascal nil
   "Major mode for editing Pascal source in Emacs."
+  :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
   :group 'languages)
 
 (defvar pascal-mode-abbrev-table nil
   "Abbrev table in use in Pascal-mode buffers.")
 (define-abbrev-table 'pascal-mode-abbrev-table ())
 
-(defvar pascal-mode-map ()
+(defvar pascal-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map ";"        'electric-pascal-semi-or-dot)
+    (define-key map "."        'electric-pascal-semi-or-dot)
+    (define-key map ":"        'electric-pascal-colon)
+    (define-key map "="        'electric-pascal-equal)
+    (define-key map "#"        'electric-pascal-hash)
+    (define-key map "\r"       'electric-pascal-terminate-line)
+    (define-key map "\t"       'electric-pascal-tab)
+    (define-key map "\M-\t"    'pascal-complete-word)
+    (define-key map "\M-?"     'pascal-show-completions)
+    (define-key map "\177"     'backward-delete-char-untabify)
+    (define-key map "\M-\C-h"  'pascal-mark-defun)
+    (define-key map "\C-c\C-b" 'pascal-insert-block)
+    (define-key map "\M-*"     'pascal-star-comment)
+    (define-key map "\C-c\C-c" 'pascal-comment-area)
+    (define-key map "\C-c\C-u" 'pascal-uncomment-area)
+    (define-key map "\M-\C-a"  'pascal-beg-of-defun)
+    (define-key map "\M-\C-e"  'pascal-end-of-defun)
+    (define-key map "\C-c\C-d" 'pascal-goto-defun)
+    (define-key map "\C-c\C-o" 'pascal-outline-mode)
+    ;; A command to change the whole buffer won't be used terribly
+    ;; often, so no need for a key binding.
+    ;; (define-key map "\C-cd"    'pascal-downcase-keywords)
+    ;; (define-key map "\C-cu"    'pascal-upcase-keywords)
+    ;; (define-key map "\C-cc"    'pascal-capitalize-keywords)
+    map)
   "Keymap used in Pascal mode.")
-(if pascal-mode-map
-    ()
-  (setq pascal-mode-map (make-sparse-keymap))
-  (define-key pascal-mode-map ";"        'electric-pascal-semi-or-dot)
-  (define-key pascal-mode-map "."        'electric-pascal-semi-or-dot)
-  (define-key pascal-mode-map ":"        'electric-pascal-colon)
-  (define-key pascal-mode-map "="        'electric-pascal-equal)
-  (define-key pascal-mode-map "#"        'electric-pascal-hash)
-  (define-key pascal-mode-map "\r"       'electric-pascal-terminate-line)
-  (define-key pascal-mode-map "\t"       'electric-pascal-tab)
-  (define-key pascal-mode-map "\M-\t"    'pascal-complete-word)
-  (define-key pascal-mode-map "\M-?"     'pascal-show-completions)
-  (define-key pascal-mode-map "\177"     'backward-delete-char-untabify)
-  (define-key pascal-mode-map "\M-\C-h"  'pascal-mark-defun)
-  (define-key pascal-mode-map "\C-c\C-b" 'pascal-insert-block)
-  (define-key pascal-mode-map "\M-*"     'pascal-star-comment)
-  (define-key pascal-mode-map "\C-c\C-c" 'pascal-comment-area)
-  (define-key pascal-mode-map "\C-c\C-u" 'pascal-uncomment-area)
-  (define-key pascal-mode-map "\M-\C-a"  'pascal-beg-of-defun)
-  (define-key pascal-mode-map "\M-\C-e"  'pascal-end-of-defun)
-  (define-key pascal-mode-map "\C-c\C-d" 'pascal-goto-defun)
-  (define-key pascal-mode-map "\C-c\C-o" 'pascal-outline)
-;;; A command to change the whole buffer won't be used terribly
-;;; often, so no need for a key binding.
-;  (define-key pascal-mode-map "\C-cd"    'pascal-downcase-keywords)
-;  (define-key pascal-mode-map "\C-cu"    'pascal-upcase-keywords)
-;  (define-key pascal-mode-map "\C-cc"    'pascal-capitalize-keywords)
-  )
 
 (defvar pascal-imenu-generic-expression
   '((nil "^[ \t]*\\(function\\|procedure\\)[ \t\n]+\\([a-zA-Z0-9_.:]+\\)" 2))
 (defconst pascal-exclude-str-start "{-----\\/----- EXCLUDED -----\\/-----")
 (defconst pascal-exclude-str-end " -----/\\----- EXCLUDED -----/\\-----}")
 
-(defvar pascal-mode-syntax-table nil
+(defvar pascal-mode-syntax-table
+  (let ((st (make-syntax-table)))
+    (modify-syntax-entry ?\\ "."   st)
+    (modify-syntax-entry ?\( "()1" st)
+    (modify-syntax-entry ?\) ")(4" st)
+    ;; This used to use comment-syntax `b'.  But the only document I could
+    ;; find about the syntax of Pascal's comments said that (* ... } is
+    ;; a valid comment, just as { ... *) or (* ... *) or { ... }.
+    (modify-syntax-entry ?* ". 23" st)
+    (modify-syntax-entry ?{ "<"    st)
+    (modify-syntax-entry ?} ">"    st)
+    (modify-syntax-entry ?+ "."    st)
+    (modify-syntax-entry ?- "."    st)
+    (modify-syntax-entry ?= "."    st)
+    (modify-syntax-entry ?% "."    st)
+    (modify-syntax-entry ?< "."    st)
+    (modify-syntax-entry ?> "."    st)
+    (modify-syntax-entry ?& "."    st)
+    (modify-syntax-entry ?| "."    st)
+    (modify-syntax-entry ?_ "_"    st)
+    (modify-syntax-entry ?\' "\""  st)
+    st)
   "Syntax table in use in Pascal-mode buffers.")
 
-(if pascal-mode-syntax-table
-    ()
-  (setq pascal-mode-syntax-table (make-syntax-table))
-  (modify-syntax-entry ?\\ "."   pascal-mode-syntax-table)
-  (modify-syntax-entry ?( "()1"  pascal-mode-syntax-table)
-  (modify-syntax-entry ?) ")(4"  pascal-mode-syntax-table)
-  (modify-syntax-entry ?* ". 23b" pascal-mode-syntax-table)
-  (modify-syntax-entry ?{ "<"    pascal-mode-syntax-table)
-  (modify-syntax-entry ?} ">"    pascal-mode-syntax-table)
-  (modify-syntax-entry ?+ "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?- "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?= "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?% "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?< "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?> "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?& "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?| "."    pascal-mode-syntax-table)
-  (modify-syntax-entry ?_ "_"    pascal-mode-syntax-table)
-  (modify-syntax-entry ?\' "\""  pascal-mode-syntax-table))
+
 
 (defconst pascal-font-lock-keywords (purecopy
   (list
@@ -326,7 +327,7 @@ Other useful functions are:
 \\[pascal-beg-of-defun]\t- Move to beginning of current function.
 \\[pascal-end-of-defun]\t- Move to end of current function.
 \\[pascal-goto-defun]\t- Goto function prompted for in the minibuffer.
-\\[pascal-outline]\t- Enter pascal-outline-mode (see also pascal-outline).
+\\[pascal-outline-mode]\t- Enter `pascal-outline-mode'.
 
 Variables controlling indentation/edit style:
 
@@ -520,8 +521,8 @@ This puts the mark at the end, and point at the beginning."
   (pascal-end-of-defun)
   (push-mark (point))
   (pascal-beg-of-defun)
-  (if (fboundp 'zmacs-activate-region)
-      (zmacs-activate-region)))
+  (when (featurep 'xemacs)
+    (zmacs-activate-region)))
 
 (defun pascal-comment-area (start end)
   "Put the region into a Pascal comment.
@@ -791,8 +792,7 @@ on the line which ends a function or procedure named NAME."
 (defun pascal-indent-command ()
   "Indent for special part of code."
   (let* ((indent-str (pascal-calculate-indent))
-        (type (car indent-str))
-        (ind (car (cdr indent-str))))
+        (type (car indent-str)))
     (cond ((and (eq type 'paramlist)
                (or (memq 'all pascal-auto-lineup)
                    (memq 'paramlist pascal-auto-lineup)))
@@ -970,7 +970,7 @@ Do not count labels, case-statements or records."
                 (end-of-line)
                 (point-marker)
               (re-search-backward "\\<case\\>" nil t)))
-       (beg (point)) oldpos
+       (beg (point))
        (ind 0))
     ;; Get right indent
     (while (< (point) end)
@@ -985,7 +985,6 @@ Do not count labels, case-statements or records."
                (setq ind (current-column)))
            (pascal-end-of-statement))))
     (goto-char beg)
-    (setq oldpos (marker-position end))
     ;; Indent all case statements
     (while (< (point) end)
       (if (re-search-forward
@@ -998,7 +997,6 @@ Do not count labels, case-statements or records."
        (forward-char 1)
        (delete-horizontal-space)
        (insert " "))
-      (setq oldpos (point))
       (pascal-end-of-statement))
     (goto-char savepos)))
 
@@ -1379,7 +1377,7 @@ indent of the current line in parameterlist."
            ((and (not (null (cdr allcomp))) (= (length pascal-str)
                                                (length match)))
             (with-output-to-temp-buffer "*Completions*"
-              (display-completion-list allcomp))
+              (display-completion-list allcomp pascal-str))
             ;; Wait for a keypress. Then delete *Completion*  window
             (momentary-string-display "" (point))
             (delete-window (get-buffer-window (get-buffer "*Completions*")))
@@ -1399,7 +1397,7 @@ indent of the current line in parameterlist."
                    (all-completions pascal-str 'pascal-completion))))
     ;; Show possible completions in a temporary buffer.
     (with-output-to-temp-buffer "*Completions*"
-      (display-completion-list allcomp))
+      (display-completion-list allcomp pascal-str))
     ;; Wait for a keypress. Then delete *Completion*  window
     (momentary-string-display "" (point))
     (delete-window (get-buffer-window (get-buffer "*Completions*")))))
@@ -1469,7 +1467,7 @@ The default is a name found in the buffer around point."
                      default ""))
         (label (if (not (string= default ""))
                    ;; Do completion with default
-                   (completing-read (concat "Label: (default " default ") ")
+                   (completing-read (concat "Label (default " default "): ")
                                     'pascal-comp-defun nil t "")
                  ;; There is no default value. Complete without it
                  (completing-read "Label: "
@@ -1489,30 +1487,20 @@ The default is a name found in the buffer around point."
 ;;;
 ;;; Pascal-outline-mode
 ;;;
-(defvar pascal-outline-map nil "Keymap used in Pascal Outline mode.")
-
-(if pascal-outline-map
-    nil
-  (if (fboundp 'set-keymap-name)
-      (set-keymap-name pascal-outline-map 'pascal-outline-map))
-  (if (fboundp 'set-keymap-parent)
-      (set-keymap-parent (setq pascal-outline-map (make-sparse-keymap))
-                        pascal-mode-map)
-    (setq pascal-outline-map (copy-keymap pascal-mode-map)))
-  (define-key pascal-outline-map "\M-\C-a"  'pascal-outline-prev-defun)
-  (define-key pascal-outline-map "\M-\C-e"  'pascal-outline-next-defun)
-  (define-key pascal-outline-map "\C-c\C-d" 'pascal-outline-goto-defun)
-  (define-key pascal-outline-map "\C-c\C-s" 'pascal-show-all)
-  (define-key pascal-outline-map "\C-c\C-h" 'pascal-hide-other-defuns))
-
-(defvar pascal-outline-mode nil "Non-nil while using Pascal Outline mode.")
-(make-variable-buffer-local 'pascal-outline-mode)
-(set-default 'pascal-outline-mode nil)
-(if (not (assoc 'pascal-outline-mode minor-mode-alist))
-    (setq minor-mode-alist (append minor-mode-alist
-                                  (list '(pascal-outline-mode " Outl")))))
-
-(defun pascal-outline (&optional arg)
+(defvar pascal-outline-map
+  (let ((map (make-sparse-keymap)))
+    (if (fboundp 'set-keymap-name)
+        (set-keymap-name pascal-outline-map 'pascal-outline-map))
+    (define-key map "\M-\C-a"  'pascal-outline-prev-defun)
+    (define-key map "\M-\C-e"  'pascal-outline-next-defun)
+    (define-key map "\C-c\C-d" 'pascal-outline-goto-defun)
+    (define-key map "\C-c\C-s" 'pascal-show-all)
+    (define-key map "\C-c\C-h" 'pascal-hide-other-defuns)
+    map)
+  "Keymap used in Pascal Outline mode.")
+
+(define-obsolete-function-alias 'pascal-outline 'pascal-outline-mode)
+(define-minor-mode pascal-outline-mode
   "Outline-line minor mode for Pascal mode.
 When in Pascal Outline mode, portions
 of the text being edited may be made invisible. \\<pascal-outline-map>
@@ -1530,26 +1518,26 @@ Pascal Outline mode provides some additional commands.
 \\[pascal-hide-other-defuns]\
 \t- Hide everything but the current function (function under the cursor).
 \\[pascal-outline]\t- Leave pascal-outline-mode."
-  (interactive "P")
-  (setq pascal-outline-mode
-       (if (null arg) (not pascal-outline-mode) t))
-  (if (fboundp 'redraw-mode-line)
-      (redraw-mode-line))
-  (if pascal-outline-mode
-      (progn
-       (setq selective-display t)
-       (use-local-map pascal-outline-map))
-    (progn
-      (setq selective-display nil)
-      (pascal-show-all)
-      (use-local-map pascal-mode-map))))
+  :init-value nil :lighter " Outl" :keymap pascal-outline-map
+  (add-to-invisibility-spec '(pascal . t))
+  (unless pascal-outline-mode
+    (pascal-show-all)))
 
 (defun pascal-outline-change (b e pascal-flag)
-  (let ((modp (buffer-modified-p)))
-    (unwind-protect
-       (subst-char-in-region b e (if (= pascal-flag ?\n)
-                                     ?\^M ?\n) pascal-flag)
-      (set-buffer-modified-p modp))))
+  (save-excursion
+    ;; This used to use selective display so the boundaries used by the
+    ;; callers didn't have to be precise, since it just looked for \n or \^M
+    ;; and switched them.
+    (goto-char b) (setq b (line-end-position))
+    (goto-char e) (setq e (line-end-position)))
+  (when (> e b)
+    ;; We could try and optimize this in the case where the region is
+    ;; already hidden.  But I'm not sure it's worth the trouble.
+    (remove-overlays b e 'invisible 'pascal)
+    (when (eq pascal-flag ?\^M)
+      (let ((ol (make-overlay b e nil t nil)))
+        (overlay-put ol 'invisible 'pascal)
+        (overlay-put ol 'evaporate t)))))
 
 (defun pascal-show-all ()
   "Show all of the text in the buffer."
@@ -1627,5 +1615,5 @@ Pascal Outline mode provides some additional commands.
 
 (provide 'pascal)
 
-;;; arch-tag: 04535136-fd93-40b4-a505-c9bebdc051f5
+;; arch-tag: 04535136-fd93-40b4-a505-c9bebdc051f5
 ;;; pascal.el ends here