]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/delphi.el
(etags-tags-completion-table): Use progress reporter.
[gnu-emacs] / lisp / progmodes / delphi.el
index 55ab9cdd566f2b9b47dee9d0accdec8d8a082701..4ebbc54969712f8bf71e760ec520457a4911b610 100644 (file)
@@ -1,4 +1,4 @@
-;; delphi.el --- Major mode for editing Delphi source (Object Pascal) in Emacs
+;;; delphi.el --- major mode for editing Delphi source (Object Pascal) in Emacs
 
 ;; Copyright (C) 1998, 1999 Free Software Foundation, Inc.
 
@@ -38,7 +38,7 @@
 ;; (add-hook 'delphi-mode-hook 'turn-on-font-lock)
 
 ;; If font-lock is not loaded by default, you might have to do:
-;; 
+;;
 ;; (autoload 'font-lock-mode "font-lock")
 ;; (autoload 'turn-on-font-lock "font-lock")
 ;; (setq font-lock-support-mode 'lazy-lock-mode)
 
 (provide 'delphi)
 
-(defconst delphi-version
-  (let ((revision "$Revision: 3.0 $"))
-    (string-match ": \\([^ ]+\\)" revision)
-    (match-string 1 revision))
-  "Version of this delphi mode.")
-;;; $Log: delphi.el,v $
-;;; Revision 3.0  1999/08/03 04:59:02  blaak
-;;; Re-release as an official Emacs language mode
-;;;
-
 (eval-and-compile
   ;; Allow execution on pre Emacs 20 versions.
   (or (fboundp 'when)
@@ -99,6 +89,7 @@
 
 (defgroup delphi nil
   "Major mode for editing Delphi source in Emacs"
+  :version "21.1"
   :group 'languages)
 
 (defconst delphi-debug nil
@@ -152,36 +143,45 @@ end;                            end;"
   :type 'boolean
   :group 'delphi)
 
-(defcustom delphi-tab-always-indent t
+(defcustom delphi-tab-always-indents t
   "*Non-nil means TAB in Delphi mode should always reindent the current line,
 regardless of where in the line point is when the TAB command is used."
   :type 'boolean
   :group 'delphi)
 
+(defcustom delphi-newline-always-indents t
+  "*Non-nil means NEWLINE in Delphi mode should always reindent the current
+line, insert a blank line and move to the default indent column of the blank
+line. If nil, then no indentation occurs, and NEWLINE does the usual
+behaviour. This is useful when one needs to do customized indentation that
+differs from the default."
+  :type 'boolean
+  :group 'delphi)
+
 (defcustom delphi-comment-face 'font-lock-comment-face
   "*Face used to color delphi comments."
-  :type 'facep
+  :type 'face
   :group 'delphi)
 
 (defcustom delphi-string-face 'font-lock-string-face
   "*Face used to color delphi strings."
-  :type 'facep
+  :type 'face
   :group 'delphi)
 
 (defcustom delphi-keyword-face 'font-lock-keyword-face
   "*Face used to color delphi keywords."
-  :type 'facep
+  :type 'face
   :group 'delphi)
 
 (defcustom delphi-other-face nil
   "*Face used to color everything else."
-  :type 'facep
+  :type 'face
   :group 'delphi)
 
 (defconst delphi-directives
   '(absolute abstract assembler automated cdecl default dispid dynamic
     export external far forward index inline message name near nodefault
-    overload override pascal private protected public published read readonly 
+    overload override pascal private protected public published read readonly
     register reintroduce resident resourcestring safecall stdcall stored
     virtual write writeonly)
   "Delphi4 directives.")
@@ -192,9 +192,9 @@ regardless of where in the line point is when the TAB command is used."
      and array as asm at begin case class const constructor contains
      destructor dispinterface div do downto else end except exports
      file finalization finally for function goto if implementation implements
-     in inherited initialization interface is label library mod nil not 
+     in inherited initialization interface is label library mod nil not
      of object on or out package packed procedure program property
-     raise record repeat requires result self set shl shr then threadvar 
+     raise record repeat requires result self set shl shr then threadvar
      to try type unit uses until var while with xor
 
      ;; These routines should be keywords, if Borland had the balls.
@@ -242,8 +242,8 @@ are followed by an expression.")
 (defconst delphi-visibilities '(public private protected published automated)
   "Class visibilities.")
 
-(defconst delphi-block-statements 
-  '(begin try case repeat initialization finalization)
+(defconst delphi-block-statements
+  '(begin try case repeat initialization finalization asm)
   "Statements that contain multiple substatements.")
 
 (defconst delphi-mid-block-statements
@@ -257,7 +257,7 @@ are followed by an expression.")
   `(,@delphi-end-block-statements ,@delphi-mid-block-statements)
   "Statements that match the indentation of the parent block.")
 
-(defconst delphi-decl-sections '(type const var label)
+(defconst delphi-decl-sections '(type const var label resourcestring)
   "Denotes the start of a declaration section.")
 
 (defconst delphi-class-types '(class object)
@@ -520,7 +520,7 @@ routine.")
                  ;; We have an end only if there is some string content (at
                  ;; least a starting delimiter).
                  (not (delphi-is-literal-end (1- p)))))
-                 
+
         ;; Special case: strings cannot span lines.
         (and (delphi-is kind delphi-strings) (eq ?\n (char-after (1- p)))))))
 
@@ -562,7 +562,7 @@ routine.")
            ;; We are completing an incomplete literal.
            (let ((kind (delphi-literal-kind (1- search-start))))
              (delphi-complete-literal kind limit)
-             (delphi-set-text-properties 
+             (delphi-set-text-properties
               search-start (point) (delphi-literal-text-properties kind))))
 
           ((re-search-forward
@@ -577,7 +577,7 @@ routine.")
                  (start (match-beginning 0)))
              (delphi-set-text-properties search-start start nil)
              (delphi-complete-literal kind limit)
-             (delphi-set-text-properties 
+             (delphi-set-text-properties
               start (point) (delphi-literal-text-properties kind))))
 
           ;; Nothing found. Mark it as a non-literal.
@@ -729,14 +729,14 @@ routine.")
       (while (< p to)
         ;; Color the token and move past it.
         (setq token (delphi-token-at p))
-        (add-text-properties 
+        (add-text-properties
          (delphi-token-start token) (delphi-token-end token)
          (list 'face (delphi-face-of (delphi-token-kind token)) 'lazy-lock t))
         (setq p (delphi-token-end token))
         (delphi-step-progress p "Fontifying" delphi-fontifying-progress-step))
       (delphi-progress-done)))))
 
-(defconst delphi-ignore-changes t
+(defvar delphi-ignore-changes t
   "Internal flag to control if the delphi-mode responds to buffer changes.
 Defaults to t in case the delphi-after-change function is called on a
 non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
@@ -750,7 +750,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
        (delphi-progress-start)
        ;; Reparse at least from the token previous to the change to the end of
        ;; line after the change.
-       (delphi-parse-region-until-stable 
+       (delphi-parse-region-until-stable
         (delphi-token-start (delphi-token-at (1- change-start)))
         (progn (goto-char change-end) (end-of-line) (point)))
        (delphi-progress-done)))))
@@ -808,7 +808,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
     (catch 'done
       (while token
         (setq kind (delphi-token-kind token))
-        (cond 
+        (cond
          ;; Skip over ()/[] groups.
          ((eq 'close-group kind) (setq token (delphi-group-start token)))
 
@@ -830,10 +830,10 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
     (catch 'done
       (while token
         (setq kind (delphi-token-kind token))
-        (cond 
+        (cond
          ((and (eq 'colon kind)
                (delphi-is (delphi-token-kind last-token)
-                          `(,@delphi-block-statements 
+                          `(,@delphi-block-statements
                             ,@delphi-expr-statements)))
           ;; We hit a label followed by a statement. Indent to the statement.
           (throw 'done nil))
@@ -910,7 +910,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
          ((delphi-composite-type-start token last-token)
           (throw 'done (if stop-on-class last-token token)))
          )
-        (unless (delphi-is token-kind delphi-whitespace) 
+        (unless (delphi-is token-kind delphi-whitespace)
           (setq last-token token))
         (setq token (delphi-previous-token token)))
       ;; Start not found.
@@ -1031,7 +1031,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
 
 (defun delphi-is-use-clause-end (at-token last-token last-colon from-kind)
   ;; True if we are after the end of a uses type clause.
-  (when (and last-token 
+  (when (and last-token
              (not last-colon)
              (eq 'comma (delphi-token-kind at-token))
              (eq 'semicolon from-kind))
@@ -1141,11 +1141,18 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
                    ;; Indent to use clause keyword.
                    (delphi-line-indent-of token))))
 
+         ;; Assembly sections always indent in from the asm keyword.
+         ((eq token-kind 'asm)
+          (throw 'done (delphi-stmt-line-indent-of token delphi-indent-level)))
+
          ;; An enclosing statement delimits a previous statement.
          ;; We try to use the existing indent of the previous statement,
          ;; otherwise we calculate from the enclosing statement.
          ((delphi-is token-kind delphi-previous-enclosing-statements)
-          (throw 'done (if last-token (delphi-line-indent-of last-token)
+          (throw 'done (if last-token
+                           ;; Otherwise indent to the last token
+                           (delphi-line-indent-of last-token)
+                         ;; Just indent from the enclosing keyword
                          (delphi-line-indent-of token delphi-indent-level))))
 
          ;; A class or record declaration also delimits a previous statement.
@@ -1223,7 +1230,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
 
          ;; An enclosing ":" means a label.
          ((and (eq 'colon token-kind)
-               (delphi-is (delphi-token-kind section-token) 
+               (delphi-is (delphi-token-kind section-token)
                           delphi-block-statements)
                (not last-terminator)
                (not expr-delimited)
@@ -1257,7 +1264,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
         (from-kind (delphi-token-kind from-token))
         (token-kind nil)
         (stmt-start nil)
-        (last-token nil)        
+        (last-token nil)
         (equals-encountered nil)
         (before-equals nil)
         (expr-delimited nil))
@@ -1316,10 +1323,10 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
                  (if stmt-start
                      ;; We are not actually indenting to the case statement,
                      ;; but are within a label expression.
-                     (delphi-stmt-line-indent-of 
+                     (delphi-stmt-line-indent-of
                       stmt-start delphi-indent-level)
                    ;; Indent from the case keyword.
-                   (delphi-stmt-line-indent-of 
+                   (delphi-stmt-line-indent-of
                     token delphi-case-label-indent))))
 
          ;; Body expression statements are enclosing. Indent from the
@@ -1327,7 +1334,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
          ;; it.
          ((delphi-is token-kind delphi-body-expr-statements)
           (throw 'done
-                 (delphi-stmt-line-indent-of 
+                 (delphi-stmt-line-indent-of
                   (or stmt-start token) delphi-indent-level)))
 
          ;; An else statement is enclosing, but it doesn't have an expression.
@@ -1374,6 +1381,10 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
 
                  ((+ (delphi-section-indent-of token) delphi-indent-level)))))
 
+         ;; Assembly sections always indent in from the asm keyword.
+         ((eq token-kind 'asm)
+          (throw 'done (delphi-stmt-line-indent-of token delphi-indent-level)))
+
          ;; Stop at an enclosing statement and indent from it.
          ((delphi-is token-kind delphi-enclosing-statements)
           (throw 'done (delphi-stmt-line-indent-of
@@ -1409,18 +1420,18 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
            ;;          + 2;
            ;; which doesn't look right.
            ;;;; Align binary ops with the before token.
-           ;;((delphi-is from-kind delphi-binary-ops) 
+           ;;((delphi-is from-kind delphi-binary-ops)
            ;;(throw 'done (delphi-indent-of before-equals 0)))
 
            ;; Assignments (:=) we skip over to get a normal indent.
            ((eq (delphi-token-kind last-token) 'equals))
 
            ;; Otherwise indent in from the equals.
-           ((throw 'done 
+           ((throw 'done
                    (delphi-indent-of before-equals delphi-indent-level)))))
 
          ;; Remember any "=" we encounter if it has not already been processed.
-         ((eq token-kind 'equals) 
+         ((eq token-kind 'equals)
           (setq equals-encountered token
                 before-equals last-token))
          )
@@ -1456,7 +1467,7 @@ non-delphi buffer. Set to nil in a delphi buffer.  To override, just do:
 
                   ((delphi-is token-kind delphi-match-block-statements)
                    ;; Use the block's indentation.
-                   (let ((block-start 
+                   (let ((block-start
                           (delphi-block-start token 'stop-on-class)))
                      (cond
                       ;; When trailing a body statement, indent to
@@ -1620,23 +1631,25 @@ before the indent, the point is moved to the indent."
   (delphi-debug-tokenize-region (window-start) (window-end)))
 
 (defun delphi-newline ()
-  "Terminate the current line with a newline and indent the next."
+  "Terminate the current line with a newline and indent the next, unless
+`delphi-newline-always-indents' is nil, in which case no reindenting occurs."
   (interactive)
   ;; Remove trailing spaces
   (delete-horizontal-space)
   (newline)
-  ;; Indent both the (now) previous and current line first.
-  (save-excursion
-    (previous-line 1)
-    (delphi-indent-line))
-  (delphi-indent-line))
+  (when delphi-newline-always-indents
+    ;; Indent both the (now) previous and current line first.
+    (save-excursion
+      (previous-line 1)
+      (delphi-indent-line))
+    (delphi-indent-line)))
 
 
 (defun delphi-tab ()
   "Indent the current line or insert a TAB, depending on the value of
-delphi-tab-always-indent and the current line position."
+`delphi-tab-always-indents' and the current line position."
   (interactive)
-  (if (or delphi-tab-always-indent ; We are always indenting
+  (if (or delphi-tab-always-indents ; We are always indenting
           ;; Or we are before the first non-space character on the line.
           (save-excursion (skip-chars-backward delphi-space-chars) (bolp)))
       (delphi-indent-line)
@@ -1897,9 +1910,9 @@ comment block. If not in a // comment, just does a normal newline."
             (list '("\r" delphi-newline)
                   '("\t" delphi-tab)
                   '("\177" backward-delete-char-untabify)
-                  '("\C-cd" delphi-find-current-def)
-                  '("\C-cx" delphi-find-current-xdef)
-                  '("\C-cb" delphi-find-current-body)
+;;                '("\C-cd" delphi-find-current-def)
+;;                '("\C-cx" delphi-find-current-xdef)
+;;                '("\C-cb" delphi-find-current-body)
                   '("\C-cu" delphi-find-unit)
                   '("\M-q" delphi-fill-comment)
                   '("\M-j" delphi-new-comment-line)
@@ -1916,9 +1929,6 @@ This is ok since we do our own keyword/comment/string face coloring.")
 (defun delphi-mode (&optional skip-initial-parsing)
   "Major mode for editing Delphi code. \\<delphi-mode-map>
 \\[delphi-tab]\t- Indents the current line for Delphi code.
-\\[delphi-find-current-def]\t- Find previous definition of identifier at the point.
-\\[delphi-find-current-xdef]\t- Find definition, but also in external units.
-\\[delphi-find-current-body]\t- Find the body of the identifier at the point.
 \\[delphi-find-unit]\t- Search for a Delphi source file.
 \\[delphi-fill-comment]\t- Fill the current comment.
 \\[delphi-new-comment-line]\t- If in a // comment, do a new comment line.
@@ -1933,9 +1943,13 @@ Customization:
     Extra indentation for blocks in compound statements.
  `delphi-case-label-indent'           (default 0)
     Extra indentation for case statement labels.
- `delphi-tab-always-indent          (default t)
+ `delphi-tab-always-indents'          (default t)
     Non-nil means TAB in Delphi mode should always reindent the current line,
     regardless of where in the line point is when the TAB command is used.
+ `delphi-newline-always-indents'      (default t)
+    Non-nil means NEWLINE in Delphi mode should always reindent the current
+    line, insert a blank line and move to the default indent column of the
+    blank line.
  `delphi-search-path'                 (default .)
     Directories to search when finding external units.
  `delphi-verbose'                     (default nil)
@@ -1978,7 +1992,6 @@ no args, if that value is non-nil."
 
   ;; We need to keep track of changes to the buffer to determine if we need
   ;; to retokenize changed text.
-  (make-local-hook 'after-change-functions)
   (add-hook 'after-change-functions 'delphi-after-change nil t)
 
   (widen)
@@ -1990,3 +2003,6 @@ no args, if that value is non-nil."
        (delphi-progress-done))))
 
   (run-hooks 'delphi-mode-hook))
+
+;;; arch-tag: 410e192d-e9b5-4397-ad62-12340fc3fa41
+;;; delphi.el ends here