X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ffe832ea680b4820f5ff399191f7f2d41350ee2e..b3253cd4b4bcbe1ab4ad1fdc98b30c33af70332c:/lisp/progmodes/delphi.el diff --git a/lisp/progmodes/delphi.el b/lisp/progmodes/delphi.el index d98bb62c0b..2558456bc0 100644 --- a/lisp/progmodes/delphi.el +++ b/lisp/progmodes/delphi.el @@ -1,27 +1,27 @@ ;;; delphi.el --- major mode for editing Delphi source (Object Pascal) in Emacs -;; Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 -;; Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, +;; 2008, 2009, 2010 Free Software Foundation, Inc. -;; Author: Ray Blaak -;; Maintainer: FSF (Blaak's email addr bounces, Aug 2005) +;; Authors: Ray Blaak , +;; Simon South +;; Maintainer: Simon South ;; Keywords: languages ;; This file is part of GNU Emacs. -;; 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 3, or (at your option) any later -;; version. +;; 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 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 MERCHANTABILITY or FITNESS -;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -;; details. +;; GNU Emacs 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -239,10 +239,14 @@ are followed by an expression.") (defconst delphi-decl-sections '(type const var label resourcestring) "Denotes the start of a declaration section.") +(defconst delphi-interface-types '(dispinterface interface) + "Interface types.") + (defconst delphi-class-types '(class object) "Class types.") -(defconst delphi-composite-types `(,@delphi-class-types record) +(defconst delphi-composite-types + `(,@delphi-class-types ,@delphi-interface-types record) "Types that contain declarations within them.") (defconst delphi-unit-sections @@ -624,7 +628,9 @@ routine.") (defun delphi-token-at (p) ;; Returns the token from parsing text at point p. (when (and (<= (point-min) p) (<= p (point-max))) - (cond ((delphi-literal-token-at p)) + (cond ((delphi-char-token-at p ?\n 'newline)) + + ((delphi-literal-token-at p)) ((delphi-space-token-at p)) @@ -634,7 +640,6 @@ routine.") ((delphi-char-token-at p ?\) 'close-group)) ((delphi-char-token-at p ?\[ 'open-group)) ((delphi-char-token-at p ?\] 'close-group)) - ((delphi-char-token-at p ?\n 'newline)) ((delphi-char-token-at p ?\; 'semicolon)) ((delphi-char-token-at p ?. 'dot)) ((delphi-char-token-at p ?, 'comma)) @@ -836,8 +841,9 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do: (delphi-stmt-line-indent-of token delphi-indent-level)))) (defun delphi-composite-type-start (token last-token) - ;; Returns true (actually the last-token) if the pair equals (= class) or (= - ;; record), and nil otherwise. + ;; Returns true (actually the last-token) if the pair equals (= class), (= + ;; dispinterface), (= interface), (= object), or (= record), and nil + ;; otherwise. (if (and (eq 'equals (delphi-token-kind token)) (delphi-is (delphi-token-kind last-token) delphi-composite-types)) last-token)) @@ -883,7 +889,24 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do: (setq token (delphi-block-start token))) ;; Regular block start found. - ((delphi-is token-kind delphi-block-statements) (throw 'done token)) + ((delphi-is token-kind delphi-block-statements) + (throw 'done + ;; As a special case, when a "case" block appears + ;; within a record declaration (to denote a variant + ;; part), the record declaration should be considered + ;; the enclosing block. + (if (eq 'case token-kind) + (let ((enclosing-token + (delphi-block-start token + 'stop-on-class))) + (if + (eq 'record + (delphi-token-kind enclosing-token)) + (if stop-on-class + enclosing-token + (delphi-previous-token enclosing-token)) + token)) + token))) ;; A class/record start also begins a block. ((delphi-composite-type-start token last-token) @@ -1053,6 +1076,7 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do: (token-kind nil) (from-kind (delphi-token-kind from-token)) (last-colon nil) + (last-of nil) (last-token nil)) (catch 'done (while token @@ -1096,9 +1120,17 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do: ;; Ignore whitespace. ((delphi-is token-kind delphi-whitespace)) - ;; Remember any ':' we encounter, since that affects how we indent to - ;; a case statement. - ((eq 'colon token-kind) (setq last-colon token)) + ;; Remember any "of" we encounter, since that affects how we + ;; indent to a case statement within a record declaration + ;; (i.e. a variant part). + ((eq 'of token-kind) + (setq last-of token)) + + ;; Remember any ':' we encounter (until we reach an "of"), + ;; since that affects how we indent to case statements in + ;; general. + ((eq 'colon token-kind) + (unless last-of (setq last-colon token))) ;; A case statement delimits a previous statement. We indent labels ;; specially. @@ -1328,7 +1360,29 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do: delphi-indent-level))) ;; In unit sections we indent right to the left. - ((delphi-is token-kind delphi-unit-sections) (throw 'done 0)) + ((delphi-is token-kind delphi-unit-sections) + (throw 'done + ;; Handle specially the case of "interface", which can be used + ;; to start either a unit section or an interface definition. + (if (delphi-is token-kind delphi-interface-types) + (progn + ;; Find the previous non-whitespace token. + (while (progn + (setq last-token token + token (delphi-previous-token token) + token-kind (delphi-token-kind token)) + (and token + (delphi-is token-kind + delphi-whitespace)))) + ;; If this token is an equals sign, "interface" is being + ;; used to start an interface definition and we should + ;; treat it as a composite type; otherwise, we should + ;; consider it the start of a unit section. + (if (and token (eq token-kind 'equals)) + (delphi-line-indent-of last-token + delphi-indent-level) + 0)) + 0))) ;; A previous terminator means we can stop. ((delphi-is token-kind delphi-previous-terminators) @@ -1343,7 +1397,7 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do: ;; Indent in from the expression. (delphi-indent-of last-token delphi-indent-level)) - ;; No enclosing expression; use the previous statment's + ;; No enclosing expression; use the previous statement's ;; indent. ((delphi-previous-indent-of token))))) @@ -1625,14 +1679,23 @@ before the indent, the point is moved to the indent." (defun delphi-tab () - "Indent the current line or insert a TAB, depending on the value of -`delphi-tab-always-indents' and the current line position." + "Indent the region, when Transient Mark mode is enabled and the region is +active. Otherwise, indent the current line or insert a TAB, depending on the +value of `delphi-tab-always-indents' and the current line position." (interactive) - (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) - (insert "\t"))) + (cond ((use-region-p) + ;; If Transient Mark mode is enabled and the region is active, indent + ;; the entire region. + (indent-region (region-beginning) (region-end))) + ((or delphi-tab-always-indents + (save-excursion (skip-chars-backward delphi-space-chars) (bolp))) + ;; Otherwise, if we are configured always to indent (regardless of the + ;; point's position in the line) or we are before the first non-space + ;; character on the line, indent the line. + (delphi-indent-line)) + (t + ;; Otherwise, insert a tab character. + (insert "\t")))) (defun delphi-is-directory (path) @@ -1908,7 +1971,8 @@ This is ok since we do our own keyword/comment/string face coloring.") ;;;###autoload (defun delphi-mode (&optional skip-initial-parsing) "Major mode for editing Delphi code. \\ -\\[delphi-tab]\t- Indents the current line for Delphi code. +\\[delphi-tab]\t- Indents the current line (or region, if Transient Mark mode +\t is enabled and the region is active) of Delphi code. \\[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. @@ -1984,5 +2048,5 @@ no args, if that value is non-nil." (run-mode-hooks 'delphi-mode-hook)) -;;; arch-tag: 410e192d-e9b5-4397-ad62-12340fc3fa41 +;; arch-tag: 410e192d-e9b5-4397-ad62-12340fc3fa41 ;;; delphi.el ends here