comparison lisp/progmodes/pascal.el @ 19148:7c41b30f50ce

(pascal-mode-syntax-table): _ is now a symbol constituent. (pascal-indent-case): Removed unnecessary calls to marker-position. (pascal-indent-declaration): Editing a parameterlist at the end of a buffer does not hang. Removed unnecessary call to marker-position. (pascal-get-lineup-indent): Removed unused variable. Now indents parameterlist correctly. (pascal-completion-response): Removed unused variable.
author Richard M. Stallman <rms@gnu.org>
date Mon, 04 Aug 1997 19:42:32 +0000
parents 11218164bc54
children 90f306f86f5d
comparison
equal deleted inserted replaced
19147:ec57f19bc39c 19148:7c41b30f50ce
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, 1995, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997 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
7 7
8 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
42 ;; pascal-tab-always-indent t 42 ;; pascal-tab-always-indent t
43 ;; pascal-auto-endcomments t 43 ;; pascal-auto-endcomments t
44 ;; pascal-auto-lineup '(all) 44 ;; pascal-auto-lineup '(all)
45 ;; pascal-toggle-completions nil 45 ;; pascal-toggle-completions nil
46 ;; pascal-type-keywords '("array" "file" "packed" "char" 46 ;; pascal-type-keywords '("array" "file" "packed" "char"
47 ;; "integer" "real" "string" "record") 47 ;; "integer" "real" "string" "record")
48 ;; pascal-start-keywords '("begin" "end" "function" "procedure" 48 ;; pascal-start-keywords '("begin" "end" "function" "procedure"
49 ;; "repeat" "until" "while" "read" "readln" 49 ;; "repeat" "until" "while" "read" "readln"
50 ;; "reset" "rewrite" "write" "writeln") 50 ;; "reset" "rewrite" "write" "writeln")
51 ;; pascal-separator-keywords '("downto" "else" "mod" "div" "then")) 51 ;; pascal-separator-keywords '("downto" "else" "mod" "div" "then"))
52 52
53 ;; KNOWN BUGS / BUGREPORTS 53 ;; KNOWN BUGS / BUGREPORTS
54 ;; ======================= 54 ;; =======================
55 ;; As far as I know, there are no bugs in the current version of this 55 ;; As far as I know, there are no bugs in the current version of this
148 (modify-syntax-entry ?% "." pascal-mode-syntax-table) 148 (modify-syntax-entry ?% "." pascal-mode-syntax-table)
149 (modify-syntax-entry ?< "." pascal-mode-syntax-table) 149 (modify-syntax-entry ?< "." pascal-mode-syntax-table)
150 (modify-syntax-entry ?> "." pascal-mode-syntax-table) 150 (modify-syntax-entry ?> "." pascal-mode-syntax-table)
151 (modify-syntax-entry ?& "." pascal-mode-syntax-table) 151 (modify-syntax-entry ?& "." pascal-mode-syntax-table)
152 (modify-syntax-entry ?| "." pascal-mode-syntax-table) 152 (modify-syntax-entry ?| "." pascal-mode-syntax-table)
153 (modify-syntax-entry ?_ "w" pascal-mode-syntax-table) 153 (modify-syntax-entry ?_ "_" pascal-mode-syntax-table)
154 (modify-syntax-entry ?\' "\"" pascal-mode-syntax-table)) 154 (modify-syntax-entry ?\' "\"" pascal-mode-syntax-table))
155 155
156 (defvar pascal-font-lock-keywords 156 (defconst pascal-font-lock-keywords (purecopy
157 (list 157 (list
158 '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\(\\sw+\\)?" 158 '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\([a-z]\\)"
159 (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) 159 1 font-lock-keyword-face)
160 '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\([a-z][a-z0-9_]*\\)"
161 3 font-lock-function-name-face t)
160 ; ("type" "const" "real" "integer" "char" "boolean" "var" 162 ; ("type" "const" "real" "integer" "char" "boolean" "var"
161 ; "record" "array" "file") 163 ; "record" "array" "file")
162 (cons (concat "\\<\\(array\\|boolean\\|c\\(har\\|onst\\)\\|file\\|" 164 (cons (concat "\\<\\(array\\|boolean\\|c\\(har\\|onst\\)\\|file\\|"
163 "integer\\|re\\(al\\|cord\\)\\|type\\|var\\)\\>") 165 "integer\\|re\\(al\\|cord\\)\\|type\\|var\\)\\>")
164 'font-lock-type-face) 166 'font-lock-type-face)
165 '("\\<\\(label\\|external\\|forward\\)\\>" . font-lock-reference-face) 167 '("\\<\\(label\\|external\\|forward\\)\\>" . font-lock-reference-face)
166 '("\\<\\([0-9]+\\)[ \t]*:" 1 font-lock-reference-face) 168 '("\\<\\([0-9]+\\)[ \t]*:" 1 font-lock-function-name-face)
167 ; ("of" "to" "for" "if" "then" "else" "case" "while" 169 ; ("of" "to" "for" "if" "then" "else" "case" "while"
168 ; "do" "until" "and" "or" "not" "in" "with" "repeat" "begin" "end") 170 ; "do" "until" "and" "or" "not" "in" "with" "repeat" "begin" "end")
169 (concat "\\<\\(" 171 (concat "\\<\\("
170 "and\\|begin\\|case\\|do\\|e\\(lse\\|nd\\)\\|for\\|i[fn]\\|" 172 "and\\|begin\\|case\\|do\\|e\\(lse\\|nd\\)\\|for\\|i[fn]\\|"
171 "not\\|o[fr]\\|repeat\\|t\\(hen\\|o\\)\\|until\\|w\\(hile\\|ith\\)" 173 "not\\|o[fr]\\|repeat\\|t\\(hen\\|o\\)\\|until\\|w\\(hile\\|ith\\)"
172 "\\)\\>") 174 "\\)\\>")
173 '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?" 175 '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?"
174 (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))) 176 1 font-lock-keyword-face)
177 '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?"
178 2 font-lock-keyword-face t)))
175 "Additional expressions to highlight in Pascal mode.") 179 "Additional expressions to highlight in Pascal mode.")
180 (put 'pascal-mode 'font-lock-defaults '(pascal-font-lock-keywords nil t))
176 181
177 (defcustom pascal-indent-level 3 182 (defcustom pascal-indent-level 3
178 "*Indentation of Pascal statements with respect to containing block." 183 "*Indentation of Pascal statements with respect to containing block."
179 :type 'integer 184 :type 'integer
180 :group 'pascal) 185 :group 'pascal)
348 (set-syntax-table pascal-mode-syntax-table) 353 (set-syntax-table pascal-mode-syntax-table)
349 (make-local-variable 'indent-line-function) 354 (make-local-variable 'indent-line-function)
350 (setq indent-line-function 'pascal-indent-line) 355 (setq indent-line-function 'pascal-indent-line)
351 (make-local-variable 'comment-indent-function) 356 (make-local-variable 'comment-indent-function)
352 (setq comment-indent-function 'pascal-indent-comment) 357 (setq comment-indent-function 'pascal-indent-comment)
353 (make-local-variable 'comment-start)
354 (setq comment-start "{")
355 (make-local-variable 'parse-sexp-ignore-comments) 358 (make-local-variable 'parse-sexp-ignore-comments)
356 (setq parse-sexp-ignore-comments nil) 359 (setq parse-sexp-ignore-comments nil)
357 (make-local-variable 'case-fold-search) 360 (make-local-variable 'case-fold-search)
358 (setq case-fold-search t) 361 (setq case-fold-search t)
359 (make-local-variable 'comment-start) 362 (make-local-variable 'comment-start)
920 923
921 (defun pascal-indent-comment (&optional arg) 924 (defun pascal-indent-comment (&optional arg)
922 "Indent current line as comment. 925 "Indent current line as comment.
923 If optional arg is non-nil, just return the 926 If optional arg is non-nil, just return the
924 column number the line should be indented to." 927 column number the line should be indented to."
925 (let* ((stcol (save-excursion 928 (let* ((stcol (save-excursion
926 (re-search-backward "(\\*\\|{" nil t) 929 (re-search-backward "(\\*\\|{" nil t)
927 (1+ (current-column))))) 930 (1+ (current-column)))))
928 (if arg stcol 931 (if arg stcol
929 (delete-horizontal-space) 932 (delete-horizontal-space)
930 (indent-to stcol)))) 933 (indent-to stcol))))
931 934
932 (defun pascal-indent-case () 935 (defun pascal-indent-case ()
933 "Indent within case statements." 936 "Indent within case statements."
934 (let ((savepos (point-marker)) 937 (let ((savepos (point-marker))
935 (end (prog2 938 (end (prog2
937 (point-marker) 940 (point-marker)
938 (re-search-backward "\\<case\\>" nil t))) 941 (re-search-backward "\\<case\\>" nil t)))
939 (beg (point)) oldpos 942 (beg (point)) oldpos
940 (ind 0)) 943 (ind 0))
941 ;; Get right indent 944 ;; Get right indent
942 (while (< (point) (marker-position end)) 945 (while (< (point) end)
943 (if (re-search-forward 946 (if (re-search-forward
944 "^[ \t]*[^ \t,:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:" 947 "^[ \t]*[^ \t,:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:"
945 (marker-position end) 'move) 948 (marker-position end) 'move)
946 (forward-char -1)) 949 (forward-char -1))
947 (if (< (point) (marker-position end)) 950 (if (< (point) end)
948 (progn 951 (progn
949 (delete-horizontal-space) 952 (delete-horizontal-space)
950 (if (> (current-column) ind) 953 (if (> (current-column) ind)
951 (setq ind (current-column))) 954 (setq ind (current-column)))
952 (pascal-end-of-statement)))) 955 (pascal-end-of-statement))))
953 (goto-char beg) 956 (goto-char beg)
954 (setq oldpos (marker-position end)) 957 (setq oldpos (marker-position end))
955 ;; Indent all case statements 958 ;; Indent all case statements
956 (while (< (point) (marker-position end)) 959 (while (< (point) end)
957 (if (re-search-forward 960 (if (re-search-forward
958 "^[ \t]*[^][ \t,\\.:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:" 961 "^[ \t]*[^][ \t,\\.:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:"
959 (marker-position end) 'move) 962 (marker-position end) 'move)
960 (forward-char -1)) 963 (forward-char -1))
961 (indent-to (1+ ind)) 964 (indent-to (1+ ind))
1010 ind) 1013 ind)
1011 1014
1012 (goto-char stpos) 1015 (goto-char stpos)
1013 ;; Indent lines in record block 1016 ;; Indent lines in record block
1014 (if arg 1017 (if arg
1015 (while (<= (point) (marker-position edpos)) 1018 (while (<= (point) edpos)
1016 (beginning-of-line) 1019 (beginning-of-line)
1017 (delete-horizontal-space) 1020 (delete-horizontal-space)
1018 (if (looking-at "end\\>") 1021 (if (looking-at "end\\>")
1019 (indent-to arg) 1022 (indent-to arg)
1020 (indent-to (+ arg pascal-indent-level))) 1023 (indent-to (+ arg pascal-indent-level)))
1021 (forward-line 1))) 1024 (forward-line 1)))
1022 1025
1023 ;; Do lineup 1026 ;; Do lineup
1024 (setq ind (pascal-get-lineup-indent stpos edpos lineup)) 1027 (setq ind (pascal-get-lineup-indent stpos edpos lineup))
1025 (goto-char stpos) 1028 (goto-char stpos)
1026 (while (and (<= (point) (marker-position edpos)) 1029 (while (and (<= (point) edpos) (not (eobp)))
1027 (not (eobp)))
1028 (if (search-forward lineup (pascal-get-end-of-line) 'move) 1030 (if (search-forward lineup (pascal-get-end-of-line) 'move)
1029 (forward-char -1)) 1031 (forward-char -1))
1030 (delete-horizontal-space) 1032 (delete-horizontal-space)
1031 (indent-to ind) 1033 (indent-to ind)
1032 (if (not (looking-at lineup)) 1034 (if (not (looking-at lineup))
1039 (pascal-indent-declaration (current-column))) 1041 (pascal-indent-declaration (current-column)))
1040 (forward-line 1))))) 1042 (forward-line 1)))))
1041 1043
1042 ;; If arg - move point 1044 ;; If arg - move point
1043 (if arg (forward-line -1) 1045 (if arg (forward-line -1)
1044 (goto-char (marker-position pos))))) 1046 (goto-char pos))))
1045 1047
1046 ; "Return the indent level that will line up several lines within the region 1048 ; "Return the indent level that will line up several lines within the region
1047 ;from b to e nicely. The lineup string is str." 1049 ;from b to e nicely. The lineup string is str."
1048 (defun pascal-get-lineup-indent (b e str) 1050 (defun pascal-get-lineup-indent (b e str)
1049 (save-excursion 1051 (save-excursion
1050 (let ((ind 0) 1052 (let ((ind 0)
1051 (reg (concat str "\\|\\(\\<record\\>\\)")) 1053 (reg (concat str "\\|\\(\\<record\\>\\)")))
1052 nest)
1053 (goto-char b) 1054 (goto-char b)
1054 ;; Get rightmost position 1055 ;; Get rightmost position
1055 (while (< (point) e) 1056 (while (< (point) e)
1056 (setq nest 1)
1057 (if (re-search-forward reg (min e (pascal-get-end-of-line 2)) 'move) 1057 (if (re-search-forward reg (min e (pascal-get-end-of-line 2)) 'move)
1058 (progn 1058 (progn
1059 ;; Skip record blocks 1059 ;; Skip record blocks
1060 (if (match-beginning 1) 1060 (if (match-beginning 1)
1061 (pascal-declaration-end) 1061 (pascal-declaration-end)
1062 (progn 1062 (progn
1063 (goto-char (match-beginning 0)) 1063 (goto-char (match-beginning 0))
1064 (skip-chars-backward " \t") 1064 (skip-chars-backward " \t")
1065 (if (> (current-column) ind) 1065 (if (> (current-column) ind)
1066 (setq ind (current-column))) 1066 (setq ind (current-column)))
1067 (goto-char (match-end 0))))))) 1067 (goto-char (match-end 0))
1068 (end-of-line)
1069 )))))
1068 ;; In case no lineup was found 1070 ;; In case no lineup was found
1069 (if (> ind 0) 1071 (if (> ind 0)
1070 (1+ ind) 1072 (1+ ind)
1071 ;; No lineup-string found 1073 ;; No lineup-string found
1072 (goto-char b) 1074 (goto-char b)
1126 (setq pascal-all (cons match pascal-all))))) 1128 (setq pascal-all (cons match pascal-all)))))
1127 (goto-char (match-beginning 0))))) 1129 (goto-char (match-beginning 0)))))
1128 1130
1129 (defun pascal-get-completion-decl () 1131 (defun pascal-get-completion-decl ()
1130 ;; Macro for searching through current declaration (var, type or const) 1132 ;; Macro for searching through current declaration (var, type or const)
1131 ;; for matches of `str' and adding the occurrence tp `all' 1133 ;; for matches of `str' and adding the occurrence to `all'
1132 (let ((end (save-excursion (pascal-declaration-end) 1134 (let ((end (save-excursion (pascal-declaration-end)
1133 (point))) 1135 (point)))
1134 match) 1136 match)
1135 ;; Traverse lines 1137 ;; Traverse lines
1136 (while (< (point) end) 1138 (while (< (point) end)
1260 nil 1262 nil
1261 ;; Get longest string common in the labels 1263 ;; Get longest string common in the labels
1262 (let* ((elm (cdr pascal-all)) 1264 (let* ((elm (cdr pascal-all))
1263 (match (car pascal-all)) 1265 (match (car pascal-all))
1264 (min (length match)) 1266 (min (length match))
1265 exact tmp) 1267 tmp)
1266 (if (string= match pascal-str) 1268 (if (string= match pascal-str)
1267 ;; Return t if first match was an exact match 1269 ;; Return t if first match was an exact match
1268 (setq match t) 1270 (setq match t)
1269 (while (not (null elm)) 1271 (while (not (null elm))
1270 ;; Find longest common string 1272 ;; Find longest common string