chiark / gitweb /
dot/emacs: Don't prompt about following symbolic links.
[profile] / el / dot-emacs.el
CommitLineData
502f4699 1;;; -*- mode: emacs-lisp; coding: utf-8 -*-
f617db13 2;;;
f617db13
MW
3;;; Functions and macros for .emacs
4;;;
5;;; (c) 2004 Mark Wooding
6;;;
7
8;;;----- Licensing notice ---------------------------------------------------
9;;;
10;;; This program is free software; you can redistribute it and/or modify
11;;; it under the terms of the GNU General Public License as published by
12;;; the Free Software Foundation; either version 2 of the License, or
13;;; (at your option) any later version.
852cd5fb 14;;;
f617db13
MW
15;;; This program is distributed in the hope that it will be useful,
16;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;;; GNU General Public License for more details.
852cd5fb 19;;;
f617db13
MW
20;;; You should have received a copy of the GNU General Public License
21;;; along with this program; if not, write to the Free Software Foundation,
22;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
6132bc01
MW
24;;;--------------------------------------------------------------------------
25;;; Check command-line.
c7a8da49
MW
26
27(defvar mdw-fast-startup nil
28 "Whether .emacs should optimize for rapid startup.
29This may be at the expense of cool features.")
30(let ((probe nil) (next command-line-args))
c7a8da49
MW
31 (while next
32 (cond ((string= (car next) "--mdw-fast-startup")
33 (setq mdw-fast-startup t)
34 (if probe
35 (rplacd probe (cdr next))
36 (setq command-line-args (cdr next))))
37 (t
38 (setq probe next)))
39 (setq next (cdr next))))
40
6132bc01
MW
41;;;--------------------------------------------------------------------------
42;;; Some general utilities.
f617db13 43
417dcddd
MW
44(eval-when-compile
45 (unless (fboundp 'make-regexp)
46 (load "make-regexp"))
47 (require 'cl))
c7a8da49
MW
48
49(defmacro mdw-regexps (&rest list)
50 "Turn a LIST of strings into a single regular expression at compile-time."
9e789ed5
MW
51 (declare (indent nil)
52 (debug 0))
417dcddd 53 `',(make-regexp list))
c7a8da49 54
a1b01eb3
MW
55(defun mdw-wrong ()
56 "This is not the key sequence you're looking for."
57 (interactive)
58 (error "wrong button"))
59
e8ea88ba
MW
60(defun mdw-emacs-version-p (major &optional minor)
61 "Return non-nil if the running Emacs is at least version MAJOR.MINOR."
62 (or (> emacs-major-version major)
63 (and (= emacs-major-version major)
64 (>= emacs-minor-version (or minor 0)))))
65
6132bc01 66;; Some error trapping.
f617db13
MW
67;;
68;; If individual bits of this file go tits-up, we don't particularly want
69;; the whole lot to stop right there and then, because it's bloody annoying.
70
71(defmacro trap (&rest forms)
72 "Execute FORMS without allowing errors to propagate outside."
9e789ed5
MW
73 (declare (indent 0)
74 (debug t))
f617db13
MW
75 `(condition-case err
76 ,(if (cdr forms) (cons 'progn forms) (car forms))
8df912e4
MW
77 (error (message "Error (trapped): %s in %s"
78 (error-message-string err)
79 ',forms))))
f617db13 80
6132bc01 81;; Configuration reading.
f141fe0f
MW
82
83(defvar mdw-config nil)
84(defun mdw-config (sym)
85 "Read the configuration variable named SYM."
86 (unless mdw-config
daff679f
MW
87 (setq mdw-config
88 (flet ((replace (what with)
89 (goto-char (point-min))
90 (while (re-search-forward what nil t)
91 (replace-match with t))))
92 (with-temp-buffer
93 (insert-file-contents "~/.mdw.conf")
94 (replace "^[ \t]*\\(#.*\\|\\)\n" "")
95 (replace (concat "^[ \t]*"
96 "\\([-a-zA-Z0-9_.]*\\)"
97 "[ \t]*=[ \t]*"
98 "\\(.*[^ \t\n]\\|\\)"
99 "[ \t]**\\(\n\\|$\\)")
100 "(\\1 . \"\\2\")\n")
101 (car (read-from-string
102 (concat "(" (buffer-string) ")")))))))
f141fe0f
MW
103 (cdr (assq sym mdw-config)))
104
c7203018
MW
105;; Width configuration.
106
107(defvar mdw-column-width
108 (string-to-number (or (mdw-config 'emacs-width) "77"))
109 "Width of Emacs columns.")
110(defvar mdw-text-width mdw-column-width
111 "Expected width of text within columns.")
112(put 'mdw-text-width 'safe-local-variable 'integerp)
113
18bb0f77
MW
114;; Local variables hacking.
115
116(defun run-local-vars-mode-hook ()
117 "Run a hook for the major-mode after local variables have been processed."
118 (run-hooks (intern (concat (symbol-name major-mode)
119 "-local-variables-hook"))))
120(add-hook 'hack-local-variables-hook 'run-local-vars-mode-hook)
121
6132bc01 122;; Set up the load path convincingly.
eac7b622
MW
123
124(dolist (dir (append (and (boundp 'debian-emacs-flavor)
125 (list (concat "/usr/share/"
126 (symbol-name debian-emacs-flavor)
127 "/site-lisp")))))
128 (dolist (sub (directory-files dir t))
129 (when (and (file-accessible-directory-p sub)
130 (not (member sub load-path)))
131 (setq load-path (nconc load-path (list sub))))))
132
6132bc01 133;; Is an Emacs library available?
cb6e2cd1
MW
134
135(defun library-exists-p (name)
6132bc01
MW
136 "Return non-nil if NAME is an available library.
137Return non-nil if NAME.el (or NAME.elc) somewhere on the Emacs
138load path. The non-nil value is the filename we found for the
139library."
cb6e2cd1
MW
140 (let ((path load-path) elt (foundp nil))
141 (while (and path (not foundp))
142 (setq elt (car path))
143 (setq path (cdr path))
144 (setq foundp (or (let ((file (concat elt "/" name ".elc")))
145 (and (file-exists-p file) file))
146 (let ((file (concat elt "/" name ".el")))
147 (and (file-exists-p file) file)))))
148 foundp))
149
150(defun maybe-autoload (symbol file &optional docstring interactivep type)
151 "Set an autoload if the file actually exists."
152 (and (library-exists-p file)
153 (autoload symbol file docstring interactivep type)))
154
8183de08
MW
155(defun mdw-kick-menu-bar (&optional frame)
156 "Regenerate FRAME's menu bar so it doesn't have empty menus."
157 (interactive)
158 (unless frame (setq frame (selected-frame)))
159 (let ((old (frame-parameter frame 'menu-bar-lines)))
160 (set-frame-parameter frame 'menu-bar-lines 0)
161 (set-frame-parameter frame 'menu-bar-lines old)))
162
6132bc01 163;; Splitting windows.
f617db13 164
8c2b05d5
MW
165(unless (fboundp 'scroll-bar-columns)
166 (defun scroll-bar-columns (side)
167 (cond ((eq side 'left) 0)
168 (window-system 3)
169 (t 1))))
170(unless (fboundp 'fringe-columns)
171 (defun fringe-columns (side)
172 (cond ((not window-system) 0)
173 ((eq side 'left) 1)
174 (t 2))))
175
3ba0b777
MW
176(defun mdw-horizontal-window-overhead ()
177 "Computes the horizontal window overhead.
178This is the number of columns used by fringes, scroll bars and other such
179cruft."
180 (if (not window-system)
181 1
182 (let ((tot 0))
183 (dolist (what '(scroll-bar fringe))
184 (dolist (side '(left right))
185 (incf tot (funcall (intern (concat (symbol-name what) "-columns"))
186 side))))
187 tot)))
188
189(defun mdw-split-window-horizontally (&optional width)
190 "Split a window horizontally.
191Without a numeric argument, split the window approximately in
192half. With a numeric argument WIDTH, allocate WIDTH columns to
193the left-hand window (if positive) or -WIDTH columns to the
194right-hand window (if negative). Space for scroll bars and
195fringes is not taken out of the allowance for WIDTH, unlike
196\\[split-window-horizontally]."
197 (interactive "P")
198 (split-window-horizontally
199 (cond ((null width) nil)
200 ((>= width 0) (+ width (mdw-horizontal-window-overhead)))
201 ((< width 0) width))))
202
8c2b05d5 203(defun mdw-divvy-window (&optional width)
f617db13 204 "Split a wide window into appropriate widths."
8c2b05d5
MW
205 (interactive "P")
206 (setq width (cond (width (prefix-numeric-value width))
e8ea88ba 207 ((and window-system (mdw-emacs-version-p 22))
c7203018
MW
208 mdw-column-width)
209 (t (1+ mdw-column-width))))
b5d724dd 210 (let* ((win (selected-window))
3ba0b777 211 (sb-width (mdw-horizontal-window-overhead))
b5d724dd 212 (c (/ (+ (window-width) sb-width)
8c2b05d5 213 (+ width sb-width))))
f617db13
MW
214 (while (> c 1)
215 (setq c (1- c))
8c2b05d5 216 (split-window-horizontally (+ width sb-width))
f617db13
MW
217 (other-window 1))
218 (select-window win)))
219
cc2be23e
MW
220;; Don't raise windows unless I say so.
221
222(defvar mdw-inhibit-raise-frame nil
223 "*Whether `raise-frame' should do nothing when the frame is mapped.")
224
225(defadvice raise-frame
226 (around mdw-inhibit (&optional frame) activate compile)
227 "Don't actually do anything if `mdw-inhibit-raise-frame' is true, and the
228frame is actually mapped on the screen."
229 (if mdw-inhibit-raise-frame
230 (make-frame-visible frame)
231 ad-do-it))
232
233(defmacro mdw-advise-to-inhibit-raise-frame (function)
234 "Advise the FUNCTION not to raise frames, even if it wants to."
235 `(defadvice ,function
236 (around mdw-inhibit-raise (&rest hunoz) activate compile)
237 "Don't raise the window unless you have to."
238 (let ((mdw-inhibit-raise-frame t))
239 ad-do-it)))
240
241(mdw-advise-to-inhibit-raise-frame select-frame-set-input-focus)
242
a1e4004c
MW
243;; Bug fix for markdown-mode, which breaks point positioning during
244;; `query-replace'.
245(defadvice markdown-check-change-for-wiki-link
246 (around mdw-save-match activate compile)
247 "Save match data around the `markdown-mode' `after-change-functions' hook."
248 (save-match-data ad-do-it))
249
d54a4cf3
MW
250;; Bug fix for `bbdb-canonicalize-address': on Emacs 24, `run-hook-with-args'
251;; always returns nil, with the result that all email addresses are lost.
252;; Replace the function entirely.
253(defadvice bbdb-canonicalize-address
254 (around mdw-bug-fix activate compile)
255 "Don't use `run-hook-with-args', because that doesn't work."
256 (let ((net (ad-get-arg 0)))
257
258 ;; Make sure this is a proper hook list.
259 (if (functionp bbdb-canonicalize-net-hook)
260 (setq bbdb-canonicalize-net-hook (list bbdb-canonicalize-net-hook)))
261
262 ;; Iterate over the hooks until things converge.
263 (let ((donep nil))
264 (while (not donep)
265 (let (next (changep nil)
266 hook (hooks bbdb-canonicalize-net-hook))
267 (while hooks
268 (setq hook (pop hooks))
269 (setq next (funcall hook net))
270 (if (not (equal next net))
271 (setq changep t
272 net next)))
273 (setq donep (not changep)))))
274 (setq ad-return-value net)))
275
c4b18360
MW
276;; Transient mark mode hacks.
277
278(defadvice exchange-point-and-mark
279 (around mdw-highlight (&optional arg) activate compile)
280 "Maybe don't actually exchange point and mark.
281If `transient-mark-mode' is on and the mark is inactive, then
282just activate it. A non-trivial prefix argument will force the
283usual behaviour. A trivial prefix argument (i.e., just C-u) will
284activate the mark and temporarily enable `transient-mark-mode' if
285it's currently off."
286 (cond ((or mark-active
287 (and (not transient-mark-mode) (not arg))
288 (and arg (or (not (consp arg))
289 (not (= (car arg) 4)))))
290 ad-do-it)
291 (t
292 (or transient-mark-mode (setq transient-mark-mode 'only))
293 (set-mark (mark t)))))
294
6132bc01 295;; Functions for sexp diary entries.
f617db13 296
aede9fd7
MW
297(defun mdw-not-org-mode (form)
298 "As FORM, but not in Org mode agenda."
299 (and (not mdw-diary-for-org-mode-p)
300 (eval form)))
301
f617db13
MW
302(defun mdw-weekday (l)
303 "Return non-nil if `date' falls on one of the days of the week in L.
6132bc01
MW
304L is a list of day numbers (from 0 to 6 for Sunday through to
305Saturday) or symbols `sunday', `monday', etc. (or a mixture). If
306the date stored in `date' falls on a listed day, then the
307function returns non-nil."
f617db13
MW
308 (let ((d (calendar-day-of-week date)))
309 (or (memq d l)
310 (memq (nth d '(sunday monday tuesday wednesday
311 thursday friday saturday)) l))))
312
d401f71b
MW
313(defun mdw-discordian-date (date)
314 "Return the Discordian calendar date corresponding to DATE.
315
316The return value is (YOLD . st-tibs-day) or (YOLD SEASON DAYNUM DOW).
317
318The original is by David Pearson. I modified it to produce date components
319as output rather than a string."
320 (let* ((days ["Sweetmorn" "Boomtime" "Pungenday"
321 "Prickle-Prickle" "Setting Orange"])
322 (months ["Chaos" "Discord" "Confusion"
323 "Bureaucracy" "Aftermath"])
324 (day-count [0 31 59 90 120 151 181 212 243 273 304 334])
325 (year (- (extract-calendar-year date) 1900))
326 (month (1- (extract-calendar-month date)))
327 (day (1- (extract-calendar-day date)))
328 (julian (+ (aref day-count month) day))
329 (dyear (+ year 3066)))
330 (if (and (= month 1) (= day 28))
331 (cons dyear 'st-tibs-day)
332 (list dyear
333 (aref months (floor (/ julian 73)))
334 (1+ (mod julian 73))
335 (aref days (mod julian 5))))))
336
337(defun mdw-diary-discordian-date ()
338 "Convert the date in `date' to a string giving the Discordian date."
339 (let* ((ddate (mdw-discordian-date date))
340 (tail (format "in the YOLD %d" (car ddate))))
341 (if (eq (cdr ddate) 'st-tibs-day)
342 (format "St Tib's Day %s" tail)
343 (let ((season (cadr ddate))
344 (daynum (caddr ddate))
345 (dayname (cadddr ddate)))
346 (format "%s, the %d%s day of %s %s"
347 dayname
348 daynum
349 (let ((ldig (mod daynum 10)))
350 (cond ((= ldig 1) "st")
351 ((= ldig 2) "nd")
352 ((= ldig 3) "rd")
353 (t "th")))
354 season
355 tail)))))
356
f617db13
MW
357(defun mdw-todo (&optional when)
358 "Return non-nil today, or on WHEN, whichever is later."
359 (let ((w (calendar-absolute-from-gregorian (calendar-current-date)))
360 (d (calendar-absolute-from-gregorian date)))
361 (if when
362 (setq w (max w (calendar-absolute-from-gregorian
363 (cond
364 ((not european-calendar-style)
365 when)
366 ((> (car when) 100)
367 (list (nth 1 when)
368 (nth 2 when)
369 (nth 0 when)))
370 (t
371 (list (nth 1 when)
372 (nth 0 when)
373 (nth 2 when))))))))
374 (eq w d)))
375
aede9fd7
MW
376(defvar mdw-diary-for-org-mode-p nil)
377
378(defadvice org-agenda-list (around mdw-preserve-links activate)
379 (let ((mdw-diary-for-org-mode-p t))
380 ad-do-it))
381
1d342abe 382(defadvice diary-add-to-list (before mdw-trim-leading-space compile activate)
9f58a8d2
MW
383 "Trim leading space from the diary entry string."
384 (save-match-data
2745469d
MW
385 (let ((str (ad-get-arg 1))
386 (done nil) old)
387 (while (not done)
388 (setq old str)
389 (setq str (cond ((null str) nil)
390 ((string-match "\\(^\\|\n\\)[ \t]+" str)
391 (replace-match "\\1" nil nil str))
aede9fd7
MW
392 ((and mdw-diary-for-org-mode-p
393 (string-match (concat
2745469d 394 "\\(^\\|\n\\)"
aede9fd7
MW
395 "\\(" diary-time-regexp
396 "\\(-" diary-time-regexp "\\)?"
2745469d
MW
397 "\\)"
398 "\\(\t[ \t]*\\| [ \t]+\\)")
aede9fd7 399 str))
2745469d 400 (replace-match "\\1\\2 " nil nil str))
aede9fd7
MW
401 ((and (not mdw-diary-for-org-mode-p)
402 (string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]"
403 str))
404 (replace-match "\\1" nil nil str))
2745469d
MW
405 (t str)))
406 (if (equal str old) (setq done t)))
407 (ad-set-arg 1 str))))
9f58a8d2 408
319736bd
MW
409(defadvice org-bbdb-anniversaries (after mdw-fixup-list compile activate)
410 "Return a string rather than a list."
411 (with-temp-buffer
412 (let ((anyp nil))
413 (dolist (e (let ((ee ad-return-value))
414 (if (atom ee) (list ee) ee)))
415 (when e
416 (when anyp (insert ?\n))
417 (insert e)
418 (setq anyp t)))
419 (setq ad-return-value
420 (and anyp (buffer-string))))))
421
6132bc01 422;; Fighting with Org-mode's evil key maps.
16fe7c41
MW
423
424(defvar mdw-evil-keymap-keys
425 '(([S-up] . [?\C-c up])
426 ([S-down] . [?\C-c down])
427 ([S-left] . [?\C-c left])
428 ([S-right] . [?\C-c right])
429 (([M-up] [?\e up]) . [C-up])
430 (([M-down] [?\e down]) . [C-down])
431 (([M-left] [?\e left]) . [C-left])
432 (([M-right] [?\e right]) . [C-right]))
433 "Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
434The value is an alist mapping evil keys (as a list, or singleton)
435to good keys (in the same form).")
436
437(defun mdw-clobber-evil-keymap (keymap)
438 "Replace evil key bindings in the KEYMAP.
439Evil key bindings are defined in `mdw-evil-keymap-keys'."
440 (dolist (entry mdw-evil-keymap-keys)
441 (let ((binding nil)
442 (keys (if (listp (car entry))
443 (car entry)
444 (list (car entry))))
445 (replacements (if (listp (cdr entry))
446 (cdr entry)
447 (list (cdr entry)))))
448 (catch 'found
449 (dolist (key keys)
450 (setq binding (lookup-key keymap key))
451 (when binding
452 (throw 'found nil))))
453 (when binding
454 (dolist (key keys)
455 (define-key keymap key nil))
456 (dolist (key replacements)
457 (define-key keymap key binding))))))
458
0f6be0b1 459(eval-after-load "org-latex"
f0dbee84
MW
460 '(progn
461 (push '("strayman"
462 "\\documentclass{strayman}
463\\usepackage[utf8]{inputenc}
464\\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
465\\usepackage[T1]{fontenc}
466\\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
467 ("\\section{%s}" . "\\section*{%s}")
468 ("\\subsection{%s}" . "\\subsection*{%s}")
469 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
470 ("\\paragraph{%s}" . "\\paragraph*{%s}")
471 ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
472 org-export-latex-classes)))
473
8ba985cb
MW
474(setq org-export-docbook-xslt-proc-command "xsltproc --output %o %s %i"
475 org-export-docbook-xsl-fo-proc-command "fop %i.safe %o"
476 org-export-docbook-xslt-stylesheet
477 "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl")
478
5dccbe61
MW
479;; Some hacks to do with window placement.
480
481(defun mdw-clobber-other-windows-showing-buffer (buffer-or-name)
482 "Arrange that no windows on other frames are showing BUFFER-OR-NAME."
483 (interactive "bBuffer: ")
484 (let ((home-frame (selected-frame))
485 (buffer (get-buffer buffer-or-name))
486 (safe-buffer (get-buffer "*scratch*")))
487 (mapc (lambda (frame)
488 (or (eq frame home-frame)
489 (mapc (lambda (window)
490 (and (eq (window-buffer window) buffer)
491 (set-window-buffer window safe-buffer)))
492 (window-list frame))))
493 (frame-list))))
494
495(defvar mdw-inhibit-walk-windows nil
496 "If non-nil, then `walk-windows' does nothing.
497This is used by advice on `switch-to-buffer-other-frame' to inhibit finding
498buffers in random frames.")
499
500(defadvice walk-windows (around mdw-inhibit activate)
501 "If `mdw-inhibit-walk-windows' is non-nil, then do nothing."
502 (and (not mdw-inhibit-walk-windows)
503 ad-do-it))
504
505(defadvice switch-to-buffer-other-frame
506 (around mdw-always-new-frame activate)
507 "Always make a new frame.
508Even if an existing window in some random frame looks tempting."
509 (let ((mdw-inhibit-walk-windows t)) ad-do-it))
510
511(defadvice display-buffer (before mdw-inhibit-other-frames activate)
512 "Don't try to do anything fancy with other frames.
513Pretend they don't exist. They might be on other display devices."
514 (ad-set-arg 2 nil))
515
6132bc01
MW
516;;;--------------------------------------------------------------------------
517;;; Mail and news hacking.
a3bdb4d9
MW
518
519(define-derived-mode mdwmail-mode mail-mode "[mdw] mail"
6132bc01 520 "Major mode for editing news and mail messages from external programs.
a3bdb4d9
MW
521Not much right now. Just support for doing MailCrypt stuff."
522 :syntax-table nil
523 :abbrev-table nil
524 (run-hooks 'mail-setup-hook))
525
526(define-key mdwmail-mode-map [?\C-c ?\C-c] 'disabled-operation)
527
528(add-hook 'mdwail-mode-hook
529 (lambda ()
530 (set-buffer-file-coding-system 'utf-8)
531 (make-local-variable 'paragraph-separate)
532 (make-local-variable 'paragraph-start)
533 (setq paragraph-start
534 (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
535 paragraph-start))
536 (setq paragraph-separate
537 (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
538 paragraph-separate))))
539
6132bc01 540;; How to encrypt in mdwmail.
a3bdb4d9
MW
541
542(defun mdwmail-mc-encrypt (&optional recip scm start end from sign)
543 (or start
544 (setq start (save-excursion
545 (goto-char (point-min))
546 (or (search-forward "\n\n" nil t) (point-min)))))
547 (or end
548 (setq end (point-max)))
549 (mc-encrypt-generic recip scm start end from sign))
550
6132bc01 551;; How to sign in mdwmail.
a3bdb4d9
MW
552
553(defun mdwmail-mc-sign (key scm start end uclr)
554 (or start
555 (setq start (save-excursion
556 (goto-char (point-min))
557 (or (search-forward "\n\n" nil t) (point-min)))))
558 (or end
559 (setq end (point-max)))
560 (mc-sign-generic key scm start end uclr))
561
6132bc01 562;; Some signature mangling.
a3bdb4d9
MW
563
564(defun mdwmail-mangle-signature ()
565 (save-excursion
566 (goto-char (point-min))
567 (perform-replace "\n-- \n" "\n-- " nil nil nil)))
568(add-hook 'mail-setup-hook 'mdwmail-mangle-signature)
569(add-hook 'message-setup-hook 'mdwmail-mangle-signature)
570
6132bc01 571;; Insert my login name into message-ids, so I can score replies.
a3bdb4d9
MW
572
573(defadvice message-unique-id (after mdw-user-name last activate compile)
574 "Ensure that the user's name appears at the end of the message-id string,
575so that it can be used for convenient filtering."
576 (setq ad-return-value (concat ad-return-value "." (user-login-name))))
577
6132bc01 578;; Tell my movemail hack where movemail is.
a3bdb4d9
MW
579;;
580;; This is needed to shup up warnings about LD_PRELOAD.
581
582(let ((path exec-path))
583 (while path
584 (let ((try (expand-file-name "movemail" (car path))))
585 (if (file-executable-p try)
586 (setenv "REAL_MOVEMAIL" try))
587 (setq path (cdr path)))))
588
4d5799eb
MW
589;; AUTHINFO GENERIC kludge.
590
591(defvar nntp-authinfo-generic nil
592 "Set to the `NNTPAUTH' string to pass on to `authinfo-kludge'.
593
594Use this to arrange for per-server settings.")
595
596(defun nntp-open-authinfo-kludge (buffer)
597 "Open a connection to SERVER using `authinfo-kludge'."
598 (let ((proc (start-process "nntpd" buffer
599 "env" (concat "NNTPAUTH="
600 (or nntp-authinfo-generic
601 (getenv "NNTPAUTH")
602 (error "NNTPAUTH unset")))
603 "authinfo-kludge" nntp-address)))
604 (set-buffer buffer)
605 (nntp-wait-for-string "^\r*200")
606 (beginning-of-line)
607 (delete-region (point-min) (point))
608 proc))
609
d17c6756
MW
610(eval-after-load "erc"
611 '(load "~/.ercrc.el"))
612
6132bc01
MW
613;;;--------------------------------------------------------------------------
614;;; Utility functions.
f617db13 615
b5d724dd
MW
616(or (fboundp 'line-number-at-pos)
617 (defun line-number-at-pos (&optional pos)
618 (let ((opoint (or pos (point))) start)
619 (save-excursion
620 (save-restriction
621 (goto-char (point-min))
622 (widen)
623 (forward-line 0)
624 (setq start (point))
625 (goto-char opoint)
626 (forward-line 0)
627 (1+ (count-lines 1 (point))))))))
459c9fb2 628
f617db13 629(defun mdw-uniquify-alist (&rest alists)
f617db13 630 "Return the concatenation of the ALISTS with duplicate elements removed.
6132bc01
MW
631The first association with a given key prevails; others are
632ignored. The input lists are not modified, although they'll
633probably become garbage."
f617db13
MW
634 (and alists
635 (let ((start-list (cons nil nil)))
636 (mdw-do-uniquify start-list
637 start-list
638 (car alists)
639 (cdr alists)))))
640
f617db13 641(defun mdw-do-uniquify (done end l rest)
6132bc01
MW
642 "A helper function for mdw-uniquify-alist.
643The DONE argument is a list whose first element is `nil'. It
644contains the uniquified alist built so far. The leading `nil' is
645stripped off at the end of the operation; it's only there so that
646DONE always references a cons cell. END refers to the final cons
647cell in the DONE list; it is modified in place each time to avoid
648the overheads of `append'ing all the time. The L argument is the
649alist we're currently processing; the remaining alists are given
650in REST."
651
652 ;; There are several different cases to deal with here.
f617db13
MW
653 (cond
654
6132bc01
MW
655 ;; Current list isn't empty. Add the first item to the DONE list if
656 ;; there's not an item with the same KEY already there.
f617db13
MW
657 (l (or (assoc (car (car l)) done)
658 (progn
659 (setcdr end (cons (car l) nil))
660 (setq end (cdr end))))
661 (mdw-do-uniquify done end (cdr l) rest))
662
6132bc01
MW
663 ;; The list we were working on is empty. Shunt the next list into the
664 ;; current list position and go round again.
f617db13
MW
665 (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
666
6132bc01
MW
667 ;; Everything's done. Remove the leading `nil' from the DONE list and
668 ;; return it. Finished!
f617db13
MW
669 (t (cdr done))))
670
f617db13
MW
671(defun date ()
672 "Insert the current date in a pleasing way."
673 (interactive)
674 (insert (save-excursion
675 (let ((buffer (get-buffer-create "*tmp*")))
676 (unwind-protect (progn (set-buffer buffer)
677 (erase-buffer)
678 (shell-command "date +%Y-%m-%d" t)
679 (goto-char (mark))
680 (delete-backward-char 1)
681 (buffer-string))
682 (kill-buffer buffer))))))
683
f617db13
MW
684(defun uuencode (file &optional name)
685 "UUencodes a file, maybe calling it NAME, into the current buffer."
686 (interactive "fInput file name: ")
687
6132bc01 688 ;; If NAME isn't specified, then guess from the filename.
f617db13
MW
689 (if (not name)
690 (setq name
691 (substring file
692 (or (string-match "[^/]*$" file) 0))))
f617db13
MW
693 (print (format "uuencode `%s' `%s'" file name))
694
6132bc01 695 ;; Now actually do the thing.
f617db13
MW
696 (call-process "uuencode" file t nil name))
697
698(defvar np-file "~/.np"
699 "*Where the `now-playing' file is.")
700
701(defun np (&optional arg)
702 "Grabs a `now-playing' string."
703 (interactive)
704 (save-excursion
705 (or arg (progn
852cd5fb 706 (goto-char (point-max))
f617db13 707 (insert "\nNP: ")
daff679f 708 (insert-file-contents np-file)))))
f617db13 709
ae7460d4
MW
710(defun mdw-version-< (ver-a ver-b)
711 "Answer whether VER-A is strictly earlier than VER-B.
712VER-A and VER-B are version numbers, which are strings containing digit
713sequences separated by `.'."
714 (let* ((la (mapcar (lambda (x) (car (read-from-string x)))
715 (split-string ver-a "\\.")))
716 (lb (mapcar (lambda (x) (car (read-from-string x)))
717 (split-string ver-b "\\."))))
718 (catch 'done
719 (while t
720 (cond ((null la) (throw 'done lb))
721 ((null lb) (throw 'done nil))
722 ((< (car la) (car lb)) (throw 'done t))
723 ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb))))))))
724
c7a8da49 725(defun mdw-check-autorevert ()
6132bc01
MW
726 "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
727This takes into consideration whether it's been found using
728tramp, which seems to get itself into a twist."
46e69f55
MW
729 (cond ((not (boundp 'global-auto-revert-ignore-buffer))
730 nil)
731 ((and (buffer-file-name)
732 (fboundp 'tramp-tramp-file-p)
c7a8da49
MW
733 (tramp-tramp-file-p (buffer-file-name)))
734 (unless global-auto-revert-ignore-buffer
735 (setq global-auto-revert-ignore-buffer 'tramp)))
736 ((eq global-auto-revert-ignore-buffer 'tramp)
737 (setq global-auto-revert-ignore-buffer nil))))
738
739(defadvice find-file (after mdw-autorevert activate)
740 (mdw-check-autorevert))
741(defadvice write-file (after mdw-autorevert activate)
4d9f2d65 742 (mdw-check-autorevert))
eae0aa6d 743
6132bc01
MW
744;;;--------------------------------------------------------------------------
745;;; Dired hacking.
5195cbc3
MW
746
747(defadvice dired-maybe-insert-subdir
748 (around mdw-marked-insertion first activate)
6132bc01
MW
749 "The DIRNAME may be a list of directory names to insert.
750Interactively, if files are marked, then insert all of them.
751With a numeric prefix argument, select that many entries near
752point; with a non-numeric prefix argument, prompt for listing
753options."
5195cbc3
MW
754 (interactive
755 (list (dired-get-marked-files nil
756 (and (integerp current-prefix-arg)
757 current-prefix-arg)
758 #'file-directory-p)
759 (and current-prefix-arg
760 (not (integerp current-prefix-arg))
761 (read-string "Switches for listing: "
762 (or dired-subdir-switches
763 dired-actual-switches)))))
764 (let ((dirs (ad-get-arg 0)))
765 (dolist (dir (if (listp dirs) dirs (list dirs)))
766 (ad-set-arg 0 dir)
767 ad-do-it)))
768
6132bc01
MW
769;;;--------------------------------------------------------------------------
770;;; URL viewing.
a203fba8
MW
771
772(defun mdw-w3m-browse-url (url &optional new-session-p)
773 "Invoke w3m on the URL in its current window, or at least a different one.
774If NEW-SESSION-P, start a new session."
775 (interactive "sURL: \nP")
776 (save-excursion
63fb20c1
MW
777 (let ((window (selected-window)))
778 (unwind-protect
779 (progn
780 (select-window (or (and (not new-session-p)
781 (get-buffer-window "*w3m*"))
782 (progn
783 (if (one-window-p t) (split-window))
784 (get-lru-window))))
785 (w3m-browse-url url new-session-p))
786 (select-window window)))))
a203fba8
MW
787
788(defvar mdw-good-url-browsers
a0d16e44
MW
789 '(browse-url-mozilla
790 browse-url-generic
ed5e20a5 791 (w3m . mdw-w3m-browse-url)
a0d16e44 792 browse-url-w3)
6132bc01
MW
793 "List of good browsers for mdw-good-url-browsers.
794Each item is a browser function name, or a cons (CHECK . FUNC).
795A symbol FOO stands for (FOO . FOO).")
a203fba8
MW
796
797(defun mdw-good-url-browser ()
6132bc01
MW
798 "Return a good URL browser.
799Trundle the list of such things, finding the first item for which
800CHECK is fboundp, and returning the correponding FUNC."
a203fba8
MW
801 (let ((bs mdw-good-url-browsers) b check func answer)
802 (while (and bs (not answer))
803 (setq b (car bs)
804 bs (cdr bs))
805 (if (consp b)
806 (setq check (car b) func (cdr b))
807 (setq check b func b))
808 (if (fboundp check)
809 (setq answer func)))
810 answer))
811
f36cdb77
MW
812(eval-after-load "w3m-search"
813 '(progn
814 (dolist
815 (item
816 '(("g" "Google" "http://www.google.co.uk/search?q=%s")
817 ("gd" "Google Directory"
818 "http://www.google.com/search?cat=gwd/Top&q=%s")
819 ("gg" "Google Groups" "http://groups.google.com/groups?q=%s")
820 ("ward" "Ward's wiki" "http://c2.com/cgi/wiki?%s")
821 ("gi" "Images" "http://images.google.com/images?q=%s")
822 ("rfc" "RFC"
823 "http://metalzone.distorted.org.uk/ftp/pub/mirrors/rfc/rfc%s.txt.gz")
824 ("wp" "Wikipedia"
825 "http://en.wikipedia.org/wiki/Special:Search?go=Go&search=%s")
826 ("imdb" "IMDb" "http://www.imdb.com/Find?%s")
827 ("nc-wiki" "nCipher wiki"
828 "http://wiki.ncipher.com/wiki/bin/view/Devel/?topic=%s")
829 ("map" "Google maps" "http://maps.google.co.uk/maps?q=%s&hl=en")
830 ("lp" "Launchpad bug by number"
831 "https://bugs.launchpad.net/bugs/%s")
832 ("lppkg" "Launchpad bugs by package"
833 "https://bugs.launchpad.net/%s")
834 ("msdn" "MSDN"
835 "http://social.msdn.microsoft.com/Search/en-GB/?query=%s&ac=8")
836 ("debbug" "Debian bug by number"
837 "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s")
838 ("debbugpkg" "Debian bugs by package"
839 "http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=%s")
840 ("ljlogin" "LJ login" "http://www.livejournal.com/login.bml")))
841 (add-to-list 'w3m-search-engine-alist
842 (list (cadr item) (caddr item) nil))
843 (add-to-list 'w3m-uri-replace-alist
844 (list (concat "\\`" (car item) ":")
845 'w3m-search-uri-replace
846 (cadr item))))))
847
6132bc01
MW
848;;;--------------------------------------------------------------------------
849;;; Paragraph filling.
f617db13 850
6132bc01 851;; Useful variables.
f617db13
MW
852
853(defvar mdw-fill-prefix nil
6132bc01
MW
854 "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
855If there's no fill prefix currently set (by the `fill-prefix'
856variable) and there's a match from one of the regexps here, it
857gets used to set the fill-prefix for the current operation.
f617db13 858
6132bc01
MW
859The variable is a list of items of the form `REGEXP . PREFIX'; if
860the REGEXP matches, the PREFIX is used to set the fill prefix.
861It in turn is a list of things:
f617db13
MW
862
863 STRING -- insert a literal string
864 (match . N) -- insert the thing matched by bracketed subexpression N
865 (pad . N) -- a string of whitespace the same width as subexpression N
866 (expr . FORM) -- the result of evaluating FORM")
867
868(make-variable-buffer-local 'mdw-fill-prefix)
869
870(defvar mdw-hanging-indents
10fa2414 871 (concat "\\(\\("
f8bfe560 872 "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
10fa2414
MW
873 "[ \t]+"
874 "\\)?\\)")
6132bc01
MW
875 "*Standard regexp matching parts of a hanging indent.
876This is mainly useful in `auto-fill-mode'.")
f617db13 877
6132bc01 878;; Setting things up.
f617db13
MW
879
880(fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
881
6132bc01 882;; Utility functions.
f617db13 883
cd07f97f
MW
884(defun mdw-maybe-tabify (s)
885 "Tabify or untabify the string S, according to `indent-tabs-mode'."
c736b08b
MW
886 (let ((tabfun (if indent-tabs-mode #'tabify #'untabify)))
887 (with-temp-buffer
888 (save-match-data
f617db13 889 (insert s "\n")
cd07f97f 890 (let ((start (point-min)) (end (point-max)))
c736b08b
MW
891 (funcall tabfun (point-min) (point-max))
892 (setq s (buffer-substring (point-min) (1- (point-max)))))))))
f617db13
MW
893
894(defun mdw-examine-fill-prefixes (l)
6132bc01
MW
895 "Given a list of dynamic fill prefixes, pick one which matches
896context and return the static fill prefix to use. Point must be
897at the start of a line, and match data must be saved."
f617db13
MW
898 (cond ((not l) nil)
899 ((looking-at (car (car l)))
cd07f97f
MW
900 (mdw-maybe-tabify (apply #'concat
901 (mapcar #'mdw-do-prefix-match
902 (cdr (car l))))))
f617db13
MW
903 (t (mdw-examine-fill-prefixes (cdr l)))))
904
905(defun mdw-maybe-car (p)
906 "If P is a pair, return (car P), otherwise just return P."
907 (if (consp p) (car p) p))
908
909(defun mdw-padding (s)
910 "Return a string the same width as S but made entirely from whitespace."
911 (let* ((l (length s)) (i 0) (n (make-string l ? )))
912 (while (< i l)
913 (if (= 9 (aref s i))
914 (aset n i 9))
915 (setq i (1+ i)))
916 n))
917
918(defun mdw-do-prefix-match (m)
6132bc01
MW
919 "Expand a dynamic prefix match element.
920See `mdw-fill-prefix' for details."
f617db13
MW
921 (cond ((not (consp m)) (format "%s" m))
922 ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
923 ((eq (car m) 'pad) (mdw-padding (match-string
924 (mdw-maybe-car (cdr m)))))
925 ((eq (car m) 'eval) (eval (cdr m)))
926 (t "")))
927
928(defun mdw-choose-dynamic-fill-prefix ()
929 "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
930 (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
931 ((not mdw-fill-prefix) fill-prefix)
932 (t (save-excursion
933 (beginning-of-line)
934 (save-match-data
935 (mdw-examine-fill-prefixes mdw-fill-prefix))))))
936
937(defun do-auto-fill ()
6132bc01
MW
938 "Handle auto-filling, working out a dynamic fill prefix in the
939case where there isn't a sensible static one."
f617db13
MW
940 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
941 (mdw-do-auto-fill)))
942
943(defun mdw-fill-paragraph ()
944 "Fill paragraph, getting a dynamic fill prefix."
945 (interactive)
946 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
947 (fill-paragraph nil)))
948
949(defun mdw-standard-fill-prefix (rx &optional mat)
950 "Set the dynamic fill prefix, handling standard hanging indents and stuff.
6132bc01
MW
951This is just a short-cut for setting the thing by hand, and by
952design it doesn't cope with anything approximating a complicated
953case."
f617db13
MW
954 (setq mdw-fill-prefix
955 `((,(concat rx mdw-hanging-indents)
956 (match . 1)
957 (pad . ,(or mat 2))))))
958
6132bc01
MW
959;;;--------------------------------------------------------------------------
960;;; Other common declarations.
f617db13 961
6132bc01 962;; Common mode settings.
f617db13
MW
963
964(defvar mdw-auto-indent t
965 "Whether to indent automatically after a newline.")
966
0e58a7c2
MW
967(defun mdw-whitespace-mode (&optional arg)
968 "Turn on/off whitespace mode, but don't highlight trailing space."
969 (interactive "P")
970 (when (and (boundp 'whitespace-style)
971 (fboundp 'whitespace-mode))
972 (let ((whitespace-style (remove 'trailing whitespace-style)))
558fc014
MW
973 (whitespace-mode arg))
974 (setq show-trailing-whitespace whitespace-mode)))
0e58a7c2 975
21beda17
MW
976(defvar mdw-do-misc-mode-hacking nil)
977
f617db13
MW
978(defun mdw-misc-mode-config ()
979 (and mdw-auto-indent
980 (cond ((eq major-mode 'lisp-mode)
981 (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
30c8a8fb
MW
982 ((or (eq major-mode 'slime-repl-mode)
983 (eq major-mode 'asm-mode))
984 nil)
f617db13
MW
985 (t
986 (local-set-key "\C-m" 'newline-and-indent))))
2e7c6a86 987 (set (make-local-variable 'mdw-do-misc-mode-hacking) t)
f617db13 988 (local-set-key [C-return] 'newline)
8a425bd7 989 (make-local-variable 'page-delimiter)
8cb7626b 990 (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
f617db13
MW
991 (setq comment-column 40)
992 (auto-fill-mode 1)
c7203018 993 (setq fill-column mdw-text-width)
253f61b4
MW
994 (and (fboundp 'gtags-mode)
995 (gtags-mode))
ddf6e116 996 (if (fboundp 'hs-minor-mode)
612717ec 997 (trap (hs-minor-mode t))
ddf6e116 998 (outline-minor-mode t))
49b2646e 999 (reveal-mode t)
1e7a9479 1000 (trap (turn-on-font-lock)))
f617db13 1001
2e7c6a86 1002(defun mdw-post-local-vars-misc-mode-config ()
c7203018 1003 (setq whitespace-line-column mdw-text-width)
2717a191
MW
1004 (when (and mdw-do-misc-mode-hacking
1005 (not buffer-read-only))
2e7c6a86
MW
1006 (setq show-trailing-whitespace t)
1007 (mdw-whitespace-mode 1)))
1008(add-hook 'hack-local-variables-hook 'mdw-post-local-vars-misc-mode-config)
ed7b46b9 1009
2c1ccbb9
MW
1010(defmacro mdw-advise-update-angry-fruit-salad (&rest funcs)
1011 `(progn ,@(mapcar (lambda (func)
1012 `(defadvice ,func
1013 (after mdw-angry-fruit-salad activate)
1014 (when mdw-do-misc-mode-hacking
1015 (setq show-trailing-whitespace
1016 (not buffer-read-only))
1017 (mdw-whitespace-mode (if buffer-read-only 0 1)))))
1018 funcs)))
1019(mdw-advise-update-angry-fruit-salad toggle-read-only
1020 read-only-mode
1021 view-mode
1022 view-mode-enable
1023 view-mode-disable)
2717a191 1024
253f61b4 1025(eval-after-load 'gtags
506bada9
MW
1026 '(progn
1027 (dolist (key '([mouse-2] [mouse-3]))
1028 (define-key gtags-mode-map key nil))
1029 (define-key gtags-mode-map [C-S-mouse-2] 'gtags-find-tag-by-event)
1030 (define-key gtags-select-mode-map [C-S-mouse-2]
1031 'gtags-select-tag-by-event)
1032 (dolist (map (list gtags-mode-map gtags-select-mode-map))
1033 (define-key map [C-S-mouse-3] 'gtags-pop-stack))))
253f61b4 1034
6132bc01 1035;; Backup file handling.
2ae647c4
MW
1036
1037(defvar mdw-backup-disable-regexps nil
6132bc01
MW
1038 "*List of regular expressions: if a file name matches any of
1039these then the file is not backed up.")
2ae647c4
MW
1040
1041(defun mdw-backup-enable-predicate (name)
6132bc01
MW
1042 "[mdw]'s default backup predicate.
1043Allows a backup if the standard predicate would allow it, and it
1044doesn't match any of the regular expressions in
1045`mdw-backup-disable-regexps'."
2ae647c4
MW
1046 (and (normal-backup-enable-predicate name)
1047 (let ((answer t) (list mdw-backup-disable-regexps))
1048 (save-match-data
1049 (while list
1050 (if (string-match (car list) name)
1051 (setq answer nil))
1052 (setq list (cdr list)))
1053 answer))))
1054(setq backup-enable-predicate 'mdw-backup-enable-predicate)
1055
7bb78c67
MW
1056;; Frame cleanup.
1057
1058(defun mdw-last-one-out-turn-off-the-lights (frame)
1059 "Disconnect from an X display if this was the last frame on that display."
1060 (let ((frame-display (frame-parameter frame 'display)))
1061 (when (and frame-display
1062 (eq window-system 'x)
1063 (not (some (lambda (fr)
7bb78c67 1064 (and (not (eq fr frame))
a04d8f3d 1065 (string= (frame-parameter fr 'display)
d70716b5 1066 frame-display)))
7bb78c67 1067 (frame-list))))
7bb78c67
MW
1068 (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
1069(add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
1070
cfa1824e
MW
1071;;;--------------------------------------------------------------------------
1072;;; Where is point?
1073
1074(defvar mdw-point-overlay
1075 (let ((ov (make-overlay 0 0))
1076 (s "."))
1077 (overlay-put ov 'priority 2)
1078 (put-text-property 0 1 'display '(left-fringe vertical-bar) s)
1079 (overlay-put ov 'before-string s)
1080 (delete-overlay ov)
1081 ov)
1082 "An overlay used for showing where point is in the selected window.")
1083
1084(defun mdw-remove-point-overlay ()
1085 "Remove the current-point overlay."
1086 (delete-overlay mdw-point-overlay))
1087
1088(defun mdw-update-point-overlay ()
1089 "Mark the current point position with an overlay."
1090 (if (not mdw-point-overlay-mode)
1091 (mdw-remove-point-overlay)
1092 (overlay-put mdw-point-overlay 'window (selected-window))
f3674a83
MW
1093 (if (bolp)
1094 (move-overlay mdw-point-overlay
1095 (point) (1+ (point)) (current-buffer))
1096 (move-overlay mdw-point-overlay
1097 (1- (point)) (point) (current-buffer)))))
cfa1824e
MW
1098
1099(defvar mdw-point-overlay-buffers nil
1100 "List of buffers using `mdw-point-overlay-mode'.")
1101
1102(define-minor-mode mdw-point-overlay-mode
1103 "Indicate current line with an overlay."
1104 :global nil
1105 (let ((buffer (current-buffer)))
1106 (setq mdw-point-overlay-buffers
1107 (mapcan (lambda (buf)
1108 (if (and (buffer-live-p buf)
1109 (not (eq buf buffer)))
1110 (list buf)))
1111 mdw-point-overlay-buffers))
1112 (if mdw-point-overlay-mode
1113 (setq mdw-point-overlay-buffers
1114 (cons buffer mdw-point-overlay-buffers))))
1115 (cond (mdw-point-overlay-buffers
1116 (add-hook 'pre-command-hook 'mdw-remove-point-overlay)
1117 (add-hook 'post-command-hook 'mdw-update-point-overlay))
1118 (t
1119 (mdw-remove-point-overlay)
1120 (remove-hook 'pre-command-hook 'mdw-remove-point-overlay)
1121 (remove-hook 'post-command-hook 'mdw-update-point-overlay))))
1122
1123(define-globalized-minor-mode mdw-global-point-overlay-mode
1124 mdw-point-overlay-mode
1125 (lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
1126
f3674a83
MW
1127;;;--------------------------------------------------------------------------
1128;;; Fullscreen-ness.
1129
1130(defvar mdw-full-screen-parameters
1131 '((menu-bar-lines . 0)
1132 ;(vertical-scroll-bars . nil)
1133 )
1134 "Frame parameters to set when making a frame fullscreen.")
1135
1136(defvar mdw-full-screen-save
1137 '(width height)
1138 "Extra frame parameters to save when setting fullscreen.")
1139
1140(defun mdw-toggle-full-screen (&optional frame)
1141 "Show the FRAME fullscreen."
1142 (interactive)
1143 (when window-system
1144 (cond ((frame-parameter frame 'fullscreen)
1145 (set-frame-parameter frame 'fullscreen nil)
1146 (modify-frame-parameters
1147 nil
1148 (or (frame-parameter frame 'mdw-full-screen-saved)
1149 (mapcar (lambda (assoc)
1150 (assq (car assoc) default-frame-alist))
1151 mdw-full-screen-parameters))))
1152 (t
1153 (let ((saved (mapcar (lambda (param)
1154 (cons param (frame-parameter frame param)))
1155 (append (mapcar #'car
1156 mdw-full-screen-parameters)
1157 mdw-full-screen-save))))
1158 (set-frame-parameter frame 'mdw-full-screen-saved saved))
1159 (modify-frame-parameters frame mdw-full-screen-parameters)
1160 (set-frame-parameter frame 'fullscreen 'fullboth)))))
1161
6132bc01
MW
1162;;;--------------------------------------------------------------------------
1163;;; General fontification.
f617db13 1164
bc149706
MW
1165(make-face 'mdw-virgin-face)
1166
1e7a9479
MW
1167(defmacro mdw-define-face (name &rest body)
1168 "Define a face, and make sure it's actually set as the definition."
1169 (declare (indent 1)
1170 (debug 0))
1171 `(progn
bc149706 1172 (copy-face 'mdw-virgin-face ',name)
1e7a9479
MW
1173 (defvar ,name ',name)
1174 (put ',name 'face-defface-spec ',body)
88cb9c2b 1175 (face-spec-set ',name ',body nil)))
1e7a9479
MW
1176
1177(mdw-define-face default
1178 (((type w32)) :family "courier new" :height 85)
caa63513 1179 (((type x)) :family "6x13" :foundry "trad" :height 130)
db10ce0a
MW
1180 (((type color)) :foreground "white" :background "black")
1181 (t nil))
1e7a9479
MW
1182(mdw-define-face fixed-pitch
1183 (((type w32)) :family "courier new" :height 85)
caa63513 1184 (((type x)) :family "6x13" :foundry "trad" :height 130)
1e7a9479 1185 (t :foreground "white" :background "black"))
e8ea88ba 1186(if (mdw-emacs-version-p 23)
c383eb8a
MW
1187 (mdw-define-face variable-pitch
1188 (((type x)) :family "sans" :height 100))
1189 (mdw-define-face variable-pitch
3f001ff6 1190 (((type x)) :family "helvetica" :height 90)))
1e7a9479 1191(mdw-define-face region
db10ce0a
MW
1192 (((type tty) (class color)) :background "blue")
1193 (((type tty) (class mono)) :inverse-video t)
1194 (t :background "grey30"))
fa156643
MW
1195(mdw-define-face match
1196 (((type tty) (class color)) :background "blue")
1197 (((type tty) (class mono)) :inverse-video t)
1198 (t :background "blue"))
c6fe19d5
MW
1199(mdw-define-face mc/cursor-face
1200 (((type tty) (class mono)) :inverse-video t)
1201 (t :background "red"))
1e7a9479
MW
1202(mdw-define-face minibuffer-prompt
1203 (t :weight bold))
1204(mdw-define-face mode-line
db10ce0a
MW
1205 (((class color)) :foreground "blue" :background "yellow"
1206 :box (:line-width 1 :style released-button))
1207 (t :inverse-video t))
1e7a9479 1208(mdw-define-face mode-line-inactive
db10ce0a
MW
1209 (((class color)) :foreground "yellow" :background "blue"
1210 :box (:line-width 1 :style released-button))
1211 (t :inverse-video t))
ae0a853f
MW
1212(mdw-define-face nobreak-space
1213 (((type tty)))
1214 (t :inherit escape-glyph :underline t))
1e7a9479
MW
1215(mdw-define-face scroll-bar
1216 (t :foreground "black" :background "lightgrey"))
1217(mdw-define-face fringe
1218 (t :foreground "yellow"))
c383eb8a 1219(mdw-define-face show-paren-match
db10ce0a
MW
1220 (((class color)) :background "darkgreen")
1221 (t :underline t))
c383eb8a 1222(mdw-define-face show-paren-mismatch
db10ce0a
MW
1223 (((class color)) :background "red")
1224 (t :inverse-video t))
1e7a9479 1225(mdw-define-face highlight
b31f422b
MW
1226 (((type x) (class color)) :background "DarkSeaGreen4")
1227 (((type tty) (class color)) :background "cyan")
db10ce0a 1228 (t :inverse-video t))
1e7a9479
MW
1229
1230(mdw-define-face holiday-face
1231 (t :background "red"))
1232(mdw-define-face calendar-today-face
1233 (t :foreground "yellow" :weight bold))
1234
1235(mdw-define-face comint-highlight-prompt
1236 (t :weight bold))
5fd055c2
MW
1237(mdw-define-face comint-highlight-input
1238 (t nil))
1e7a9479 1239
e0e2aca3
MW
1240(mdw-define-face dired-directory
1241 (t :foreground "cyan" :weight bold))
1242(mdw-define-face dired-symlink
1243 (t :foreground "cyan"))
1244(mdw-define-face dired-perm-write
1245 (t nil))
1246
1e7a9479 1247(mdw-define-face trailing-whitespace
db10ce0a
MW
1248 (((class color)) :background "red")
1249 (t :inverse-video t))
33aa287b
MW
1250(mdw-define-face whitespace-line
1251 (((class color)) :background "darkred")
1252 (t :inverse-video :t))
1e7a9479
MW
1253(mdw-define-face mdw-punct-face
1254 (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
1255(mdw-define-face mdw-number-face
1256 (t :foreground "yellow"))
52bcde59 1257(mdw-define-face mdw-trivial-face)
1e7a9479 1258(mdw-define-face font-lock-function-name-face
c383eb8a 1259 (t :slant italic))
1e7a9479
MW
1260(mdw-define-face font-lock-keyword-face
1261 (t :weight bold))
1262(mdw-define-face font-lock-constant-face
1263 (t :slant italic))
1264(mdw-define-face font-lock-builtin-face
1265 (t :weight bold))
07965a39
MW
1266(mdw-define-face font-lock-type-face
1267 (t :weight bold :slant italic))
1e7a9479
MW
1268(mdw-define-face font-lock-reference-face
1269 (t :weight bold))
1270(mdw-define-face font-lock-variable-name-face
1271 (t :slant italic))
1272(mdw-define-face font-lock-comment-delimiter-face
db10ce0a
MW
1273 (((class mono)) :weight bold)
1274 (((type tty) (class color)) :foreground "green")
1275 (t :slant italic :foreground "SeaGreen1"))
1e7a9479 1276(mdw-define-face font-lock-comment-face
db10ce0a
MW
1277 (((class mono)) :weight bold)
1278 (((type tty) (class color)) :foreground "green")
1279 (t :slant italic :foreground "SeaGreen1"))
1e7a9479 1280(mdw-define-face font-lock-string-face
db10ce0a
MW
1281 (((class mono)) :weight bold)
1282 (((class color)) :foreground "SkyBlue1"))
898c7efb 1283
1e7a9479
MW
1284(mdw-define-face message-separator
1285 (t :background "red" :foreground "white" :weight bold))
1286(mdw-define-face message-cited-text
1287 (default :slant italic)
4790fcb7 1288 (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
1e7a9479 1289(mdw-define-face message-header-cc
4790fcb7 1290 (default :slant italic)
1e7a9479
MW
1291 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1292(mdw-define-face message-header-newsgroups
4790fcb7 1293 (default :slant italic)
1e7a9479
MW
1294 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1295(mdw-define-face message-header-subject
1e7a9479
MW
1296 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1297(mdw-define-face message-header-to
1e7a9479
MW
1298 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1299(mdw-define-face message-header-xheader
4790fcb7 1300 (default :slant italic)
1e7a9479
MW
1301 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1302(mdw-define-face message-header-other
4790fcb7 1303 (default :slant italic)
1e7a9479
MW
1304 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1305(mdw-define-face message-header-name
4790fcb7 1306 (default :weight bold)
1e7a9479 1307 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
4790fcb7 1308
69498691
MW
1309(mdw-define-face which-func
1310 (t nil))
1e7a9479 1311
4790fcb7
MW
1312(mdw-define-face gnus-header-name
1313 (default :weight bold)
1314 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1315(mdw-define-face gnus-header-subject
1316 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1317(mdw-define-face gnus-header-from
1318 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1319(mdw-define-face gnus-header-to
1320 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1321(mdw-define-face gnus-header-content
1322 (default :slant italic)
1323 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1324
1325(mdw-define-face gnus-cite-1
1326 (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
1327(mdw-define-face gnus-cite-2
1328 (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
1329(mdw-define-face gnus-cite-3
1330 (((type tty)) :foreground "magenta") (t :foreground "MediumOrchid"))
1331(mdw-define-face gnus-cite-4
1332 (((type tty)) :foreground "red") (t :foreground "firebrick2"))
1333(mdw-define-face gnus-cite-5
1334 (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
1335(mdw-define-face gnus-cite-6
1336 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
1337(mdw-define-face gnus-cite-7
1338 (((type tty)) :foreground "cyan") (t :foreground "SlateBlue1"))
1339(mdw-define-face gnus-cite-8
1340 (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
1341(mdw-define-face gnus-cite-9
1342 (((type tty)) :foreground "magenta") (t :foreground "purple2"))
1343(mdw-define-face gnus-cite-10
1344 (((type tty)) :foreground "red") (t :foreground "DarkOrange2"))
1345(mdw-define-face gnus-cite-11
1346 (t :foreground "grey"))
1347
2f238de8
MW
1348(mdw-define-face diff-header
1349 (t nil))
1e7a9479
MW
1350(mdw-define-face diff-index
1351 (t :weight bold))
1352(mdw-define-face diff-file-header
1353 (t :weight bold))
1354(mdw-define-face diff-hunk-header
1355 (t :foreground "SkyBlue1"))
1356(mdw-define-face diff-function
1357 (t :foreground "SkyBlue1" :weight bold))
1358(mdw-define-face diff-header
1359 (t :background "grey10"))
1360(mdw-define-face diff-added
1361 (t :foreground "green"))
1362(mdw-define-face diff-removed
1363 (t :foreground "red"))
5fd055c2
MW
1364(mdw-define-face diff-context
1365 (t nil))
2f238de8 1366(mdw-define-face diff-refine-change
b31f422b
MW
1367 (((class color) (type x)) :background "RoyalBlue4")
1368 (t :underline t))
5f454d3e
MW
1369(mdw-define-face diff-refine-removed
1370 (((class color) (type x)) :background "#500")
1371 (t :underline t))
1372(mdw-define-face diff-refine-added
1373 (((class color) (type x)) :background "#050")
1374 (t :underline t))
1e7a9479 1375
ad305d7e
MW
1376(mdw-define-face dylan-header-background
1377 (((class color) (type x)) :background "NavyBlue")
1378 (t :background "blue"))
1379
df082bab
MW
1380(mdw-define-face magit-diff-add
1381 (t :foreground "green"))
1382(mdw-define-face magit-diff-del
1383 (t :foreground "red"))
1384(mdw-define-face magit-diff-file-header
1385 (t :weight bold))
1386(mdw-define-face magit-diff-hunk-header
1387 (t :foreground "SkyBlue1"))
fb690b64
MW
1388(mdw-define-face magit-item-highlight
1389 (((type tty)) :background "blue")
cc71d815 1390 (t :background "grey11"))
8afc6956
MW
1391(mdw-define-face magit-log-head-label-remote
1392 (((type tty)) :background "cyan" :foreground "green")
1393 (t :background "grey11" :foreground "DarkSeaGreen2" :box t))
1394(mdw-define-face magit-log-head-label-local
1395 (((type tty)) :background "cyan" :foreground "yellow")
1396 (t :background "grey11" :foreground "LightSkyBlue1" :box t))
1397(mdw-define-face magit-log-head-label-tags
1398 (((type tty)) :background "red" :foreground "yellow")
1399 (t :background "LemonChiffon1" :foreground "goldenrod4" :box t))
1400(mdw-define-face magit-log-graph
1401 (((type tty)) :foreground "magenta")
1402 (t :foreground "grey80"))
df082bab 1403
e1b8de18
MW
1404(mdw-define-face erc-input-face
1405 (t :foreground "red"))
1406
1e7a9479
MW
1407(mdw-define-face woman-bold
1408 (t :weight bold))
1409(mdw-define-face woman-italic
1410 (t :slant italic))
1411
5a83259f
MW
1412(eval-after-load "rst"
1413 '(progn
1414 (mdw-define-face rst-level-1-face
1415 (t :foreground "SkyBlue1" :weight bold))
1416 (mdw-define-face rst-level-2-face
1417 (t :foreground "SeaGreen1" :weight bold))
1418 (mdw-define-face rst-level-3-face
1419 (t :weight bold))
1420 (mdw-define-face rst-level-4-face
1421 (t :slant italic))
1422 (mdw-define-face rst-level-5-face
1423 (t :underline t))
1424 (mdw-define-face rst-level-6-face
1425 ())))
4f251391 1426
1e7a9479
MW
1427(mdw-define-face p4-depot-added-face
1428 (t :foreground "green"))
1429(mdw-define-face p4-depot-branch-op-face
1430 (t :foreground "yellow"))
1431(mdw-define-face p4-depot-deleted-face
1432 (t :foreground "red"))
1433(mdw-define-face p4-depot-unmapped-face
1434 (t :foreground "SkyBlue1"))
1435(mdw-define-face p4-diff-change-face
1436 (t :foreground "yellow"))
1437(mdw-define-face p4-diff-del-face
1438 (t :foreground "red"))
1439(mdw-define-face p4-diff-file-face
1440 (t :foreground "SkyBlue1"))
1441(mdw-define-face p4-diff-head-face
1442 (t :background "grey10"))
1443(mdw-define-face p4-diff-ins-face
1444 (t :foreground "green"))
1445
4c39e530
MW
1446(mdw-define-face w3m-anchor-face
1447 (t :foreground "SkyBlue1" :underline t))
1448(mdw-define-face w3m-arrived-anchor-face
1449 (t :foreground "SkyBlue1" :underline t))
1450
1e7a9479
MW
1451(mdw-define-face whizzy-slice-face
1452 (t :background "grey10"))
1453(mdw-define-face whizzy-error-face
1454 (t :background "darkred"))
f617db13 1455
5fedb342
MW
1456;; Ellipses used to indicate hidden text (and similar).
1457(mdw-define-face mdw-ellipsis-face
1458 (((type tty)) :foreground "blue") (t :foreground "grey60"))
c11ac343 1459(let ((dollar (make-glyph-code ?$ 'mdw-ellipsis-face))
a8a7976a 1460 (backslash (make-glyph-code ?\\ 'mdw-ellipsis-face))
c11ac343
MW
1461 (dot (make-glyph-code ?. 'mdw-ellipsis-face))
1462 (bar (make-glyph-code ?| mdw-ellipsis-face)))
1463 (set-display-table-slot standard-display-table 0 dollar)
1464 (set-display-table-slot standard-display-table 1 backslash)
5fedb342 1465 (set-display-table-slot standard-display-table 4
c11ac343
MW
1466 (vector dot dot dot))
1467 (set-display-table-slot standard-display-table 5 bar))
5fedb342 1468
6132bc01
MW
1469;;;--------------------------------------------------------------------------
1470;;; C programming configuration.
f617db13 1471
6132bc01 1472;; Make C indentation nice.
f617db13 1473
f50c1bed
MW
1474(defun mdw-c-lineup-arglist (langelem)
1475 "Hack for DWIMmery in c-lineup-arglist."
1476 (if (save-excursion
1477 (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element)))
1478 0
1479 (c-lineup-arglist langelem)))
1480
1481(defun mdw-c-indent-extern-mumble (langelem)
1482 "Indent `extern \"...\" {' lines."
1483 (save-excursion
1484 (back-to-indentation)
1485 (if (looking-at
1486 "\\s-*\\<extern\\>\\s-*\"\\([^\\\\\"]+\\|\\.\\)*\"\\s-*{")
1487 c-basic-offset
1488 nil)))
1489
b521d36a
MW
1490(defun mdw-c-indent-arglist-nested (langelem)
1491 "Indent continued argument lists.
1492If we've nested more than one argument list, then only introduce a single
1493indentation anyway."
1494 (let ((context c-syntactic-context)
1495 (pos (c-langelem-2nd-pos c-syntactic-element))
1496 (should-indent-p t))
1497 (while (and context
1498 (eq (caar context) 'arglist-cont-nonempty))
1499 (when (and (= (caddr (pop context)) pos)
1500 context
1501 (memq (caar context) '(arglist-intro
1502 arglist-cont-nonempty)))
1503 (setq should-indent-p nil)))
1504 (if should-indent-p '+ 0)))
1505
c56296d0
MW
1506(defvar mdw-define-c-styles-hook nil
1507 "Hook run when `cc-mode' starts up to define styles.")
1508
1509(defmacro mdw-define-c-style (name &rest assocs)
1510 "Define a C style, called NAME (a symbol), setting ASSOCs.
1511A function, named `mdw-define-c-style/NAME', is defined to actually install
1512the style using `c-add-style', and added to the hook
1513`mdw-define-c-styles-hook'. If CC Mode is already loaded, then the style is
1514set."
1515 (declare (indent defun))
1516 (let* ((name-string (symbol-name name))
1517 (func (intern (concat "mdw-define-c-style/" name-string))))
1518 `(progn
1519 (defun ,func () (c-add-style ,name-string ',assocs))
1520 (and (featurep 'cc-mode) (,func))
1521 (add-hook 'mdw-define-c-styles-hook ',func))))
1522
1523(eval-after-load "cc-mode"
1524 '(run-hooks 'mdw-define-c-styles-hook))
1525
b521d36a
MW
1526(mdw-define-c-style mdw-trustonic-c
1527 (c-basic-offset . 4)
1528 (comment-column . 0)
1529 (c-indent-comment-alist (anchored-comment . (column . 0))
1530 (end-block . (space . 1))
1531 (cpp-end-block . (space . 1))
1532 (other . (space . 1)))
1533 (c-class-key . "class")
1534 (c-backslash-column . 0)
1535 (c-auto-align-backslashes . nil)
1536 (c-label-minimum-indentation . 0)
1537 (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block))
1538 (defun-open . (add 0 c-indent-one-line-block))
1539 (arglist-cont-nonempty . mdw-c-indent-arglist-nested)
1540 (topmost-intro . mdw-c-indent-extern-mumble)
1541 (cpp-define-intro . 0)
1542 (knr-argdecl . 0)
1543 (inextern-lang . [0])
1544 (label . 0)
1545 (case-label . +)
1546 (access-label . -)
1547 (inclass . +)
1548 (inline-open . ++)
1549 (statement-cont . +)
1550 (statement-case-intro . +)))
1551
c56296d0
MW
1552(mdw-define-c-style mdw-c
1553 (c-basic-offset . 2)
1554 (comment-column . 40)
1555 (c-class-key . "class")
1556 (c-backslash-column . 72)
1557 (c-label-minimum-indentation . 0)
1558 (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block))
1559 (defun-open . (add 0 c-indent-one-line-block))
1560 (arglist-cont-nonempty . mdw-c-lineup-arglist)
1561 (topmost-intro . mdw-c-indent-extern-mumble)
1562 (cpp-define-intro . 0)
1563 (knr-argdecl . 0)
1564 (inextern-lang . [0])
1565 (label . 0)
1566 (case-label . +)
1567 (access-label . -)
1568 (inclass . +)
1569 (inline-open . ++)
1570 (statement-cont . +)
1571 (statement-case-intro . +)))
1572
1573(defun mdw-set-default-c-style (modes style)
1574 "Update the default CC Mode style for MODES to be STYLE.
1575
1576MODES may be a list of major mode names or a singleton. STYLE is a style
1577name, as a symbol."
1578 (let ((modes (if (listp modes) modes (list modes)))
1579 (style (symbol-name style)))
1580 (setq c-default-style
1581 (append (mapcar (lambda (mode)
1582 (cons mode style))
1583 modes)
1584 (remove-if (lambda (assoc)
1585 (memq (car assoc) modes))
1586 (if (listp c-default-style)
1587 c-default-style
1588 (list (cons 'other c-default-style))))))))
1589(setq c-default-style "mdw-c")
1590
1591(mdw-set-default-c-style '(c-mode c++-mode) 'mdw-c)
f617db13 1592
0e7d960b
MW
1593(defvar mdw-c-comment-fill-prefix
1594 `((,(concat "\\([ \t]*/?\\)"
1595 "\\(\*\\|//]\\)"
1596 "\\([ \t]*\\)"
1597 "\\([A-Za-z]+:[ \t]*\\)?"
1598 mdw-hanging-indents)
1599 (pad . 1) (match . 2) (pad . 3) (pad . 4) (pad . 5)))
1600 "Fill prefix matching C comments (both kinds).")
1601
f617db13
MW
1602(defun mdw-fontify-c-and-c++ ()
1603
6132bc01 1604 ;; Fiddle with some syntax codes.
f617db13
MW
1605 (modify-syntax-entry ?* ". 23")
1606 (modify-syntax-entry ?/ ". 124b")
1607 (modify-syntax-entry ?\n "> b")
1608
6132bc01 1609 ;; Other stuff.
c56296d0 1610 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
f617db13 1611
6132bc01 1612 ;; Now define things to be fontified.
02109a0d 1613 (make-local-variable 'font-lock-keywords)
f617db13 1614 (let ((c-keywords
fe307a8c
MW
1615 (mdw-regexps "alignas" ;C11 macro, C++11
1616 "alignof" ;C++11
1617 "and" ;C++, C95 macro
0681f29e 1618 "and_eq" ;C++, C95 macro
7b84c078 1619 "asm" ;K&R, C++, GCC
fe307a8c 1620 "atomic" ;C11 macro, C++11 template type
26f18bd1 1621 "auto" ;K&R, C89
0681f29e
MW
1622 "bitand" ;C++, C95 macro
1623 "bitor" ;C++, C95 macro
d4783d9c 1624 "bool" ;C++, C99 macro
26f18bd1
MW
1625 "break" ;K&R, C89
1626 "case" ;K&R, C89
1627 "catch" ;C++
1628 "char" ;K&R, C89
fe307a8c
MW
1629 "char16_t" ;C++11, C11 library type
1630 "char32_t" ;C++11, C11 library type
26f18bd1 1631 "class" ;C++
d4783d9c 1632 "complex" ;C99 macro, C++ template type
0681f29e 1633 "compl" ;C++, C95 macro
26f18bd1 1634 "const" ;C89
fe307a8c 1635 "constexpr" ;C++11
26f18bd1
MW
1636 "const_cast" ;C++
1637 "continue" ;K&R, C89
fe307a8c 1638 "decltype" ;C++11
26f18bd1
MW
1639 "defined" ;C89 preprocessor
1640 "default" ;K&R, C89
1641 "delete" ;C++
1642 "do" ;K&R, C89
1643 "double" ;K&R, C89
1644 "dynamic_cast" ;C++
1645 "else" ;K&R, C89
1646 ;; "entry" ;K&R -- never used
1647 "enum" ;C89
1648 "explicit" ;C++
1649 "export" ;C++
1650 "extern" ;K&R, C89
1651 "float" ;K&R, C89
1652 "for" ;K&R, C89
1653 ;; "fortran" ;K&R
1654 "friend" ;C++
1655 "goto" ;K&R, C89
1656 "if" ;K&R, C89
d4783d9c
MW
1657 "imaginary" ;C99 macro
1658 "inline" ;C++, C99, GCC
26f18bd1
MW
1659 "int" ;K&R, C89
1660 "long" ;K&R, C89
1661 "mutable" ;C++
1662 "namespace" ;C++
1663 "new" ;C++
fe307a8c
MW
1664 "noexcept" ;C++11
1665 "noreturn" ;C11 macro
0681f29e
MW
1666 "not" ;C++, C95 macro
1667 "not_eq" ;C++, C95 macro
fe307a8c 1668 "nullptr" ;C++11
26f18bd1 1669 "operator" ;C++
0681f29e
MW
1670 "or" ;C++, C95 macro
1671 "or_eq" ;C++, C95 macro
26f18bd1
MW
1672 "private" ;C++
1673 "protected" ;C++
1674 "public" ;C++
1675 "register" ;K&R, C89
8d6d55b9 1676 "reinterpret_cast" ;C++
d4783d9c 1677 "restrict" ;C99
8d6d55b9
MW
1678 "return" ;K&R, C89
1679 "short" ;K&R, C89
1680 "signed" ;C89
1681 "sizeof" ;K&R, C89
1682 "static" ;K&R, C89
fe307a8c 1683 "static_assert" ;C11 macro, C++11
8d6d55b9
MW
1684 "static_cast" ;C++
1685 "struct" ;K&R, C89
1686 "switch" ;K&R, C89
1687 "template" ;C++
8d6d55b9 1688 "throw" ;C++
8d6d55b9 1689 "try" ;C++
fe307a8c 1690 "thread_local" ;C11 macro, C++11
8d6d55b9
MW
1691 "typedef" ;C89
1692 "typeid" ;C++
1693 "typeof" ;GCC
1694 "typename" ;C++
1695 "union" ;K&R, C89
1696 "unsigned" ;K&R, C89
1697 "using" ;C++
1698 "virtual" ;C++
1699 "void" ;C89
1700 "volatile" ;C89
1701 "wchar_t" ;C++, C89 library type
1702 "while" ;K&R, C89
0681f29e
MW
1703 "xor" ;C++, C95 macro
1704 "xor_eq" ;C++, C95 macro
fe307a8c
MW
1705 "_Alignas" ;C11
1706 "_Alignof" ;C11
1707 "_Atomic" ;C11
d4783d9c
MW
1708 "_Bool" ;C99
1709 "_Complex" ;C99
fe307a8c 1710 "_Generic" ;C11
d4783d9c 1711 "_Imaginary" ;C99
fe307a8c 1712 "_Noreturn" ;C11
d4783d9c 1713 "_Pragma" ;C99 preprocessor
fe307a8c
MW
1714 "_Static_assert" ;C11
1715 "_Thread_local" ;C11
8d6d55b9
MW
1716 "__alignof__" ;GCC
1717 "__asm__" ;GCC
1718 "__attribute__" ;GCC
1719 "__complex__" ;GCC
1720 "__const__" ;GCC
1721 "__extension__" ;GCC
1722 "__imag__" ;GCC
1723 "__inline__" ;GCC
1724 "__label__" ;GCC
1725 "__real__" ;GCC
1726 "__signed__" ;GCC
1727 "__typeof__" ;GCC
1728 "__volatile__" ;GCC
1729 ))
165cecf8 1730 (c-constants
26f18bd1 1731 (mdw-regexps "false" ;C++, C99 macro
165cecf8 1732 "this" ;C++
26f18bd1 1733 "true" ;C++, C99 macro
165cecf8 1734 ))
f617db13 1735 (preprocessor-keywords
8d6d55b9
MW
1736 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1737 "ident" "if" "ifdef" "ifndef" "import" "include"
1738 "line" "pragma" "unassert" "undef" "warning"))
f617db13 1739 (objc-keywords
8d6d55b9
MW
1740 (mdw-regexps "class" "defs" "encode" "end" "implementation"
1741 "interface" "private" "protected" "protocol" "public"
1742 "selector")))
f617db13
MW
1743
1744 (setq font-lock-keywords
1745 (list
f617db13 1746
6132bc01 1747 ;; Fontify include files as strings.
f617db13
MW
1748 (list (concat "^[ \t]*\\#[ \t]*"
1749 "\\(include\\|import\\)"
1750 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1751 '(2 font-lock-string-face))
1752
6132bc01 1753 ;; Preprocessor directives are `references'?.
f617db13
MW
1754 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1755 preprocessor-keywords
1756 "\\)\\>\\|[0-9]+\\|$\\)\\)")
1757 '(1 font-lock-keyword-face))
1758
6132bc01 1759 ;; Handle the keywords defined above.
f617db13
MW
1760 (list (concat "@\\<\\(" objc-keywords "\\)\\>")
1761 '(0 font-lock-keyword-face))
1762
1763 (list (concat "\\<\\(" c-keywords "\\)\\>")
1764 '(0 font-lock-keyword-face))
1765
165cecf8
MW
1766 (list (concat "\\<\\(" c-constants "\\)\\>")
1767 '(0 font-lock-variable-name-face))
1768
6132bc01 1769 ;; Handle numbers too.
f617db13
MW
1770 ;;
1771 ;; This looks strange, I know. It corresponds to the
1772 ;; preprocessor's idea of what a number looks like, rather than
1773 ;; anything sensible.
f617db13
MW
1774 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1775 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1776 '(0 mdw-number-face))
1777
6132bc01 1778 ;; And anything else is punctuation.
f617db13 1779 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 1780 '(0 mdw-punct-face))))))
f617db13 1781
6132bc01
MW
1782;;;--------------------------------------------------------------------------
1783;;; AP calc mode.
f617db13 1784
e7186cbe
MW
1785(define-derived-mode apcalc-mode c-mode "AP Calc"
1786 "Major mode for editing Calc code.")
f617db13
MW
1787
1788(defun mdw-fontify-apcalc ()
1789
6132bc01 1790 ;; Fiddle with some syntax codes.
f617db13
MW
1791 (modify-syntax-entry ?* ". 23")
1792 (modify-syntax-entry ?/ ". 14")
1793
6132bc01 1794 ;; Other stuff.
f617db13
MW
1795 (setq comment-start "/* ")
1796 (setq comment-end " */")
0e7d960b 1797 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
f617db13 1798
6132bc01 1799 ;; Now define things to be fontified.
02109a0d 1800 (make-local-variable 'font-lock-keywords)
f617db13 1801 (let ((c-keywords
8d6d55b9
MW
1802 (mdw-regexps "break" "case" "cd" "continue" "define" "default"
1803 "do" "else" "exit" "for" "global" "goto" "help" "if"
1804 "local" "mat" "obj" "print" "quit" "read" "return"
1805 "show" "static" "switch" "while" "write")))
f617db13
MW
1806
1807 (setq font-lock-keywords
1808 (list
f617db13 1809
6132bc01 1810 ;; Handle the keywords defined above.
f617db13
MW
1811 (list (concat "\\<\\(" c-keywords "\\)\\>")
1812 '(0 font-lock-keyword-face))
1813
6132bc01 1814 ;; Handle numbers too.
f617db13
MW
1815 ;;
1816 ;; This looks strange, I know. It corresponds to the
1817 ;; preprocessor's idea of what a number looks like, rather than
1818 ;; anything sensible.
f617db13
MW
1819 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1820 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1821 '(0 mdw-number-face))
1822
6132bc01 1823 ;; And anything else is punctuation.
f617db13 1824 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 1825 '(0 mdw-punct-face))))))
f617db13 1826
6132bc01
MW
1827;;;--------------------------------------------------------------------------
1828;;; Java programming configuration.
f617db13 1829
6132bc01 1830;; Make indentation nice.
f617db13 1831
c56296d0
MW
1832(mdw-define-c-style mdw-java
1833 (c-basic-offset . 2)
1834 (c-backslash-column . 72)
1835 (c-offsets-alist (substatement-open . 0)
1836 (label . +)
1837 (case-label . +)
1838 (access-label . 0)
1839 (inclass . +)
1840 (statement-case-intro . +)))
1841(mdw-set-default-c-style 'java-mode 'mdw-java)
f617db13 1842
6132bc01 1843;; Declare Java fontification style.
f617db13
MW
1844
1845(defun mdw-fontify-java ()
1846
6132bc01 1847 ;; Other stuff.
0e7d960b 1848 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
f617db13 1849
6132bc01 1850 ;; Now define things to be fontified.
02109a0d 1851 (make-local-variable 'font-lock-keywords)
f617db13 1852 (let ((java-keywords
8d6d55b9
MW
1853 (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1854 "char" "class" "const" "continue" "default" "do"
1855 "double" "else" "extends" "final" "finally" "float"
1856 "for" "goto" "if" "implements" "import" "instanceof"
1857 "int" "interface" "long" "native" "new" "package"
1858 "private" "protected" "public" "return" "short"
165cecf8
MW
1859 "static" "switch" "synchronized" "throw" "throws"
1860 "transient" "try" "void" "volatile" "while"))
8d6d55b9 1861
165cecf8
MW
1862 (java-constants
1863 (mdw-regexps "false" "null" "super" "this" "true")))
f617db13
MW
1864
1865 (setq font-lock-keywords
1866 (list
f617db13 1867
6132bc01 1868 ;; Handle the keywords defined above.
f617db13
MW
1869 (list (concat "\\<\\(" java-keywords "\\)\\>")
1870 '(0 font-lock-keyword-face))
1871
165cecf8
MW
1872 ;; Handle the magic constants defined above.
1873 (list (concat "\\<\\(" java-constants "\\)\\>")
1874 '(0 font-lock-variable-name-face))
1875
6132bc01 1876 ;; Handle numbers too.
f617db13
MW
1877 ;;
1878 ;; The following isn't quite right, but it's close enough.
f617db13
MW
1879 (list (concat "\\<\\("
1880 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1881 "[0-9]+\\(\\.[0-9]*\\|\\)"
1882 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1883 "[lLfFdD]?")
1884 '(0 mdw-number-face))
1885
6132bc01 1886 ;; And anything else is punctuation.
f617db13 1887 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 1888 '(0 mdw-punct-face))))))
f617db13 1889
61d63206
MW
1890;;;--------------------------------------------------------------------------
1891;;; Javascript programming configuration.
1892
1893(defun mdw-javascript-style ()
1894 (setq js-indent-level 2)
1895 (setq js-expr-indent-offset 0))
1896
1897(defun mdw-fontify-javascript ()
1898
1899 ;; Other stuff.
1900 (mdw-javascript-style)
1901 (setq js-auto-indent-flag t)
1902
1903 ;; Now define things to be fontified.
1904 (make-local-variable 'font-lock-keywords)
1905 (let ((javascript-keywords
1906 (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1907 "char" "class" "const" "continue" "debugger" "default"
1908 "delete" "do" "double" "else" "enum" "export" "extends"
1909 "final" "finally" "float" "for" "function" "goto" "if"
1910 "implements" "import" "in" "instanceof" "int"
1911 "interface" "let" "long" "native" "new" "package"
1912 "private" "protected" "public" "return" "short"
1913 "static" "super" "switch" "synchronized" "throw"
1914 "throws" "transient" "try" "typeof" "var" "void"
1915 "volatile" "while" "with" "yield"
1916
1917 "boolean" "byte" "char" "double" "float" "int" "long"
1918 "short" "void"))
1919 (javascript-constants
1920 (mdw-regexps "false" "null" "undefined" "Infinity" "NaN" "true"
1921 "arguments" "this")))
1922
1923 (setq font-lock-keywords
1924 (list
1925
1926 ;; Handle the keywords defined above.
f7856acd 1927 (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
61d63206
MW
1928 '(0 font-lock-keyword-face))
1929
1930 ;; Handle the predefined constants defined above.
f7856acd 1931 (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
61d63206
MW
1932 '(0 font-lock-variable-name-face))
1933
1934 ;; Handle numbers too.
1935 ;;
1936 ;; The following isn't quite right, but it's close enough.
f7856acd 1937 (list (concat "\\_<\\("
61d63206
MW
1938 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1939 "[0-9]+\\(\\.[0-9]*\\|\\)"
1940 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1941 "[lLfFdD]?")
1942 '(0 mdw-number-face))
1943
1944 ;; And anything else is punctuation.
1945 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 1946 '(0 mdw-punct-face))))))
61d63206 1947
ee7c3dea
MW
1948;;;--------------------------------------------------------------------------
1949;;; Scala programming configuration.
1950
1951(defun mdw-fontify-scala ()
1952
7b5903d8
MW
1953 ;; Comment filling.
1954 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1955
ee7c3dea
MW
1956 ;; Define things to be fontified.
1957 (make-local-variable 'font-lock-keywords)
1958 (let ((scala-keywords
1959 (mdw-regexps "abstract" "case" "catch" "class" "def" "do" "else"
1960 "extends" "final" "finally" "for" "forSome" "if"
1961 "implicit" "import" "lazy" "match" "new" "object"
3f017188
MW
1962 "override" "package" "private" "protected" "return"
1963 "sealed" "throw" "trait" "try" "type" "val"
ee7c3dea
MW
1964 "var" "while" "with" "yield"))
1965 (scala-constants
3f017188 1966 (mdw-regexps "false" "null" "super" "this" "true"))
7b5903d8 1967 (punctuation "[-!%^&*=+:@#~/?\\|`]"))
ee7c3dea
MW
1968
1969 (setq font-lock-keywords
1970 (list
1971
1972 ;; Magical identifiers between backticks.
1973 (list (concat "`\\([^`]+\\)`")
1974 '(1 font-lock-variable-name-face))
1975
1976 ;; Handle the keywords defined above.
1977 (list (concat "\\_<\\(" scala-keywords "\\)\\_>")
1978 '(0 font-lock-keyword-face))
1979
1980 ;; Handle the constants defined above.
1981 (list (concat "\\_<\\(" scala-constants "\\)\\_>")
1982 '(0 font-lock-variable-name-face))
1983
1984 ;; Magical identifiers between backticks.
1985 (list (concat "`\\([^`]+\\)`")
1986 '(1 font-lock-variable-name-face))
1987
1988 ;; Handle numbers too.
1989 ;;
1990 ;; As usual, not quite right.
1991 (list (concat "\\_<\\("
1992 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1993 "[0-9]+\\(\\.[0-9]*\\|\\)"
1994 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1995 "[lLfFdD]?")
1996 '(0 mdw-number-face))
1997
1998 ;; Identifiers with trailing operators.
1999 (list (concat "_\\(" punctuation "\\)+")
2000 '(0 mdw-trivial-face))
2001
2002 ;; And everything else is punctuation.
2003 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2004 '(0 mdw-punct-face)))
2005
2006 font-lock-syntactic-keywords
2007 (list
2008
2009 ;; Single quotes around characters. But not when used to quote
2010 ;; symbol names. Ugh.
2011 (list (concat "\\('\\)"
2012 "\\(" "."
2013 "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*"
2014 "u+" "[0-9a-fA-F]\\{4\\}"
2015 "\\|" "\\\\" "[0-7]\\{1,3\\}"
2016 "\\|" "\\\\" "." "\\)"
2017 "\\('\\)")
2018 '(1 "\"")
2e7c6a86 2019 '(4 "\""))))))
ee7c3dea 2020
6132bc01
MW
2021;;;--------------------------------------------------------------------------
2022;;; C# programming configuration.
e808c1e5 2023
6132bc01 2024;; Make indentation nice.
e808c1e5 2025
c56296d0
MW
2026(mdw-define-c-style mdw-csharp
2027 (c-basic-offset . 2)
2028 (c-backslash-column . 72)
2029 (c-offsets-alist (substatement-open . 0)
2030 (label . 0)
2031 (case-label . +)
2032 (access-label . 0)
2033 (inclass . +)
2034 (statement-case-intro . +)))
2035(mdw-set-default-c-style 'csharp-mode 'mdw-csharp)
e808c1e5 2036
6132bc01 2037;; Declare C# fontification style.
e808c1e5
MW
2038
2039(defun mdw-fontify-csharp ()
2040
6132bc01 2041 ;; Other stuff.
0e7d960b 2042 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
e808c1e5 2043
6132bc01 2044 ;; Now define things to be fontified.
e808c1e5
MW
2045 (make-local-variable 'font-lock-keywords)
2046 (let ((csharp-keywords
165cecf8
MW
2047 (mdw-regexps "abstract" "as" "bool" "break" "byte" "case" "catch"
2048 "char" "checked" "class" "const" "continue" "decimal"
2049 "default" "delegate" "do" "double" "else" "enum"
2050 "event" "explicit" "extern" "finally" "fixed" "float"
2051 "for" "foreach" "goto" "if" "implicit" "in" "int"
2052 "interface" "internal" "is" "lock" "long" "namespace"
2053 "new" "object" "operator" "out" "override" "params"
2054 "private" "protected" "public" "readonly" "ref"
2055 "return" "sbyte" "sealed" "short" "sizeof"
2056 "stackalloc" "static" "string" "struct" "switch"
2057 "throw" "try" "typeof" "uint" "ulong" "unchecked"
2058 "unsafe" "ushort" "using" "virtual" "void" "volatile"
2059 "while" "yield"))
2060
2061 (csharp-constants
2062 (mdw-regexps "base" "false" "null" "this" "true")))
e808c1e5
MW
2063
2064 (setq font-lock-keywords
2065 (list
e808c1e5 2066
6132bc01 2067 ;; Handle the keywords defined above.
e808c1e5
MW
2068 (list (concat "\\<\\(" csharp-keywords "\\)\\>")
2069 '(0 font-lock-keyword-face))
2070
165cecf8
MW
2071 ;; Handle the magic constants defined above.
2072 (list (concat "\\<\\(" csharp-constants "\\)\\>")
2073 '(0 font-lock-variable-name-face))
2074
6132bc01 2075 ;; Handle numbers too.
e808c1e5
MW
2076 ;;
2077 ;; The following isn't quite right, but it's close enough.
e808c1e5
MW
2078 (list (concat "\\<\\("
2079 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2080 "[0-9]+\\(\\.[0-9]*\\|\\)"
2081 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
2082 "[lLfFdD]?")
2083 '(0 mdw-number-face))
2084
6132bc01 2085 ;; And anything else is punctuation.
e808c1e5 2086 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2087 '(0 mdw-punct-face))))))
e808c1e5 2088
103c5923
MW
2089(define-derived-mode csharp-mode java-mode "C#"
2090 "Major mode for editing C# code.")
e808c1e5 2091
81fb08fc
MW
2092;;;--------------------------------------------------------------------------
2093;;; F# programming configuration.
2094
2095(setq fsharp-indent-offset 2)
2096
2097(defun mdw-fontify-fsharp ()
2098
2099 (let ((punct "=<>+-*/|&%!@?"))
2100 (do ((i 0 (1+ i)))
2101 ((>= i (length punct)))
2102 (modify-syntax-entry (aref punct i) ".")))
2103
2104 (modify-syntax-entry ?_ "_")
2105 (modify-syntax-entry ?( "(")
2106 (modify-syntax-entry ?) ")")
2107
2108 (setq indent-tabs-mode nil)
2109
2110 (let ((fsharp-keywords
2111 (mdw-regexps "abstract" "and" "as" "assert" "atomic"
165cecf8 2112 "begin" "break"
81fb08fc
MW
2113 "checked" "class" "component" "const" "constraint"
2114 "constructor" "continue"
2115 "default" "delegate" "do" "done" "downcast" "downto"
2116 "eager" "elif" "else" "end" "exception" "extern"
165cecf8 2117 "finally" "fixed" "for" "fori" "fun" "function"
81fb08fc
MW
2118 "functor"
2119 "global"
2120 "if" "in" "include" "inherit" "inline" "interface"
2121 "internal"
2122 "lazy" "let"
2123 "match" "measure" "member" "method" "mixin" "module"
2124 "mutable"
165cecf8
MW
2125 "namespace" "new"
2126 "object" "of" "open" "or" "override"
81fb08fc
MW
2127 "parallel" "params" "private" "process" "protected"
2128 "public" "pure"
2129 "rec" "recursive" "return"
2130 "sealed" "sig" "static" "struct"
165cecf8 2131 "tailcall" "then" "to" "trait" "try" "type"
81fb08fc
MW
2132 "upcast" "use"
2133 "val" "virtual" "void" "volatile"
2134 "when" "while" "with"
2135 "yield"))
2136
2137 (fsharp-builtins
165cecf8
MW
2138 (mdw-regexps "asr" "land" "lor" "lsl" "lsr" "lxor" "mod"
2139 "base" "false" "null" "true"))
81fb08fc
MW
2140
2141 (bang-keywords
2142 (mdw-regexps "do" "let" "return" "use" "yield"))
2143
2144 (preprocessor-keywords
2145 (mdw-regexps "if" "indent" "else" "endif")))
2146
2147 (setq font-lock-keywords
2148 (list (list (concat "\\(^\\|[^\"]\\)"
2149 "\\(" "(\\*"
2150 "[^*]*\\*+"
2151 "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*"
2152 ")"
2153 "\\|"
2154 "//.*"
2155 "\\)")
2156 '(2 font-lock-comment-face))
2157
2158 (list (concat "'" "\\("
2159 "\\\\"
2160 "\\(" "[ntbr'\\]"
2161 "\\|" "[0-9][0-9][0-9]"
2162 "\\|" "u" "[0-9a-fA-F]\\{4\\}"
2163 "\\|" "U" "[0-9a-fA-F]\\{8\\}"
2164 "\\)"
2165 "\\|"
2166 "." "\\)" "'"
2167 "\\|"
2168 "\"" "[^\"\\]*"
2169 "\\(" "\\\\" "\\(.\\|\n\\)"
2170 "[^\"\\]*" "\\)*"
2171 "\\(\"\\|\\'\\)")
2172 '(0 font-lock-string-face))
2173
2174 (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|"
2175 "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>"
2176 "\\|"
2177 "\\_<\\(" fsharp-keywords "\\)\\_>")
2178 '(0 font-lock-keyword-face))
2179 (list (concat "\\<\\(" fsharp-builtins "\\)\\_>")
2180 '(0 font-lock-variable-name-face))
2181
2182 (list (concat "\\_<"
2183 "\\(" "0[bB][01]+" "\\|"
2184 "0[oO][0-7]+" "\\|"
2185 "0[xX][0-9a-fA-F]+" "\\)"
2186 "\\(" "lf\\|LF" "\\|"
2187 "[uU]?[ysnlL]?" "\\)"
2188 "\\|"
2189 "\\_<"
2190 "[0-9]+" "\\("
2191 "[mMQRZING]"
2192 "\\|"
2193 "\\(\\.[0-9]*\\)?"
2194 "\\([eE][-+]?[0-9]+\\)?"
2195 "[fFmM]?"
2196 "\\|"
2197 "[uU]?[ysnlL]?"
2198 "\\)")
2199 '(0 mdw-number-face))
2200
2201 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2202 '(0 mdw-punct-face))))))
81fb08fc
MW
2203
2204(defun mdw-fontify-inferior-fsharp ()
2205 (mdw-fontify-fsharp)
2206 (setq font-lock-keywords
2207 (append (list (list "^[#-]" '(0 font-lock-comment-face))
2208 (list "^>" '(0 font-lock-keyword-face)))
2209 font-lock-keywords)))
2210
6132bc01 2211;;;--------------------------------------------------------------------------
07965a39
MW
2212;;; Go programming configuration.
2213
2214(defun mdw-fontify-go ()
2215
2216 (make-local-variable 'font-lock-keywords)
2217 (let ((go-keywords
2218 (mdw-regexps "break" "case" "chan" "const" "continue"
2219 "default" "defer" "else" "fallthrough" "for"
2220 "func" "go" "goto" "if" "import"
2221 "interface" "map" "package" "range" "return"
fc79ff88
MW
2222 "select" "struct" "switch" "type" "var"))
2223 (go-intrinsics
2224 (mdw-regexps "bool" "byte" "complex64" "complex128" "error"
2225 "float32" "float64" "int" "uint8" "int16" "int32"
2226 "int64" "rune" "string" "uint" "uint8" "uint16"
2227 "uint32" "uint64" "uintptr" "void"
2228 "false" "iota" "nil" "true"
2229 "init" "main"
2230 "append" "cap" "copy" "delete" "imag" "len" "make"
2231 "new" "panic" "real" "recover")))
07965a39
MW
2232
2233 (setq font-lock-keywords
2234 (list
2235
2236 ;; Handle the keywords defined above.
2237 (list (concat "\\<\\(" go-keywords "\\)\\>")
2238 '(0 font-lock-keyword-face))
fc79ff88
MW
2239 (list (concat "\\<\\(" go-intrinsics "\\)\\>")
2240 '(0 font-lock-variable-name-face))
07965a39 2241
cbbea94e
MW
2242 ;; Strings and characters.
2243 (list (concat "'"
2244 "\\(" "[^\\']" "\\|"
2245 "\\\\"
2246 "\\(" "[abfnrtv\\'\"]" "\\|"
2247 "[0-7]\\{3\\}" "\\|"
2248 "x" "[0-9A-Fa-f]\\{2\\}" "\\|"
2249 "u" "[0-9A-Fa-f]\\{4\\}" "\\|"
2250 "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)"
2251 "'"
2252 "\\|"
2253 "\""
2254 "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*"
2255 "\\(\"\\|$\\)"
2256 "\\|"
2257 "`" "[^`]+" "`")
2258 '(0 font-lock-string-face))
2259
07965a39
MW
2260 ;; Handle numbers too.
2261 ;;
2262 ;; The following isn't quite right, but it's close enough.
2263 (list (concat "\\<\\("
2264 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2265 "[0-9]+\\(\\.[0-9]*\\|\\)"
2266 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
2267 '(0 mdw-number-face))
2268
2269 ;; And anything else is punctuation.
2270 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2271 '(0 mdw-punct-face))))))
07965a39 2272
36db1ea7
MW
2273;;;--------------------------------------------------------------------------
2274;;; Rust programming configuration.
2275
2276(setq-default rust-indent-offset 2)
2277
2278(defun mdw-self-insert-and-indent (count)
2279 (interactive "p")
2280 (self-insert-command count)
2281 (indent-according-to-mode))
2282
2283(defun mdw-fontify-rust ()
2284
2285 ;; Hack syntax categories.
2286 (modify-syntax-entry ?= ".")
2287
2288 ;; Fontify keywords and things.
2289 (make-local-variable 'font-lock-keywords)
2290 (let ((rust-keywords
2291 (mdw-regexps "abstract" "alignof" "as"
2292 "become" "box" "break"
2293 "const" "continue" "create"
2294 "do"
2295 "else" "enum" "extern"
2296 "false" "final" "fn" "for"
2297 "if" "impl" "in"
2298 "let" "loop"
2299 "macro" "match" "mod" "move" "mut"
2300 "offsetof" "override"
2301 "priv" "pub" "pure"
2302 "ref" "return"
2303 "self" "sizeof" "static" "struct" "super"
2304 "true" "trait" "type" "typeof"
2305 "unsafe" "unsized" "use"
2306 "virtual"
2307 "where" "while"
2308 "yield"))
2309 (rust-builtins
2310 (mdw-regexps "array" "pointer" "slice" "tuple"
2311 "bool" "true" "false"
2312 "f32" "f64"
2313 "i8" "i16" "i32" "i64" "isize"
2314 "u8" "u16" "u32" "u64" "usize"
2315 "char" "str")))
2316 (setq font-lock-keywords
2317 (list
2318
2319 ;; Handle the keywords defined above.
2320 (list (concat "\\<\\(" rust-keywords "\\)\\>")
2321 '(0 font-lock-keyword-face))
2322 (list (concat "\\<\\(" rust-builtins "\\)\\>")
2323 '(0 font-lock-variable-name-face))
2324
2325 ;; Handle numbers too.
2326 (list (concat "\\<\\("
2327 "[0-9][0-9_]*"
2328 "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
2329 "\\|" "\\.[0-9_]+"
2330 "\\)"
2331 "\\(f32\\|f64\\)?"
2332 "\\|" "\\(" "[0-9][0-9_]*"
2333 "\\|" "0x[0-9a-fA-F_]+"
2334 "\\|" "0o[0-7_]+"
2335 "\\|" "0b[01_]+"
2336 "\\)"
2337 "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?"
2338 "\\)\\>")
2339 '(0 mdw-number-face))
2340
2341 ;; And anything else is punctuation.
2342 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2343 '(0 mdw-punct-face)))))
2344
2345 ;; Hack key bindings.
d2f85967 2346 (local-set-key [?{] 'mdw-self-insert-and-indent)
2e7c6a86 2347 (local-set-key [?}] 'mdw-self-insert-and-indent))
36db1ea7 2348
07965a39 2349;;;--------------------------------------------------------------------------
6132bc01 2350;;; Awk programming configuration.
f617db13 2351
6132bc01 2352;; Make Awk indentation nice.
f617db13 2353
c56296d0
MW
2354(mdw-define-c-style mdw-awk
2355 (c-basic-offset . 2)
2356 (c-offsets-alist (substatement-open . 0)
2357 (c-backslash-column . 72)
2358 (statement-cont . 0)
2359 (statement-case-intro . +)))
2360(mdw-set-default-c-style 'awk-mode 'mdw-awk)
f617db13 2361
6132bc01 2362;; Declare Awk fontification style.
f617db13
MW
2363
2364(defun mdw-fontify-awk ()
2365
6132bc01 2366 ;; Miscellaneous fiddling.
f617db13
MW
2367 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2368
6132bc01 2369 ;; Now define things to be fontified.
02109a0d 2370 (make-local-variable 'font-lock-keywords)
f617db13 2371 (let ((c-keywords
8d6d55b9
MW
2372 (mdw-regexps "BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
2373 "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
2374 "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
2375 "RSTART" "RLENGTH" "RT" "SUBSEP"
2376 "atan2" "break" "close" "continue" "cos" "delete"
2377 "do" "else" "exit" "exp" "fflush" "file" "for" "func"
2378 "function" "gensub" "getline" "gsub" "if" "in"
2379 "index" "int" "length" "log" "match" "next" "rand"
2380 "return" "print" "printf" "sin" "split" "sprintf"
2381 "sqrt" "srand" "strftime" "sub" "substr" "system"
2382 "systime" "tolower" "toupper" "while")))
f617db13
MW
2383
2384 (setq font-lock-keywords
2385 (list
f617db13 2386
6132bc01 2387 ;; Handle the keywords defined above.
f617db13
MW
2388 (list (concat "\\<\\(" c-keywords "\\)\\>")
2389 '(0 font-lock-keyword-face))
2390
6132bc01 2391 ;; Handle numbers too.
f617db13
MW
2392 ;;
2393 ;; The following isn't quite right, but it's close enough.
f617db13
MW
2394 (list (concat "\\<\\("
2395 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
2396 "[0-9]+\\(\\.[0-9]*\\|\\)"
2397 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
2398 "[uUlL]*")
2399 '(0 mdw-number-face))
2400
6132bc01 2401 ;; And anything else is punctuation.
f617db13 2402 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2403 '(0 mdw-punct-face))))))
f617db13 2404
6132bc01
MW
2405;;;--------------------------------------------------------------------------
2406;;; Perl programming style.
f617db13 2407
6132bc01 2408;; Perl indentation style.
f617db13 2409
88158daf
MW
2410(setq perl-indent-level 2)
2411
f617db13
MW
2412(setq cperl-indent-level 2)
2413(setq cperl-continued-statement-offset 2)
2414(setq cperl-continued-brace-offset 0)
2415(setq cperl-brace-offset -2)
2416(setq cperl-brace-imaginary-offset 0)
2417(setq cperl-label-offset 0)
2418
6132bc01 2419;; Define perl fontification style.
f617db13
MW
2420
2421(defun mdw-fontify-perl ()
2422
6132bc01 2423 ;; Miscellaneous fiddling.
f617db13
MW
2424 (modify-syntax-entry ?$ "\\")
2425 (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
a3b8176f 2426 (modify-syntax-entry ?: "." font-lock-syntax-table)
f617db13
MW
2427 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2428
6132bc01 2429 ;; Now define fontification things.
02109a0d 2430 (make-local-variable 'font-lock-keywords)
f617db13 2431 (let ((perl-keywords
821c4945
MW
2432 (mdw-regexps "and"
2433 "break"
2434 "cmp" "continue"
2435 "default" "do"
2436 "else" "elsif" "eq"
2437 "for" "foreach"
2438 "ge" "given" "gt" "goto"
2439 "if"
2440 "last" "le" "local" "lt"
2441 "my"
2442 "ne" "next"
2443 "or" "our"
2444 "package"
2445 "redo" "require" "return"
2446 "sub"
2447 "undef" "unless" "until" "use"
2448 "when" "while")))
f617db13
MW
2449
2450 (setq font-lock-keywords
2451 (list
f617db13 2452
6132bc01 2453 ;; Set up the keywords defined above.
f617db13
MW
2454 (list (concat "\\<\\(" perl-keywords "\\)\\>")
2455 '(0 font-lock-keyword-face))
2456
6132bc01 2457 ;; At least numbers are simpler than C.
f617db13
MW
2458 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2459 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2460 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2461 '(0 mdw-number-face))
2462
6132bc01 2463 ;; And anything else is punctuation.
f617db13 2464 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2465 '(0 mdw-punct-face))))))
f617db13
MW
2466
2467(defun perl-number-tests (&optional arg)
2468 "Assign consecutive numbers to lines containing `#t'. With ARG,
2469strip numbers instead."
2470 (interactive "P")
2471 (save-excursion
2472 (goto-char (point-min))
2473 (let ((i 0) (fmt (if arg "" " %4d")))
2474 (while (search-forward "#t" nil t)
2475 (delete-region (point) (line-end-position))
2476 (setq i (1+ i))
2477 (insert (format fmt i)))
2478 (goto-char (point-min))
2479 (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
2480 (replace-match (format "\\1%d" i))))))
2481
6132bc01
MW
2482;;;--------------------------------------------------------------------------
2483;;; Python programming style.
f617db13 2484
99fe6ef5 2485(defun mdw-fontify-pythonic (keywords)
f617db13 2486
6132bc01 2487 ;; Miscellaneous fiddling.
f617db13 2488 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
7c0fcfde 2489 (setq indent-tabs-mode nil)
f617db13 2490
6132bc01 2491 ;; Now define fontification things.
02109a0d 2492 (make-local-variable 'font-lock-keywords)
99fe6ef5
MW
2493 (setq font-lock-keywords
2494 (list
f617db13 2495
be2cc788 2496 ;; Set up the keywords defined above.
4b037109 2497 (list (concat "\\_<\\(" keywords "\\)\\_>")
99fe6ef5 2498 '(0 font-lock-keyword-face))
f617db13 2499
be2cc788 2500 ;; At least numbers are simpler than C.
4b037109
MW
2501 (list (concat "\\_<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2502 "\\_<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
99fe6ef5
MW
2503 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
2504 '(0 mdw-number-face))
f617db13 2505
be2cc788 2506 ;; And anything else is punctuation.
99fe6ef5 2507 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2508 '(0 mdw-punct-face)))))
99fe6ef5 2509
be2cc788 2510;; Define Python fontification styles.
99fe6ef5
MW
2511
2512(defun mdw-fontify-python ()
2513 (mdw-fontify-pythonic
2514 (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
2515 "del" "elif" "else" "except" "exec" "finally" "for"
2516 "from" "global" "if" "import" "in" "is" "lambda"
2517 "not" "or" "pass" "print" "raise" "return" "try"
2518 "while" "with" "yield")))
2519
2520(defun mdw-fontify-pyrex ()
2521 (mdw-fontify-pythonic
2522 (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
2523 "ctypedef" "def" "del" "elif" "else" "except" "exec"
2524 "extern" "finally" "for" "from" "global" "if"
2525 "import" "in" "is" "lambda" "not" "or" "pass" "print"
2526 "raise" "return" "struct" "try" "while" "with"
2527 "yield")))
f617db13 2528
6132bc01
MW
2529;;;--------------------------------------------------------------------------
2530;;; Icon programming style.
cc1980e1 2531
6132bc01 2532;; Icon indentation style.
cc1980e1
MW
2533
2534(setq icon-brace-offset 0
2535 icon-continued-brace-offset 0
2536 icon-continued-statement-offset 2
2537 icon-indent-level 2)
2538
6132bc01 2539;; Define Icon fontification style.
cc1980e1
MW
2540
2541(defun mdw-fontify-icon ()
2542
6132bc01 2543 ;; Miscellaneous fiddling.
cc1980e1
MW
2544 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2545
6132bc01 2546 ;; Now define fontification things.
cc1980e1
MW
2547 (make-local-variable 'font-lock-keywords)
2548 (let ((icon-keywords
2549 (mdw-regexps "break" "by" "case" "create" "default" "do" "else"
2550 "end" "every" "fail" "global" "if" "initial"
2551 "invocable" "link" "local" "next" "not" "of"
2552 "procedure" "record" "repeat" "return" "static"
2553 "suspend" "then" "to" "until" "while"))
2554 (preprocessor-keywords
2555 (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
2556 "include" "line" "undef")))
2557 (setq font-lock-keywords
2558 (list
2559
6132bc01 2560 ;; Set up the keywords defined above.
cc1980e1
MW
2561 (list (concat "\\<\\(" icon-keywords "\\)\\>")
2562 '(0 font-lock-keyword-face))
2563
6132bc01 2564 ;; The things that Icon calls keywords.
cc1980e1
MW
2565 (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
2566
6132bc01 2567 ;; At least numbers are simpler than C.
cc1980e1
MW
2568 (list (concat "\\<[0-9]+"
2569 "\\([rR][0-9a-zA-Z]+\\|"
2570 "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
2571 "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
2572 '(0 mdw-number-face))
2573
6132bc01 2574 ;; Preprocessor.
cc1980e1
MW
2575 (list (concat "^[ \t]*$[ \t]*\\<\\("
2576 preprocessor-keywords
2577 "\\)\\>")
2578 '(0 font-lock-keyword-face))
2579
6132bc01 2580 ;; And anything else is punctuation.
cc1980e1 2581 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2582 '(0 mdw-punct-face))))))
cc1980e1 2583
6132bc01
MW
2584;;;--------------------------------------------------------------------------
2585;;; Assembler mode.
30c8a8fb
MW
2586
2587(defun mdw-fontify-asm ()
2588 (modify-syntax-entry ?' "\"")
2589 (modify-syntax-entry ?. "w")
9032280b 2590 (modify-syntax-entry ?\n ">")
30c8a8fb
MW
2591 (setf fill-prefix nil)
2592 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
2593
227b2b2b
MW
2594(defun mdw-asm-set-comment ()
2595 (modify-syntax-entry ?; "."
2596 )
2597 (modify-syntax-entry asm-comment-char "<b")
2598 (setq comment-start (string asm-comment-char ? )))
2599(add-hook 'asm-mode-local-variables-hook 'mdw-asm-set-comment)
2600(put 'asm-comment-char 'safe-local-variable 'characterp)
9032280b 2601
6132bc01
MW
2602;;;--------------------------------------------------------------------------
2603;;; TCL configuration.
f617db13
MW
2604
2605(defun mdw-fontify-tcl ()
2606 (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
2607 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
02109a0d 2608 (make-local-variable 'font-lock-keywords)
f617db13
MW
2609 (setq font-lock-keywords
2610 (list
f617db13
MW
2611 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2612 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2613 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2614 '(0 mdw-number-face))
2615 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2616 '(0 mdw-punct-face)))))
f617db13 2617
ad305d7e
MW
2618;;;--------------------------------------------------------------------------
2619;;; Dylan programming configuration.
2620
2621(defun mdw-fontify-dylan ()
2622
2623 (make-local-variable 'font-lock-keywords)
2624
2625 ;; Horrors. `dylan-mode' sets the `major-mode' name after calling this
2626 ;; hook, which undoes all of our configuration.
2627 (setq major-mode 'dylan-mode)
2628 (font-lock-set-defaults)
2629
2630 (let* ((word "[-_a-zA-Z!*@<>$%]+")
2631 (dylan-keywords (mdw-regexps
2632
2633 "C-address" "C-callable-wrapper" "C-function"
2634 "C-mapped-subtype" "C-pointer-type" "C-struct"
2635 "C-subtype" "C-union" "C-variable"
2636
2637 "above" "abstract" "afterwards" "all"
2638 "begin" "below" "block" "by"
2639 "case" "class" "cleanup" "constant" "create"
2640 "define" "domain"
2641 "else" "elseif" "end" "exception" "export"
2642 "finally" "for" "from" "function"
2643 "generic"
2644 "handler"
2645 "if" "in" "instance" "interface" "iterate"
2646 "keyed-by"
2647 "let" "library" "local"
2648 "macro" "method" "module"
2649 "otherwise"
2650 "profiling"
2651 "select" "slot" "subclass"
2652 "table" "then" "to"
2653 "unless" "until" "use"
2654 "variable" "virtual"
2655 "when" "while"))
2656 (sharp-keywords (mdw-regexps
2657 "all-keys" "key" "next" "rest" "include"
2658 "t" "f")))
2659 (setq font-lock-keywords
2660 (list (list (concat "\\<\\(" dylan-keywords
ce29694e 2661 "\\|" "with\\(out\\)?-" word
ad305d7e
MW
2662 "\\)\\>")
2663 '(0 font-lock-keyword-face))
ce29694e
MW
2664 (list (concat "\\<" word ":" "\\|"
2665 "#\\(" sharp-keywords "\\)\\>")
ad305d7e
MW
2666 '(0 font-lock-variable-name-face))
2667 (list (concat "\\("
2668 "\\([-+]\\|\\<\\)[0-9]+" "\\("
2669 "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
2670 "\\|" "/[0-9]+"
2671 "\\)"
2672 "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
2673 "\\|" "#b[01]+"
2674 "\\|" "#o[0-7]+"
2675 "\\|" "#x[0-9a-zA-Z]+"
2676 "\\)\\>")
2677 '(0 mdw-number-face))
2678 (list (concat "\\("
2679 "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
2680 "\\_<[-+*/=<>:&|]+\\_>"
2681 "\\)")
2e7c6a86 2682 '(0 mdw-punct-face))))))
ad305d7e 2683
7fce54c3
MW
2684;;;--------------------------------------------------------------------------
2685;;; Algol 68 configuration.
2686
2687(setq a68-indent-step 2)
2688
2689(defun mdw-fontify-algol-68 ()
2690
2691 ;; Fix up the syntax table.
2692 (modify-syntax-entry ?# "!" a68-mode-syntax-table)
2693 (dolist (ch '(?- ?+ ?= ?< ?> ?* ?/ ?| ?&))
2694 (modify-syntax-entry ch "." a68-mode-syntax-table))
2695
2696 (make-local-variable 'font-lock-keywords)
2697
2698 (let ((not-comment
2699 (let ((word "COMMENT"))
2700 (do ((regexp (concat "[^" (substring word 0 1) "]+")
2701 (concat regexp "\\|"
2702 (substring word 0 i)
2703 "[^" (substring word i (1+ i)) "]"))
2704 (i 1 (1+ i)))
2705 ((>= i (length word)) regexp)))))
2706 (setq font-lock-keywords
2707 (list (list (concat "\\<COMMENT\\>"
2708 "\\(" not-comment "\\)\\{0,5\\}"
2709 "\\(\\'\\|\\<COMMENT\\>\\)")
2710 '(0 font-lock-comment-face))
2711 (list (concat "\\<CO\\>"
2712 "\\([^C]+\\|C[^O]\\)\\{0,5\\}"
2713 "\\($\\|\\<CO\\>\\)")
2714 '(0 font-lock-comment-face))
2715 (list "\\<[A-Z_]+\\>"
2716 '(0 font-lock-keyword-face))
2717 (list (concat "\\<"
2718 "[0-9]+"
2719 "\\(\\.[0-9]+\\)?"
2720 "\\([eE][-+]?[0-9]+\\)?"
2721 "\\>")
2722 '(0 mdw-number-face))
2723 (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/"
2e7c6a86 2724 '(0 mdw-punct-face))))))
7fce54c3 2725
6132bc01
MW
2726;;;--------------------------------------------------------------------------
2727;;; REXX configuration.
f617db13
MW
2728
2729(defun mdw-rexx-electric-* ()
2730 (interactive)
2731 (insert ?*)
2732 (rexx-indent-line))
2733
2734(defun mdw-rexx-indent-newline-indent ()
2735 (interactive)
2736 (rexx-indent-line)
2737 (if abbrev-mode (expand-abbrev))
2738 (newline-and-indent))
2739
2740(defun mdw-fontify-rexx ()
2741
6132bc01 2742 ;; Various bits of fiddling.
f617db13
MW
2743 (setq mdw-auto-indent nil)
2744 (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
2745 (local-set-key [?*] 'mdw-rexx-electric-*)
2746 (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
e443a4cd 2747 '(?! ?? ?# ?@ ?$))
f617db13
MW
2748 (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
2749
6132bc01 2750 ;; Set up keywords and things for fontification.
f617db13
MW
2751 (make-local-variable 'font-lock-keywords-case-fold-search)
2752 (setq font-lock-keywords-case-fold-search t)
2753
2754 (setq rexx-indent 2)
2755 (setq rexx-end-indent rexx-indent)
f617db13
MW
2756 (setq rexx-cont-indent rexx-indent)
2757
02109a0d 2758 (make-local-variable 'font-lock-keywords)
f617db13 2759 (let ((rexx-keywords
8d6d55b9
MW
2760 (mdw-regexps "address" "arg" "by" "call" "digits" "do" "drop"
2761 "else" "end" "engineering" "exit" "expose" "for"
2762 "forever" "form" "fuzz" "if" "interpret" "iterate"
2763 "leave" "linein" "name" "nop" "numeric" "off" "on"
2764 "options" "otherwise" "parse" "procedure" "pull"
2765 "push" "queue" "return" "say" "select" "signal"
2766 "scientific" "source" "then" "trace" "to" "until"
2767 "upper" "value" "var" "version" "when" "while"
2768 "with"
2769
2770 "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
2771 "center" "center" "charin" "charout" "chars"
2772 "compare" "condition" "copies" "c2d" "c2x"
2773 "datatype" "date" "delstr" "delword" "d2c" "d2x"
2774 "errortext" "format" "fuzz" "insert" "lastpos"
2775 "left" "length" "lineout" "lines" "max" "min"
2776 "overlay" "pos" "queued" "random" "reverse" "right"
2777 "sign" "sourceline" "space" "stream" "strip"
2778 "substr" "subword" "symbol" "time" "translate"
2779 "trunc" "value" "verify" "word" "wordindex"
2780 "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
2781 "x2d")))
f617db13
MW
2782
2783 (setq font-lock-keywords
2784 (list
f617db13 2785
6132bc01 2786 ;; Set up the keywords defined above.
f617db13
MW
2787 (list (concat "\\<\\(" rexx-keywords "\\)\\>")
2788 '(0 font-lock-keyword-face))
2789
6132bc01 2790 ;; Fontify all symbols the same way.
f617db13
MW
2791 (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
2792 "[A-Za-z0-9.!?_#@$]+\\)")
2793 '(0 font-lock-variable-name-face))
2794
6132bc01 2795 ;; And everything else is punctuation.
f617db13 2796 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2797 '(0 mdw-punct-face))))))
f617db13 2798
6132bc01
MW
2799;;;--------------------------------------------------------------------------
2800;;; Standard ML programming style.
f617db13
MW
2801
2802(defun mdw-fontify-sml ()
2803
6132bc01 2804 ;; Make underscore an honorary letter.
f617db13
MW
2805 (modify-syntax-entry ?' "w")
2806
6132bc01 2807 ;; Set fill prefix.
f617db13
MW
2808 (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
2809
6132bc01 2810 ;; Now define fontification things.
02109a0d 2811 (make-local-variable 'font-lock-keywords)
f617db13 2812 (let ((sml-keywords
8d6d55b9
MW
2813 (mdw-regexps "abstype" "and" "andalso" "as"
2814 "case"
2815 "datatype" "do"
2816 "else" "end" "eqtype" "exception"
2817 "fn" "fun" "functor"
2818 "handle"
2819 "if" "in" "include" "infix" "infixr"
2820 "let" "local"
2821 "nonfix"
2822 "of" "op" "open" "orelse"
2823 "raise" "rec"
2824 "sharing" "sig" "signature" "struct" "structure"
2825 "then" "type"
2826 "val"
2827 "where" "while" "with" "withtype")))
f617db13
MW
2828
2829 (setq font-lock-keywords
2830 (list
f617db13 2831
6132bc01 2832 ;; Set up the keywords defined above.
f617db13
MW
2833 (list (concat "\\<\\(" sml-keywords "\\)\\>")
2834 '(0 font-lock-keyword-face))
2835
6132bc01 2836 ;; At least numbers are simpler than C.
f617db13
MW
2837 (list (concat "\\<\\(\\~\\|\\)"
2838 "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
852cd5fb
MW
2839 "[wW][0-9]+\\)\\|"
2840 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
2841 "\\([eE]\\(\\~\\|\\)"
2842 "[0-9]+\\|\\)\\)\\)")
f617db13
MW
2843 '(0 mdw-number-face))
2844
6132bc01 2845 ;; And anything else is punctuation.
f617db13 2846 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2847 '(0 mdw-punct-face))))))
f617db13 2848
6132bc01
MW
2849;;;--------------------------------------------------------------------------
2850;;; Haskell configuration.
f617db13
MW
2851
2852(defun mdw-fontify-haskell ()
2853
6132bc01 2854 ;; Fiddle with syntax table to get comments right.
5952a020
MW
2855 (modify-syntax-entry ?' "_")
2856 (modify-syntax-entry ?- ". 12")
f617db13
MW
2857 (modify-syntax-entry ?\n ">")
2858
4d90cf3d
MW
2859 ;; Make punctuation be punctuation
2860 (let ((punct "=<>+-*/|&%!@?$.^:#`"))
2861 (do ((i 0 (1+ i)))
2862 ((>= i (length punct)))
2863 (modify-syntax-entry (aref punct i) ".")))
2864
6132bc01 2865 ;; Set fill prefix.
f617db13
MW
2866 (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
2867
6132bc01 2868 ;; Fiddle with fontification.
02109a0d 2869 (make-local-variable 'font-lock-keywords)
f617db13 2870 (let ((haskell-keywords
5952a020
MW
2871 (mdw-regexps "as"
2872 "case" "ccall" "class"
2873 "data" "default" "deriving" "do"
2874 "else" "exists"
2875 "forall" "foreign"
2876 "hiding"
2877 "if" "import" "in" "infix" "infixl" "infixr" "instance"
2878 "let"
2879 "mdo" "module"
2880 "newtype"
2881 "of"
2882 "proc"
2883 "qualified"
2884 "rec"
2885 "safe" "stdcall"
2886 "then" "type"
2887 "unsafe"
2888 "where"))
2889 (control-sequences
2890 (mdw-regexps "ACK" "BEL" "BS" "CAN" "CR" "DC1" "DC2" "DC3" "DC4"
2891 "DEL" "DLE" "EM" "ENQ" "EOT" "ESC" "ETB" "ETX" "FF"
2892 "FS" "GS" "HT" "LF" "NAK" "NUL" "RS" "SI" "SO" "SOH"
2893 "SP" "STX" "SUB" "SYN" "US" "VT")))
f617db13
MW
2894
2895 (setq font-lock-keywords
2896 (list
5952a020
MW
2897 (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
2898 "\\(-+}\\|-*\\'\\)"
2899 "\\|"
2900 "--.*$")
f617db13 2901 '(0 font-lock-comment-face))
5952a020 2902 (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
f617db13 2903 '(0 font-lock-keyword-face))
5952a020
MW
2904 (list (concat "'\\("
2905 "[^\\]"
2906 "\\|"
2907 "\\\\"
2908 "\\(" "[abfnrtv\\\"']" "\\|"
2909 "^" "\\(" control-sequences "\\|"
2910 "[]A-Z@[\\^_]" "\\)" "\\|"
2911 "\\|"
2912 "[0-9]+" "\\|"
2913 "[oO][0-7]+" "\\|"
2914 "[xX][0-9A-Fa-f]+"
2915 "\\)"
2916 "\\)'")
2917 '(0 font-lock-string-face))
2918 (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>"
2919 '(0 font-lock-variable-name-face))
2920 (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|"
2921 "\\_<[0-9]+\\(\\.[0-9]*\\|\\)"
f617db13
MW
2922 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
2923 '(0 mdw-number-face))
2924 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2925 '(0 mdw-punct-face))))))
f617db13 2926
6132bc01
MW
2927;;;--------------------------------------------------------------------------
2928;;; Erlang configuration.
2ded9493 2929
52941dec 2930(setq erlang-electric-commands nil)
2ded9493
MW
2931
2932(defun mdw-fontify-erlang ()
2933
6132bc01 2934 ;; Set fill prefix.
2ded9493
MW
2935 (mdw-standard-fill-prefix "\\([ \t]*{?%*[ \t]*\\)")
2936
6132bc01 2937 ;; Fiddle with fontification.
2ded9493
MW
2938 (make-local-variable 'font-lock-keywords)
2939 (let ((erlang-keywords
2940 (mdw-regexps "after" "and" "andalso"
2941 "band" "begin" "bnot" "bor" "bsl" "bsr" "bxor"
2942 "case" "catch" "cond"
2943 "div" "end" "fun" "if" "let" "not"
2944 "of" "or" "orelse"
2945 "query" "receive" "rem" "try" "when" "xor")))
2946
2947 (setq font-lock-keywords
2948 (list
2949 (list "%.*$"
2950 '(0 font-lock-comment-face))
2951 (list (concat "\\<\\(" erlang-keywords "\\)\\>")
2952 '(0 font-lock-keyword-face))
2953 (list (concat "^-\\sw+\\>")
2954 '(0 font-lock-keyword-face))
2955 (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
2956 '(0 mdw-number-face))
2957 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 2958 '(0 mdw-punct-face))))))
2ded9493 2959
6132bc01
MW
2960;;;--------------------------------------------------------------------------
2961;;; Texinfo configuration.
f617db13
MW
2962
2963(defun mdw-fontify-texinfo ()
2964
6132bc01 2965 ;; Set fill prefix.
f617db13
MW
2966 (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
2967
6132bc01 2968 ;; Real fontification things.
02109a0d 2969 (make-local-variable 'font-lock-keywords)
f617db13
MW
2970 (setq font-lock-keywords
2971 (list
f617db13 2972
6132bc01 2973 ;; Environment names are keywords.
f617db13
MW
2974 (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
2975 '(2 font-lock-keyword-face))
2976
6132bc01 2977 ;; Unmark escaped magic characters.
f617db13
MW
2978 (list "\\(@\\)\\([@{}]\\)"
2979 '(1 font-lock-keyword-face)
2980 '(2 font-lock-variable-name-face))
2981
6132bc01 2982 ;; Make sure we get comments properly.
f617db13
MW
2983 (list "@c\\(\\|omment\\)\\( .*\\)?$"
2984 '(0 font-lock-comment-face))
2985
6132bc01 2986 ;; Command names are keywords.
f617db13
MW
2987 (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
2988 '(0 font-lock-keyword-face))
2989
6132bc01 2990 ;; Fontify TeX special characters as punctuation.
f617db13 2991 (list "[{}]+"
2e7c6a86 2992 '(0 mdw-punct-face)))))
f617db13 2993
6132bc01
MW
2994;;;--------------------------------------------------------------------------
2995;;; TeX and LaTeX configuration.
f617db13
MW
2996
2997(defun mdw-fontify-tex ()
2998 (setq ispell-parser 'tex)
55f80fae 2999 (turn-on-reftex)
f617db13 3000
6132bc01 3001 ;; Don't make maths into a string.
f617db13
MW
3002 (modify-syntax-entry ?$ ".")
3003 (modify-syntax-entry ?$ "." font-lock-syntax-table)
3004 (local-set-key [?$] 'self-insert-command)
3005
df200ecd
MW
3006 ;; Make `tab' be useful, given that tab stops in TeX don't work well.
3007 (local-set-key "\C-i" 'indent-relative)
3008 (setq indent-tabs-mode nil)
3009
6132bc01 3010 ;; Set fill prefix.
f617db13
MW
3011 (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
3012
6132bc01 3013 ;; Real fontification things.
02109a0d 3014 (make-local-variable 'font-lock-keywords)
f617db13
MW
3015 (setq font-lock-keywords
3016 (list
f617db13 3017
6132bc01 3018 ;; Environment names are keywords.
f617db13
MW
3019 (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
3020 "{\\([^}\n]*\\)}")
3021 '(2 font-lock-keyword-face))
3022
6132bc01 3023 ;; Suspended environment names are keywords too.
f617db13
MW
3024 (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
3025 "{\\([^}\n]*\\)}")
3026 '(3 font-lock-keyword-face))
3027
6132bc01 3028 ;; Command names are keywords.
f617db13
MW
3029 (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
3030 '(0 font-lock-keyword-face))
3031
6132bc01 3032 ;; Handle @/.../ for italics.
f617db13 3033 ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
852cd5fb
MW
3034 ;; '(1 font-lock-keyword-face)
3035 ;; '(3 font-lock-keyword-face))
f617db13 3036
6132bc01 3037 ;; Handle @*...* for boldness.
f617db13 3038 ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
852cd5fb
MW
3039 ;; '(1 font-lock-keyword-face)
3040 ;; '(3 font-lock-keyword-face))
f617db13 3041
6132bc01 3042 ;; Handle @`...' for literal syntax things.
f617db13 3043 ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
852cd5fb
MW
3044 ;; '(1 font-lock-keyword-face)
3045 ;; '(3 font-lock-keyword-face))
f617db13 3046
6132bc01 3047 ;; Handle @<...> for nonterminals.
f617db13 3048 ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
852cd5fb
MW
3049 ;; '(1 font-lock-keyword-face)
3050 ;; '(3 font-lock-keyword-face))
f617db13 3051
6132bc01 3052 ;; Handle other @-commands.
f617db13 3053 ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
852cd5fb 3054 ;; '(0 font-lock-keyword-face))
f617db13 3055
6132bc01 3056 ;; Make sure we get comments properly.
f617db13
MW
3057 (list "%.*"
3058 '(0 font-lock-comment-face))
3059
6132bc01 3060 ;; Fontify TeX special characters as punctuation.
f617db13 3061 (list "[$^_{}#&]"
2e7c6a86 3062 '(0 mdw-punct-face)))))
f617db13 3063
6132bc01
MW
3064;;;--------------------------------------------------------------------------
3065;;; SGML hacking.
f25cf300
MW
3066
3067(defun mdw-sgml-mode ()
3068 (interactive)
3069 (sgml-mode)
3070 (mdw-standard-fill-prefix "")
8a425bd7 3071 (make-local-variable 'sgml-delimiters)
f25cf300
MW
3072 (setq sgml-delimiters
3073 '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
3074 "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
3075 "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
3076 "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
3077 "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
3078 "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
3079 "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
3080 "NULL" ""))
3081 (setq major-mode 'mdw-sgml-mode)
3082 (setq mode-name "[mdw] SGML")
3083 (run-hooks 'mdw-sgml-mode-hook))
6cb52f8b
MW
3084
3085;;;--------------------------------------------------------------------------
3086;;; Configuration files.
3087
3088(defvar mdw-conf-quote-normal nil
3089 "*Control syntax category of quote characters `\"' and `''.
3090If this is `t', consider quote characters to be normal
3091punctuation, as for `conf-quote-normal'. If this is `nil' then
3092leave quote characters as quotes. If this is a list, then
3093consider the quote characters in the list to be normal
3094punctuation. If this is a single quote character, then consider
3095that character only to be normal punctuation.")
3096(defun mdw-conf-quote-normal-acceptable-value-p (value)
3097 "Is the VALUE is an acceptable value for `mdw-conf-quote-normal'?"
3098 (or (booleanp value)
3099 (every (lambda (v) (memq v '(?\" ?')))
3100 (if (listp value) value (list value)))))
18bb0f77
MW
3101(put 'mdw-conf-quote-normal 'safe-local-variable
3102 'mdw-conf-quote-normal-acceptable-value-p)
6cb52f8b
MW
3103
3104(defun mdw-fix-up-quote ()
3105 "Apply the setting of `mdw-conf-quote-normal'."
3106 (let ((flag mdw-conf-quote-normal))
3107 (cond ((eq flag t)
3108 (conf-quote-normal t))
3109 ((not flag)
3110 nil)
3111 (t
3112 (let ((table (copy-syntax-table (syntax-table))))
3113 (mapc (lambda (ch) (modify-syntax-entry ch "." table))
3114 (if (listp flag) flag (list flag)))
3115 (set-syntax-table table)
3116 (and font-lock-mode (font-lock-fontify-buffer)))))))
18bb0f77 3117(add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t)
f25cf300 3118
6132bc01
MW
3119;;;--------------------------------------------------------------------------
3120;;; Shell scripts.
f617db13
MW
3121
3122(defun mdw-setup-sh-script-mode ()
3123
6132bc01 3124 ;; Fetch the shell interpreter's name.
f617db13
MW
3125 (let ((shell-name sh-shell-file))
3126
6132bc01 3127 ;; Try reading the hash-bang line.
f617db13
MW
3128 (save-excursion
3129 (goto-char (point-min))
3130 (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
3131 (setq shell-name (match-string 1))))
3132
6132bc01 3133 ;; Now try to set the shell.
f617db13
MW
3134 ;;
3135 ;; Don't let `sh-set-shell' bugger up my script.
f617db13
MW
3136 (let ((executable-set-magic #'(lambda (s &rest r) s)))
3137 (sh-set-shell shell-name)))
3138
10c51541
MW
3139 ;; Don't insert here-document scaffolding automatically.
3140 (local-set-key "<" 'self-insert-command)
3141
6132bc01 3142 ;; Now enable my keys and the fontification.
f617db13
MW
3143 (mdw-misc-mode-config)
3144
6132bc01 3145 ;; Set the indentation level correctly.
f617db13
MW
3146 (setq sh-indentation 2)
3147 (setq sh-basic-offset 2))
3148
070c1dca
MW
3149(setq sh-shell-file "/bin/sh")
3150
6d6e095a
MW
3151;; Awful hacking to override the shell detection for particular scripts.
3152(defmacro define-custom-shell-mode (name shell)
3153 `(defun ,name ()
3154 (interactive)
3155 (set (make-local-variable 'sh-shell-file) ,shell)
3156 (sh-mode)))
3157(define-custom-shell-mode bash-mode "/bin/bash")
3158(define-custom-shell-mode rc-mode "/usr/bin/rc")
3159(put 'sh-shell-file 'permanent-local t)
3160
3161;; Hack the rc syntax table. Backquotes aren't paired in rc.
3162(eval-after-load "sh-script"
3163 '(or (assq 'rc sh-mode-syntax-table-input)
3164 (let ((frag '(nil
3165 ?# "<"
3166 ?\n ">#"
3167 ?\" "\"\""
3168 ?\' "\"\'"
3169 ?$ "'"
3170 ?\` "."
3171 ?! "_"
3172 ?% "_"
3173 ?. "_"
3174 ?^ "_"
3175 ?~ "_"
3176 ?, "_"
3177 ?= "."
3178 ?< "."
3179 ?> "."))
3180 (assoc (assq 'rc sh-mode-syntax-table-input)))
3181 (if assoc
3182 (rplacd assoc frag)
3183 (setq sh-mode-syntax-table-input
3184 (cons (cons 'rc frag)
3185 sh-mode-syntax-table-input))))))
3186
092f0a38
MW
3187;;;--------------------------------------------------------------------------
3188;;; Emacs shell mode.
3189
3190(defun mdw-eshell-prompt ()
3191 (let ((left "[") (right "]"))
3192 (when (= (user-uid) 0)
3193 (setq left "«" right "»"))
3194 (concat left
3195 (save-match-data
3196 (replace-regexp-in-string "\\..*$" "" (system-name)))
3197 " "
2d8b2924
MW
3198 (let* ((pwd (eshell/pwd)) (npwd (length pwd))
3199 (home (expand-file-name "~")) (nhome (length home)))
3200 (if (and (>= npwd nhome)
3201 (or (= nhome npwd)
5801e199
MW
3202 (= (elt pwd nhome) ?/))
3203 (string= (substring pwd 0 nhome) home))
2d8b2924
MW
3204 (concat "~" (substring pwd (length home)))
3205 pwd))
092f0a38
MW
3206 right)))
3207(setq eshell-prompt-function 'mdw-eshell-prompt)
ac4ae7cd 3208(setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
092f0a38 3209
2d8b2924
MW
3210(defun eshell/e (file) (find-file file) nil)
3211(defun eshell/ee (file) (find-file-other-window file) nil)
3212(defun eshell/w3m (url) (w3m-goto-url url) nil)
415a23dd 3213
092f0a38
MW
3214(mdw-define-face eshell-prompt (t :weight bold))
3215(mdw-define-face eshell-ls-archive (t :weight bold :foreground "red"))
3216(mdw-define-face eshell-ls-backup (t :foreground "lightgrey" :slant italic))
3217(mdw-define-face eshell-ls-product (t :foreground "lightgrey" :slant italic))
3218(mdw-define-face eshell-ls-clutter (t :foreground "lightgrey" :slant italic))
3219(mdw-define-face eshell-ls-executable (t :weight bold))
3220(mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
3221(mdw-define-face eshell-ls-readonly (t nil))
3222(mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
3223
6132bc01
MW
3224;;;--------------------------------------------------------------------------
3225;;; Messages-file mode.
f617db13 3226
4bb22eea 3227(defun messages-mode-guts ()
f617db13
MW
3228 (setq messages-mode-syntax-table (make-syntax-table))
3229 (set-syntax-table messages-mode-syntax-table)
f617db13
MW
3230 (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
3231 (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
3232 (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
3233 (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
3234 (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
3235 (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
3236 (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
3237 (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
3238 (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
3239 (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
3240 (make-local-variable 'comment-start)
3241 (make-local-variable 'comment-end)
3242 (make-local-variable 'indent-line-function)
3243 (setq indent-line-function 'indent-relative)
3244 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
3245 (make-local-variable 'font-lock-defaults)
4bb22eea 3246 (make-local-variable 'messages-mode-keywords)
f617db13 3247 (let ((keywords
8d6d55b9
MW
3248 (mdw-regexps "array" "bitmap" "callback" "docs[ \t]+enum"
3249 "export" "enum" "fixed-octetstring" "flags"
3250 "harmless" "map" "nested" "optional"
3251 "optional-tagged" "package" "primitive"
3252 "primitive-nullfree" "relaxed[ \t]+enum"
3253 "set" "table" "tagged-optional" "union"
3254 "variadic" "vector" "version" "version-tag")))
4bb22eea 3255 (setq messages-mode-keywords
f617db13
MW
3256 (list
3257 (list (concat "\\<\\(" keywords "\\)\\>:")
3258 '(0 font-lock-keyword-face))
3259 '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
3260 '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
3261 (0 font-lock-variable-name-face))
3262 '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
3263 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3264 (0 mdw-punct-face)))))
3265 (setq font-lock-defaults
4bb22eea 3266 '(messages-mode-keywords nil nil nil nil))
f617db13
MW
3267 (run-hooks 'messages-file-hook))
3268
3269(defun messages-mode ()
3270 (interactive)
3271 (fundamental-mode)
3272 (setq major-mode 'messages-mode)
3273 (setq mode-name "Messages")
4bb22eea 3274 (messages-mode-guts)
f617db13
MW
3275 (modify-syntax-entry ?# "<" messages-mode-syntax-table)
3276 (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
3277 (setq comment-start "# ")
3278 (setq comment-end "")
f617db13
MW
3279 (run-hooks 'messages-mode-hook))
3280
3281(defun cpp-messages-mode ()
3282 (interactive)
3283 (fundamental-mode)
3284 (setq major-mode 'cpp-messages-mode)
3285 (setq mode-name "CPP Messages")
4bb22eea 3286 (messages-mode-guts)
f617db13
MW
3287 (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
3288 (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
3289 (setq comment-start "/* ")
3290 (setq comment-end " */")
3291 (let ((preprocessor-keywords
8d6d55b9
MW
3292 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
3293 "ident" "if" "ifdef" "ifndef" "import" "include"
3294 "line" "pragma" "unassert" "undef" "warning")))
4bb22eea 3295 (setq messages-mode-keywords
f617db13
MW
3296 (append (list (list (concat "^[ \t]*\\#[ \t]*"
3297 "\\(include\\|import\\)"
3298 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
3299 '(2 font-lock-string-face))
3300 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
3301 preprocessor-keywords
852cd5fb 3302 "\\)\\>\\|[0-9]+\\|$\\)\\)")
f617db13 3303 '(1 font-lock-keyword-face)))
4bb22eea 3304 messages-mode-keywords)))
297d60aa 3305 (run-hooks 'cpp-messages-mode-hook))
f617db13 3306
297d60aa
MW
3307(add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
3308(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
f617db13
MW
3309; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
3310
6132bc01
MW
3311;;;--------------------------------------------------------------------------
3312;;; Messages-file mode.
f617db13
MW
3313
3314(defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
3315 "Face to use for subsittution directives.")
3316(make-face 'mallow-driver-substitution-face)
3317(defvar mallow-driver-text-face 'mallow-driver-text-face
3318 "Face to use for body text.")
3319(make-face 'mallow-driver-text-face)
3320
3321(defun mallow-driver-mode ()
3322 (interactive)
3323 (fundamental-mode)
3324 (setq major-mode 'mallow-driver-mode)
3325 (setq mode-name "Mallow driver")
3326 (setq mallow-driver-mode-syntax-table (make-syntax-table))
3327 (set-syntax-table mallow-driver-mode-syntax-table)
3328 (make-local-variable 'comment-start)
3329 (make-local-variable 'comment-end)
3330 (make-local-variable 'indent-line-function)
3331 (setq indent-line-function 'indent-relative)
3332 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
3333 (make-local-variable 'font-lock-defaults)
3334 (make-local-variable 'mallow-driver-mode-keywords)
3335 (let ((keywords
8d6d55b9
MW
3336 (mdw-regexps "each" "divert" "file" "if"
3337 "perl" "set" "string" "type" "write")))
f617db13
MW
3338 (setq mallow-driver-mode-keywords
3339 (list
3340 (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
3341 '(0 font-lock-keyword-face))
3342 (list "^%\\s *\\(#.*\\|\\)$"
3343 '(0 font-lock-comment-face))
3344 (list "^%"
3345 '(0 font-lock-keyword-face))
3346 (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
3347 (list "\\${[^}]*}"
3348 '(0 mallow-driver-substitution-face t)))))
3349 (setq font-lock-defaults
3350 '(mallow-driver-mode-keywords nil nil nil nil))
3351 (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
3352 (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
3353 (setq comment-start "%# ")
3354 (setq comment-end "")
f617db13
MW
3355 (run-hooks 'mallow-driver-mode-hook))
3356
3357(add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
3358
6132bc01
MW
3359;;;--------------------------------------------------------------------------
3360;;; NFast debugs.
f617db13
MW
3361
3362(defun nfast-debug-mode ()
3363 (interactive)
3364 (fundamental-mode)
3365 (setq major-mode 'nfast-debug-mode)
3366 (setq mode-name "NFast debug")
3367 (setq messages-mode-syntax-table (make-syntax-table))
3368 (set-syntax-table messages-mode-syntax-table)
3369 (make-local-variable 'font-lock-defaults)
3370 (make-local-variable 'nfast-debug-mode-keywords)
3371 (setq truncate-lines t)
3372 (setq nfast-debug-mode-keywords
3373 (list
3374 '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
3375 (0 font-lock-keyword-face))
3376 (list (concat "^[ \t]+\\(\\("
3377 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
3378 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
3379 "[ \t]+\\)*"
3380 "[0-9a-fA-F]+\\)[ \t]*$")
3381 '(0 mdw-number-face))
3382 '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
3383 (1 font-lock-keyword-face))
3384 '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
3385 (1 font-lock-warning-face))
3386 '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
3387 (1 nil))
3388 (list (concat "^[ \t]+\\.cmd=[ \t]+"
3389 "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
3390 '(1 font-lock-keyword-face))
3391 '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
3392 '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
3393 '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
3394 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
3395 (setq font-lock-defaults
3396 '(nfast-debug-mode-keywords nil nil nil nil))
f617db13
MW
3397 (run-hooks 'nfast-debug-mode-hook))
3398
6132bc01
MW
3399;;;--------------------------------------------------------------------------
3400;;; Other languages.
f617db13 3401
6132bc01 3402;; Smalltalk.
f617db13
MW
3403
3404(defun mdw-setup-smalltalk ()
3405 (and mdw-auto-indent
3406 (local-set-key "\C-m" 'smalltalk-newline-and-indent))
8a425bd7 3407 (make-local-variable 'mdw-auto-indent)
f617db13
MW
3408 (setq mdw-auto-indent nil)
3409 (local-set-key "\C-i" 'smalltalk-reindent))
3410
3411(defun mdw-fontify-smalltalk ()
02109a0d 3412 (make-local-variable 'font-lock-keywords)
f617db13
MW
3413 (setq font-lock-keywords
3414 (list
f617db13
MW
3415 (list "\\<[A-Z][a-zA-Z0-9]*\\>"
3416 '(0 font-lock-keyword-face))
3417 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
3418 "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
3419 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
3420 '(0 mdw-number-face))
3421 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 3422 '(0 mdw-punct-face)))))
f617db13 3423
6132bc01 3424;; Lispy languages.
f617db13 3425
873d87df
MW
3426;; Unpleasant bodge.
3427(unless (boundp 'slime-repl-mode-map)
3428 (setq slime-repl-mode-map (make-sparse-keymap)))
3429
f617db13
MW
3430(defun mdw-indent-newline-and-indent ()
3431 (interactive)
3432 (indent-for-tab-command)
3433 (newline-and-indent))
3434
3435(eval-after-load "cl-indent"
3436 '(progn
3437 (mapc #'(lambda (pair)
3438 (put (car pair)
3439 'common-lisp-indent-function
3440 (cdr pair)))
3441 '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
3442 (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
3443
3444(defun mdw-common-lisp-indent ()
8a425bd7 3445 (make-local-variable 'lisp-indent-function)
f617db13
MW
3446 (setq lisp-indent-function 'common-lisp-indent-function))
3447
037be6de 3448(setq lisp-simple-loop-indentation 2
95575d1f
MW
3449 lisp-loop-keyword-indentation 6
3450 lisp-loop-forms-indentation 6)
3451
f617db13
MW
3452(defun mdw-fontify-lispy ()
3453
6132bc01 3454 ;; Set fill prefix.
f617db13
MW
3455 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
3456
6132bc01 3457 ;; Not much fontification needed.
02109a0d 3458 (make-local-variable 'font-lock-keywords)
f617db13 3459 (setq font-lock-keywords
2287504f
MW
3460 (list (list (concat "\\("
3461 "\\_<[-+]?"
3462 "\\(" "[0-9]+/[0-9]+"
3463 "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|"
3464 "\\.[0-9]+" "\\)"
3465 "\\([dDeEfFlLsS][-+]?[0-9]+\\)?"
3466 "\\)"
3467 "\\|"
3468 "#"
3469 "\\(" "x" "[-+]?"
3470 "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?"
3471 "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?"
3472 "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?"
3473 "\\|" "[0-9]+" "r" "[-+]?"
3474 "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?"
3475 "\\)"
3476 "\\)\\_>")
3477 '(0 mdw-number-face))
3478 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2e7c6a86 3479 '(0 mdw-punct-face)))))
f617db13
MW
3480
3481(defun comint-send-and-indent ()
3482 (interactive)
3483 (comint-send-input)
3484 (and mdw-auto-indent
3485 (indent-for-tab-command)))
3486
ec007bea 3487(defun mdw-setup-m4 ()
ed5d93a4
MW
3488
3489 ;; Inexplicably, Emacs doesn't match braces in m4 mode. This is very
3490 ;; annoying: fix it.
3491 (modify-syntax-entry ?{ "(")
3492 (modify-syntax-entry ?} ")")
3493
3494 ;; Fill prefix.
ec007bea
MW
3495 (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
3496
6132bc01
MW
3497;;;--------------------------------------------------------------------------
3498;;; Text mode.
f617db13
MW
3499
3500(defun mdw-text-mode ()
3501 (setq fill-column 72)
3502 (flyspell-mode t)
3503 (mdw-standard-fill-prefix
c7a8da49 3504 "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
f617db13
MW
3505 (auto-fill-mode 1))
3506
6132bc01 3507;;;--------------------------------------------------------------------------
faf2cef7 3508;;; Outline and hide/show modes.
5de5db48
MW
3509
3510(defun mdw-outline-collapse-all ()
3511 "Completely collapse everything in the entire buffer."
3512 (interactive)
3513 (save-excursion
3514 (goto-char (point-min))
3515 (while (< (point) (point-max))
3516 (hide-subtree)
3517 (forward-line))))
3518
faf2cef7
MW
3519(setq hs-hide-comments-when-hiding-all nil)
3520
b200af26 3521(defadvice hs-hide-all (after hide-first-comment activate)
941c29ba 3522 (save-excursion (hs-hide-initial-comment-block)))
b200af26 3523
6132bc01
MW
3524;;;--------------------------------------------------------------------------
3525;;; Shell mode.
f617db13
MW
3526
3527(defun mdw-sh-mode-setup ()
3528 (local-set-key [?\C-a] 'comint-bol)
3529 (add-hook 'comint-output-filter-functions
3530 'comint-watch-for-password-prompt))
3531
3532(defun mdw-term-mode-setup ()
3d9147ea 3533 (setq term-prompt-regexp shell-prompt-pattern)
f617db13
MW
3534 (make-local-variable 'mouse-yank-at-point)
3535 (make-local-variable 'transient-mark-mode)
3536 (setq mouse-yank-at-point t)
f617db13
MW
3537 (auto-fill-mode -1)
3538 (setq tab-width 8))
3539
3d9147ea
MW
3540(defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
3541(defun term-send-meta-left () (interactive) (term-send-raw-string "\e\e[D"))
3542(defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
3543(defun term-send-meta-meta-something ()
3544 (interactive)
3545 (term-send-raw-string "\e\e")
3546 (term-send-raw))
3547(eval-after-load 'term
3548 '(progn
3549 (define-key term-raw-map [?\e ?\e] nil)
3550 (define-key term-raw-map [?\e ?\e t] 'term-send-meta-meta-something)
3551 (define-key term-raw-map [?\C-/] 'term-send-ctrl-uscore)
3552 (define-key term-raw-map [M-right] 'term-send-meta-right)
3553 (define-key term-raw-map [?\e ?\M-O ?C] 'term-send-meta-right)
3554 (define-key term-raw-map [M-left] 'term-send-meta-left)
3555 (define-key term-raw-map [?\e ?\M-O ?D] 'term-send-meta-left)))
3556
c4434c20
MW
3557(defadvice term-exec (before program-args-list compile activate)
3558 "If the PROGRAM argument is a list, interpret it as (PROGRAM . SWITCHES).
3559This allows you to pass a list of arguments through `ansi-term'."
3560 (let ((program (ad-get-arg 2)))
3561 (if (listp program)
3562 (progn
3563 (ad-set-arg 2 (car program))
3564 (ad-set-arg 4 (cdr program))))))
3565
3566(defun ssh (host)
3567 "Open a terminal containing an ssh session to the HOST."
3568 (interactive "sHost: ")
3569 (ansi-term (list "ssh" host) (format "ssh@%s" host)))
3570
5aa1b95f
MW
3571(defvar git-grep-command
3572 "env PAGER=cat git grep --no-color -nH -e "
3573 "*The default command for \\[git-grep].")
3574
3575(defvar git-grep-history nil)
3576
3577(defun git-grep (command-args)
3578 "Run `git grep' with user-specified args and collect output in a buffer."
3579 (interactive
3580 (list (read-shell-command "Run git grep (like this): "
3581 git-grep-command 'git-grep-history)))
3582 (grep command-args))
3583
e07e3320
MW
3584;;;--------------------------------------------------------------------------
3585;;; Inferior Emacs Lisp.
3586
3587(setq comint-prompt-read-only t)
3588
3589(eval-after-load "comint"
3590 '(progn
3591 (define-key comint-mode-map "\C-w" 'comint-kill-region)
3592 (define-key comint-mode-map [C-S-backspace] 'comint-kill-whole-line)))
3593
3594(eval-after-load "ielm"
3595 '(progn
3596 (define-key ielm-map "\C-w" 'comint-kill-region)
3597 (define-key ielm-map [C-S-backspace] 'comint-kill-whole-line)))
3598
f617db13
MW
3599;;;----- That's all, folks --------------------------------------------------
3600
3601(provide 'dot-emacs)