diff options
| author | Richard M. Stallman | 1999-07-12 16:14:13 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1999-07-12 16:14:13 +0000 |
| commit | 27b53c17fa043c272724ea33bd83224fac57a677 (patch) | |
| tree | c13add000f250839e43ba93c762aac21470c3b2e | |
| parent | 9658746b2a033069217972dc34bece79f4a41313 (diff) | |
| download | emacs-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.el | 122 |
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. |
| 200 | If this is nil, TAB inserts a tab if it is at the end of the line | 206 | If 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 | |||
| 216 | respectively. The word 'all' will do all lineups. '(case paramlist) for | 222 | respectively. The word 'all' will do all lineups. '(case paramlist) for |
| 217 | instance will do lineup in case-statements and parameterlist, while '(all) | 223 | instance will do lineup in case-statements and parameterlist, while '(all) |
| 218 | will do all lineups." | 224 | will 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 | ||
| 324 | Variables controlling indentation/edit style: | 331 | Variables 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 | ||
| 342 | See also the user variables pascal-type-keywords, pascal-start-keywords and | 351 | See 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) |