Mercurial > emacs
comparison lisp/progmodes/pascal.el @ 10446:034609a036b1
(pascal-mode-map, pascal-outline-map):
C-c C-b now inserts block. C-c C-d does goto-defun.
`#' calls on electric-pascal-hash.
(pascal-calculate-indent, pascal-indent-alist)
(electric-pascal-tab, pascal-indent-case):
Better handling of indent within case. Support for CPP.
The `;' in the last statement of a subblock may be omitted.
(electric-pascal-hash): New function.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Tue, 17 Jan 1995 20:53:31 +0000 |
parents | ef7c2b4dfee4 |
children | 38b5efae433a |
comparison
equal
deleted
inserted
replaced
10445:a657f6491234 | 10446:034609a036b1 |
---|---|
57 ;;; find any bugs, you may submit them to: espensk@stud.cs.uit.no | 57 ;;; find any bugs, you may submit them to: espensk@stud.cs.uit.no |
58 ;;; as well as to bug-gnu-emacs@prep.ai.mit.edu. | 58 ;;; as well as to bug-gnu-emacs@prep.ai.mit.edu. |
59 | 59 |
60 ;;; Code: | 60 ;;; Code: |
61 | 61 |
62 (defconst pascal-mode-version "2.3" | 62 (defconst pascal-mode-version "2.4" |
63 "Version of `pascal.el'.") | 63 "Version of `pascal.el'.") |
64 | 64 |
65 (defvar pascal-mode-abbrev-table nil | 65 (defvar pascal-mode-abbrev-table nil |
66 "Abbrev table in use in Pascal-mode buffers.") | 66 "Abbrev table in use in Pascal-mode buffers.") |
67 (define-abbrev-table 'pascal-mode-abbrev-table ()) | 67 (define-abbrev-table 'pascal-mode-abbrev-table ()) |
73 (setq pascal-mode-map (make-sparse-keymap)) | 73 (setq pascal-mode-map (make-sparse-keymap)) |
74 (define-key pascal-mode-map ";" 'electric-pascal-semi-or-dot) | 74 (define-key pascal-mode-map ";" 'electric-pascal-semi-or-dot) |
75 (define-key pascal-mode-map "." 'electric-pascal-semi-or-dot) | 75 (define-key pascal-mode-map "." 'electric-pascal-semi-or-dot) |
76 (define-key pascal-mode-map ":" 'electric-pascal-colon) | 76 (define-key pascal-mode-map ":" 'electric-pascal-colon) |
77 (define-key pascal-mode-map "=" 'electric-pascal-equal) | 77 (define-key pascal-mode-map "=" 'electric-pascal-equal) |
78 (define-key pascal-mode-map "#" 'electric-pascal-hash) | |
78 (define-key pascal-mode-map "\r" 'electric-pascal-terminate-line) | 79 (define-key pascal-mode-map "\r" 'electric-pascal-terminate-line) |
79 (define-key pascal-mode-map "\t" 'electric-pascal-tab) | 80 (define-key pascal-mode-map "\t" 'electric-pascal-tab) |
80 (define-key pascal-mode-map "\e\t" 'pascal-complete-word) | 81 (define-key pascal-mode-map "\M-\t" 'pascal-complete-word) |
81 (define-key pascal-mode-map "\e?" 'pascal-show-completions) | 82 (define-key pascal-mode-map "\M-?" 'pascal-show-completions) |
82 (define-key pascal-mode-map "\177" 'backward-delete-char-untabify) | 83 (define-key pascal-mode-map "\177" 'backward-delete-char-untabify) |
83 (define-key pascal-mode-map "\e\C-h" 'pascal-mark-defun) | 84 (define-key pascal-mode-map "\M-\C-h" 'pascal-mark-defun) |
84 (define-key pascal-mode-map "\C-cb" 'pascal-insert-block) | 85 (define-key pascal-mode-map "\C-c\C-b" 'pascal-insert-block) |
85 (define-key pascal-mode-map "\M-*" 'pascal-star-comment) | 86 (define-key pascal-mode-map "\M-*" 'pascal-star-comment) |
86 (define-key pascal-mode-map "\C-c\C-c" 'pascal-comment-area) | 87 (define-key pascal-mode-map "\C-c\C-c" 'pascal-comment-area) |
87 (define-key pascal-mode-map "\C-c\C-u" 'pascal-uncomment-area) | 88 (define-key pascal-mode-map "\C-c\C-u" 'pascal-uncomment-area) |
88 (define-key pascal-mode-map "\e\C-a" 'pascal-beg-of-defun) | 89 (define-key pascal-mode-map "\M-\C-a" 'pascal-beg-of-defun) |
89 (define-key pascal-mode-map "\e\C-e" 'pascal-end-of-defun) | 90 (define-key pascal-mode-map "\M-\C-e" 'pascal-end-of-defun) |
90 (define-key pascal-mode-map "\C-cg" 'pascal-goto-defun) | 91 (define-key pascal-mode-map "\C-c\C-d" 'pascal-goto-defun) |
91 (define-key pascal-mode-map "\C-c\C-o" 'pascal-outline) | 92 (define-key pascal-mode-map "\C-c\C-o" 'pascal-outline) |
92 ;;; A command to change the whole buffer won't be used terribly | 93 ;;; A command to change the whole buffer won't be used terribly |
93 ;;; often, so no need for a key binding. | 94 ;;; often, so no need for a key binding. |
94 ; (define-key pascal-mode-map "\C-cd" 'pascal-downcase-keywords) | 95 ; (define-key pascal-mode-map "\C-cd" 'pascal-downcase-keywords) |
95 ; (define-key pascal-mode-map "\C-cu" 'pascal-upcase-keywords) | 96 ; (define-key pascal-mode-map "\C-cu" 'pascal-upcase-keywords) |
96 ; (define-key pascal-mode-map "\C-cc" 'pascal-capitalize-keywords) | 97 ; (define-key pascal-mode-map "\C-cc" 'pascal-capitalize-keywords) |
313 (set-syntax-table pascal-mode-syntax-table) | 314 (set-syntax-table pascal-mode-syntax-table) |
314 (make-local-variable 'indent-line-function) | 315 (make-local-variable 'indent-line-function) |
315 (setq indent-line-function 'pascal-indent-line) | 316 (setq indent-line-function 'pascal-indent-line) |
316 (setq comment-indent-function 'pascal-indent-comment) | 317 (setq comment-indent-function 'pascal-indent-comment) |
317 (make-local-variable 'parse-sexp-ignore-comments) | 318 (make-local-variable 'parse-sexp-ignore-comments) |
318 (setq parse-sexp-ignore-comments t) | 319 (setq parse-sexp-ignore-comments nil) |
319 (make-local-variable 'case-fold-search) | 320 (make-local-variable 'case-fold-search) |
320 (setq case-fold-search t) | 321 (setq case-fold-search t) |
321 (make-local-variable 'comment-start-skip) | 322 (make-local-variable 'comment-start-skip) |
322 (setq comment-start-skip "(\\*+ *\\|{ *") | 323 (setq comment-start-skip "(\\*+ *\\|{ *") |
323 (make-local-variable 'comment-end) | 324 (make-local-variable 'comment-end) |
395 (insert last-command-char) | 396 (insert last-command-char) |
396 (if (eq (car (pascal-calculate-indent)) 'declaration) | 397 (if (eq (car (pascal-calculate-indent)) 'declaration) |
397 (let ((pascal-tab-always-indent nil)) | 398 (let ((pascal-tab-always-indent nil)) |
398 (pascal-indent-command)))) | 399 (pascal-indent-command)))) |
399 | 400 |
401 (defun electric-pascal-hash () | |
402 "Insert `#', and indent to coulmn 0 if this is a CPP directive." | |
403 (interactive) | |
404 (insert last-command-char) | |
405 (if (save-excursion (beginning-of-line) (looking-at "^[ \t]*#")) | |
406 (save-excursion (beginning-of-line) | |
407 (delete-horizontal-space)))) | |
408 | |
400 (defun electric-pascal-tab () | 409 (defun electric-pascal-tab () |
401 "Function called when TAB is pressed in Pascal mode." | 410 "Function called when TAB is pressed in Pascal mode." |
402 (interactive) | 411 (interactive) |
403 ;; Do nothing if within a string. | 412 ;; Do nothing if within a string or in a CPP directive. |
404 (if (pascal-within-string) | 413 (if (or (pascal-within-string) |
414 (and (not (bolp)) | |
415 (save-excursion (beginning-of-line) (eq (following-char) ?#)))) | |
405 (insert "\t") | 416 (insert "\t") |
406 ;; If pascal-tab-always-indent, indent the beginning of the line. | 417 ;; If pascal-tab-always-indent, indent the beginning of the line. |
407 (if pascal-tab-always-indent | 418 (if pascal-tab-always-indent |
408 (save-excursion | 419 (save-excursion |
409 (beginning-of-line) | 420 (beginning-of-line) |
706 ;;; Indentation | 717 ;;; Indentation |
707 ;;; | 718 ;;; |
708 (defconst pascal-indent-alist | 719 (defconst pascal-indent-alist |
709 '((block . (+ ind pascal-indent-level)) | 720 '((block . (+ ind pascal-indent-level)) |
710 (case . (+ ind pascal-case-indent)) | 721 (case . (+ ind pascal-case-indent)) |
722 (caseblock . ind) (cpp . 0) | |
711 (declaration . (+ ind pascal-indent-level)) | 723 (declaration . (+ ind pascal-indent-level)) |
712 (paramlist . (pascal-indent-paramlist t)) | 724 (paramlist . (pascal-indent-paramlist t)) |
713 (comment . (pascal-indent-comment t)) | 725 (comment . (pascal-indent-comment t)) |
714 (defun . ind) (contexp . ind) | 726 (defun . ind) (contexp . ind) |
715 (unknown . 0) (string . 0))) | 727 (unknown . 0) (string . 0))) |
741 (type (car indent-str)) | 753 (type (car indent-str)) |
742 (ind (car (cdr indent-str)))) | 754 (ind (car (cdr indent-str)))) |
743 (if (looking-at "^[0-9a-zA-Z]+[ \t]*:[^=]") | 755 (if (looking-at "^[0-9a-zA-Z]+[ \t]*:[^=]") |
744 (search-forward ":" nil t)) | 756 (search-forward ":" nil t)) |
745 (delete-horizontal-space) | 757 (delete-horizontal-space) |
746 ;; Some thing should not be indented | 758 ;; Some things should not be indented |
747 (if (or (and (eq type 'declaration) (looking-at pascal-declaration-re)) | 759 (if (or (and (eq type 'declaration) (looking-at pascal-declaration-re)) |
760 (eq type 'cpp) | |
748 (looking-at pascal-defun-re)) | 761 (looking-at pascal-defun-re)) |
749 () | 762 () |
750 ;; Other things should have no extra indent | 763 ;; Other things should have no extra indent |
751 (if (looking-at pascal-noindent-re) | 764 (if (looking-at pascal-noindent-re) |
752 (indent-to ind) | 765 (indent-to ind) |
758 "Calculate the indent of the current Pascal line. | 771 "Calculate the indent of the current Pascal line. |
759 Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)." | 772 Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)." |
760 (save-excursion | 773 (save-excursion |
761 (let* ((oldpos (point)) | 774 (let* ((oldpos (point)) |
762 (state (save-excursion (parse-partial-sexp (point-min) (point)))) | 775 (state (save-excursion (parse-partial-sexp (point-min) (point)))) |
763 (nest 0) (par 0) (complete nil) | 776 (nest 0) (par 0) (complete (looking-at "[ \t]*end\\>")) |
764 (elsed (looking-at "[ \t]*else\\>")) | 777 (elsed (looking-at "[ \t]*else\\>")) |
765 (type (catch 'nesting | 778 (type (catch 'nesting |
766 ;; Check if inside a string, comment or parenthesis | 779 ;; Check if inside a string, comment or parenthesis |
767 (cond ((nth 3 state) (throw 'nesting 'string)) | 780 (cond ((nth 3 state) (throw 'nesting 'string)) |
768 ((nth 4 state) (throw 'nesting 'comment)) | 781 ((nth 4 state) (throw 'nesting 'comment)) |
769 ((> (car state) 0) | 782 ((> (car state) 0) |
770 (goto-char (scan-lists (point) -1 (car state))) | 783 (goto-char (scan-lists (point) -1 (car state))) |
771 (setq par (1+ (current-column))))) | 784 (setq par (1+ (current-column)))) |
785 ((save-excursion (beginning-of-line) | |
786 (eq (following-char) ?#)) | |
787 (throw 'nesting 'cpp))) | |
772 ;; Loop until correct indent is found | 788 ;; Loop until correct indent is found |
773 (while t | 789 (while t |
774 (backward-sexp 1) | 790 (backward-sexp 1) |
775 (cond (;--Nest block outwards | 791 (cond (;--Escape from case statements |
792 (and (looking-at "[A-Za-z0-9]+[ \t]*:[^=]") | |
793 (not complete) | |
794 (save-excursion (skip-chars-backward " \t") | |
795 (bolp)) | |
796 (= (save-excursion | |
797 (end-of-line) (backward-sexp) (point)) | |
798 (point)) | |
799 (> (save-excursion (goto-char oldpos) | |
800 (beginning-of-line) | |
801 (point)) | |
802 (point))) | |
803 (throw 'nesting 'caseblock)) | |
804 (;--Nest block outwards | |
776 (looking-at pascal-beg-block-re) | 805 (looking-at pascal-beg-block-re) |
777 (if (= nest 0) | 806 (if (= nest 0) |
778 (cond ((looking-at "case\\>") | 807 (cond ((looking-at "case\\>") |
779 (throw 'nesting 'case)) | 808 (throw 'nesting 'case)) |
780 ((looking-at "record\\>") | 809 ((looking-at "record\\>") |
820 (setq complete t)) | 849 (setq complete t)) |
821 (;--No known statements | 850 (;--No known statements |
822 (bobp) | 851 (bobp) |
823 (throw 'nesting 'unknown)) | 852 (throw 'nesting 'unknown)) |
824 ))))) | 853 ))))) |
854 | |
825 ;; Return type of block and indent level. | 855 ;; Return type of block and indent level. |
826 (if (> par 0) ; Unclosed Parenthesis | 856 (if (> par 0) ; Unclosed Parenthesis |
827 (list 'contexp par) | 857 (list 'contexp par) |
828 (list type (pascal-indent-level)))))) | 858 (list type (pascal-indent-level)))))) |
829 | 859 |
872 (goto-char beg) | 902 (goto-char beg) |
873 (setq oldpos (marker-position end)) | 903 (setq oldpos (marker-position end)) |
874 ;; Indent all case statements | 904 ;; Indent all case statements |
875 (while (< (point) (marker-position end)) | 905 (while (< (point) (marker-position end)) |
876 (if (re-search-forward | 906 (if (re-search-forward |
877 "^[ \t]*[^ \t,:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:" | 907 "^[ \t]*[^][ \t,\\.:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:" |
878 (marker-position end) 'move) | 908 (marker-position end) 'move) |
879 (forward-char -1)) | 909 (forward-char -1)) |
880 (indent-to (1+ ind)) | 910 (indent-to (1+ ind)) |
881 (if (/= (following-char) ?:) | 911 (if (/= (following-char) ?:) |
882 () | 912 () |
1371 (set-keymap-name pascal-outline-map 'pascal-outline-map)) | 1401 (set-keymap-name pascal-outline-map 'pascal-outline-map)) |
1372 (if (not (boundp 'set-keymap-parent)) | 1402 (if (not (boundp 'set-keymap-parent)) |
1373 (setq pascal-outline-map (copy-keymap pascal-mode-map)) | 1403 (setq pascal-outline-map (copy-keymap pascal-mode-map)) |
1374 (setq pascal-outline-map (make-sparse-keymap)) | 1404 (setq pascal-outline-map (make-sparse-keymap)) |
1375 (set-keymap-parent pascal-outline-map pascal-mode-map)) | 1405 (set-keymap-parent pascal-outline-map pascal-mode-map)) |
1376 (define-key pascal-outline-map "\e\C-a" 'pascal-outline-prev-defun) | 1406 (define-key pascal-outline-map "\M-\C-a" 'pascal-outline-prev-defun) |
1377 (define-key pascal-outline-map "\e\C-e" 'pascal-outline-next-defun) | 1407 (define-key pascal-outline-map "\M-\C-e" 'pascal-outline-next-defun) |
1378 (define-key pascal-outline-map "\C-c\C-d" 'pascal-outline-goto-defun) | 1408 (define-key pascal-outline-map "\C-c\C-d" 'pascal-outline-goto-defun) |
1379 (define-key pascal-outline-map "\C-c\C-s" 'pascal-show-all) | 1409 (define-key pascal-outline-map "\C-c\C-s" 'pascal-show-all) |
1380 (define-key pascal-outline-map "\C-c\C-h" 'pascal-hide-other-defuns)) | 1410 (define-key pascal-outline-map "\C-c\C-h" 'pascal-hide-other-defuns)) |
1381 | 1411 |
1382 (defvar pascal-outline-mode nil "Non-nil while using Pascal Outline mode.") | 1412 (defvar pascal-outline-mode nil "Non-nil while using Pascal Outline mode.") |