aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1999-07-12 16:14:13 +0000
committerRichard M. Stallman1999-07-12 16:14:13 +0000
commit27b53c17fa043c272724ea33bd83224fac57a677 (patch)
treec13add000f250839e43ba93c762aac21470c3b2e
parent9658746b2a033069217972dc34bece79f4a41313 (diff)
downloademacs-27b53c17fa043c272724ea33bd83224fac57a677.tar.gz
emacs-27b53c17fa043c272724ea33bd83224fac57a677.zip
(pascal-beg-of-defun): More intuitive behavior when having nested functons.
(pascal-indent-nested-functions) (pascal-indent-line) (pascal-calculate-indent) (pascal-get-lineup-indent): Support for indenting nested functions.
-rw-r--r--lisp/progmodes/pascal.el122
1 files changed, 78 insertions, 44 deletions
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
index 3cbfc5c8fd2..d27a84543d6 100644
--- a/lisp/progmodes/pascal.el
+++ b/lisp/progmodes/pascal.el
@@ -1,6 +1,6 @@
1;;; pascal.el --- major mode for editing pascal source in Emacs 1;;; pascal.el --- major mode for editing pascal source in Emacs
2 2
3;; Copyright (C) 1993, 1994, 95, 96, 97, 1998 Free Software Foundation, Inc. 3;; Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
4 4
5;; Author: Espen Skoglund <espensk@stud.cs.uit.no> 5;; Author: Espen Skoglund <espensk@stud.cs.uit.no>
6;; Keywords: languages 6;; Keywords: languages
@@ -119,6 +119,7 @@
119(defconst pascal-beg-block-re "\\<\\(begin\\|case\\|record\\|repeat\\)\\>") 119(defconst pascal-beg-block-re "\\<\\(begin\\|case\\|record\\|repeat\\)\\>")
120(defconst pascal-end-block-re "\\<\\(end\\|until\\)\\>") 120(defconst pascal-end-block-re "\\<\\(end\\|until\\)\\>")
121(defconst pascal-declaration-re "\\<\\(const\\|label\\|type\\|var\\)\\>") 121(defconst pascal-declaration-re "\\<\\(const\\|label\\|type\\|var\\)\\>")
122(defconst pascal-progbeg-re "\\<\\program\\>")
122(defconst pascal-defun-re "\\<\\(function\\|procedure\\|program\\)\\>") 123(defconst pascal-defun-re "\\<\\(function\\|procedure\\|program\\)\\>")
123(defconst pascal-sub-block-re "\\<\\(if\\|else\\|for\\|while\\|with\\)\\>") 124(defconst pascal-sub-block-re "\\<\\(if\\|else\\|for\\|while\\|with\\)\\>")
124(defconst pascal-noindent-re "\\<\\(begin\\|end\\|until\\|else\\)\\>") 125(defconst pascal-noindent-re "\\<\\(begin\\|end\\|until\\|else\\)\\>")
@@ -195,6 +196,11 @@ These include after semicolons and after the punctuation mark after an `end'."
195 :type 'boolean 196 :type 'boolean
196 :group 'pascal) 197 :group 'pascal)
197 198
199(defcustom pascal-indent-nested-functions t
200 "*Non-nil means nested functions are indented."
201 :type 'boolean
202 :group 'pascal)
203
198(defcustom pascal-tab-always-indent t 204(defcustom pascal-tab-always-indent t
199 "*Non-nil means TAB in Pascal mode should always reindent the current line. 205 "*Non-nil means TAB in Pascal mode should always reindent the current line.
200If this is nil, TAB inserts a tab if it is at the end of the line 206If this is nil, TAB inserts a tab if it is at the end of the line
@@ -216,10 +222,11 @@ do auto lineup in parameterlist, declarations or case-statements
216respectively. The word 'all' will do all lineups. '(case paramlist) for 222respectively. The word 'all' will do all lineups. '(case paramlist) for
217instance will do lineup in case-statements and parameterlist, while '(all) 223instance will do lineup in case-statements and parameterlist, while '(all)
218will do all lineups." 224will do all lineups."
219 :type '(repeat (choice (const all) 225 :type '(set :extra-offset 8
220 (const paramlist) 226 (const :tag "Everything" all)
221 (const declaration) 227 (const :tag "Parameter lists" paramlist)
222 (const case))) 228 (const :tag "Decalrations" declaration)
229 (const :tag "Case statements" case))
223 :group 'pascal) 230 :group 'pascal)
224 231
225(defcustom pascal-toggle-completions nil 232(defcustom pascal-toggle-completions nil
@@ -323,20 +330,22 @@ Other useful functions are:
323 330
324Variables controlling indentation/edit style: 331Variables controlling indentation/edit style:
325 332
326 pascal-indent-level (default 3) 333 pascal-indent-level (default 3)
327 Indentation of Pascal statements with respect to containing block. 334 Indentation of Pascal statements with respect to containing block.
328 pascal-case-indent (default 2) 335 pascal-case-indent (default 2)
329 Indentation for case statements. 336 Indentation for case statements.
330 pascal-auto-newline (default nil) 337 pascal-auto-newline (default nil)
331 Non-nil means automatically newline after semicolons and the punctuation 338 Non-nil means automatically newline after semicolons and the punctuation
332 mark after an end. 339 mark after an end.
340 pascal-indent-nested-functions (default t)
341 Non-nil means nested functions are indented.
333 pascal-tab-always-indent (default t) 342 pascal-tab-always-indent (default t)
334 Non-nil means TAB in Pascal mode should always reindent the current line, 343 Non-nil means TAB in Pascal mode should always reindent the current line,
335 regardless of where in the line point is when the TAB command is used. 344 regardless of where in the line point is when the TAB command is used.
336 pascal-auto-endcomments (default t) 345 pascal-auto-endcomments (default t)
337 Non-nil means a comment { ... } is set after the ends which ends cases and 346 Non-nil means a comment { ... } is set after the ends which ends cases and
338 functions. The name of the function or case will be set between the braces. 347 functions. The name of the function or case will be set between the braces.
339 pascal-auto-lineup (default t) 348 pascal-auto-lineup (default t)
340 List of contexts where auto lineup of :'s or ='s should be done. 349 List of contexts where auto lineup of :'s or ='s should be done.
341 350
342See also the user variables pascal-type-keywords, pascal-start-keywords and 351See also the user variables pascal-type-keywords, pascal-start-keywords and
@@ -611,7 +620,7 @@ area. See also `pascal-comment-area'."
611 (setq func (1+ func))) 620 (setq func (1+ func)))
612 (setq nest (1- nest))) 621 (setq nest (1- nest)))
613 ((match-end 3) ; function|procedure 622 ((match-end 3) ; function|procedure
614 (if (or (> nest 0) (= 0 func)) 623 (if (= 0 func)
615 (throw 'found t) 624 (throw 'found t)
616 (setq func (1- func))))))) 625 (setq func (1- func)))))))
617 nil)) 626 nil))
@@ -777,7 +786,7 @@ on the line which ends a function or procedure named NAME."
777 (paramlist . (pascal-indent-paramlist t)) 786 (paramlist . (pascal-indent-paramlist t))
778 (comment . (pascal-indent-comment t)) 787 (comment . (pascal-indent-comment t))
779 (defun . ind) (contexp . ind) 788 (defun . ind) (contexp . ind)
780 (unknown . 0) (string . 0))) 789 (unknown . ind) (string . 0) (progbeg . 0)))
781 790
782(defun pascal-indent-command () 791(defun pascal-indent-command ()
783 "Indent for special part of code." 792 "Indent for special part of code."
@@ -805,20 +814,27 @@ on the line which ends a function or procedure named NAME."
805 (let* ((indent-str (pascal-calculate-indent)) 814 (let* ((indent-str (pascal-calculate-indent))
806 (type (car indent-str)) 815 (type (car indent-str))
807 (ind (car (cdr indent-str)))) 816 (ind (car (cdr indent-str))))
808 (if (looking-at "^[0-9a-zA-Z]+[ \t]*:[^=]") 817 ;; Labels should not be indented.
818 (if (and (looking-at "^[0-9a-zA-Z]+[ \t]*:[^=]")
819 (not (eq type 'declaration)))
809 (search-forward ":" nil t)) 820 (search-forward ":" nil t))
810 (delete-horizontal-space) 821 (delete-horizontal-space)
811 ;; Some things should not be indented 822 (cond (; Some things should not be indented
812 (if (or (and (eq type 'declaration) (looking-at pascal-declaration-re)) 823 (or (and (eq type 'declaration) (looking-at pascal-declaration-re))
813 (eq type 'cpp) 824 (eq type 'cpp))
814 (looking-at pascal-defun-re)) 825 ())
815 () 826 (; Other things should have no extra indent
816 ;; Other things should have no extra indent 827 (looking-at pascal-noindent-re)
817 (if (looking-at pascal-noindent-re) 828 (indent-to ind))
818 (indent-to ind) 829 (; Nested functions should be indented
819 ;; But most lines are treated this way: 830 (looking-at pascal-defun-re)
820 (indent-to (eval (cdr (assoc type pascal-indent-alist)))) 831 (if (and pascal-indent-nested-functions
821 )))) 832 (eq type 'defun))
833 (indent-to (+ ind pascal-indent-level))
834 (indent-to ind)))
835 (; But most lines are treated this way
836 (indent-to (eval (cdr (assoc type pascal-indent-alist))))
837 ))))
822 838
823(defun pascal-calculate-indent () 839(defun pascal-calculate-indent ()
824 "Calculate the indent of the current Pascal line. 840 "Calculate the indent of the current Pascal line.
@@ -828,7 +844,8 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
828 (oldpos (point)) 844 (oldpos (point))
829 (state (save-excursion (parse-partial-sexp (point-min) (point)))) 845 (state (save-excursion (parse-partial-sexp (point-min) (point))))
830 (nest 0) (par 0) (complete (looking-at "[ \t]*end\\>")) 846 (nest 0) (par 0) (complete (looking-at "[ \t]*end\\>"))
831 (elsed (looking-at "[ \t]*else\\>")) 847 (elsed (looking-at "[ \t]*else\\>")) (funccnt 0)
848 (did-func (looking-at "[ \t]*\\(procedure\\|function\\)\\>"))
832 (type (catch 'nesting 849 (type (catch 'nesting
833 ;; Check if inside a string, comment or parenthesis 850 ;; Check if inside a string, comment or parenthesis
834 (cond ((nth 3 state) (throw 'nesting 'string)) 851 (cond ((nth 3 state) (throw 'nesting 'string))
@@ -855,6 +872,12 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
855 (point)) 872 (point))
856 (point))) 873 (point)))
857 (throw 'nesting 'caseblock)) 874 (throw 'nesting 'caseblock))
875 (;--Beginning of program
876 (looking-at pascal-progbeg-re)
877 (throw 'nesting 'progbeg))
878 (;--No known statements
879 (bobp)
880 (throw 'nesting 'progbeg))
858 (;--Nest block outwards 881 (;--Nest block outwards
859 (looking-at pascal-beg-block-re) 882 (looking-at pascal-beg-block-re)
860 (if (= nest 0) 883 (if (= nest 0)
@@ -863,16 +886,26 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
863 ((looking-at "record\\>") 886 ((looking-at "record\\>")
864 (throw 'nesting 'declaration)) 887 (throw 'nesting 'declaration))
865 (t (throw 'nesting 'block))) 888 (t (throw 'nesting 'block)))
889 (if (and (looking-at "record\\>") (= nest 1))
890 (setq funccnt (1- funccnt)))
866 (setq nest (1- nest)))) 891 (setq nest (1- nest))))
867 (;--Nest block inwards 892 (;--Nest block inwards
868 (looking-at pascal-end-block-re) 893 (looking-at pascal-end-block-re)
869 (if (and (looking-at "end\\s ") 894 (if (and (looking-at "end\\s ")
870 elsed (not complete)) 895 elsed (not complete))
871 (throw 'nesting 'block)) 896 (throw 'nesting 'block))
897 (if (= nest 0)
898 (setq funccnt (1+ funccnt)))
872 (setq complete t 899 (setq complete t
873 nest (1+ nest))) 900 nest (1+ nest)))
874 (;--Defun (or parameter list) 901 (;--Defun (or parameter list)
875 (looking-at pascal-defun-re) 902 (and (looking-at pascal-defun-re)
903 (progn (setq funccnt (1- funccnt)
904 did-func t)
905 (or (bolp) (< funccnt 0))))
906 ;; Prevent searching whole buffer
907 (if (and (bolp) (>= funccnt 0))
908 (throw 'nesting 'progbeg))
876 (if (= 0 par) 909 (if (= 0 par)
877 (throw 'nesting 'defun) 910 (throw 'nesting 'defun)
878 (setq par 0) 911 (setq par 0)
@@ -886,7 +919,9 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
886 (throw 'nesting 'declaration) 919 (throw 'nesting 'declaration)
887 (throw 'nesting 'paramlist))))) 920 (throw 'nesting 'paramlist)))))
888 (;--Declaration part 921 (;--Declaration part
889 (looking-at pascal-declaration-re) 922 (and (looking-at pascal-declaration-re)
923 (not did-func)
924 (= funccnt 0))
890 (if (save-excursion 925 (if (save-excursion
891 (goto-char oldpos) 926 (goto-char oldpos)
892 (forward-line -1) 927 (forward-line -1)
@@ -897,9 +932,6 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
897 (and (not complete) 932 (and (not complete)
898 (looking-at pascal-sub-block-re)) 933 (looking-at pascal-sub-block-re))
899 (throw 'nesting 'block)) 934 (throw 'nesting 'block))
900 (;--No known statements
901 (bobp)
902 (throw 'nesting 'unknown))
903 (;--Found complete statement 935 (;--Found complete statement
904 (save-excursion (forward-sexp 1) 936 (save-excursion (forward-sexp 1)
905 (= (following-char) ?\;)) 937 (= (following-char) ?\;))
@@ -1052,23 +1084,25 @@ indent of the current line in parameterlist."
1052(defun pascal-get-lineup-indent (b e str) 1084(defun pascal-get-lineup-indent (b e str)
1053 (save-excursion 1085 (save-excursion
1054 (let ((ind 0) 1086 (let ((ind 0)
1055 (reg (concat str "\\|\\(\\<record\\>\\)"))) 1087 (reg (concat str "\\|\\(\\<record\\>\\)\\|" pascal-defun-re)))
1056 (goto-char b) 1088 (goto-char b)
1057 ;; Get rightmost position 1089 ;; Get rightmost position
1058 (while (< (point) e) 1090 (while (< (point) e)
1059 (if (re-search-forward reg (min e (pascal-get-end-of-line 2)) 'move) 1091 (and (re-search-forward reg (min e (pascal-get-end-of-line 2)) 'move)
1060 (progn 1092 (cond ((match-beginning 1)
1061 ;; Skip record blocks 1093 ;; Skip record blocks
1062 (if (match-beginning 1) 1094 (pascal-declaration-end))
1063 (pascal-declaration-end) 1095 ((match-beginning 2)
1064 (progn 1096 ;; We have entered a new procedure. Exit.
1065 (goto-char (match-beginning 0)) 1097 (goto-char e))
1066 (skip-chars-backward " \t") 1098 (t
1067 (if (> (current-column) ind) 1099 (goto-char (match-beginning 0))
1068 (setq ind (current-column))) 1100 (skip-chars-backward " \t")
1069 (goto-char (match-end 0)) 1101 (if (> (current-column) ind)
1070 (end-of-line) 1102 (setq ind (current-column)))
1071 ))))) 1103 (goto-char (match-end 0))
1104 (end-of-line)
1105 ))))
1072 ;; In case no lineup was found 1106 ;; In case no lineup was found
1073 (if (> ind 0) 1107 (if (> ind 0)
1074 (1+ ind) 1108 (1+ ind)