]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/pascal.el
Use \r rather than ^M in string literals
[gnu-emacs] / lisp / progmodes / pascal.el
index 1af527c2c427fe3d513411158869254be7b45df3..c05bda5c9257a4e85c99435934ac70806e1f9692 100644 (file)
@@ -1,7 +1,6 @@
-;;; pascal.el --- major mode for editing pascal source in Emacs
+;;; pascal.el --- major mode for editing pascal source in Emacs -*- lexical-binding: t -*-
 
-;; Copyright (C) 1993-2011
-;;               Free Software Foundation, Inc.
+;; Copyright (C) 1993-2015 Free Software Foundation, Inc.
 
 ;; Author: Espen Skoglund <esk@gnu.org>
 ;; Keywords: languages
@@ -27,8 +26,8 @@
 ;; =====
 
 ;; Emacs should enter Pascal mode when you find a Pascal source file.
-;; When you have entered Pascal mode, you may get more info by pressing
-;; C-h m. You may also get online help describing various functions by:
+;; When you have entered Pascal mode, you can get more info by pressing
+;; C-h m.  You can also get help describing various functions by:
 ;; C-h f <Name of function you want described>
 
 ;; If you want to customize Pascal mode to fit you better, you may add
@@ -41,7 +40,6 @@
 ;;       pascal-tab-always-indent  t
 ;;       pascal-auto-endcomments   t
 ;;       pascal-auto-lineup        '(all)
-;;       pascal-toggle-completions nil
 ;;       pascal-type-keywords      '("array" "file" "packed" "char"
 ;;                                  "integer" "real" "string" "record")
 ;;       pascal-start-keywords     '("begin" "end" "function" "procedure"
@@ -59,7 +57,6 @@
 \f
 ;;; Code:
 
-(eval-when-compile (require 'cl))
 
 (defgroup pascal nil
   "Major mode for editing Pascal source in Emacs."
@@ -67,7 +64,7 @@
   :group 'languages)
 
 (defvar pascal-mode-abbrev-table nil
-  "Abbrev table in use in Pascal-mode buffers.")
+  "Abbrev table in use in Pascal mode buffers.")
 (define-abbrev-table 'pascal-mode-abbrev-table ())
 
 (defvar pascal-mode-map
     (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)
+    ;; These are user preferences, so not to set by default.
+    ;;(define-key map "\r"       'electric-pascal-terminate-line)
+    ;;(define-key map "\t"       'electric-pascal-tab)
+    (define-key map "\M-\t"    'completion-at-point)
+    (define-key map "\M-?"     'completion-help-at-point)
     (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)
 
 (defvar pascal-imenu-generic-expression
   '((nil "^[ \t]*\\(function\\|procedure\\)[ \t\n]+\\([a-zA-Z0-9_.:]+\\)" 2))
-  "Imenu expression for Pascal-mode.  See `imenu-generic-expression'.")
+  "Imenu expression for Pascal mode.  See `imenu-generic-expression'.")
 
 (defvar pascal-keywords
   '("and" "array" "begin" "case" "const" "div" "do" "downto" "else" "end"
   "\\<\\(label\\|var\\|type\\|const\\|until\\|end\\|begin\\|repeat\\|else\\)\\>")
 
 ;;; Strings used to mark beginning and end of excluded text
-(defconst pascal-exclude-str-start "{-----\\/----- EXCLUDED -----\\/-----")
-(defconst pascal-exclude-str-end " -----/\\----- EXCLUDED -----/\\-----}")
+(defconst pascal-exclude-str-start "{-----\\/----- EXCLUDED -----\\/-----"
+  "String used to mark beginning of excluded text.")
+(defconst pascal-exclude-str-end " -----/\\----- EXCLUDED -----/\\-----}"
+  "String used to mark end of excluded text.")
 
 (defvar pascal-mode-syntax-table
   (let ((st (make-syntax-table)))
     ;; find about the syntax of Pascal's comments said that (* ... } is
     ;; a valid comment, just as { ... *) or (* ... *) or { ... }.
     (modify-syntax-entry ?* ". 23" st)
+    ;; Allow //...\n comments as accepted by Free Pascal (bug#13585).
+    (modify-syntax-entry ?/ ". 12c" st)
+    (modify-syntax-entry ?\n "> c" st)
     (modify-syntax-entry ?{ "<"    st)
     (modify-syntax-entry ?} ">"    st)
     (modify-syntax-entry ?+ "."    st)
 
 
 
-(defconst pascal-font-lock-keywords (purecopy
-  (list
-   '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\([a-z]\\)"
-     1 font-lock-keyword-face)
-   '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\([a-z][a-z0-9_]*\\)"
-     3 font-lock-function-name-face t)
-;   ("type" "const" "real" "integer" "char" "boolean" "var"
-;    "record" "array" "file")
-   (cons (concat "\\<\\(array\\|boolean\\|c\\(har\\|onst\\)\\|file\\|"
-                "integer\\|re\\(al\\|cord\\)\\|type\\|var\\)\\>")
-        'font-lock-type-face)
-   '("\\<\\(label\\|external\\|forward\\)\\>" . font-lock-constant-face)
-   '("\\<\\([0-9]+\\)[ \t]*:" 1 font-lock-function-name-face)
-;   ("of" "to" "for" "if" "then" "else" "case" "while"
-;    "do" "until" "and" "or" "not" "in" "with" "repeat" "begin" "end")
-   (concat "\\<\\("
-          "and\\|begin\\|case\\|do\\|e\\(lse\\|nd\\)\\|for\\|i[fn]\\|"
-          "not\\|o[fr]\\|repeat\\|t\\(hen\\|o\\)\\|until\\|w\\(hile\\|ith\\)"
-          "\\)\\>")
-   '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?"
-     1 font-lock-keyword-face)
-   '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?"
-     2 font-lock-keyword-face t)))
+(defconst pascal-font-lock-keywords
+  `(("\\_<\\(function\\|pro\\(cedure\\|gram\\)\\)[ \t]+\\([[:alpha:]][[:alnum:]_]*\\)"
+     (1 font-lock-keyword-face)
+     (3 font-lock-function-name-face))
+    ;; ("type" "const" "real" "integer" "char" "boolean" "var"
+    ;;  "record" "array" "file")
+    (,(concat "\\_<\\(array\\|boolean\\|c\\(har\\|onst\\)\\|file\\|"
+              "integer\\|re\\(al\\|cord\\)\\|type\\|var\\)\\_>")
+     . font-lock-type-face)
+    ("\\_<\\(label\\|external\\|forward\\)\\_>" . font-lock-constant-face)
+    ("\\_<\\([0-9]+\\)[ \t]*:" 1 font-lock-function-name-face)
+    ;; ("of" "to" "for" "if" "then" "else" "case" "while"
+    ;;  "do" "until" "and" "or" "not" "in" "with" "repeat" "begin" "end")
+    ,(concat "\\_<\\("
+             "and\\|begin\\|case\\|do\\|e\\(lse\\|nd\\)\\|for\\|i[fn]\\|"
+             "not\\|o[fr]\\|repeat\\|t\\(hen\\|o\\)\\|until\\|w\\(hile\\|ith\\)"
+             "\\)\\_>")
+    ("\\_<\\(goto\\)\\_>[ \t]*\\([0-9]+\\)?"
+     (1 font-lock-keyword-face) (2 font-lock-keyword-face t)))
   "Additional expressions to highlight in Pascal mode.")
-(put 'pascal-mode 'font-lock-defaults '(pascal-font-lock-keywords nil t))
+
+(defconst pascal--syntax-propertize
+  (syntax-propertize-rules
+   ;; The syntax-table settings are too coarse and end up treating /* and (/
+   ;; as comment starters.  Fix it here by removing the "2" from the syntax
+   ;; of the second char of such sequences.
+   ("/\\(\\*\\)" (1 ". 3b"))
+   ("(\\(\\/\\)" (1 (prog1 ". 1c" (forward-char -1) nil)))
+   ;; Pascal uses '' and "" rather than \' and \" to escape quotes.
+   ("''\\|\"\"" (0 (if (save-excursion
+                         (nth 3 (syntax-ppss (match-beginning 0))))
+                       (string-to-syntax ".")
+                     ;; In case of 3 or more quotes in a row, only advance
+                     ;; one quote at a time.
+                     (forward-char -1)
+                     nil)))))
 
 (defcustom pascal-indent-level 3
-  "*Indentation of Pascal statements with respect to containing block."
+  "Indentation of Pascal statements with respect to containing block."
   :type 'integer
   :group 'pascal)
 
 (defcustom pascal-case-indent 2
-  "*Indentation for case statements."
+  "Indentation for case statements."
   :type 'integer
   :group 'pascal)
 
 (defcustom pascal-auto-newline nil
-  "*Non-nil means automatically insert newlines in certain cases.
+  "Non-nil means automatically insert newlines in certain cases.
 These include after semicolons and after the punctuation mark after an `end'."
   :type 'boolean
   :group 'pascal)
 
 (defcustom pascal-indent-nested-functions t
-  "*Non-nil means nested functions are indented."
+  "Non-nil means nested functions are indented."
   :type 'boolean
   :group 'pascal)
 
 (defcustom pascal-tab-always-indent t
-  "*Non-nil means TAB in Pascal mode should always reindent the current line.
+  "Non-nil means TAB in Pascal mode should always reindent the current line.
 If this is nil, TAB inserts a tab if it is at the end of the line
 and follows non-whitespace text."
   :type 'boolean
   :group 'pascal)
 
 (defcustom pascal-auto-endcomments t
-  "*Non-nil means automatically insert comments after certain `end's.
-Specifically, this is done after the ends of cases statements and functions.
+  "Non-nil means automatically insert comments after certain `end's.
+Specifically, this is done after the ends of case statements and functions.
 The name of the function or case is included between the braces."
   :type 'boolean
   :group 'pascal)
 
 (defcustom pascal-auto-lineup '(all)
-  "*List of contexts where auto lineup of :'s or ='s should be done.
+  "List of contexts where auto lineup of :'s or ='s should be done.
 Elements can be of type: 'paramlist', 'declaration' or 'case', which will
 do auto lineup in parameterlist, declarations or case-statements
 respectively.  The word 'all' will do all lineups.  '(case paramlist) for
@@ -228,21 +242,21 @@ will do all lineups."
   :type '(set :extra-offset 8
              (const :tag "Everything" all)
              (const :tag "Parameter lists" paramlist)
-             (const :tag "Decalrations" declaration)
+             (const :tag "Declarations" declaration)
              (const :tag "Case statements" case))
   :group 'pascal)
 
-(defcustom pascal-toggle-completions nil
-  "*Non-nil means \\<pascal-mode-map>\\[pascal-complete-word] should try all possible completions one by one.
-Repeated use of \\[pascal-complete-word] will show you all of them.
-Normally, when there is more than one possible completion,
-it displays a list of all possible completions."
-  :type 'boolean
-  :group 'pascal)
+(defvar pascal-toggle-completions nil
+  "If non-nil, `pascal-complete-word' tries all possible completions.
+Repeated use of \\[pascal-complete-word] then shows all
+completions in turn, instead of displaying a list of all possible
+completions.")
+(make-obsolete-variable 'pascal-toggle-completions
+                        'completion-cycle-threshold "24.1")
 
 (defcustom pascal-type-keywords
   '("array" "file" "packed" "char" "integer" "real" "string" "record")
-  "*Keywords for types used when completing a word in a declaration or parmlist.
+  "Keywords for types used when completing a word in a declaration or parmlist.
 These include integer, real, char, etc.
 The types defined within the Pascal program
 are handled in another way, and should not be added to this list."
@@ -252,7 +266,7 @@ are handled in another way, and should not be added to this list."
 (defcustom pascal-start-keywords
   '("begin" "end" "function" "procedure" "repeat" "until" "while"
     "read" "readln" "reset" "rewrite" "write" "writeln")
-  "*Keywords to complete when standing at the first word of a statement.
+  "Keywords to complete when standing at the first word of a statement.
 These are keywords such as begin, repeat, until, readln.
 The procedures and variables defined within the Pascal program
 are handled in another way, and should not be added to this list."
@@ -261,7 +275,7 @@ are handled in another way, and should not be added to this list."
 
 (defcustom pascal-separator-keywords
   '("downto" "else" "mod" "div" "then")
-  "*Keywords to complete when NOT standing at the first word of a statement.
+  "Keywords to complete when NOT standing at the first word of a statement.
 These are keywords such as downto, else, mod, then.
 Variables and function names defined within the Pascal program
 are handled in another way, and should not be added to this list."
@@ -300,12 +314,12 @@ are handled in another way, and should not be added to this list."
 
 ;;;###autoload
 (define-derived-mode pascal-mode prog-mode "Pascal"
-  "Major mode for editing Pascal code. \\<pascal-mode-map>
+  "Major mode for editing Pascal code.\\<pascal-mode-map>
 TAB indents for Pascal code.  Delete converts tabs to spaces as it moves back.
 
-\\[pascal-complete-word] completes the word around current point with respect \
+\\[completion-at-point] completes the word around current point with respect \
 to position in code
-\\[pascal-show-completions] shows all possible completions at this point.
+\\[completion-help-at-point] shows all possible completions at this point.
 
 Other useful functions are:
 
@@ -341,26 +355,23 @@ Variables controlling indentation/edit style:
     List of contexts where auto lineup of :'s or ='s should be done.
 
 See also the user variables `pascal-type-keywords', `pascal-start-keywords' and
-`pascal-separator-keywords'.
-
-Turning on Pascal mode calls the value of the variable pascal-mode-hook with
-no args, if that value is non-nil."
-  (set (make-local-variable 'local-abbrev-table) pascal-mode-abbrev-table)
-  (set (make-local-variable 'indent-line-function) 'pascal-indent-line)
-  (set (make-local-variable 'comment-indent-function) 'pascal-indent-comment)
-  (set (make-local-variable 'parse-sexp-ignore-comments) nil)
-  (set (make-local-variable 'blink-matching-paren-dont-ignore-comments) t)
-  (set (make-local-variable 'case-fold-search) t)
-  (set (make-local-variable 'comment-start) "{")
-  (set (make-local-variable 'comment-start-skip) "(\\*+ *\\|{ *")
-  (set (make-local-variable 'comment-end) "}")
+`pascal-separator-keywords'."
+  (setq-local local-abbrev-table pascal-mode-abbrev-table)
+  (setq-local indent-line-function 'pascal-indent-line)
+  (setq-local comment-indent-function 'pascal-indent-comment)
+  (setq-local parse-sexp-ignore-comments nil)
+  (setq-local blink-matching-paren-dont-ignore-comments t)
+  (setq-local case-fold-search t)
+  (setq-local comment-start "{")
+  (setq-local comment-start-skip "(\\*+ *\\|{ *")
+  (setq-local comment-end "}")
+  (add-hook 'completion-at-point-functions 'pascal-completions-at-point nil t)
   ;; Font lock support
-  (set (make-local-variable 'font-lock-defaults)
-       '(pascal-font-lock-keywords nil t))
+  (setq-local font-lock-defaults '(pascal-font-lock-keywords nil t))
+  (setq-local syntax-propertize-function pascal--syntax-propertize)
   ;; Imenu support
-  (set (make-local-variable 'imenu-generic-expression)
-       pascal-imenu-generic-expression)
-  (set (make-local-variable 'imenu-case-fold-search) t)
+  (setq-local imenu-generic-expression pascal-imenu-generic-expression)
+  (setq-local imenu-case-fold-search t)
   ;; Pascal-mode's own hide/show support.
   (add-to-invisibility-spec '(pascal . t)))
 
@@ -414,7 +425,7 @@ no args, if that value is non-nil."
       (electric-pascal-terminate-line)))
 
 (defun electric-pascal-colon ()
-  "Insert `:' and do all indentions except line indent on this line."
+  "Insert `:' and do all indentations except line indent on this line."
   (interactive)
   (insert last-command-event)
   ;; Do nothing if within string.
@@ -427,7 +438,7 @@ no args, if that value is non-nil."
       (pascal-indent-command))))
 
 (defun electric-pascal-equal ()
-  "Insert `=', and do indention if within type declaration."
+  "Insert `=', and do indentation if within type declaration."
   (interactive)
   (insert last-command-event)
   (if (eq (car (pascal-calculate-indent)) 'declaration)
@@ -467,6 +478,8 @@ no args, if that value is non-nil."
 ;;;
 ;;; Interactive functions
 ;;;
+(defvar pascal--extra-indent 0)
+
 (defun pascal-insert-block ()
   "Insert Pascal begin ... end; block in the code with right indentation."
   (interactive)
@@ -491,7 +504,7 @@ no args, if that value is non-nil."
   (insert "  "))
 
 (defun pascal-mark-defun ()
-  "Mark the current pascal function (or procedure).
+  "Mark the current Pascal function (or procedure).
 This puts the mark at the end, and point at the beginning."
   (interactive)
   (push-mark (point))
@@ -502,14 +515,14 @@ This puts the mark at the end, and point at the beginning."
     (zmacs-activate-region)))
 
 (defun pascal-comment-area (start end)
-  "Put the region into a Pascal comment.
+  "Put the region into a Pascal comment.\\<pascal-mode-map>
 The comments that are in this area are \"deformed\":
 `*)' becomes `!(*' and `}' becomes `!{'.
 These deformed comments are returned to normal if you use
 \\[pascal-uncomment-area] to undo the commenting.
 
-The commented area starts with `pascal-exclude-str-start', and ends with
-`pascal-include-str-end'.  But if you change these variables,
+The commented area starts with `pascal-exclude-str-start', and ends
+with `pascal-exclude-str-end'.  But if you change these variables,
 \\[pascal-uncomment-area] won't recognize the comments."
   (interactive "r")
   (save-excursion
@@ -537,8 +550,8 @@ The commented area starts with `pascal-exclude-str-start', and ends with
 
 (defun pascal-uncomment-area ()
   "Uncomment a commented area; change deformed comments back to normal.
-This command does nothing if the pointer is not in a commented
-area.  See also `pascal-comment-area'."
+This command does nothing if the pointer is not in a commented area.
+See also `pascal-comment-area'."
   (interactive)
   (save-excursion
     (let ((start (point))
@@ -757,14 +770,14 @@ on the line which ends a function or procedure named NAME."
 ;;; Indentation
 ;;;
 (defconst pascal-indent-alist
-  '((block . (+ ind pascal-indent-level))
-    (case . (+ ind pascal-case-indent))
-    (caseblock . ind) (cpp . 0)
-    (declaration . (+ ind pascal-indent-level))
+  '((block . (+ pascal--extra-indent pascal-indent-level))
+    (case . (+ pascal--extra-indent pascal-case-indent))
+    (caseblock . pascal--extra-indent) (cpp . 0)
+    (declaration . (+ pascal--extra-indent pascal-indent-level))
     (paramlist . (pascal-indent-paramlist t))
     (comment . (pascal-indent-comment))
-    (defun . ind) (contexp . ind)
-    (unknown . ind) (string . 0) (progbeg . 0)))
+    (defun . pascal--extra-indent) (contexp . pascal--extra-indent)
+    (unknown . pascal--extra-indent) (string . 0) (progbeg . 0)))
 
 (defun pascal-indent-command ()
   "Indent for special part of code."
@@ -790,7 +803,7 @@ on the line which ends a function or procedure named NAME."
   "Indent current line as a Pascal statement."
   (let* ((indent-str (pascal-calculate-indent))
         (type (car indent-str))
-        (ind (car (cdr indent-str))))
+        (pascal--extra-indent (car (cdr indent-str))))
     ;; Labels should not be indented.
     (if (and (looking-at "^[0-9a-zA-Z]+[ \t]*:[^=]")
             (not (eq type 'declaration)))
@@ -802,13 +815,13 @@ on the line which ends a function or procedure named NAME."
           ())
          (; Other things should have no extra indent
           (looking-at pascal-noindent-re)
-          (indent-to ind))
+          (indent-to pascal--extra-indent))
          (; Nested functions should be indented
           (looking-at pascal-defun-re)
           (if (and pascal-indent-nested-functions
                    (eq type 'defun))
-              (indent-to (+ ind pascal-indent-level))
-            (indent-to ind)))
+              (indent-to (+ pascal--extra-indent pascal-indent-level))
+            (indent-to pascal--extra-indent)))
          (; But most lines are treated this way
           (indent-to (eval (cdr (assoc type pascal-indent-alist))))
           ))))
@@ -922,7 +935,7 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
 
 (defun pascal-indent-level ()
   "Return the indent-level the current statement has.
-Do not count labels, case-statements or records."
+Do not count labels, case statements or records."
   (save-excursion
     (beginning-of-line)
     (if (looking-at "[ \t]*[0-9a-zA-Z]+[ \t]*:[^=]")
@@ -948,7 +961,7 @@ Do not count labels, case-statements or records."
                 (point-marker)
               (re-search-backward "\\<case\\>" nil t)))
        (beg (point))
-       (ind 0))
+       (pascal--extra-indent 0))
     ;; Get right indent
     (while (< (point) end)
       (if (re-search-forward
@@ -958,8 +971,8 @@ Do not count labels, case-statements or records."
       (if (< (point) end)
          (progn
            (delete-horizontal-space)
-           (if (> (current-column) ind)
-               (setq ind (current-column)))
+           (if (> (current-column) pascal--extra-indent)
+               (setq pascal--extra-indent (current-column)))
            (pascal-end-of-statement))))
     (goto-char beg)
     ;; Indent all case statements
@@ -968,7 +981,7 @@ Do not count labels, case-statements or records."
           "^[ \t]*[^][ \t,\\.:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:"
           (marker-position end) 'move)
          (forward-char -1))
-      (indent-to (1+ ind))
+      (indent-to (1+ pascal--extra-indent))
       (if (/= (following-char) ?:)
          ()
        (forward-char 1)
@@ -979,7 +992,7 @@ Do not count labels, case-statements or records."
 
 (defun pascal-indent-paramlist (&optional arg)
   "Indent current line in parameterlist.
-If optional arg is non-nil, just return the
+If optional ARG is non-nil, just return the
 indent of the current line in parameterlist."
   (save-excursion
     (let* ((oldpos (point))
@@ -1016,7 +1029,7 @@ indent of the current line in parameterlist."
                                 (max (progn (pascal-declaration-end)
                                             (point))
                                      pos))))
-           ind)
+           pascal--extra-indent)
 
        (goto-char stpos)
        ;; Indent lines in record block
@@ -1030,13 +1043,13 @@ indent of the current line in parameterlist."
              (forward-line 1)))
 
        ;; Do lineup
-       (setq ind (pascal-get-lineup-indent stpos edpos lineup))
+       (setq pascal--extra-indent (pascal-get-lineup-indent stpos edpos lineup))
        (goto-char stpos)
        (while (and (<= (point) edpos) (not (eobp)))
          (if (search-forward lineup (point-at-eol) 'move)
              (forward-char -1))
          (delete-horizontal-space)
-         (indent-to ind)
+         (indent-to pascal--extra-indent)
          (if (not (looking-at lineup))
              (forward-line 1) ; No more indent if there is no : or =
            (forward-char 1)
@@ -1055,7 +1068,7 @@ indent of the current line in parameterlist."
 ;from b to e nicely. The lineup string is str."
 (defun pascal-get-lineup-indent (b e str)
   (save-excursion
-    (let ((ind 0)
+    (let ((pascal--extra-indent 0)
          (reg (concat str "\\|\\(\\<record\\>\\)\\|" pascal-defun-re)))
       (goto-char b)
       ;; Get rightmost position
@@ -1070,14 +1083,14 @@ indent of the current line in parameterlist."
                   (t
                    (goto-char (match-beginning 0))
                    (skip-chars-backward " \t")
-                   (if (> (current-column) ind)
-                       (setq ind (current-column)))
+                   (if (> (current-column) pascal--extra-indent)
+                       (setq pascal--extra-indent (current-column)))
                    (goto-char (match-end 0))
                    (end-of-line)
                    ))))
       ;; In case no lineup was found
-      (if (> ind 0)
-         (1+ ind)
+      (if (> pascal--extra-indent 0)
+         (1+ pascal--extra-indent)
        ;; No lineup-string found
        (goto-char b)
        (end-of-line)
@@ -1287,54 +1300,17 @@ indent of the current line in parameterlist."
 (defvar pascal-last-word-shown nil)
 (defvar pascal-last-completions nil)
 
-(defun pascal-complete-word ()
-  "Complete word at current point.
-\(See also `pascal-toggle-completions', `pascal-type-keywords',
-`pascal-start-keywords' and `pascal-separator-keywords'.)"
-  (interactive)
+(defun pascal-completions-at-point ()
   (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
         (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point))))
+    (when (> e b)
+      (list b e #'pascal-completion))))
 
-    ;; Toggle-completions inserts whole labels
-    (if pascal-toggle-completions
-       (let* ((pascal-str (buffer-substring b e))
-               (allcomp (if (and pascal-toggle-completions
-                                 (string= pascal-last-word-shown pascal-str))
-                            pascal-last-completions
-                          (all-completions pascal-str 'pascal-completion))))
-         ;; Update entry number in list
-         (setq pascal-last-completions allcomp
-               pascal-last-word-numb
-               (if (>= pascal-last-word-numb (1- (length allcomp)))
-                   0
-                 (1+ pascal-last-word-numb)))
-         (setq pascal-last-word-shown (elt allcomp pascal-last-word-numb))
-         ;; Display next match or same string if no match was found
-         (if allcomp
-              (progn
-                (goto-char e)
-                (insert-before-markers pascal-last-word-shown)
-                (delete-region b e))
-           (message "(No match)")))
-      ;; The other form of completion does not necessarily do that.
-      (completion-in-region b e 'pascal-completion))))
-
-(defun pascal-show-completions ()
-  "Show all possible completions at current point."
-  (interactive)
-  (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
-        (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
-        (pascal-str (buffer-substring b e))
-        (allcomp (if (and pascal-toggle-completions
-                          (string= pascal-last-word-shown pascal-str))
-                     pascal-last-completions
-                   (all-completions pascal-str 'pascal-completion))))
-    ;; Show possible completions in a temporary buffer.
-    (with-output-to-temp-buffer "*Completions*"
-      (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*")))))
+(define-obsolete-function-alias 'pascal-complete-word
+  'completion-at-point "24.1")
+
+(define-obsolete-function-alias 'pascal-show-completions
+  'completion-help-at-point "24.1")
 
 
 (defun pascal-get-default-symbol ()
@@ -1389,21 +1365,21 @@ The default is a name found in the buffer around point."
         (default (if (pascal-comp-defun default nil 'lambda)
                      default ""))
         (label
-          ;; Do completion with default
+          ;; Do completion with default.
           (completing-read (if (not (string= default ""))
                                (concat "Label (default " default "): ")
                              "Label: ")
                            ;; Complete with the defuns found in the
                            ;; current-buffer.
-                           (lexical-let ((buf (current-buffer)))
+                           (let ((buf (current-buffer)))
                              (lambda (s p a)
                                (with-current-buffer buf
                                  (pascal-comp-defun s p a))))
                            nil t "")))
-    ;; If there was no response on prompt, use default value
+    ;; If there was no response on prompt, use default value.
     (if (string= label "")
        (setq label default))
-    ;; Goto right place in buffer if label is not an empty string
+    ;; Goto right place in buffer if label is not an empty string.
     (or (string= label "")
        (progn
          (goto-char (point-min))
@@ -1430,8 +1406,12 @@ The default is a name found in the buffer around point."
 (define-obsolete-function-alias 'pascal-outline 'pascal-outline-mode "22.1")
 (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>
+With a prefix argument ARG, enable the mode if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil.
+
+When enabled, portions of the text being edited may be made
+invisible.\\<pascal-outline-map>
 
 Pascal Outline mode provides some additional commands.
 
@@ -1445,7 +1425,7 @@ Pascal Outline mode provides some additional commands.
 \\[pascal-show-all]\t- Show the whole buffer.
 \\[pascal-hide-other-defuns]\
 \t- Hide everything but the current function (function under the cursor).
-\\[pascal-outline]\t- Leave pascal-outline-mode."
+\\[pascal-outline]\t- Leave Pascal Outline mode."
   :init-value nil :lighter " Outl" :keymap pascal-outline-map
   (add-to-invisibility-spec '(pascal . t))
   (unless pascal-outline-mode