diff options
| author | Richard M. Stallman | 1994-09-03 03:34:55 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-09-03 03:34:55 +0000 |
| commit | 3a3ee4454ba715bb39b0627f0f6886b81c9203fc (patch) | |
| tree | 10b868b193f9ec7e19139b485c6ba73ab9923f01 | |
| parent | e8c138c21b7b8320d8ae350c741c793552afab25 (diff) | |
| download | emacs-3a3ee4454ba715bb39b0627f0f6886b81c9203fc.tar.gz emacs-3a3ee4454ba715bb39b0627f0f6886b81c9203fc.zip | |
(pascal-auto-lineup): New variable.
(pascal-end-of-statement): New function.
(pascal-indent-command): Now does optional lineups of : and =.
(pascal-indent-case): Uses pascal-end-of-statement to skip the
case statements.
(pascal-indent-declaration): Indent correctly
when record blocks are used within parameterlists.
(pascal-declaration-beg): Strange -0 argument removed.
(pascal-type-completion): Fix typo in regexp.
(pascal-get-lineup-indent): Use match-end instead of end-of-line.
| -rw-r--r-- | lisp/progmodes/pascal.el | 136 |
1 files changed, 103 insertions, 33 deletions
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el index c89ff26e7d0..bdc2cb689ba 100644 --- a/lisp/progmodes/pascal.el +++ b/lisp/progmodes/pascal.el | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | ;;; pascal-auto-newline nil | 40 | ;;; pascal-auto-newline nil |
| 41 | ;;; pascal-tab-always-indent t | 41 | ;;; pascal-tab-always-indent t |
| 42 | ;;; pascal-auto-endcomments t | 42 | ;;; pascal-auto-endcomments t |
| 43 | ;;; pascal-auto-lineup '(all) | ||
| 43 | ;;; pascal-toggle-completions nil | 44 | ;;; pascal-toggle-completions nil |
| 44 | ;;; pascal-type-keywords '("array" "file" "packed" "char" | 45 | ;;; pascal-type-keywords '("array" "file" "packed" "char" |
| 45 | ;;; "integer" "real" "string" "record") | 46 | ;;; "integer" "real" "string" "record") |
| @@ -58,8 +59,8 @@ | |||
| 58 | 59 | ||
| 59 | ;;; Code: | 60 | ;;; Code: |
| 60 | 61 | ||
| 61 | (defconst pascal-mode-version "2.1a" | 62 | (defconst pascal-mode-version "2.3" |
| 62 | "Version of `pascal-mode.el'.") | 63 | "Version of `pascal.el'.") |
| 63 | 64 | ||
| 64 | (defvar pascal-mode-abbrev-table nil | 65 | (defvar pascal-mode-abbrev-table nil |
| 65 | "Abbrev table in use in Pascal-mode buffers.") | 66 | "Abbrev table in use in Pascal-mode buffers.") |
| @@ -147,27 +148,42 @@ | |||
| 147 | 148 | ||
| 148 | (defvar pascal-indent-level 3 | 149 | (defvar pascal-indent-level 3 |
| 149 | "*Indentation of Pascal statements with respect to containing block.") | 150 | "*Indentation of Pascal statements with respect to containing block.") |
| 151 | |||
| 150 | (defvar pascal-case-indent 2 | 152 | (defvar pascal-case-indent 2 |
| 151 | "*Indentation for case statements.") | 153 | "*Indentation for case statements.") |
| 154 | |||
| 152 | (defvar pascal-auto-newline nil | 155 | (defvar pascal-auto-newline nil |
| 153 | "*Non-nil means automatically newline after simcolons and the punctation mark | 156 | "*Non-nil means automatically newline after simcolons and the punctation mark |
| 154 | after an end.") | 157 | after an end.") |
| 158 | |||
| 155 | (defvar pascal-tab-always-indent t | 159 | (defvar pascal-tab-always-indent t |
| 156 | "*Non-nil means TAB in Pascal mode should always reindent the current line, | 160 | "*Non-nil means TAB in Pascal mode should always reindent the current line, |
| 157 | regardless of where in the line point is when the TAB command is used.") | 161 | regardless of where in the line point is when the TAB command is used.") |
| 162 | |||
| 158 | (defvar pascal-auto-endcomments t | 163 | (defvar pascal-auto-endcomments t |
| 159 | "*Non-nil means a comment { ... } is set after the ends which ends cases and | 164 | "*Non-nil means a comment { ... } is set after the ends which ends cases and |
| 160 | functions. The name of the function or case will be set between the braces.") | 165 | functions. The name of the function or case will be set between the braces.") |
| 166 | |||
| 167 | (defvar pascal-auto-lineup '(all) | ||
| 168 | "*List of contexts where auto lineup of :'s or ='s should be done. | ||
| 169 | Elements can be of type: 'paramlist', 'declaration' or 'case', which will | ||
| 170 | do auto lineup in parameterlist, declarations or case-statements | ||
| 171 | respectively. The word 'all' will do all lineups. '(case paramlist) for | ||
| 172 | instance will do lineup in case-statements and parameterlist, while '(all) | ||
| 173 | will do all lineups.") | ||
| 174 | |||
| 161 | (defvar pascal-toggle-completions nil | 175 | (defvar pascal-toggle-completions nil |
| 162 | "*Non-nil means that \\<pascal-mode-map>\\[pascal-complete-label] should \ | 176 | "*Non-nil means that \\<pascal-mode-map>\\[pascal-complete-label] should \ |
| 163 | not display a completion buffer when | 177 | not display a completion buffer when |
| 164 | the label couldn't be completed, but instead toggle the possible completions | 178 | the label couldn't be completed, but instead toggle the possible completions |
| 165 | with repeated \\[pascal-complete-label]'s.") | 179 | with repeated \\[pascal-complete-label]'s.") |
| 180 | |||
| 166 | (defvar pascal-type-keywords | 181 | (defvar pascal-type-keywords |
| 167 | '("array" "file" "packed" "char" "integer" "real" "string" "record") | 182 | '("array" "file" "packed" "char" "integer" "real" "string" "record") |
| 168 | "*Keywords for types used when completing a word in a declaration or parmlist. | 183 | "*Keywords for types used when completing a word in a declaration or parmlist. |
| 169 | \(eg. integer, real, char.) The types defined within the Pascal program | 184 | \(eg. integer, real, char.) The types defined within the Pascal program |
| 170 | will be completed runtime, and should not be added to this list.") | 185 | will be completed runtime, and should not be added to this list.") |
| 186 | |||
| 171 | (defvar pascal-start-keywords | 187 | (defvar pascal-start-keywords |
| 172 | '("begin" "end" "function" "procedure" "repeat" "until" "while" | 188 | '("begin" "end" "function" "procedure" "repeat" "until" "while" |
| 173 | "read" "readln" "reset" "rewrite" "write" "writeln") | 189 | "read" "readln" "reset" "rewrite" "write" "writeln") |
| @@ -175,6 +191,7 @@ will be completed runtime, and should not be added to this list.") | |||
| 175 | \(eg. begin, repeat, until, readln.) | 191 | \(eg. begin, repeat, until, readln.) |
| 176 | The procedures and variables defined within the Pascal program | 192 | The procedures and variables defined within the Pascal program |
| 177 | will be completed runtime and should not be added to this list.") | 193 | will be completed runtime and should not be added to this list.") |
| 194 | |||
| 178 | (defvar pascal-separator-keywords | 195 | (defvar pascal-separator-keywords |
| 179 | '("downto" "else" "mod" "div" "then") | 196 | '("downto" "else" "mod" "div" "then") |
| 180 | "*Keywords to complete when NOT standing at the first word of a statement. | 197 | "*Keywords to complete when NOT standing at the first word of a statement. |
| @@ -205,14 +222,16 @@ Pascal program are completed runtime and should not be added to this list.") | |||
| 205 | (cond ((match-beginning 1) (setq nest (1+ nest))) | 222 | (cond ((match-beginning 1) (setq nest (1+ nest))) |
| 206 | ((match-beginning 2) (setq nest (1- nest))))))) | 223 | ((match-beginning 2) (setq nest (1- nest))))))) |
| 207 | 224 | ||
| 225 | |||
| 208 | (defun pascal-declaration-beg () | 226 | (defun pascal-declaration-beg () |
| 209 | (let ((nest 1)) | 227 | (let ((nest 1)) |
| 210 | (while (and (> nest 0) | 228 | (while (and (> nest 0) |
| 211 | (re-search-backward "[:=]\\|\\<\\(type\\|var\\|label\\|const\\)\\>\\|\\(\\<record\\>\\)\\|\\(\\<end\\>\\)" (pascal-get-beg-of-line -0) t)) | 229 | (re-search-backward "[:=]\\|\\<\\(type\\|var\\|label\\|const\\)\\>\\|\\(\\<record\\>\\)\\|\\(\\<end\\>\\)" (pascal-get-beg-of-line 0) t)) |
| 212 | (cond ((match-beginning 1) (setq nest 0)) | 230 | (cond ((match-beginning 1) (setq nest 0)) |
| 213 | ((match-beginning 2) (setq nest (1- nest))) | 231 | ((match-beginning 2) (setq nest (1- nest))) |
| 214 | ((match-beginning 3) (setq nest (1+ nest))))) | 232 | ((match-beginning 3) (setq nest (1+ nest))))) |
| 215 | (= nest 0))) | 233 | (= nest 0))) |
| 234 | |||
| 216 | 235 | ||
| 217 | (defsubst pascal-within-string () | 236 | (defsubst pascal-within-string () |
| 218 | (save-excursion | 237 | (save-excursion |
| @@ -250,12 +269,14 @@ Variables controlling indentation/edit style: | |||
| 250 | pascal-auto-newline (default nil) | 269 | pascal-auto-newline (default nil) |
| 251 | Non-nil means automatically newline after simcolons and the punctation mark | 270 | Non-nil means automatically newline after simcolons and the punctation mark |
| 252 | after an end. | 271 | after an end. |
| 253 | pascal-tab-always-indent (defualt t) | 272 | pascal-tab-always-indent (default t) |
| 254 | Non-nil means TAB in Pascal mode should always reindent the current line, | 273 | Non-nil means TAB in Pascal mode should always reindent the current line, |
| 255 | regardless of where in the line point is when the TAB command is used. | 274 | regardless of where in the line point is when the TAB command is used. |
| 256 | pascal-auto-endcomments (default t) | 275 | pascal-auto-endcomments (default t) |
| 257 | Non-nil means a comment { ... } is set after the ends which ends cases and | 276 | Non-nil means a comment { ... } is set after the ends which ends cases and |
| 258 | functions. The name of the function or case will be set between the braces. | 277 | functions. The name of the function or case will be set between the braces. |
| 278 | pascal-auto-lineup (default t) | ||
| 279 | List of contexts where auto lineup of :'s or ='s hould be done. | ||
| 259 | 280 | ||
| 260 | See also the user variables pascal-type-keywords, pascal-start-keywords and | 281 | See also the user variables pascal-type-keywords, pascal-start-keywords and |
| 261 | pascal-separator-keywords. | 282 | pascal-separator-keywords. |
| @@ -537,6 +558,43 @@ area. See also `pascal-comment-area'." | |||
| 537 | (setq func (1+ func)))))) | 558 | (setq func (1+ func)))))) |
| 538 | (forward-line 1)) | 559 | (forward-line 1)) |
| 539 | 560 | ||
| 561 | (defun pascal-end-of-statement () | ||
| 562 | "Move forward to end of current statement." | ||
| 563 | (interactive) | ||
| 564 | (let ((nest 0) pos | ||
| 565 | (regexp (concat "\\(" pascal-beg-block-re "\\)\\|\\(" | ||
| 566 | pascal-end-block-re "\\)"))) | ||
| 567 | (if (not (looking-at "[ \t\n]")) (forward-sexp -1)) | ||
| 568 | (or (looking-at pascal-beg-block-re) | ||
| 569 | ;; Skip to end of statement | ||
| 570 | (setq pos (catch 'found | ||
| 571 | (while t | ||
| 572 | (forward-sexp 1) | ||
| 573 | (cond ((looking-at "[ \t]*;") | ||
| 574 | (skip-chars-forward "^;") | ||
| 575 | (forward-char 1) | ||
| 576 | (throw 'found (point))) | ||
| 577 | ((save-excursion | ||
| 578 | (forward-sexp -1) | ||
| 579 | (looking-at pascal-beg-block-re)) | ||
| 580 | (goto-char (match-beginning 0)) | ||
| 581 | (throw 'found nil)) | ||
| 582 | ((eobp) | ||
| 583 | (throw 'found (point)))))))) | ||
| 584 | (if (not pos) | ||
| 585 | ;; Skip a whole block | ||
| 586 | (catch 'found | ||
| 587 | (while t | ||
| 588 | (re-search-forward regexp nil 'move) | ||
| 589 | (setq nest (if (match-end 1) | ||
| 590 | (1+ nest) | ||
| 591 | (1- nest))) | ||
| 592 | (cond ((eobp) | ||
| 593 | (throw 'found (point))) | ||
| 594 | ((= 0 nest) | ||
| 595 | (throw 'found (pascal-end-of-statement)))))) | ||
| 596 | pos))) | ||
| 597 | |||
| 540 | (defun pascal-downcase-keywords () | 598 | (defun pascal-downcase-keywords () |
| 541 | "Downcase all Pascal keywords in the buffer." | 599 | "Downcase all Pascal keywords in the buffer." |
| 542 | (interactive) | 600 | (interactive) |
| @@ -634,12 +692,18 @@ on the line which ends a function or procedure named NAME." | |||
| 634 | (let* ((indent-str (pascal-calculate-indent)) | 692 | (let* ((indent-str (pascal-calculate-indent)) |
| 635 | (type (car indent-str)) | 693 | (type (car indent-str)) |
| 636 | (ind (car (cdr indent-str)))) | 694 | (ind (car (cdr indent-str)))) |
| 637 | (cond ((eq type 'paramlist) | 695 | (cond ((and (eq type 'paramlist) |
| 696 | (or (memq 'all pascal-auto-lineup) | ||
| 697 | (memq 'paramlist pascal-auto-lineup))) | ||
| 638 | (pascal-indent-paramlist) | 698 | (pascal-indent-paramlist) |
| 639 | (pascal-indent-paramlist)) | 699 | (pascal-indent-paramlist)) |
| 640 | ((eq type 'declaration) | 700 | ((and (eq type 'declaration) |
| 701 | (or (memq 'all pascal-auto-lineup) | ||
| 702 | (memq 'declaration pascal-auto-lineup))) | ||
| 641 | (pascal-indent-declaration)) | 703 | (pascal-indent-declaration)) |
| 642 | ((and (eq type 'case) (not (looking-at "^[ \t]*$"))) | 704 | ((and (eq type 'case) (not (looking-at "^[ \t]*$")) |
| 705 | (or (memq 'all pascal-auto-lineup) | ||
| 706 | (memq 'case pascal-auto-lineup))) | ||
| 643 | (pascal-indent-case))) | 707 | (pascal-indent-case))) |
| 644 | (if (looking-at "[ \t]+$") | 708 | (if (looking-at "[ \t]+$") |
| 645 | (skip-chars-forward " \t")))) | 709 | (skip-chars-forward " \t")))) |
| @@ -766,7 +830,7 @@ column number the line should be indented to." | |||
| 766 | (end-of-line) | 830 | (end-of-line) |
| 767 | (point-marker) | 831 | (point-marker) |
| 768 | (re-search-backward "\\<case\\>" nil t))) | 832 | (re-search-backward "\\<case\\>" nil t))) |
| 769 | (beg (point)) | 833 | (beg (point)) oldpos |
| 770 | (ind 0)) | 834 | (ind 0)) |
| 771 | ;; Get right indent | 835 | ;; Get right indent |
| 772 | (while (< (point) (marker-position end)) | 836 | (while (< (point) (marker-position end)) |
| @@ -777,8 +841,9 @@ column number the line should be indented to." | |||
| 777 | (delete-horizontal-space) | 841 | (delete-horizontal-space) |
| 778 | (if (> (current-column) ind) | 842 | (if (> (current-column) ind) |
| 779 | (setq ind (current-column))) | 843 | (setq ind (current-column))) |
| 780 | (beginning-of-line 2)) | 844 | (pascal-end-of-statement)) |
| 781 | (goto-char beg) | 845 | (goto-char beg) |
| 846 | (setq oldpos (marker-position end)) | ||
| 782 | ;; Indent all case statements | 847 | ;; Indent all case statements |
| 783 | (while (< (point) (marker-position end)) | 848 | (while (< (point) (marker-position end)) |
| 784 | (if (re-search-forward | 849 | (if (re-search-forward |
| @@ -790,7 +855,10 @@ column number the line should be indented to." | |||
| 790 | () | 855 | () |
| 791 | (forward-char 1) | 856 | (forward-char 1) |
| 792 | (delete-horizontal-space) | 857 | (delete-horizontal-space) |
| 793 | (insert " "))))) | 858 | (insert " ")) |
| 859 | (setq oldpos (point)) | ||
| 860 | (pascal-end-of-statement)) | ||
| 861 | (goto-char oldpos))) | ||
| 794 | 862 | ||
| 795 | (defun pascal-indent-paramlist (&optional arg) | 863 | (defun pascal-indent-paramlist (&optional arg) |
| 796 | "Indent current line in parameterlist. | 864 | "Indent current line in parameterlist. |
| @@ -878,15 +946,16 @@ indent of the current line in parameterlist." | |||
| 878 | (while (< (point) e) | 946 | (while (< (point) e) |
| 879 | (setq nest 1) | 947 | (setq nest 1) |
| 880 | (if (re-search-forward reg (min e (pascal-get-end-of-line 2)) 'move) | 948 | (if (re-search-forward reg (min e (pascal-get-end-of-line 2)) 'move) |
| 881 | ;; Skip record blocks | 949 | (progn |
| 882 | (if (match-beginning 1) | 950 | ;; Skip record blocks |
| 883 | (pascal-declaration-end) | 951 | (if (match-beginning 1) |
| 884 | (progn | 952 | (pascal-declaration-end) |
| 885 | (goto-char (match-beginning 0)) | 953 | (progn |
| 886 | (skip-chars-backward " \t") | 954 | (goto-char (match-beginning 0)) |
| 887 | (if (> (current-column) ind) | 955 | (skip-chars-backward " \t") |
| 888 | (setq ind (current-column))) | 956 | (if (> (current-column) ind) |
| 889 | (end-of-line))))) | 957 | (setq ind (current-column))) |
| 958 | (goto-char (match-end 0))))))) | ||
| 890 | ;; In case no lineup was found | 959 | ;; In case no lineup was found |
| 891 | (if (> ind 0) | 960 | (if (> ind 0) |
| 892 | (1+ ind) | 961 | (1+ ind) |
| @@ -977,7 +1046,7 @@ indent of the current line in parameterlist." | |||
| 977 | (point)) | 1046 | (point)) |
| 978 | (forward-char 1))) | 1047 | (forward-char 1))) |
| 979 | (re-search-forward | 1048 | (re-search-forward |
| 980 | "\\<type\\>\\|\\<\\(begin\\|function\\|proceudre\\)\\>" | 1049 | "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>" |
| 981 | start t) | 1050 | start t) |
| 982 | (not (match-end 1))) | 1051 | (not (match-end 1))) |
| 983 | ;; Check current type declaration | 1052 | ;; Check current type declaration |
| @@ -1041,28 +1110,29 @@ indent of the current line in parameterlist." | |||
| 1041 | (or (eq state 'declaration) (eq state 'paramlist) | 1110 | (or (eq state 'declaration) (eq state 'paramlist) |
| 1042 | (and (eq state 'defun) | 1111 | (and (eq state 'defun) |
| 1043 | (save-excursion | 1112 | (save-excursion |
| 1044 | (re-search-backward ")[ \t]*:" (pascal-get-beg-of-line) t)))) | 1113 | (re-search-backward ")[ \t]*:" |
| 1114 | (pascal-get-beg-of-line) t)))) | ||
| 1045 | (if (or (eq state 'paramlist) (eq state 'defun)) | 1115 | (if (or (eq state 'paramlist) (eq state 'defun)) |
| 1046 | (pascal-beg-of-defun)) | 1116 | (pascal-beg-of-defun)) |
| 1047 | (pascal-type-completion) | 1117 | (pascal-type-completion) |
| 1048 | (pascal-keyword-completion pascal-type-keywords)) | 1118 | (pascal-keyword-completion pascal-type-keywords)) |
| 1049 | (;--Starting a new statement | 1119 | (;--Starting a new statement |
| 1050 | (and (not (eq state 'contexp)) | 1120 | (and (not (eq state 'contexp)) |
| 1051 | (save-excursion | 1121 | (save-excursion |
| 1052 | (skip-chars-backward "a-zA-Z0-9_.") | 1122 | (skip-chars-backward "a-zA-Z0-9_.") |
| 1053 | (backward-sexp 1) | 1123 | (backward-sexp 1) |
| 1054 | (or (looking-at pascal-nosemi-re) | 1124 | (or (looking-at pascal-nosemi-re) |
| 1055 | (progn | 1125 | (progn |
| 1056 | (forward-sexp 1) | 1126 | (forward-sexp 1) |
| 1057 | (looking-at "\\s *\\(;\\|:[^=]\\)"))))) | 1127 | (looking-at "\\s *\\(;\\|:[^=]\\)"))))) |
| 1058 | (save-excursion (pascal-var-completion)) | 1128 | (save-excursion (pascal-var-completion)) |
| 1059 | (pascal-func-completion 'procedure) | 1129 | (pascal-func-completion 'procedure) |
| 1060 | (pascal-keyword-completion pascal-start-keywords)) | 1130 | (pascal-keyword-completion pascal-start-keywords)) |
| 1061 | (t;--Anywhere else | 1131 | (t;--Anywhere else |
| 1062 | (save-excursion (pascal-var-completion)) | 1132 | (save-excursion (pascal-var-completion)) |
| 1063 | (pascal-func-completion 'function) | 1133 | (pascal-func-completion 'function) |
| 1064 | (pascal-keyword-completion pascal-separator-keywords)))) | 1134 | (pascal-keyword-completion pascal-separator-keywords)))) |
| 1065 | 1135 | ||
| 1066 | ;; Now we have built a list of all matches. Give response to caller | 1136 | ;; Now we have built a list of all matches. Give response to caller |
| 1067 | (pascal-completion-response)))) | 1137 | (pascal-completion-response)))) |
| 1068 | 1138 | ||