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