source: project/wiki/emacs-multi-mode @ 25498

Last change on this file since 25498 was 25498, checked in by svnwiki, 9 years ago

Anonymous wiki edit for IP [70.71.179.201]: Use emscript instead

File size: 3.8 KB
RevLine 
[25497]1This script will switch between scheme-mode and c-mode in Emacs, using the #> .. <# and <<ENDC .. ENDC delimiters.
2
[25498]3<enscript highlight="elisp">
4(require 'multi-mode)
5
6(defun scheme-c-mode ()
7  "Mode for editing C embedded in Scheme, using multi-mode."
8  (interactive)
9  (set (make-local-variable 'multi-alist)
10       '((scheme-mode)
11         (c-mode . scheme-c-header-region)
12         (c-mode . scheme-c-inline-region)))
13  (multi-mode-install-modes))
14
15(defun scheme-c-header-region (pos)
16  "Mode-selecting function for C embedded in Scheme."
17  (let ((case-fold-search t)
18        foreign-start foreign-end next-foreign)
19    (save-excursion
20      (save-restriction
21        (widen)
22        (goto-char pos)
23        (save-excursion
24          (let* ((p1 (save-excursion
25                       ;; Check whether we're on the processing
26                       ;; instruction start.  Skip definitely clear of
27                       ;; it and then search backwards.
28                       (goto-char (min (point-max) (+ (point) 2)))
29                       (search-backward "#>" (- (point) 3) t)))
30                 (match-end (if p1 (match-end 0)))
31                 ;; Otherwise search backwards simply.
32                 (p2 (unless p1 (search-backward "#>" nil t))))
33            (if p2 (setq match-end (match-end 0)))
34            (setq foreign-start (or p1 p2))
35            ;; Ready to search for matching terminator or next
36            ;; processing instruction.
37            (goto-char (or match-end pos)))
38          (if foreign-start
39              ;; Look forward for the FOREIGN terminator.
40              (let* ((p1 (save-excursion
41                           ;; Check whether we're on the terminator.
42                           (backward-char 1)
43                           (search-backward "<#" (- (point) 2) t)))
44                     (p2 (unless p1 (search-forward "<#" nil t))))
45                (setq foreign-end (or p1 p2 (point-max)))
46                (goto-char pos)))
47          (if (and foreign-start foreign-end (< pos foreign-end))
48              ;; We were between FOREIGN start and terminator.
49              (list 'c-mode foreign-start foreign-end)
50            ;; Otherwise, look forward for a FOREIGN to delimit the Scheme
51            ;; region.
52            (setq next-foreign
53                  (if (search-forward "#>" nil t)
54                      (match-beginning 0)
55                    (point-max)))
56            (if foreign-start
57                (list 'scheme-mode (or foreign-end (point-min)) next-foreign)
58              (list 'scheme-mode (point-min) next-foreign))))))))
59
60(defun scheme-c-inline-region (pos)
61  "Mode-selecting function for C embedded in Scheme."
62  (let ((case-fold-search t)
63        foreign-start foreign-end next-foreign)
64    (save-excursion
65      (save-restriction
66        (widen)
67        (goto-char pos)
68        (save-excursion
69          (let* ((p1 (save-excursion
70                       ;; Check whether we're on the processing
71                       ;; instruction start.  Skip definitely clear of
72                       ;; it and then search backwards.
73                       (goto-char (min (point-max) (+ (point) 6)))
74                       (search-backward "<<ENDC" (- (point) 11) t)))
75                 (match-end (if p1 (match-end 0)))
76                 ;; Otherwise search backwards simply.
77                 (p2 (unless p1 (search-backward "<<ENDC" nil t))))
78            (if p2 (setq match-end (match-end 0)))
79            (setq foreign-start (or p1 p2))
80            ;; Ready to search for matching terminator or next
81            ;; processing instruction.
82            (goto-char (or match-end pos)))
83          (if foreign-start
84              ;; Look forward for the FOREIGN terminator.
85              (let* ((p1 (save-excursion
86                           ;; Check whether we're on the terminator.
87                           (backward-char 1)
88                           (search-backward "ENDC" (- (point) 4) t)))
89                     (p2 (unless p1 (search-forward "ENDC" nil t))))
90                (setq foreign-end (or p1 p2 (point-max)))
91                (goto-char pos)))
92          (if (and foreign-start foreign-end (< pos foreign-end))
93              ;; We were between FOREIGN start and terminator.
94              (list 'c-mode foreign-start foreign-end)
95            ;; Otherwise, look forward for a FOREIGN to delimit the Scheme
96            ;; region.
97            (setq next-foreign
98                  (if (search-forward "<<ENDC" nil t)
99                      (match-beginning 0)
100                    (point-max)))
101            (if foreign-start
102                (list 'scheme-mode (or foreign-end (point-min)) next-foreign)
103              (list 'scheme-mode (point-min) next-foreign))))))))
104
105(provide 'scheme-c-mode)
106</enscript>
Note: See TracBrowser for help on using the repository browser.