~ubuntu-branches/ubuntu/hardy/ess/hardy

« back to all changes in this revision

Viewing changes to lisp/noweb-font-lock-mode.el

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2005-03-22 13:48:07 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050322134807-9mpmbb799jugf248
Tags: 5.2.6-1
* New upstream release
* chmod -R u+w on orig source

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
;; noweb-font-lock-mode.el - edit noweb files with GNU Emacs
 
2
 
2
3
;; Copyright (C) 1999 by  Adnan Yaqub (AYaqub@orga.com)
3
4
;;                    and Mark Lunt (mark.lunt@mrc-bsu.cam.ac.uk
4
 
;; 
 
5
;; Copyright (C) 2002 by A.J. Rossini <rossini@u.washington.edu>
 
6
;; Copyright (C) 2003--2004 A.J. Rossini, Rich M. Heiberger, Martin
 
7
;;      Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
 
8
 
 
9
;; Maintainers: ESS-core <ESS-core@stat.math.ethz.ch>
 
10
 
5
11
;; This program is free software; you can redistribute it and/or modify
6
12
;; it under the terms of the GNU General Public License as published by
7
13
;; the Free Software Foundation; either version 2, or (at your option)
8
14
;; any later version.
9
 
;; 
 
15
;;
10
16
;; This program is distributed in the hope that it will be useful,
11
17
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12
18
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
19
;; GNU General Public License for more details.
14
 
;; 
 
20
;;
15
21
;; You should have received a copy of the GNU General Public License
16
22
;; along with this program; if not, write to the Free Software
17
23
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
;; 
19
 
;; 
 
24
;;
 
25
;;
20
26
;;; Code-dependent highlighting
21
27
 
22
28
;;  *****
23
 
;;  
 
29
;;
24
30
;;  Adding highlighting to noweb-mode.el
25
 
;;  
 
31
;;
26
32
;;  Here is a description of how one can add highlighting via the
27
33
;;  font-lock package to noweb buffers.  It uses the hooks provided by
28
34
;;  noweb-mode.el.  The solution provides the following features:
33
39
;;  3) The code chunks with mode comments (-*- mode -*-) on the first
34
40
;;  line of the first chunk with this name are highlighted in the mode
35
41
;;  in the comment.
36
 
;;  
 
42
;;
37
43
;;  For example, given the file:
38
 
;;  
 
44
;;
39
45
;;    % -*- mode: Noweb; noweb-code-mode: c-mode -*-
40
 
;;  
 
46
;;
41
47
;;    \begin{itemize}
42
48
;;    \item a main routine written in C,
43
49
;;    \item a log configuration file parser written in YACC, and
44
50
;;    \item a lexical analyzer written in Lex.
45
51
;;    \end{itemize}
46
 
;;  
 
52
;;
47
53
;;    <<warning c comment>>=
48
54
;;    /* DO NOT EDIT ME! */
49
55
;;    /* This file was automatically generated from %W% (%G%). */
50
56
;;    @
51
 
;;  
 
57
;;
52
58
;;    <<warning nroff comment>>=
53
59
;;    .\" -*- nroff -*-
54
60
;;    .\" DO NOT EDIT ME!
55
61
;;    .\" This file was automatically generated from %W% (%G%).
56
62
;;    @
57
 
;;  
 
63
;;
58
64
;;  The LaTeX list is highlighted in latex-mode (the default noweb doc
59
65
;;  mode), the chunk <<warning c comment>> is highlighted in c-mode (the
60
66
;;  default noweb code mode), and the chunk <<warning nroff comment>> is
61
67
;;  highlighted in nroff-mode due to the "-*- nroff -*-" comment.
62
 
;;  
 
68
;;
63
69
;;  Chunks are highlighted each time point moves into them from a
64
70
;;  different mode. They are also fontified 'on the fly', but this is
65
71
;;  less reliable, since the syntax can depend on the context. It's as
66
72
;;  good as you would get outside noweb-mode, though.
67
 
;;  
68
 
;;  To use it, you must add 
69
 
;;  (require noweb-font-lock-mode) to your .emacs file. 
 
73
;;
 
74
;;  To use it, you must add
 
75
;;  (require noweb-font-lock-mode) to your .emacs file.
70
76
;;  Then, if you use either global-font-lock or turn-on-font-lock
71
77
;;  statements, any noweb-mode buffers will be fontified
72
78
;;  appropriately. (We have to redefine turn-on-font-lock, but it
82
88
 
83
89
;;  2) The highlighting sometimes get confused, but this is no longer
84
90
;;  a noweb problem. Highlighting should work as well within a chunk
85
 
;;  as it does without noweb-mode.  
 
91
;;  as it does without noweb-mode.
86
92
;;  There are some problems with, for example latex-mode: a `$' in a
87
93
;;  verbatim environment with throw the font-locking out.
88
94
;;  One slight blemish is that code-quotes are highlighted as comments
99
105
  "Buffer local variable, t iff this buffer is using noweb-font-lock-mode.")
100
106
 
101
107
(defvar noweb-use-font-lock-mode t
102
 
  "DO NOT CHANGE THIS VARIABLE 
 
108
  "DO NOT CHANGE THIS VARIABLE
103
109
If you use nw-turn-on-font-lock to turn on font-locking, then turn it
104
110
off again, it would come back on again of its own accord when you
105
111
changed major-mode. This variable is used internally to stop it.")
140
146
                                   (list '(noweb-font-lock-mode " NWFL")))))
141
147
 
142
148
;; An ugly kludge to get around problems with global-font-lock, which
143
 
;; fontifies the entire buffer in the new major mode every time you 
144
 
;; change mode, which is time-consuming and makes a pigs trotters of 
 
149
;; fontifies the entire buffer in the new major mode every time you
 
150
;; change mode, which is time-consuming and makes a pigs trotters of
145
151
;; it. Trying to stop it looks tricky, but using this function as your
146
152
;; `font-lock-fontify-buffer' function stops it wasting your time
147
153
 
152
158
;; enabling it to be called as noweb-font-lock-minor-mode instead.
153
159
 
154
160
(defun noweb-font-lock-minor-mode ( &optional arg)
155
 
  "Minor meta mode for managing syntax highlighting in noweb files. 
 
161
  "Minor meta mode for managing syntax highlighting in noweb files.
156
162
See NOWEB-FONT-LOCK-MODE."
157
163
  (interactive)
158
164
  (noweb-font-lock-mode arg))
167
173
      (progn
168
174
; This bit is tricky: copied almost verbatim from bib-cite-mode.el
169
175
; It seems to ensure that the variable noweb-font-lock-mode is made
170
 
; local to this buffer. It then sets noweb-font-lock-mode to `t' if 
 
176
; local to this buffer. It then sets noweb-font-lock-mode to `t' if
171
177
;     1) It was called with a prefix argument greater than 0
172
178
; or  2) It was called with no argument, and noweb-font-lock-mode is
173
179
;        currently nil
179
185
             (not noweb-font-lock-mode)))
180
186
    ;; Now, if noweb-font-lock-mode is true, we want to turn
181
187
    ;; noweb-font-lock-mode on
182
 
    (cond 
 
188
    (cond
183
189
     (noweb-font-lock-mode                 ;Setup the minor-mode
184
190
      (progn
185
 
        (if global-font-lock-mode 
 
191
        (if (and (boundp 'global-font-lock-mode) global-font-lock-mode)
186
192
            (progn
187
193
              (mapcar 'noweb-make-variable-permanent-local
188
194
                      '(font-lock-fontify-buffer-function
196
202
                  after-change-functions))
197
203
        (setq noweb-font-lock-mode t)
198
204
        (make-local-hook 'after-change-functions)
199
 
        (add-hook 'after-change-functions 
 
205
        (add-hook 'after-change-functions
200
206
                  'font-lock-after-change-function nil t)
201
207
        (add-hook 'noweb-font-lock-mode-hook 'noweb-font-lock-mode-fn)
202
 
        (add-hook 'noweb-changed-chunk-hook 
 
208
        (add-hook 'noweb-changed-chunk-hook
203
209
                  'noweb-font-lock-fontify-this-chunk)
204
 
        (run-hooks 'noweb-font-lock-mode-hook)  
 
210
        (run-hooks 'noweb-font-lock-mode-hook)
205
211
        (message "noweb-font-lock mode: use `M-x noweb-font-lock-describe-mode' for more info")))
206
212
     ;; If we didn't do the above, then we want to turn noweb-font-lock-mode
207
213
     ;; off, no matter what (hence the condition `t')
208
214
    (t
209
215
     (progn
210
 
       (if global-font-lock-mode
 
216
       (if (and (boundp 'global-font-lock-mode) global-font-lock-mode)
211
217
           (progn
212
218
             ;; (setq font-lock-fontify-buffer-function
213
 
             ;;       'font-lock-default-fontify-buffer) 
 
219
             ;;       'font-lock-default-fontify-buffer)
214
220
             ;; Get back our unfontify buffer function
215
221
             (setq font-lock-unfontify-buffer-function
216
222
                   'font-lock-default-unfontify-buffer)))
217
223
       (remove-hook 'noweb-font-lock-mode-hook 'noweb-font-lock-mode-fn)
218
 
       (remove-hook 'noweb-changed-chunk-hook 
 
224
       (remove-hook 'noweb-changed-chunk-hook
219
225
                    'noweb-font-lock-fontify-this-chunk)
220
 
       (remove-hook 'after-change-functions 
 
226
       (remove-hook 'after-change-functions
221
227
                    'font-lock-after-change-function )
222
228
       (font-lock-default-unfontify-buffer)
223
229
       (setq noweb-use-font-lock-mode nil)
231
237
 
232
238
(defun noweb-font-lock-fontify-chunk-by-number ( chunk-num )
233
239
  "Fontify chunk chunk-num based on the current major mode."
234
 
  (save-excursion 
 
240
  (save-excursion
235
241
    (font-lock-set-defaults)
236
242
    (setq old-beginning-of-syntax font-lock-beginning-of-syntax-function)
237
243
    (setq font-lock-beginning-of-syntax-function 'noweb-start-of-syntax)
238
 
    (setq font-lock-keywords 
 
244
    (setq font-lock-keywords
239
245
;         (append font-lock-keywords
240
 
;                 '(("\\(\\[\\[\\)\\([^]]*\\]*\\)\\(\\]\\]\\|\\$\\)" 
 
246
;                 '(("\\(\\[\\[\\)\\([^]]*\\]*\\)\\(\\]\\]\\|\\$\\)"
241
247
;                    (1 noweb-font-lock-brackets-face prepend )
242
248
;                    (2 noweb-font-lock-code-quote-face prepend)
243
249
;                    (3 noweb-font-lock-brackets-face prepend))
245
251
;                    (1 noweb-font-lock-brackets-face  prepend )
246
252
;                    (2 noweb-font-lock-chunk-name-face prepend)
247
253
;                    (3 noweb-font-lock-brackets-face prepend))
248
 
;                   ("^@[ \t\n]+" 
 
254
;                   ("^@[ \t\n]+"
249
255
;                    (0 noweb-font-lock-doc-start-face prepend )))))
250
256
          (append font-lock-keywords
251
 
                  '(("\\(\\[\\[\\)\\([^]]*\\]*\\)\\(\\]\\]\\|\\$\\)" 
 
257
                  '(("\\(\\[\\[\\)\\([^]]*\\]*\\)\\(\\]\\]\\|\\$\\)"
252
258
                     (1 font-lock-reference-face prepend )
253
259
                     (2 font-lock-keyword-face prepend)
254
260
                     (3 font-lock-reference-face prepend))
256
262
                     (1 font-lock-reference-face  prepend )
257
263
                     (2 font-lock-keyword-face prepend)
258
264
                     (3 font-lock-reference-face prepend))
259
 
                    ("^@[ \t\n]+" 
 
265
                    ("^@[ \t\n]+"
260
266
                     (0 font-lock-reference-face prepend )))))
261
267
 
262
268
 
263
 
    (let ((r (cons (marker-position (cdr (aref noweb-chunk-vector 
 
269
    (let ((r (cons (marker-position (cdr (aref noweb-chunk-vector
264
270
                                               chunk-num)))
265
 
                   (marker-position (cdr (aref noweb-chunk-vector 
 
271
                   (marker-position (cdr (aref noweb-chunk-vector
266
272
                                               (1+ chunk-num)))))))
267
273
      (font-lock-fontify-region (car r) (cdr r))
268
274
      t)))
269
275
 
270
276
(defun noweb-font-lock-fontify-this-chunk ()
271
 
  "Fontify this chunk according to its own major mode. 
 
277
  "Fontify this chunk according to its own major mode.
272
278
Since we are in the chunk, the major mode will already have been set
273
279
by noweb-mode.el"
274
280
  (interactive)
287
293
;; pass. This could still be a little slow if we have to swap between
288
294
;; different code modes regularly, but it should be bearable. It should
289
295
;; only happen when the file is first read in, anyway
290
 
  (save-excursion 
 
296
  (save-excursion
291
297
  (let (start-chunk end-chunk this-chunk chunk-counter)
292
298
    (setq this-chunk (noweb-find-chunk-index-buffer))
293
299
    (if noweb-font-lock-max-initial-chunks
294
300
        (progn
295
 
          (setq start-chunk 
296
 
                (max 0 
297
 
                     (- this-chunk 
 
301
          (setq start-chunk
 
302
                (max 0
 
303
                     (- this-chunk
298
304
                        (/ noweb-font-lock-max-initial-chunks 2))))
299
305
;; Don't you just love hairy lisp syntax ? The above means set the
300
306
;; starting chunk to the current chunk minus half of
304
310
          (if (> end-chunk (- (length noweb-chunk-vector) 2))
305
311
              (setq end-chunk (- (length noweb-chunk-vector) 2))))
306
312
;; If noweb-font-lock-max-initial-chunks is nil, do the whole buffer
307
 
      (progn 
 
313
      (progn
308
314
        (setq start-chunk 0)
309
315
        (setq end-chunk (- (length noweb-chunk-vector) 2))))
310
316
    (noweb-font-lock-fontify-chunks start-chunk end-chunk))))
333
339
        (if  (not (stringp (car (aref noweb-chunk-vector chunk-counter))))
334
340
            (noweb-font-lock-fontify-chunk-by-number chunk-counter))
335
341
        (message "Fontifying documentation chunks: chunk %d" chunk-counter)
336
 
        (setq chunk-counter (+ 1 chunk-counter))) 
 
342
        (setq chunk-counter (+ 1 chunk-counter)))
337
343
      ;; Go back to the start and go through the chunks, fontifying the code ones.
338
 
      (setq chunk-counter start-chunk)  
 
344
      (setq chunk-counter start-chunk)
339
345
      (message "About to do code chunks")
340
346
      (while (<= chunk-counter end-chunk)
341
347
        (if (stringp (car (aref noweb-chunk-vector chunk-counter)))
358
364
;; noweb-font-lock-mode. I had hoped that providing a replacement
359
365
;; `nw-turn-on-font-lock' would solve the problem, but it didn't
360
366
;; (sometimes turn-on-font-lock appears in places other than
361
 
;; `.emacs', such as in ESS). So rather than have it fall over if 
362
 
;; turn-on-lock was around, I redefined turn-on-font-lock to do the 
 
367
;; `.emacs', such as in ESS). So rather than have it fall over if
 
368
;; turn-on-lock was around, I redefined turn-on-font-lock to do the
363
369
;; right thing.
364
370
 
365
371
(defvar noweb-old-turn-on-font-lock nil)
379
385
 
380
386
(provide 'noweb-font-lock-mode)
381
387
;;  *****
382
 
;;  
 
388
;;
383
389
;;  Adnan Yaqub (AYaqub@orga.com)
384
390
;;  ORGA Kartensysteme GmbH // An der Kapelle 2 // D-33104 Paderborn // Germany
385
391
;;  Tel. +49 5254 991-823 //Fax. +49 5254 991-749