chiark / gitweb /
el/dot-emacs.el: Load ERC configuration in advance.
[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
6132bc01 55;; Some error trapping.
f617db13
MW
56;;
57;; If individual bits of this file go tits-up, we don't particularly want
58;; the whole lot to stop right there and then, because it's bloody annoying.
59
60(defmacro trap (&rest forms)
61 "Execute FORMS without allowing errors to propagate outside."
9e789ed5
MW
62 (declare (indent 0)
63 (debug t))
f617db13
MW
64 `(condition-case err
65 ,(if (cdr forms) (cons 'progn forms) (car forms))
8df912e4
MW
66 (error (message "Error (trapped): %s in %s"
67 (error-message-string err)
68 ',forms))))
f617db13 69
6132bc01 70;; Configuration reading.
f141fe0f
MW
71
72(defvar mdw-config nil)
73(defun mdw-config (sym)
74 "Read the configuration variable named SYM."
75 (unless mdw-config
daff679f
MW
76 (setq mdw-config
77 (flet ((replace (what with)
78 (goto-char (point-min))
79 (while (re-search-forward what nil t)
80 (replace-match with t))))
81 (with-temp-buffer
82 (insert-file-contents "~/.mdw.conf")
83 (replace "^[ \t]*\\(#.*\\|\\)\n" "")
84 (replace (concat "^[ \t]*"
85 "\\([-a-zA-Z0-9_.]*\\)"
86 "[ \t]*=[ \t]*"
87 "\\(.*[^ \t\n]\\|\\)"
88 "[ \t]**\\(\n\\|$\\)")
89 "(\\1 . \"\\2\")\n")
90 (car (read-from-string
91 (concat "(" (buffer-string) ")")))))))
f141fe0f
MW
92 (cdr (assq sym mdw-config)))
93
6132bc01 94;; Set up the load path convincingly.
eac7b622
MW
95
96(dolist (dir (append (and (boundp 'debian-emacs-flavor)
97 (list (concat "/usr/share/"
98 (symbol-name debian-emacs-flavor)
99 "/site-lisp")))))
100 (dolist (sub (directory-files dir t))
101 (when (and (file-accessible-directory-p sub)
102 (not (member sub load-path)))
103 (setq load-path (nconc load-path (list sub))))))
104
6132bc01 105;; Is an Emacs library available?
cb6e2cd1
MW
106
107(defun library-exists-p (name)
6132bc01
MW
108 "Return non-nil if NAME is an available library.
109Return non-nil if NAME.el (or NAME.elc) somewhere on the Emacs
110load path. The non-nil value is the filename we found for the
111library."
cb6e2cd1
MW
112 (let ((path load-path) elt (foundp nil))
113 (while (and path (not foundp))
114 (setq elt (car path))
115 (setq path (cdr path))
116 (setq foundp (or (let ((file (concat elt "/" name ".elc")))
117 (and (file-exists-p file) file))
118 (let ((file (concat elt "/" name ".el")))
119 (and (file-exists-p file) file)))))
120 foundp))
121
122(defun maybe-autoload (symbol file &optional docstring interactivep type)
123 "Set an autoload if the file actually exists."
124 (and (library-exists-p file)
125 (autoload symbol file docstring interactivep type)))
126
6132bc01 127;; Splitting windows.
f617db13 128
8c2b05d5
MW
129(unless (fboundp 'scroll-bar-columns)
130 (defun scroll-bar-columns (side)
131 (cond ((eq side 'left) 0)
132 (window-system 3)
133 (t 1))))
134(unless (fboundp 'fringe-columns)
135 (defun fringe-columns (side)
136 (cond ((not window-system) 0)
137 ((eq side 'left) 1)
138 (t 2))))
139
3ba0b777
MW
140(defun mdw-horizontal-window-overhead ()
141 "Computes the horizontal window overhead.
142This is the number of columns used by fringes, scroll bars and other such
143cruft."
144 (if (not window-system)
145 1
146 (let ((tot 0))
147 (dolist (what '(scroll-bar fringe))
148 (dolist (side '(left right))
149 (incf tot (funcall (intern (concat (symbol-name what) "-columns"))
150 side))))
151 tot)))
152
153(defun mdw-split-window-horizontally (&optional width)
154 "Split a window horizontally.
155Without a numeric argument, split the window approximately in
156half. With a numeric argument WIDTH, allocate WIDTH columns to
157the left-hand window (if positive) or -WIDTH columns to the
158right-hand window (if negative). Space for scroll bars and
159fringes is not taken out of the allowance for WIDTH, unlike
160\\[split-window-horizontally]."
161 (interactive "P")
162 (split-window-horizontally
163 (cond ((null width) nil)
164 ((>= width 0) (+ width (mdw-horizontal-window-overhead)))
165 ((< width 0) width))))
166
8c2b05d5 167(defun mdw-divvy-window (&optional width)
f617db13 168 "Split a wide window into appropriate widths."
8c2b05d5
MW
169 (interactive "P")
170 (setq width (cond (width (prefix-numeric-value width))
171 ((and window-system
172 (>= emacs-major-version 22))
173 77)
174 (t 78)))
b5d724dd 175 (let* ((win (selected-window))
3ba0b777 176 (sb-width (mdw-horizontal-window-overhead))
b5d724dd 177 (c (/ (+ (window-width) sb-width)
8c2b05d5 178 (+ width sb-width))))
f617db13
MW
179 (while (> c 1)
180 (setq c (1- c))
8c2b05d5 181 (split-window-horizontally (+ width sb-width))
f617db13
MW
182 (other-window 1))
183 (select-window win)))
184
c4b18360
MW
185;; Transient mark mode hacks.
186
187(defadvice exchange-point-and-mark
188 (around mdw-highlight (&optional arg) activate compile)
189 "Maybe don't actually exchange point and mark.
190If `transient-mark-mode' is on and the mark is inactive, then
191just activate it. A non-trivial prefix argument will force the
192usual behaviour. A trivial prefix argument (i.e., just C-u) will
193activate the mark and temporarily enable `transient-mark-mode' if
194it's currently off."
195 (cond ((or mark-active
196 (and (not transient-mark-mode) (not arg))
197 (and arg (or (not (consp arg))
198 (not (= (car arg) 4)))))
199 ad-do-it)
200 (t
201 (or transient-mark-mode (setq transient-mark-mode 'only))
202 (set-mark (mark t)))))
203
6132bc01 204;; Functions for sexp diary entries.
f617db13
MW
205
206(defun mdw-weekday (l)
207 "Return non-nil if `date' falls on one of the days of the week in L.
6132bc01
MW
208L is a list of day numbers (from 0 to 6 for Sunday through to
209Saturday) or symbols `sunday', `monday', etc. (or a mixture). If
210the date stored in `date' falls on a listed day, then the
211function returns non-nil."
f617db13
MW
212 (let ((d (calendar-day-of-week date)))
213 (or (memq d l)
214 (memq (nth d '(sunday monday tuesday wednesday
215 thursday friday saturday)) l))))
216
217(defun mdw-todo (&optional when)
218 "Return non-nil today, or on WHEN, whichever is later."
219 (let ((w (calendar-absolute-from-gregorian (calendar-current-date)))
220 (d (calendar-absolute-from-gregorian date)))
221 (if when
222 (setq w (max w (calendar-absolute-from-gregorian
223 (cond
224 ((not european-calendar-style)
225 when)
226 ((> (car when) 100)
227 (list (nth 1 when)
228 (nth 2 when)
229 (nth 0 when)))
230 (t
231 (list (nth 1 when)
232 (nth 0 when)
233 (nth 2 when))))))))
234 (eq w d)))
235
6132bc01 236;; Fighting with Org-mode's evil key maps.
16fe7c41
MW
237
238(defvar mdw-evil-keymap-keys
239 '(([S-up] . [?\C-c up])
240 ([S-down] . [?\C-c down])
241 ([S-left] . [?\C-c left])
242 ([S-right] . [?\C-c right])
243 (([M-up] [?\e up]) . [C-up])
244 (([M-down] [?\e down]) . [C-down])
245 (([M-left] [?\e left]) . [C-left])
246 (([M-right] [?\e right]) . [C-right]))
247 "Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
248The value is an alist mapping evil keys (as a list, or singleton)
249to good keys (in the same form).")
250
251(defun mdw-clobber-evil-keymap (keymap)
252 "Replace evil key bindings in the KEYMAP.
253Evil key bindings are defined in `mdw-evil-keymap-keys'."
254 (dolist (entry mdw-evil-keymap-keys)
255 (let ((binding nil)
256 (keys (if (listp (car entry))
257 (car entry)
258 (list (car entry))))
259 (replacements (if (listp (cdr entry))
260 (cdr entry)
261 (list (cdr entry)))))
262 (catch 'found
263 (dolist (key keys)
264 (setq binding (lookup-key keymap key))
265 (when binding
266 (throw 'found nil))))
267 (when binding
268 (dolist (key keys)
269 (define-key keymap key nil))
270 (dolist (key replacements)
271 (define-key keymap key binding))))))
272
0f6be0b1 273(eval-after-load "org-latex"
f0dbee84
MW
274 '(progn
275 (push '("strayman"
276 "\\documentclass{strayman}
277\\usepackage[utf8]{inputenc}
278\\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
279\\usepackage[T1]{fontenc}
280\\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
281 ("\\section{%s}" . "\\section*{%s}")
282 ("\\subsection{%s}" . "\\subsection*{%s}")
283 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
284 ("\\paragraph{%s}" . "\\paragraph*{%s}")
285 ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
286 org-export-latex-classes)))
287
6132bc01
MW
288;;;--------------------------------------------------------------------------
289;;; Mail and news hacking.
a3bdb4d9
MW
290
291(define-derived-mode mdwmail-mode mail-mode "[mdw] mail"
6132bc01 292 "Major mode for editing news and mail messages from external programs.
a3bdb4d9
MW
293Not much right now. Just support for doing MailCrypt stuff."
294 :syntax-table nil
295 :abbrev-table nil
296 (run-hooks 'mail-setup-hook))
297
298(define-key mdwmail-mode-map [?\C-c ?\C-c] 'disabled-operation)
299
300(add-hook 'mdwail-mode-hook
301 (lambda ()
302 (set-buffer-file-coding-system 'utf-8)
303 (make-local-variable 'paragraph-separate)
304 (make-local-variable 'paragraph-start)
305 (setq paragraph-start
306 (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
307 paragraph-start))
308 (setq paragraph-separate
309 (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
310 paragraph-separate))))
311
6132bc01 312;; How to encrypt in mdwmail.
a3bdb4d9
MW
313
314(defun mdwmail-mc-encrypt (&optional recip scm start end from sign)
315 (or start
316 (setq start (save-excursion
317 (goto-char (point-min))
318 (or (search-forward "\n\n" nil t) (point-min)))))
319 (or end
320 (setq end (point-max)))
321 (mc-encrypt-generic recip scm start end from sign))
322
6132bc01 323;; How to sign in mdwmail.
a3bdb4d9
MW
324
325(defun mdwmail-mc-sign (key scm start end uclr)
326 (or start
327 (setq start (save-excursion
328 (goto-char (point-min))
329 (or (search-forward "\n\n" nil t) (point-min)))))
330 (or end
331 (setq end (point-max)))
332 (mc-sign-generic key scm start end uclr))
333
6132bc01 334;; Some signature mangling.
a3bdb4d9
MW
335
336(defun mdwmail-mangle-signature ()
337 (save-excursion
338 (goto-char (point-min))
339 (perform-replace "\n-- \n" "\n-- " nil nil nil)))
340(add-hook 'mail-setup-hook 'mdwmail-mangle-signature)
341(add-hook 'message-setup-hook 'mdwmail-mangle-signature)
342
6132bc01 343;; Insert my login name into message-ids, so I can score replies.
a3bdb4d9
MW
344
345(defadvice message-unique-id (after mdw-user-name last activate compile)
346 "Ensure that the user's name appears at the end of the message-id string,
347so that it can be used for convenient filtering."
348 (setq ad-return-value (concat ad-return-value "." (user-login-name))))
349
6132bc01 350;; Tell my movemail hack where movemail is.
a3bdb4d9
MW
351;;
352;; This is needed to shup up warnings about LD_PRELOAD.
353
354(let ((path exec-path))
355 (while path
356 (let ((try (expand-file-name "movemail" (car path))))
357 (if (file-executable-p try)
358 (setenv "REAL_MOVEMAIL" try))
359 (setq path (cdr path)))))
360
d17c6756
MW
361(eval-after-load "erc"
362 '(load "~/.ercrc.el"))
363
6132bc01
MW
364;;;--------------------------------------------------------------------------
365;;; Utility functions.
f617db13 366
b5d724dd
MW
367(or (fboundp 'line-number-at-pos)
368 (defun line-number-at-pos (&optional pos)
369 (let ((opoint (or pos (point))) start)
370 (save-excursion
371 (save-restriction
372 (goto-char (point-min))
373 (widen)
374 (forward-line 0)
375 (setq start (point))
376 (goto-char opoint)
377 (forward-line 0)
378 (1+ (count-lines 1 (point))))))))
459c9fb2 379
f617db13 380(defun mdw-uniquify-alist (&rest alists)
f617db13 381 "Return the concatenation of the ALISTS with duplicate elements removed.
6132bc01
MW
382The first association with a given key prevails; others are
383ignored. The input lists are not modified, although they'll
384probably become garbage."
f617db13
MW
385 (and alists
386 (let ((start-list (cons nil nil)))
387 (mdw-do-uniquify start-list
388 start-list
389 (car alists)
390 (cdr alists)))))
391
f617db13 392(defun mdw-do-uniquify (done end l rest)
6132bc01
MW
393 "A helper function for mdw-uniquify-alist.
394The DONE argument is a list whose first element is `nil'. It
395contains the uniquified alist built so far. The leading `nil' is
396stripped off at the end of the operation; it's only there so that
397DONE always references a cons cell. END refers to the final cons
398cell in the DONE list; it is modified in place each time to avoid
399the overheads of `append'ing all the time. The L argument is the
400alist we're currently processing; the remaining alists are given
401in REST."
402
403 ;; There are several different cases to deal with here.
f617db13
MW
404 (cond
405
6132bc01
MW
406 ;; Current list isn't empty. Add the first item to the DONE list if
407 ;; there's not an item with the same KEY already there.
f617db13
MW
408 (l (or (assoc (car (car l)) done)
409 (progn
410 (setcdr end (cons (car l) nil))
411 (setq end (cdr end))))
412 (mdw-do-uniquify done end (cdr l) rest))
413
6132bc01
MW
414 ;; The list we were working on is empty. Shunt the next list into the
415 ;; current list position and go round again.
f617db13
MW
416 (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
417
6132bc01
MW
418 ;; Everything's done. Remove the leading `nil' from the DONE list and
419 ;; return it. Finished!
f617db13
MW
420 (t (cdr done))))
421
f617db13
MW
422(defun date ()
423 "Insert the current date in a pleasing way."
424 (interactive)
425 (insert (save-excursion
426 (let ((buffer (get-buffer-create "*tmp*")))
427 (unwind-protect (progn (set-buffer buffer)
428 (erase-buffer)
429 (shell-command "date +%Y-%m-%d" t)
430 (goto-char (mark))
431 (delete-backward-char 1)
432 (buffer-string))
433 (kill-buffer buffer))))))
434
f617db13
MW
435(defun uuencode (file &optional name)
436 "UUencodes a file, maybe calling it NAME, into the current buffer."
437 (interactive "fInput file name: ")
438
6132bc01 439 ;; If NAME isn't specified, then guess from the filename.
f617db13
MW
440 (if (not name)
441 (setq name
442 (substring file
443 (or (string-match "[^/]*$" file) 0))))
f617db13
MW
444 (print (format "uuencode `%s' `%s'" file name))
445
6132bc01 446 ;; Now actually do the thing.
f617db13
MW
447 (call-process "uuencode" file t nil name))
448
449(defvar np-file "~/.np"
450 "*Where the `now-playing' file is.")
451
452(defun np (&optional arg)
453 "Grabs a `now-playing' string."
454 (interactive)
455 (save-excursion
456 (or arg (progn
852cd5fb 457 (goto-char (point-max))
f617db13 458 (insert "\nNP: ")
daff679f 459 (insert-file-contents np-file)))))
f617db13 460
ae7460d4
MW
461(defun mdw-version-< (ver-a ver-b)
462 "Answer whether VER-A is strictly earlier than VER-B.
463VER-A and VER-B are version numbers, which are strings containing digit
464sequences separated by `.'."
465 (let* ((la (mapcar (lambda (x) (car (read-from-string x)))
466 (split-string ver-a "\\.")))
467 (lb (mapcar (lambda (x) (car (read-from-string x)))
468 (split-string ver-b "\\."))))
469 (catch 'done
470 (while t
471 (cond ((null la) (throw 'done lb))
472 ((null lb) (throw 'done nil))
473 ((< (car la) (car lb)) (throw 'done t))
474 ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb))))))))
475
c7a8da49 476(defun mdw-check-autorevert ()
6132bc01
MW
477 "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
478This takes into consideration whether it's been found using
479tramp, which seems to get itself into a twist."
46e69f55
MW
480 (cond ((not (boundp 'global-auto-revert-ignore-buffer))
481 nil)
482 ((and (buffer-file-name)
483 (fboundp 'tramp-tramp-file-p)
c7a8da49
MW
484 (tramp-tramp-file-p (buffer-file-name)))
485 (unless global-auto-revert-ignore-buffer
486 (setq global-auto-revert-ignore-buffer 'tramp)))
487 ((eq global-auto-revert-ignore-buffer 'tramp)
488 (setq global-auto-revert-ignore-buffer nil))))
489
490(defadvice find-file (after mdw-autorevert activate)
491 (mdw-check-autorevert))
492(defadvice write-file (after mdw-autorevert activate)
4d9f2d65 493 (mdw-check-autorevert))
eae0aa6d 494
6132bc01
MW
495;;;--------------------------------------------------------------------------
496;;; Dired hacking.
5195cbc3
MW
497
498(defadvice dired-maybe-insert-subdir
499 (around mdw-marked-insertion first activate)
6132bc01
MW
500 "The DIRNAME may be a list of directory names to insert.
501Interactively, if files are marked, then insert all of them.
502With a numeric prefix argument, select that many entries near
503point; with a non-numeric prefix argument, prompt for listing
504options."
5195cbc3
MW
505 (interactive
506 (list (dired-get-marked-files nil
507 (and (integerp current-prefix-arg)
508 current-prefix-arg)
509 #'file-directory-p)
510 (and current-prefix-arg
511 (not (integerp current-prefix-arg))
512 (read-string "Switches for listing: "
513 (or dired-subdir-switches
514 dired-actual-switches)))))
515 (let ((dirs (ad-get-arg 0)))
516 (dolist (dir (if (listp dirs) dirs (list dirs)))
517 (ad-set-arg 0 dir)
518 ad-do-it)))
519
6132bc01
MW
520;;;--------------------------------------------------------------------------
521;;; URL viewing.
a203fba8
MW
522
523(defun mdw-w3m-browse-url (url &optional new-session-p)
524 "Invoke w3m on the URL in its current window, or at least a different one.
525If NEW-SESSION-P, start a new session."
526 (interactive "sURL: \nP")
527 (save-excursion
63fb20c1
MW
528 (let ((window (selected-window)))
529 (unwind-protect
530 (progn
531 (select-window (or (and (not new-session-p)
532 (get-buffer-window "*w3m*"))
533 (progn
534 (if (one-window-p t) (split-window))
535 (get-lru-window))))
536 (w3m-browse-url url new-session-p))
537 (select-window window)))))
a203fba8
MW
538
539(defvar mdw-good-url-browsers
ed5e20a5
MW
540 '(browse-url-generic
541 (w3m . mdw-w3m-browse-url)
a203fba8
MW
542 browse-url-w3
543 browse-url-mozilla)
6132bc01
MW
544 "List of good browsers for mdw-good-url-browsers.
545Each item is a browser function name, or a cons (CHECK . FUNC).
546A symbol FOO stands for (FOO . FOO).")
a203fba8
MW
547
548(defun mdw-good-url-browser ()
6132bc01
MW
549 "Return a good URL browser.
550Trundle the list of such things, finding the first item for which
551CHECK is fboundp, and returning the correponding FUNC."
a203fba8
MW
552 (let ((bs mdw-good-url-browsers) b check func answer)
553 (while (and bs (not answer))
554 (setq b (car bs)
555 bs (cdr bs))
556 (if (consp b)
557 (setq check (car b) func (cdr b))
558 (setq check b func b))
559 (if (fboundp check)
560 (setq answer func)))
561 answer))
562
f36cdb77
MW
563(eval-after-load "w3m-search"
564 '(progn
565 (dolist
566 (item
567 '(("g" "Google" "http://www.google.co.uk/search?q=%s")
568 ("gd" "Google Directory"
569 "http://www.google.com/search?cat=gwd/Top&q=%s")
570 ("gg" "Google Groups" "http://groups.google.com/groups?q=%s")
571 ("ward" "Ward's wiki" "http://c2.com/cgi/wiki?%s")
572 ("gi" "Images" "http://images.google.com/images?q=%s")
573 ("rfc" "RFC"
574 "http://metalzone.distorted.org.uk/ftp/pub/mirrors/rfc/rfc%s.txt.gz")
575 ("wp" "Wikipedia"
576 "http://en.wikipedia.org/wiki/Special:Search?go=Go&search=%s")
577 ("imdb" "IMDb" "http://www.imdb.com/Find?%s")
578 ("nc-wiki" "nCipher wiki"
579 "http://wiki.ncipher.com/wiki/bin/view/Devel/?topic=%s")
580 ("map" "Google maps" "http://maps.google.co.uk/maps?q=%s&hl=en")
581 ("lp" "Launchpad bug by number"
582 "https://bugs.launchpad.net/bugs/%s")
583 ("lppkg" "Launchpad bugs by package"
584 "https://bugs.launchpad.net/%s")
585 ("msdn" "MSDN"
586 "http://social.msdn.microsoft.com/Search/en-GB/?query=%s&ac=8")
587 ("debbug" "Debian bug by number"
588 "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s")
589 ("debbugpkg" "Debian bugs by package"
590 "http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=%s")
591 ("ljlogin" "LJ login" "http://www.livejournal.com/login.bml")))
592 (add-to-list 'w3m-search-engine-alist
593 (list (cadr item) (caddr item) nil))
594 (add-to-list 'w3m-uri-replace-alist
595 (list (concat "\\`" (car item) ":")
596 'w3m-search-uri-replace
597 (cadr item))))))
598
6132bc01
MW
599;;;--------------------------------------------------------------------------
600;;; Paragraph filling.
f617db13 601
6132bc01 602;; Useful variables.
f617db13
MW
603
604(defvar mdw-fill-prefix nil
6132bc01
MW
605 "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
606If there's no fill prefix currently set (by the `fill-prefix'
607variable) and there's a match from one of the regexps here, it
608gets used to set the fill-prefix for the current operation.
f617db13 609
6132bc01
MW
610The variable is a list of items of the form `REGEXP . PREFIX'; if
611the REGEXP matches, the PREFIX is used to set the fill prefix.
612It in turn is a list of things:
f617db13
MW
613
614 STRING -- insert a literal string
615 (match . N) -- insert the thing matched by bracketed subexpression N
616 (pad . N) -- a string of whitespace the same width as subexpression N
617 (expr . FORM) -- the result of evaluating FORM")
618
619(make-variable-buffer-local 'mdw-fill-prefix)
620
621(defvar mdw-hanging-indents
10fa2414 622 (concat "\\(\\("
f8bfe560 623 "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
10fa2414
MW
624 "[ \t]+"
625 "\\)?\\)")
6132bc01
MW
626 "*Standard regexp matching parts of a hanging indent.
627This is mainly useful in `auto-fill-mode'.")
f617db13 628
6132bc01 629;; Setting things up.
f617db13
MW
630
631(fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
632
6132bc01 633;; Utility functions.
f617db13
MW
634
635(defun mdw-tabify (s)
636 "Tabify the string S. This is a horrid hack."
637 (save-excursion
638 (save-match-data
639 (let (start end)
640 (beginning-of-line)
641 (setq start (point-marker))
642 (insert s "\n")
643 (setq end (point-marker))
644 (tabify start end)
645 (setq s (buffer-substring start (1- end)))
646 (delete-region start end)
647 (set-marker start nil)
648 (set-marker end nil)
649 s))))
650
651(defun mdw-examine-fill-prefixes (l)
6132bc01
MW
652 "Given a list of dynamic fill prefixes, pick one which matches
653context and return the static fill prefix to use. Point must be
654at the start of a line, and match data must be saved."
f617db13
MW
655 (cond ((not l) nil)
656 ((looking-at (car (car l)))
657 (mdw-tabify (apply (function concat)
658 (mapcar (function mdw-do-prefix-match)
659 (cdr (car l))))))
660 (t (mdw-examine-fill-prefixes (cdr l)))))
661
662(defun mdw-maybe-car (p)
663 "If P is a pair, return (car P), otherwise just return P."
664 (if (consp p) (car p) p))
665
666(defun mdw-padding (s)
667 "Return a string the same width as S but made entirely from whitespace."
668 (let* ((l (length s)) (i 0) (n (make-string l ? )))
669 (while (< i l)
670 (if (= 9 (aref s i))
671 (aset n i 9))
672 (setq i (1+ i)))
673 n))
674
675(defun mdw-do-prefix-match (m)
6132bc01
MW
676 "Expand a dynamic prefix match element.
677See `mdw-fill-prefix' for details."
f617db13
MW
678 (cond ((not (consp m)) (format "%s" m))
679 ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
680 ((eq (car m) 'pad) (mdw-padding (match-string
681 (mdw-maybe-car (cdr m)))))
682 ((eq (car m) 'eval) (eval (cdr m)))
683 (t "")))
684
685(defun mdw-choose-dynamic-fill-prefix ()
686 "Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
687 (cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
688 ((not mdw-fill-prefix) fill-prefix)
689 (t (save-excursion
690 (beginning-of-line)
691 (save-match-data
692 (mdw-examine-fill-prefixes mdw-fill-prefix))))))
693
694(defun do-auto-fill ()
6132bc01
MW
695 "Handle auto-filling, working out a dynamic fill prefix in the
696case where there isn't a sensible static one."
f617db13
MW
697 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
698 (mdw-do-auto-fill)))
699
700(defun mdw-fill-paragraph ()
701 "Fill paragraph, getting a dynamic fill prefix."
702 (interactive)
703 (let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
704 (fill-paragraph nil)))
705
706(defun mdw-standard-fill-prefix (rx &optional mat)
707 "Set the dynamic fill prefix, handling standard hanging indents and stuff.
6132bc01
MW
708This is just a short-cut for setting the thing by hand, and by
709design it doesn't cope with anything approximating a complicated
710case."
f617db13
MW
711 (setq mdw-fill-prefix
712 `((,(concat rx mdw-hanging-indents)
713 (match . 1)
714 (pad . ,(or mat 2))))))
715
6132bc01
MW
716;;;--------------------------------------------------------------------------
717;;; Other common declarations.
f617db13 718
6132bc01 719;; Common mode settings.
f617db13
MW
720
721(defvar mdw-auto-indent t
722 "Whether to indent automatically after a newline.")
723
0e58a7c2
MW
724(defun mdw-whitespace-mode (&optional arg)
725 "Turn on/off whitespace mode, but don't highlight trailing space."
726 (interactive "P")
727 (when (and (boundp 'whitespace-style)
728 (fboundp 'whitespace-mode))
729 (let ((whitespace-style (remove 'trailing whitespace-style)))
558fc014
MW
730 (whitespace-mode arg))
731 (setq show-trailing-whitespace whitespace-mode)))
0e58a7c2 732
f617db13
MW
733(defun mdw-misc-mode-config ()
734 (and mdw-auto-indent
735 (cond ((eq major-mode 'lisp-mode)
736 (local-set-key "\C-m" 'mdw-indent-newline-and-indent))
30c8a8fb
MW
737 ((or (eq major-mode 'slime-repl-mode)
738 (eq major-mode 'asm-mode))
739 nil)
f617db13
MW
740 (t
741 (local-set-key "\C-m" 'newline-and-indent))))
742 (local-set-key [C-return] 'newline)
8a425bd7 743 (make-local-variable 'page-delimiter)
8cb7626b 744 (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
f617db13
MW
745 (setq comment-column 40)
746 (auto-fill-mode 1)
747 (setq fill-column 77)
473ff3b0 748 (setq show-trailing-whitespace t)
0e58a7c2 749 (mdw-whitespace-mode 1)
253f61b4
MW
750 (and (fboundp 'gtags-mode)
751 (gtags-mode))
ddf6e116
MW
752 (if (fboundp 'hs-minor-mode)
753 (hs-minor-mode t)
754 (outline-minor-mode t))
49b2646e 755 (reveal-mode t)
1e7a9479 756 (trap (turn-on-font-lock)))
f617db13 757
ed7b46b9 758(defun mdw-post-config-mode-hack ()
0e58a7c2 759 (mdw-whitespace-mode 1))
ed7b46b9 760
253f61b4 761(eval-after-load 'gtags
506bada9
MW
762 '(progn
763 (dolist (key '([mouse-2] [mouse-3]))
764 (define-key gtags-mode-map key nil))
765 (define-key gtags-mode-map [C-S-mouse-2] 'gtags-find-tag-by-event)
766 (define-key gtags-select-mode-map [C-S-mouse-2]
767 'gtags-select-tag-by-event)
768 (dolist (map (list gtags-mode-map gtags-select-mode-map))
769 (define-key map [C-S-mouse-3] 'gtags-pop-stack))))
253f61b4 770
6132bc01 771;; Backup file handling.
2ae647c4
MW
772
773(defvar mdw-backup-disable-regexps nil
6132bc01
MW
774 "*List of regular expressions: if a file name matches any of
775these then the file is not backed up.")
2ae647c4
MW
776
777(defun mdw-backup-enable-predicate (name)
6132bc01
MW
778 "[mdw]'s default backup predicate.
779Allows a backup if the standard predicate would allow it, and it
780doesn't match any of the regular expressions in
781`mdw-backup-disable-regexps'."
2ae647c4
MW
782 (and (normal-backup-enable-predicate name)
783 (let ((answer t) (list mdw-backup-disable-regexps))
784 (save-match-data
785 (while list
786 (if (string-match (car list) name)
787 (setq answer nil))
788 (setq list (cdr list)))
789 answer))))
790(setq backup-enable-predicate 'mdw-backup-enable-predicate)
791
7bb78c67
MW
792;; Frame cleanup.
793
794(defun mdw-last-one-out-turn-off-the-lights (frame)
795 "Disconnect from an X display if this was the last frame on that display."
796 (let ((frame-display (frame-parameter frame 'display)))
797 (when (and frame-display
798 (eq window-system 'x)
799 (not (some (lambda (fr)
7bb78c67 800 (and (not (eq fr frame))
a04d8f3d 801 (string= (frame-parameter fr 'display)
d70716b5 802 frame-display)))
7bb78c67 803 (frame-list))))
7bb78c67
MW
804 (run-with-idle-timer 0 nil #'x-close-connection frame-display))))
805(add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
806
6132bc01
MW
807;;;--------------------------------------------------------------------------
808;;; General fontification.
f617db13 809
1e7a9479
MW
810(defmacro mdw-define-face (name &rest body)
811 "Define a face, and make sure it's actually set as the definition."
812 (declare (indent 1)
813 (debug 0))
814 `(progn
815 (make-face ',name)
816 (defvar ,name ',name)
817 (put ',name 'face-defface-spec ',body)
88cb9c2b 818 (face-spec-set ',name ',body nil)))
1e7a9479
MW
819
820(mdw-define-face default
821 (((type w32)) :family "courier new" :height 85)
822 (((type x)) :family "6x13" :height 130)
db10ce0a
MW
823 (((type color)) :foreground "white" :background "black")
824 (t nil))
1e7a9479
MW
825(mdw-define-face fixed-pitch
826 (((type w32)) :family "courier new" :height 85)
827 (((type x)) :family "6x13" :height 130)
828 (t :foreground "white" :background "black"))
c383eb8a
MW
829(if (>= emacs-major-version 23)
830 (mdw-define-face variable-pitch
831 (((type x)) :family "sans" :height 100))
832 (mdw-define-face variable-pitch
3f001ff6 833 (((type x)) :family "helvetica" :height 90)))
1e7a9479 834(mdw-define-face region
db10ce0a
MW
835 (((type tty) (class color)) :background "blue")
836 (((type tty) (class mono)) :inverse-video t)
837 (t :background "grey30"))
1e7a9479
MW
838(mdw-define-face minibuffer-prompt
839 (t :weight bold))
840(mdw-define-face mode-line
db10ce0a
MW
841 (((class color)) :foreground "blue" :background "yellow"
842 :box (:line-width 1 :style released-button))
843 (t :inverse-video t))
1e7a9479 844(mdw-define-face mode-line-inactive
db10ce0a
MW
845 (((class color)) :foreground "yellow" :background "blue"
846 :box (:line-width 1 :style released-button))
847 (t :inverse-video t))
1e7a9479
MW
848(mdw-define-face scroll-bar
849 (t :foreground "black" :background "lightgrey"))
850(mdw-define-face fringe
851 (t :foreground "yellow"))
c383eb8a 852(mdw-define-face show-paren-match
db10ce0a
MW
853 (((class color)) :background "darkgreen")
854 (t :underline t))
c383eb8a 855(mdw-define-face show-paren-mismatch
db10ce0a
MW
856 (((class color)) :background "red")
857 (t :inverse-video t))
1e7a9479 858(mdw-define-face highlight
db10ce0a
MW
859 (((class color)) :background "DarkSeaGreen4")
860 (t :inverse-video t))
1e7a9479
MW
861
862(mdw-define-face holiday-face
863 (t :background "red"))
864(mdw-define-face calendar-today-face
865 (t :foreground "yellow" :weight bold))
866
867(mdw-define-face comint-highlight-prompt
868 (t :weight bold))
5fd055c2
MW
869(mdw-define-face comint-highlight-input
870 (t nil))
1e7a9479 871
e0e2aca3
MW
872(mdw-define-face dired-directory
873 (t :foreground "cyan" :weight bold))
874(mdw-define-face dired-symlink
875 (t :foreground "cyan"))
876(mdw-define-face dired-perm-write
877 (t nil))
878
1e7a9479 879(mdw-define-face trailing-whitespace
db10ce0a
MW
880 (((class color)) :background "red")
881 (t :inverse-video t))
1e7a9479
MW
882(mdw-define-face mdw-punct-face
883 (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
884(mdw-define-face mdw-number-face
885 (t :foreground "yellow"))
886(mdw-define-face font-lock-function-name-face
c383eb8a 887 (t :slant italic))
1e7a9479
MW
888(mdw-define-face font-lock-keyword-face
889 (t :weight bold))
890(mdw-define-face font-lock-constant-face
891 (t :slant italic))
892(mdw-define-face font-lock-builtin-face
893 (t :weight bold))
07965a39
MW
894(mdw-define-face font-lock-type-face
895 (t :weight bold :slant italic))
1e7a9479
MW
896(mdw-define-face font-lock-reference-face
897 (t :weight bold))
898(mdw-define-face font-lock-variable-name-face
899 (t :slant italic))
900(mdw-define-face font-lock-comment-delimiter-face
db10ce0a
MW
901 (((class mono)) :weight bold)
902 (((type tty) (class color)) :foreground "green")
903 (t :slant italic :foreground "SeaGreen1"))
1e7a9479 904(mdw-define-face font-lock-comment-face
db10ce0a
MW
905 (((class mono)) :weight bold)
906 (((type tty) (class color)) :foreground "green")
907 (t :slant italic :foreground "SeaGreen1"))
1e7a9479 908(mdw-define-face font-lock-string-face
db10ce0a
MW
909 (((class mono)) :weight bold)
910 (((class color)) :foreground "SkyBlue1"))
1e7a9479
MW
911(mdw-define-face message-separator
912 (t :background "red" :foreground "white" :weight bold))
913(mdw-define-face message-cited-text
914 (default :slant italic)
915 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
916(mdw-define-face message-header-cc
917 (default :weight bold)
918 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
919(mdw-define-face message-header-newsgroups
920 (default :weight bold)
921 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
922(mdw-define-face message-header-subject
923 (default :weight bold)
924 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
925(mdw-define-face message-header-to
926 (default :weight bold)
927 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
928(mdw-define-face message-header-xheader
929 (default :weight bold)
930 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
931(mdw-define-face message-header-other
932 (default :weight bold)
933 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
934(mdw-define-face message-header-name
935 (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
69498691
MW
936(mdw-define-face which-func
937 (t nil))
1e7a9479
MW
938
939(mdw-define-face diff-index
940 (t :weight bold))
941(mdw-define-face diff-file-header
942 (t :weight bold))
943(mdw-define-face diff-hunk-header
944 (t :foreground "SkyBlue1"))
945(mdw-define-face diff-function
946 (t :foreground "SkyBlue1" :weight bold))
947(mdw-define-face diff-header
948 (t :background "grey10"))
949(mdw-define-face diff-added
950 (t :foreground "green"))
951(mdw-define-face diff-removed
952 (t :foreground "red"))
5fd055c2
MW
953(mdw-define-face diff-context
954 (t nil))
1e7a9479 955
e1b8de18
MW
956(mdw-define-face erc-input-face
957 (t :foreground "red"))
958
1e7a9479
MW
959(mdw-define-face woman-bold
960 (t :weight bold))
961(mdw-define-face woman-italic
962 (t :slant italic))
963
964(mdw-define-face p4-depot-added-face
965 (t :foreground "green"))
966(mdw-define-face p4-depot-branch-op-face
967 (t :foreground "yellow"))
968(mdw-define-face p4-depot-deleted-face
969 (t :foreground "red"))
970(mdw-define-face p4-depot-unmapped-face
971 (t :foreground "SkyBlue1"))
972(mdw-define-face p4-diff-change-face
973 (t :foreground "yellow"))
974(mdw-define-face p4-diff-del-face
975 (t :foreground "red"))
976(mdw-define-face p4-diff-file-face
977 (t :foreground "SkyBlue1"))
978(mdw-define-face p4-diff-head-face
979 (t :background "grey10"))
980(mdw-define-face p4-diff-ins-face
981 (t :foreground "green"))
982
983(mdw-define-face whizzy-slice-face
984 (t :background "grey10"))
985(mdw-define-face whizzy-error-face
986 (t :background "darkred"))
f617db13 987
6132bc01
MW
988;;;--------------------------------------------------------------------------
989;;; C programming configuration.
f617db13 990
6132bc01 991;; Linux kernel hacking.
f617db13
MW
992
993(defvar linux-c-mode-hook)
994
995(defun linux-c-mode ()
996 (interactive)
997 (c-mode)
998 (setq major-mode 'linux-c-mode)
999 (setq mode-name "Linux C")
1000 (run-hooks 'linux-c-mode-hook))
1001
6132bc01 1002;; Make C indentation nice.
f617db13 1003
f50c1bed
MW
1004(defun mdw-c-lineup-arglist (langelem)
1005 "Hack for DWIMmery in c-lineup-arglist."
1006 (if (save-excursion
1007 (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element)))
1008 0
1009 (c-lineup-arglist langelem)))
1010
1011(defun mdw-c-indent-extern-mumble (langelem)
1012 "Indent `extern \"...\" {' lines."
1013 (save-excursion
1014 (back-to-indentation)
1015 (if (looking-at
1016 "\\s-*\\<extern\\>\\s-*\"\\([^\\\\\"]+\\|\\.\\)*\"\\s-*{")
1017 c-basic-offset
1018 nil)))
1019
f617db13
MW
1020(defun mdw-c-style ()
1021 (c-add-style "[mdw] C and C++ style"
1022 '((c-basic-offset . 2)
f617db13
MW
1023 (comment-column . 40)
1024 (c-class-key . "class")
f50c1bed
MW
1025 (c-backslash-column . 72)
1026 (c-offsets-alist
1027 (substatement-open . (add 0 c-indent-one-line-block))
1028 (defun-open . (add 0 c-indent-one-line-block))
1029 (arglist-cont-nonempty . mdw-c-lineup-arglist)
1030 (topmost-intro . mdw-c-indent-extern-mumble)
1031 (cpp-define-intro . 0)
1032 (inextern-lang . [0])
1033 (label . 0)
1034 (case-label . +)
1035 (access-label . -)
1036 (inclass . +)
1037 (inline-open . ++)
1038 (statement-cont . 0)
1039 (statement-case-intro . +)))
f617db13
MW
1040 t))
1041
0e7d960b
MW
1042(defvar mdw-c-comment-fill-prefix
1043 `((,(concat "\\([ \t]*/?\\)"
1044 "\\(\*\\|//]\\)"
1045 "\\([ \t]*\\)"
1046 "\\([A-Za-z]+:[ \t]*\\)?"
1047 mdw-hanging-indents)
1048 (pad . 1) (match . 2) (pad . 3) (pad . 4) (pad . 5)))
1049 "Fill prefix matching C comments (both kinds).")
1050
f617db13
MW
1051(defun mdw-fontify-c-and-c++ ()
1052
6132bc01 1053 ;; Fiddle with some syntax codes.
f617db13
MW
1054 (modify-syntax-entry ?* ". 23")
1055 (modify-syntax-entry ?/ ". 124b")
1056 (modify-syntax-entry ?\n "> b")
1057
6132bc01 1058 ;; Other stuff.
f617db13
MW
1059 (mdw-c-style)
1060 (setq c-hanging-comment-ender-p nil)
1061 (setq c-backslash-column 72)
1062 (setq c-label-minimum-indentation 0)
0e7d960b 1063 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
f617db13 1064
6132bc01 1065 ;; Now define things to be fontified.
02109a0d 1066 (make-local-variable 'font-lock-keywords)
f617db13 1067 (let ((c-keywords
8d6d55b9
MW
1068 (mdw-regexps "and" ;C++
1069 "and_eq" ;C++
1070 "asm" ;K&R, GCC
1071 "auto" ;K&R, C89
1072 "bitand" ;C++
1073 "bitor" ;C++
1074 "bool" ;C++, C9X macro
1075 "break" ;K&R, C89
1076 "case" ;K&R, C89
1077 "catch" ;C++
1078 "char" ;K&R, C89
1079 "class" ;C++
1080 "complex" ;C9X macro, C++ template type
1081 "compl" ;C++
1082 "const" ;C89
1083 "const_cast" ;C++
1084 "continue" ;K&R, C89
1085 "defined" ;C89 preprocessor
1086 "default" ;K&R, C89
1087 "delete" ;C++
1088 "do" ;K&R, C89
1089 "double" ;K&R, C89
1090 "dynamic_cast" ;C++
1091 "else" ;K&R, C89
1092 ;; "entry" ;K&R -- never used
1093 "enum" ;C89
1094 "explicit" ;C++
1095 "export" ;C++
1096 "extern" ;K&R, C89
1097 "false" ;C++, C9X macro
1098 "float" ;K&R, C89
1099 "for" ;K&R, C89
1100 ;; "fortran" ;K&R
1101 "friend" ;C++
1102 "goto" ;K&R, C89
1103 "if" ;K&R, C89
1104 "imaginary" ;C9X macro
1105 "inline" ;C++, C9X, GCC
1106 "int" ;K&R, C89
1107 "long" ;K&R, C89
1108 "mutable" ;C++
1109 "namespace" ;C++
1110 "new" ;C++
1111 "operator" ;C++
1112 "or" ;C++
1113 "or_eq" ;C++
1114 "private" ;C++
1115 "protected" ;C++
1116 "public" ;C++
1117 "register" ;K&R, C89
1118 "reinterpret_cast" ;C++
1119 "restrict" ;C9X
1120 "return" ;K&R, C89
1121 "short" ;K&R, C89
1122 "signed" ;C89
1123 "sizeof" ;K&R, C89
1124 "static" ;K&R, C89
1125 "static_cast" ;C++
1126 "struct" ;K&R, C89
1127 "switch" ;K&R, C89
1128 "template" ;C++
1129 "this" ;C++
1130 "throw" ;C++
1131 "true" ;C++, C9X macro
1132 "try" ;C++
1133 "this" ;C++
1134 "typedef" ;C89
1135 "typeid" ;C++
1136 "typeof" ;GCC
1137 "typename" ;C++
1138 "union" ;K&R, C89
1139 "unsigned" ;K&R, C89
1140 "using" ;C++
1141 "virtual" ;C++
1142 "void" ;C89
1143 "volatile" ;C89
1144 "wchar_t" ;C++, C89 library type
1145 "while" ;K&R, C89
1146 "xor" ;C++
1147 "xor_eq" ;C++
1148 "_Bool" ;C9X
1149 "_Complex" ;C9X
1150 "_Imaginary" ;C9X
1151 "_Pragma" ;C9X preprocessor
1152 "__alignof__" ;GCC
1153 "__asm__" ;GCC
1154 "__attribute__" ;GCC
1155 "__complex__" ;GCC
1156 "__const__" ;GCC
1157 "__extension__" ;GCC
1158 "__imag__" ;GCC
1159 "__inline__" ;GCC
1160 "__label__" ;GCC
1161 "__real__" ;GCC
1162 "__signed__" ;GCC
1163 "__typeof__" ;GCC
1164 "__volatile__" ;GCC
1165 ))
f617db13 1166 (preprocessor-keywords
8d6d55b9
MW
1167 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1168 "ident" "if" "ifdef" "ifndef" "import" "include"
1169 "line" "pragma" "unassert" "undef" "warning"))
f617db13 1170 (objc-keywords
8d6d55b9
MW
1171 (mdw-regexps "class" "defs" "encode" "end" "implementation"
1172 "interface" "private" "protected" "protocol" "public"
1173 "selector")))
f617db13
MW
1174
1175 (setq font-lock-keywords
1176 (list
f617db13 1177
6132bc01 1178 ;; Fontify include files as strings.
f617db13
MW
1179 (list (concat "^[ \t]*\\#[ \t]*"
1180 "\\(include\\|import\\)"
1181 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1182 '(2 font-lock-string-face))
1183
6132bc01 1184 ;; Preprocessor directives are `references'?.
f617db13
MW
1185 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1186 preprocessor-keywords
1187 "\\)\\>\\|[0-9]+\\|$\\)\\)")
1188 '(1 font-lock-keyword-face))
1189
6132bc01 1190 ;; Handle the keywords defined above.
f617db13
MW
1191 (list (concat "@\\<\\(" objc-keywords "\\)\\>")
1192 '(0 font-lock-keyword-face))
1193
1194 (list (concat "\\<\\(" c-keywords "\\)\\>")
1195 '(0 font-lock-keyword-face))
1196
6132bc01 1197 ;; Handle numbers too.
f617db13
MW
1198 ;;
1199 ;; This looks strange, I know. It corresponds to the
1200 ;; preprocessor's idea of what a number looks like, rather than
1201 ;; anything sensible.
f617db13
MW
1202 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1203 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1204 '(0 mdw-number-face))
1205
6132bc01 1206 ;; And anything else is punctuation.
f617db13 1207 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1208 '(0 mdw-punct-face))))
1209
1210 (mdw-post-config-mode-hack)))
f617db13 1211
6132bc01
MW
1212;;;--------------------------------------------------------------------------
1213;;; AP calc mode.
f617db13
MW
1214
1215(defun apcalc-mode ()
1216 (interactive)
1217 (c-mode)
1218 (setq major-mode 'apcalc-mode)
1219 (setq mode-name "AP Calc")
1220 (run-hooks 'apcalc-mode-hook))
1221
1222(defun mdw-fontify-apcalc ()
1223
6132bc01 1224 ;; Fiddle with some syntax codes.
f617db13
MW
1225 (modify-syntax-entry ?* ". 23")
1226 (modify-syntax-entry ?/ ". 14")
1227
6132bc01 1228 ;; Other stuff.
f617db13
MW
1229 (mdw-c-style)
1230 (setq c-hanging-comment-ender-p nil)
1231 (setq c-backslash-column 72)
1232 (setq comment-start "/* ")
1233 (setq comment-end " */")
0e7d960b 1234 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
f617db13 1235
6132bc01 1236 ;; Now define things to be fontified.
02109a0d 1237 (make-local-variable 'font-lock-keywords)
f617db13 1238 (let ((c-keywords
8d6d55b9
MW
1239 (mdw-regexps "break" "case" "cd" "continue" "define" "default"
1240 "do" "else" "exit" "for" "global" "goto" "help" "if"
1241 "local" "mat" "obj" "print" "quit" "read" "return"
1242 "show" "static" "switch" "while" "write")))
f617db13
MW
1243
1244 (setq font-lock-keywords
1245 (list
f617db13 1246
6132bc01 1247 ;; Handle the keywords defined above.
f617db13
MW
1248 (list (concat "\\<\\(" c-keywords "\\)\\>")
1249 '(0 font-lock-keyword-face))
1250
6132bc01 1251 ;; Handle numbers too.
f617db13
MW
1252 ;;
1253 ;; This looks strange, I know. It corresponds to the
1254 ;; preprocessor's idea of what a number looks like, rather than
1255 ;; anything sensible.
f617db13
MW
1256 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1257 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1258 '(0 mdw-number-face))
1259
6132bc01 1260 ;; And anything else is punctuation.
f617db13 1261 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1262 '(0 mdw-punct-face)))))
1263
1264 (mdw-post-config-mode-hack))
f617db13 1265
6132bc01
MW
1266;;;--------------------------------------------------------------------------
1267;;; Java programming configuration.
f617db13 1268
6132bc01 1269;; Make indentation nice.
f617db13
MW
1270
1271(defun mdw-java-style ()
1272 (c-add-style "[mdw] Java style"
1273 '((c-basic-offset . 2)
f617db13
MW
1274 (c-offsets-alist (substatement-open . 0)
1275 (label . +)
1276 (case-label . +)
1277 (access-label . 0)
1278 (inclass . +)
1279 (statement-case-intro . +)))
1280 t))
1281
6132bc01 1282;; Declare Java fontification style.
f617db13
MW
1283
1284(defun mdw-fontify-java ()
1285
6132bc01 1286 ;; Other stuff.
f617db13 1287 (mdw-java-style)
f617db13
MW
1288 (setq c-hanging-comment-ender-p nil)
1289 (setq c-backslash-column 72)
0e7d960b 1290 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
f617db13 1291
6132bc01 1292 ;; Now define things to be fontified.
02109a0d 1293 (make-local-variable 'font-lock-keywords)
f617db13 1294 (let ((java-keywords
8d6d55b9
MW
1295 (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
1296 "char" "class" "const" "continue" "default" "do"
1297 "double" "else" "extends" "final" "finally" "float"
1298 "for" "goto" "if" "implements" "import" "instanceof"
1299 "int" "interface" "long" "native" "new" "package"
1300 "private" "protected" "public" "return" "short"
1301 "static" "super" "switch" "synchronized" "this"
1302 "throw" "throws" "transient" "try" "void" "volatile"
1303 "while"
1304
1305 "false" "null" "true")))
f617db13
MW
1306
1307 (setq font-lock-keywords
1308 (list
f617db13 1309
6132bc01 1310 ;; Handle the keywords defined above.
f617db13
MW
1311 (list (concat "\\<\\(" java-keywords "\\)\\>")
1312 '(0 font-lock-keyword-face))
1313
6132bc01 1314 ;; Handle numbers too.
f617db13
MW
1315 ;;
1316 ;; The following isn't quite right, but it's close enough.
f617db13
MW
1317 (list (concat "\\<\\("
1318 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1319 "[0-9]+\\(\\.[0-9]*\\|\\)"
1320 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1321 "[lLfFdD]?")
1322 '(0 mdw-number-face))
1323
6132bc01 1324 ;; And anything else is punctuation.
f617db13 1325 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1326 '(0 mdw-punct-face)))))
1327
1328 (mdw-post-config-mode-hack))
f617db13 1329
6132bc01
MW
1330;;;--------------------------------------------------------------------------
1331;;; C# programming configuration.
e808c1e5 1332
6132bc01 1333;; Make indentation nice.
e808c1e5
MW
1334
1335(defun mdw-csharp-style ()
1336 (c-add-style "[mdw] C# style"
1337 '((c-basic-offset . 2)
e808c1e5
MW
1338 (c-offsets-alist (substatement-open . 0)
1339 (label . 0)
1340 (case-label . +)
1341 (access-label . 0)
1342 (inclass . +)
1343 (statement-case-intro . +)))
1344 t))
1345
6132bc01 1346;; Declare C# fontification style.
e808c1e5
MW
1347
1348(defun mdw-fontify-csharp ()
1349
6132bc01 1350 ;; Other stuff.
e808c1e5 1351 (mdw-csharp-style)
e808c1e5
MW
1352 (setq c-hanging-comment-ender-p nil)
1353 (setq c-backslash-column 72)
0e7d960b 1354 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
e808c1e5 1355
6132bc01 1356 ;; Now define things to be fontified.
e808c1e5
MW
1357 (make-local-variable 'font-lock-keywords)
1358 (let ((csharp-keywords
8d6d55b9
MW
1359 (mdw-regexps "abstract" "as" "base" "bool" "break"
1360 "byte" "case" "catch" "char" "checked"
1361 "class" "const" "continue" "decimal" "default"
1362 "delegate" "do" "double" "else" "enum"
1363 "event" "explicit" "extern" "false" "finally"
1364 "fixed" "float" "for" "foreach" "goto"
1365 "if" "implicit" "in" "int" "interface"
1366 "internal" "is" "lock" "long" "namespace"
1367 "new" "null" "object" "operator" "out"
1368 "override" "params" "private" "protected" "public"
1369 "readonly" "ref" "return" "sbyte" "sealed"
1370 "short" "sizeof" "stackalloc" "static" "string"
1371 "struct" "switch" "this" "throw" "true"
1372 "try" "typeof" "uint" "ulong" "unchecked"
1373 "unsafe" "ushort" "using" "virtual" "void"
1374 "volatile" "while" "yield")))
e808c1e5
MW
1375
1376 (setq font-lock-keywords
1377 (list
e808c1e5 1378
6132bc01 1379 ;; Handle the keywords defined above.
e808c1e5
MW
1380 (list (concat "\\<\\(" csharp-keywords "\\)\\>")
1381 '(0 font-lock-keyword-face))
1382
6132bc01 1383 ;; Handle numbers too.
e808c1e5
MW
1384 ;;
1385 ;; The following isn't quite right, but it's close enough.
e808c1e5
MW
1386 (list (concat "\\<\\("
1387 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1388 "[0-9]+\\(\\.[0-9]*\\|\\)"
1389 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1390 "[lLfFdD]?")
1391 '(0 mdw-number-face))
1392
6132bc01 1393 ;; And anything else is punctuation.
e808c1e5 1394 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1395 '(0 mdw-punct-face)))))
1396
1397 (mdw-post-config-mode-hack))
e808c1e5 1398
103c5923
MW
1399(define-derived-mode csharp-mode java-mode "C#"
1400 "Major mode for editing C# code.")
e808c1e5 1401
6132bc01 1402;;;--------------------------------------------------------------------------
07965a39
MW
1403;;; Go programming configuration.
1404
1405(defun mdw-fontify-go ()
1406
1407 (make-local-variable 'font-lock-keywords)
1408 (let ((go-keywords
1409 (mdw-regexps "break" "case" "chan" "const" "continue"
1410 "default" "defer" "else" "fallthrough" "for"
1411 "func" "go" "goto" "if" "import"
1412 "interface" "map" "package" "range" "return"
1413 "select" "struct" "switch" "type" "var")))
1414
1415 (setq font-lock-keywords
1416 (list
1417
1418 ;; Handle the keywords defined above.
1419 (list (concat "\\<\\(" go-keywords "\\)\\>")
1420 '(0 font-lock-keyword-face))
1421
1422 ;; Handle numbers too.
1423 ;;
1424 ;; The following isn't quite right, but it's close enough.
1425 (list (concat "\\<\\("
1426 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1427 "[0-9]+\\(\\.[0-9]*\\|\\)"
1428 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
1429 '(0 mdw-number-face))
1430
1431 ;; And anything else is punctuation.
1432 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1433 '(0 mdw-punct-face)))))
1434
1435 (mdw-post-config-mode-hack))
07965a39
MW
1436
1437;;;--------------------------------------------------------------------------
6132bc01 1438;;; Awk programming configuration.
f617db13 1439
6132bc01 1440;; Make Awk indentation nice.
f617db13
MW
1441
1442(defun mdw-awk-style ()
1443 (c-add-style "[mdw] Awk style"
1444 '((c-basic-offset . 2)
f617db13
MW
1445 (c-offsets-alist (substatement-open . 0)
1446 (statement-cont . 0)
1447 (statement-case-intro . +)))
1448 t))
1449
6132bc01 1450;; Declare Awk fontification style.
f617db13
MW
1451
1452(defun mdw-fontify-awk ()
1453
6132bc01 1454 ;; Miscellaneous fiddling.
f617db13
MW
1455 (mdw-awk-style)
1456 (setq c-backslash-column 72)
1457 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1458
6132bc01 1459 ;; Now define things to be fontified.
02109a0d 1460 (make-local-variable 'font-lock-keywords)
f617db13 1461 (let ((c-keywords
8d6d55b9
MW
1462 (mdw-regexps "BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT"
1463 "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR"
1464 "FS" "IGNORECASE" "NF" "NR" "OFMT" "OFS" "ORS" "RS"
1465 "RSTART" "RLENGTH" "RT" "SUBSEP"
1466 "atan2" "break" "close" "continue" "cos" "delete"
1467 "do" "else" "exit" "exp" "fflush" "file" "for" "func"
1468 "function" "gensub" "getline" "gsub" "if" "in"
1469 "index" "int" "length" "log" "match" "next" "rand"
1470 "return" "print" "printf" "sin" "split" "sprintf"
1471 "sqrt" "srand" "strftime" "sub" "substr" "system"
1472 "systime" "tolower" "toupper" "while")))
f617db13
MW
1473
1474 (setq font-lock-keywords
1475 (list
f617db13 1476
6132bc01 1477 ;; Handle the keywords defined above.
f617db13
MW
1478 (list (concat "\\<\\(" c-keywords "\\)\\>")
1479 '(0 font-lock-keyword-face))
1480
6132bc01 1481 ;; Handle numbers too.
f617db13
MW
1482 ;;
1483 ;; The following isn't quite right, but it's close enough.
f617db13
MW
1484 (list (concat "\\<\\("
1485 "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1486 "[0-9]+\\(\\.[0-9]*\\|\\)"
1487 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
1488 "[uUlL]*")
1489 '(0 mdw-number-face))
1490
6132bc01 1491 ;; And anything else is punctuation.
f617db13 1492 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1493 '(0 mdw-punct-face)))))
1494
1495 (mdw-post-config-mode-hack))
f617db13 1496
6132bc01
MW
1497;;;--------------------------------------------------------------------------
1498;;; Perl programming style.
f617db13 1499
6132bc01 1500;; Perl indentation style.
f617db13 1501
f617db13
MW
1502(setq cperl-indent-level 2)
1503(setq cperl-continued-statement-offset 2)
1504(setq cperl-continued-brace-offset 0)
1505(setq cperl-brace-offset -2)
1506(setq cperl-brace-imaginary-offset 0)
1507(setq cperl-label-offset 0)
1508
6132bc01 1509;; Define perl fontification style.
f617db13
MW
1510
1511(defun mdw-fontify-perl ()
1512
6132bc01 1513 ;; Miscellaneous fiddling.
f617db13
MW
1514 (modify-syntax-entry ?$ "\\")
1515 (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
1516 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1517
6132bc01 1518 ;; Now define fontification things.
02109a0d 1519 (make-local-variable 'font-lock-keywords)
f617db13 1520 (let ((perl-keywords
8d6d55b9
MW
1521 (mdw-regexps "and" "cmp" "continue" "do" "else" "elsif" "eq"
1522 "for" "foreach" "ge" "gt" "goto" "if"
1523 "last" "le" "lt" "local" "my" "ne" "next" "or"
1524 "package" "redo" "require" "return" "sub"
1525 "undef" "unless" "until" "use" "while")))
f617db13
MW
1526
1527 (setq font-lock-keywords
1528 (list
f617db13 1529
6132bc01 1530 ;; Set up the keywords defined above.
f617db13
MW
1531 (list (concat "\\<\\(" perl-keywords "\\)\\>")
1532 '(0 font-lock-keyword-face))
1533
6132bc01 1534 ;; At least numbers are simpler than C.
f617db13
MW
1535 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1536 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1537 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1538 '(0 mdw-number-face))
1539
6132bc01 1540 ;; And anything else is punctuation.
f617db13 1541 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1542 '(0 mdw-punct-face)))))
1543
1544 (mdw-post-config-mode-hack))
f617db13
MW
1545
1546(defun perl-number-tests (&optional arg)
1547 "Assign consecutive numbers to lines containing `#t'. With ARG,
1548strip numbers instead."
1549 (interactive "P")
1550 (save-excursion
1551 (goto-char (point-min))
1552 (let ((i 0) (fmt (if arg "" " %4d")))
1553 (while (search-forward "#t" nil t)
1554 (delete-region (point) (line-end-position))
1555 (setq i (1+ i))
1556 (insert (format fmt i)))
1557 (goto-char (point-min))
1558 (if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
1559 (replace-match (format "\\1%d" i))))))
1560
6132bc01
MW
1561;;;--------------------------------------------------------------------------
1562;;; Python programming style.
f617db13 1563
99fe6ef5 1564(defun mdw-fontify-pythonic (keywords)
f617db13 1565
6132bc01 1566 ;; Miscellaneous fiddling.
f617db13 1567 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
7c0fcfde 1568 (setq indent-tabs-mode nil)
f617db13 1569
6132bc01 1570 ;; Now define fontification things.
02109a0d 1571 (make-local-variable 'font-lock-keywords)
99fe6ef5
MW
1572 (setq font-lock-keywords
1573 (list
f617db13 1574
be2cc788 1575 ;; Set up the keywords defined above.
29826b11 1576 (list (concat "\\<\\(" keywords "\\)\\>")
99fe6ef5 1577 '(0 font-lock-keyword-face))
f617db13 1578
be2cc788 1579 ;; At least numbers are simpler than C.
99fe6ef5
MW
1580 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1581 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1582 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
1583 '(0 mdw-number-face))
f617db13 1584
be2cc788 1585 ;; And anything else is punctuation.
99fe6ef5 1586 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1587 '(0 mdw-punct-face))))
1588
1589 (mdw-post-config-mode-hack))
99fe6ef5 1590
be2cc788 1591;; Define Python fontification styles.
99fe6ef5
MW
1592
1593(defun mdw-fontify-python ()
1594 (mdw-fontify-pythonic
1595 (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
1596 "del" "elif" "else" "except" "exec" "finally" "for"
1597 "from" "global" "if" "import" "in" "is" "lambda"
1598 "not" "or" "pass" "print" "raise" "return" "try"
1599 "while" "with" "yield")))
1600
1601(defun mdw-fontify-pyrex ()
1602 (mdw-fontify-pythonic
1603 (mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
1604 "ctypedef" "def" "del" "elif" "else" "except" "exec"
1605 "extern" "finally" "for" "from" "global" "if"
1606 "import" "in" "is" "lambda" "not" "or" "pass" "print"
1607 "raise" "return" "struct" "try" "while" "with"
1608 "yield")))
f617db13 1609
6132bc01
MW
1610;;;--------------------------------------------------------------------------
1611;;; Icon programming style.
cc1980e1 1612
6132bc01 1613;; Icon indentation style.
cc1980e1
MW
1614
1615(setq icon-brace-offset 0
1616 icon-continued-brace-offset 0
1617 icon-continued-statement-offset 2
1618 icon-indent-level 2)
1619
6132bc01 1620;; Define Icon fontification style.
cc1980e1
MW
1621
1622(defun mdw-fontify-icon ()
1623
6132bc01 1624 ;; Miscellaneous fiddling.
cc1980e1
MW
1625 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
1626
6132bc01 1627 ;; Now define fontification things.
cc1980e1
MW
1628 (make-local-variable 'font-lock-keywords)
1629 (let ((icon-keywords
1630 (mdw-regexps "break" "by" "case" "create" "default" "do" "else"
1631 "end" "every" "fail" "global" "if" "initial"
1632 "invocable" "link" "local" "next" "not" "of"
1633 "procedure" "record" "repeat" "return" "static"
1634 "suspend" "then" "to" "until" "while"))
1635 (preprocessor-keywords
1636 (mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
1637 "include" "line" "undef")))
1638 (setq font-lock-keywords
1639 (list
1640
6132bc01 1641 ;; Set up the keywords defined above.
cc1980e1
MW
1642 (list (concat "\\<\\(" icon-keywords "\\)\\>")
1643 '(0 font-lock-keyword-face))
1644
6132bc01 1645 ;; The things that Icon calls keywords.
cc1980e1
MW
1646 (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
1647
6132bc01 1648 ;; At least numbers are simpler than C.
cc1980e1
MW
1649 (list (concat "\\<[0-9]+"
1650 "\\([rR][0-9a-zA-Z]+\\|"
1651 "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
1652 "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
1653 '(0 mdw-number-face))
1654
6132bc01 1655 ;; Preprocessor.
cc1980e1
MW
1656 (list (concat "^[ \t]*$[ \t]*\\<\\("
1657 preprocessor-keywords
1658 "\\)\\>")
1659 '(0 font-lock-keyword-face))
1660
6132bc01 1661 ;; And anything else is punctuation.
cc1980e1 1662 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1663 '(0 mdw-punct-face)))))
1664
1665 (mdw-post-config-mode-hack))
cc1980e1 1666
6132bc01
MW
1667;;;--------------------------------------------------------------------------
1668;;; ARM assembler programming configuration.
f617db13 1669
6132bc01 1670;; There doesn't appear to be an Emacs mode for this yet.
f617db13
MW
1671;;
1672;; Better do something about that, I suppose.
1673
1674(defvar arm-assembler-mode-map nil)
1675(defvar arm-assembler-abbrev-table nil)
1676(defvar arm-assembler-mode-syntax-table (make-syntax-table))
1677
1678(or arm-assembler-mode-map
1679 (progn
1680 (setq arm-assembler-mode-map (make-sparse-keymap))
1681 (define-key arm-assembler-mode-map "\C-m" 'arm-assembler-newline)
1682 (define-key arm-assembler-mode-map [C-return] 'newline)
1683 (define-key arm-assembler-mode-map "\t" 'tab-to-tab-stop)))
1684
1685(defun arm-assembler-mode ()
1686 "Major mode for ARM assembler programs"
1687 (interactive)
1688
6132bc01 1689 ;; Do standard major mode things.
f617db13
MW
1690 (kill-all-local-variables)
1691 (use-local-map arm-assembler-mode-map)
1692 (setq local-abbrev-table arm-assembler-abbrev-table)
1693 (setq major-mode 'arm-assembler-mode)
1694 (setq mode-name "ARM assembler")
1695
6132bc01 1696 ;; Set up syntax table.
f617db13
MW
1697 (set-syntax-table arm-assembler-mode-syntax-table)
1698 (modify-syntax-entry ?; ; Nasty hack
1699 "<" arm-assembler-mode-syntax-table)
1700 (modify-syntax-entry ?\n ">" arm-assembler-mode-syntax-table)
1701 (modify-syntax-entry ?_ "_" arm-assembler-mode-syntax-table)
1702
1703 (make-local-variable 'comment-start)
1704 (setq comment-start ";")
1705 (make-local-variable 'comment-end)
1706 (setq comment-end "")
1707 (make-local-variable 'comment-column)
1708 (setq comment-column 48)
1709 (make-local-variable 'comment-start-skip)
1710 (setq comment-start-skip ";+[ \t]*")
1711
6132bc01 1712 ;; Play with indentation.
f617db13
MW
1713 (make-local-variable 'indent-line-function)
1714 (setq indent-line-function 'indent-relative-maybe)
1715
6132bc01 1716 ;; Set fill prefix.
f617db13
MW
1717 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
1718
6132bc01 1719 ;; Fiddle with fontification.
02109a0d 1720 (make-local-variable 'font-lock-keywords)
f617db13
MW
1721 (setq font-lock-keywords
1722 (list
f617db13 1723
6132bc01 1724 ;; Handle numbers too.
f617db13
MW
1725 ;;
1726 ;; The following isn't quite right, but it's close enough.
f617db13
MW
1727 (list (concat "\\("
1728 "&[0-9a-fA-F]+\\|"
1729 "\\<[0-9]+\\(\\.[0-9]*\\|_[0-9a-zA-Z]+\\|\\)"
1730 "\\)")
1731 '(0 mdw-number-face))
1732
6132bc01 1733 ;; Do something about operators.
f617db13
MW
1734 (list "^[^ \t]*[ \t]+\\(GET\\|LNK\\)[ \t]+\\([^;\n]*\\)"
1735 '(1 font-lock-keyword-face)
1736 '(2 font-lock-string-face))
1737 (list ":[a-zA-Z]+:"
1738 '(0 font-lock-keyword-face))
1739
6132bc01 1740 ;; Do menemonics and directives.
f617db13
MW
1741 (list "^[^ \t]*[ \t]+\\([a-zA-Z]+\\)"
1742 '(1 font-lock-keyword-face))
1743
6132bc01 1744 ;; And anything else is punctuation.
f617db13 1745 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9 1746 '(0 mdw-punct-face)))
f617db13 1747
ed7b46b9 1748 (mdw-post-config-mode-hack))
f617db13
MW
1749 (run-hooks 'arm-assembler-mode-hook))
1750
6132bc01
MW
1751;;;--------------------------------------------------------------------------
1752;;; Assembler mode.
30c8a8fb
MW
1753
1754(defun mdw-fontify-asm ()
1755 (modify-syntax-entry ?' "\"")
1756 (modify-syntax-entry ?. "w")
1757 (setf fill-prefix nil)
1758 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
1759
6132bc01
MW
1760;;;--------------------------------------------------------------------------
1761;;; TCL configuration.
f617db13
MW
1762
1763(defun mdw-fontify-tcl ()
1764 (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
1765 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
02109a0d 1766 (make-local-variable 'font-lock-keywords)
f617db13
MW
1767 (setq font-lock-keywords
1768 (list
f617db13
MW
1769 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
1770 "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
1771 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
1772 '(0 mdw-number-face))
1773 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1774 '(0 mdw-punct-face))))
1775 (mdw-post-config-mode-hack))
f617db13 1776
6132bc01
MW
1777;;;--------------------------------------------------------------------------
1778;;; REXX configuration.
f617db13
MW
1779
1780(defun mdw-rexx-electric-* ()
1781 (interactive)
1782 (insert ?*)
1783 (rexx-indent-line))
1784
1785(defun mdw-rexx-indent-newline-indent ()
1786 (interactive)
1787 (rexx-indent-line)
1788 (if abbrev-mode (expand-abbrev))
1789 (newline-and-indent))
1790
1791(defun mdw-fontify-rexx ()
1792
6132bc01 1793 ;; Various bits of fiddling.
f617db13
MW
1794 (setq mdw-auto-indent nil)
1795 (local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
1796 (local-set-key [?*] 'mdw-rexx-electric-*)
1797 (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
e443a4cd 1798 '(?! ?? ?# ?@ ?$))
f617db13
MW
1799 (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
1800
6132bc01 1801 ;; Set up keywords and things for fontification.
f617db13
MW
1802 (make-local-variable 'font-lock-keywords-case-fold-search)
1803 (setq font-lock-keywords-case-fold-search t)
1804
1805 (setq rexx-indent 2)
1806 (setq rexx-end-indent rexx-indent)
f617db13
MW
1807 (setq rexx-cont-indent rexx-indent)
1808
02109a0d 1809 (make-local-variable 'font-lock-keywords)
f617db13 1810 (let ((rexx-keywords
8d6d55b9
MW
1811 (mdw-regexps "address" "arg" "by" "call" "digits" "do" "drop"
1812 "else" "end" "engineering" "exit" "expose" "for"
1813 "forever" "form" "fuzz" "if" "interpret" "iterate"
1814 "leave" "linein" "name" "nop" "numeric" "off" "on"
1815 "options" "otherwise" "parse" "procedure" "pull"
1816 "push" "queue" "return" "say" "select" "signal"
1817 "scientific" "source" "then" "trace" "to" "until"
1818 "upper" "value" "var" "version" "when" "while"
1819 "with"
1820
1821 "abbrev" "abs" "bitand" "bitor" "bitxor" "b2x"
1822 "center" "center" "charin" "charout" "chars"
1823 "compare" "condition" "copies" "c2d" "c2x"
1824 "datatype" "date" "delstr" "delword" "d2c" "d2x"
1825 "errortext" "format" "fuzz" "insert" "lastpos"
1826 "left" "length" "lineout" "lines" "max" "min"
1827 "overlay" "pos" "queued" "random" "reverse" "right"
1828 "sign" "sourceline" "space" "stream" "strip"
1829 "substr" "subword" "symbol" "time" "translate"
1830 "trunc" "value" "verify" "word" "wordindex"
1831 "wordlength" "wordpos" "words" "xrange" "x2b" "x2c"
1832 "x2d")))
f617db13
MW
1833
1834 (setq font-lock-keywords
1835 (list
f617db13 1836
6132bc01 1837 ;; Set up the keywords defined above.
f617db13
MW
1838 (list (concat "\\<\\(" rexx-keywords "\\)\\>")
1839 '(0 font-lock-keyword-face))
1840
6132bc01 1841 ;; Fontify all symbols the same way.
f617db13
MW
1842 (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
1843 "[A-Za-z0-9.!?_#@$]+\\)")
1844 '(0 font-lock-variable-name-face))
1845
6132bc01 1846 ;; And everything else is punctuation.
f617db13 1847 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1848 '(0 mdw-punct-face)))))
1849
1850 (mdw-post-config-mode-hack))
f617db13 1851
6132bc01
MW
1852;;;--------------------------------------------------------------------------
1853;;; Standard ML programming style.
f617db13
MW
1854
1855(defun mdw-fontify-sml ()
1856
6132bc01 1857 ;; Make underscore an honorary letter.
f617db13
MW
1858 (modify-syntax-entry ?' "w")
1859
6132bc01 1860 ;; Set fill prefix.
f617db13
MW
1861 (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
1862
6132bc01 1863 ;; Now define fontification things.
02109a0d 1864 (make-local-variable 'font-lock-keywords)
f617db13 1865 (let ((sml-keywords
8d6d55b9
MW
1866 (mdw-regexps "abstype" "and" "andalso" "as"
1867 "case"
1868 "datatype" "do"
1869 "else" "end" "eqtype" "exception"
1870 "fn" "fun" "functor"
1871 "handle"
1872 "if" "in" "include" "infix" "infixr"
1873 "let" "local"
1874 "nonfix"
1875 "of" "op" "open" "orelse"
1876 "raise" "rec"
1877 "sharing" "sig" "signature" "struct" "structure"
1878 "then" "type"
1879 "val"
1880 "where" "while" "with" "withtype")))
f617db13
MW
1881
1882 (setq font-lock-keywords
1883 (list
f617db13 1884
6132bc01 1885 ;; Set up the keywords defined above.
f617db13
MW
1886 (list (concat "\\<\\(" sml-keywords "\\)\\>")
1887 '(0 font-lock-keyword-face))
1888
6132bc01 1889 ;; At least numbers are simpler than C.
f617db13
MW
1890 (list (concat "\\<\\(\\~\\|\\)"
1891 "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
852cd5fb
MW
1892 "[wW][0-9]+\\)\\|"
1893 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
1894 "\\([eE]\\(\\~\\|\\)"
1895 "[0-9]+\\|\\)\\)\\)")
f617db13
MW
1896 '(0 mdw-number-face))
1897
6132bc01 1898 ;; And anything else is punctuation.
f617db13 1899 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1900 '(0 mdw-punct-face)))))
1901
1902 (mdw-post-config-mode-hack))
f617db13 1903
6132bc01
MW
1904;;;--------------------------------------------------------------------------
1905;;; Haskell configuration.
f617db13
MW
1906
1907(defun mdw-fontify-haskell ()
1908
6132bc01 1909 ;; Fiddle with syntax table to get comments right.
f617db13
MW
1910 (modify-syntax-entry ?' "\"")
1911 (modify-syntax-entry ?- ". 123")
1912 (modify-syntax-entry ?{ ". 1b")
1913 (modify-syntax-entry ?} ". 4b")
1914 (modify-syntax-entry ?\n ">")
1915
6132bc01 1916 ;; Set fill prefix.
f617db13
MW
1917 (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
1918
6132bc01 1919 ;; Fiddle with fontification.
02109a0d 1920 (make-local-variable 'font-lock-keywords)
f617db13 1921 (let ((haskell-keywords
8d6d55b9
MW
1922 (mdw-regexps "as" "case" "ccall" "class" "data" "default"
1923 "deriving" "do" "else" "foreign" "hiding" "if"
1924 "import" "in" "infix" "infixl" "infixr" "instance"
1925 "let" "module" "newtype" "of" "qualified" "safe"
1926 "stdcall" "then" "type" "unsafe" "where")))
f617db13
MW
1927
1928 (setq font-lock-keywords
1929 (list
f617db13
MW
1930 (list "--.*$"
1931 '(0 font-lock-comment-face))
1932 (list (concat "\\<\\(" haskell-keywords "\\)\\>")
1933 '(0 font-lock-keyword-face))
1934 (list (concat "\\<0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
1935 "\\<[0-9][0-9_]*\\(\\.[0-9]*\\|\\)"
1936 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
1937 '(0 mdw-number-face))
1938 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1939 '(0 mdw-punct-face)))))
1940
1941 (mdw-post-config-mode-hack))
f617db13 1942
6132bc01
MW
1943;;;--------------------------------------------------------------------------
1944;;; Erlang configuration.
2ded9493 1945
52941dec 1946(setq erlang-electric-commands nil)
2ded9493
MW
1947
1948(defun mdw-fontify-erlang ()
1949
6132bc01 1950 ;; Set fill prefix.
2ded9493
MW
1951 (mdw-standard-fill-prefix "\\([ \t]*{?%*[ \t]*\\)")
1952
6132bc01 1953 ;; Fiddle with fontification.
2ded9493
MW
1954 (make-local-variable 'font-lock-keywords)
1955 (let ((erlang-keywords
1956 (mdw-regexps "after" "and" "andalso"
1957 "band" "begin" "bnot" "bor" "bsl" "bsr" "bxor"
1958 "case" "catch" "cond"
1959 "div" "end" "fun" "if" "let" "not"
1960 "of" "or" "orelse"
1961 "query" "receive" "rem" "try" "when" "xor")))
1962
1963 (setq font-lock-keywords
1964 (list
1965 (list "%.*$"
1966 '(0 font-lock-comment-face))
1967 (list (concat "\\<\\(" erlang-keywords "\\)\\>")
1968 '(0 font-lock-keyword-face))
1969 (list (concat "^-\\sw+\\>")
1970 '(0 font-lock-keyword-face))
1971 (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
1972 '(0 mdw-number-face))
1973 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
1974 '(0 mdw-punct-face)))))
1975
1976 (mdw-post-config-mode-hack))
2ded9493 1977
6132bc01
MW
1978;;;--------------------------------------------------------------------------
1979;;; Texinfo configuration.
f617db13
MW
1980
1981(defun mdw-fontify-texinfo ()
1982
6132bc01 1983 ;; Set fill prefix.
f617db13
MW
1984 (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
1985
6132bc01 1986 ;; Real fontification things.
02109a0d 1987 (make-local-variable 'font-lock-keywords)
f617db13
MW
1988 (setq font-lock-keywords
1989 (list
f617db13 1990
6132bc01 1991 ;; Environment names are keywords.
f617db13
MW
1992 (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
1993 '(2 font-lock-keyword-face))
1994
6132bc01 1995 ;; Unmark escaped magic characters.
f617db13
MW
1996 (list "\\(@\\)\\([@{}]\\)"
1997 '(1 font-lock-keyword-face)
1998 '(2 font-lock-variable-name-face))
1999
6132bc01 2000 ;; Make sure we get comments properly.
f617db13
MW
2001 (list "@c\\(\\|omment\\)\\( .*\\)?$"
2002 '(0 font-lock-comment-face))
2003
6132bc01 2004 ;; Command names are keywords.
f617db13
MW
2005 (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
2006 '(0 font-lock-keyword-face))
2007
6132bc01 2008 ;; Fontify TeX special characters as punctuation.
f617db13 2009 (list "[{}]+"
ed7b46b9
MW
2010 '(0 mdw-punct-face))))
2011
2012 (mdw-post-config-mode-hack))
f617db13 2013
6132bc01
MW
2014;;;--------------------------------------------------------------------------
2015;;; TeX and LaTeX configuration.
f617db13
MW
2016
2017(defun mdw-fontify-tex ()
2018 (setq ispell-parser 'tex)
55f80fae 2019 (turn-on-reftex)
f617db13 2020
6132bc01 2021 ;; Don't make maths into a string.
f617db13
MW
2022 (modify-syntax-entry ?$ ".")
2023 (modify-syntax-entry ?$ "." font-lock-syntax-table)
2024 (local-set-key [?$] 'self-insert-command)
2025
6132bc01 2026 ;; Set fill prefix.
f617db13
MW
2027 (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
2028
6132bc01 2029 ;; Real fontification things.
02109a0d 2030 (make-local-variable 'font-lock-keywords)
f617db13
MW
2031 (setq font-lock-keywords
2032 (list
f617db13 2033
6132bc01 2034 ;; Environment names are keywords.
f617db13
MW
2035 (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
2036 "{\\([^}\n]*\\)}")
2037 '(2 font-lock-keyword-face))
2038
6132bc01 2039 ;; Suspended environment names are keywords too.
f617db13
MW
2040 (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
2041 "{\\([^}\n]*\\)}")
2042 '(3 font-lock-keyword-face))
2043
6132bc01 2044 ;; Command names are keywords.
f617db13
MW
2045 (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
2046 '(0 font-lock-keyword-face))
2047
6132bc01 2048 ;; Handle @/.../ for italics.
f617db13 2049 ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
852cd5fb
MW
2050 ;; '(1 font-lock-keyword-face)
2051 ;; '(3 font-lock-keyword-face))
f617db13 2052
6132bc01 2053 ;; Handle @*...* for boldness.
f617db13 2054 ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
852cd5fb
MW
2055 ;; '(1 font-lock-keyword-face)
2056 ;; '(3 font-lock-keyword-face))
f617db13 2057
6132bc01 2058 ;; Handle @`...' for literal syntax things.
f617db13 2059 ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
852cd5fb
MW
2060 ;; '(1 font-lock-keyword-face)
2061 ;; '(3 font-lock-keyword-face))
f617db13 2062
6132bc01 2063 ;; Handle @<...> for nonterminals.
f617db13 2064 ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
852cd5fb
MW
2065 ;; '(1 font-lock-keyword-face)
2066 ;; '(3 font-lock-keyword-face))
f617db13 2067
6132bc01 2068 ;; Handle other @-commands.
f617db13 2069 ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
852cd5fb 2070 ;; '(0 font-lock-keyword-face))
f617db13 2071
6132bc01 2072 ;; Make sure we get comments properly.
f617db13
MW
2073 (list "%.*"
2074 '(0 font-lock-comment-face))
2075
6132bc01 2076 ;; Fontify TeX special characters as punctuation.
f617db13 2077 (list "[$^_{}#&]"
ed7b46b9
MW
2078 '(0 mdw-punct-face))))
2079
2080 (mdw-post-config-mode-hack))
f617db13 2081
6132bc01
MW
2082;;;--------------------------------------------------------------------------
2083;;; SGML hacking.
f25cf300
MW
2084
2085(defun mdw-sgml-mode ()
2086 (interactive)
2087 (sgml-mode)
2088 (mdw-standard-fill-prefix "")
8a425bd7 2089 (make-local-variable 'sgml-delimiters)
f25cf300
MW
2090 (setq sgml-delimiters
2091 '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
2092 "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
2093 "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
2094 "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
2095 "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
2096 "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
2097 "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
2098 "NULL" ""))
2099 (setq major-mode 'mdw-sgml-mode)
2100 (setq mode-name "[mdw] SGML")
2101 (run-hooks 'mdw-sgml-mode-hook))
2102
6132bc01
MW
2103;;;--------------------------------------------------------------------------
2104;;; Shell scripts.
f617db13
MW
2105
2106(defun mdw-setup-sh-script-mode ()
2107
6132bc01 2108 ;; Fetch the shell interpreter's name.
f617db13
MW
2109 (let ((shell-name sh-shell-file))
2110
6132bc01 2111 ;; Try reading the hash-bang line.
f617db13
MW
2112 (save-excursion
2113 (goto-char (point-min))
2114 (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
2115 (setq shell-name (match-string 1))))
2116
6132bc01 2117 ;; Now try to set the shell.
f617db13
MW
2118 ;;
2119 ;; Don't let `sh-set-shell' bugger up my script.
f617db13
MW
2120 (let ((executable-set-magic #'(lambda (s &rest r) s)))
2121 (sh-set-shell shell-name)))
2122
6132bc01 2123 ;; Now enable my keys and the fontification.
f617db13
MW
2124 (mdw-misc-mode-config)
2125
6132bc01 2126 ;; Set the indentation level correctly.
f617db13
MW
2127 (setq sh-indentation 2)
2128 (setq sh-basic-offset 2))
2129
092f0a38
MW
2130;;;--------------------------------------------------------------------------
2131;;; Emacs shell mode.
2132
2133(defun mdw-eshell-prompt ()
2134 (let ((left "[") (right "]"))
2135 (when (= (user-uid) 0)
2136 (setq left "«" right "»"))
2137 (concat left
2138 (save-match-data
2139 (replace-regexp-in-string "\\..*$" "" (system-name)))
2140 " "
2d8b2924
MW
2141 (let* ((pwd (eshell/pwd)) (npwd (length pwd))
2142 (home (expand-file-name "~")) (nhome (length home)))
2143 (if (and (>= npwd nhome)
2144 (or (= nhome npwd)
2145 (= (elt pwd nhome) ?/)
2146 (string= (substring pwd 0 nhome) home)))
2147 (concat "~" (substring pwd (length home)))
2148 pwd))
092f0a38
MW
2149 right)))
2150(setq eshell-prompt-function 'mdw-eshell-prompt)
ac4ae7cd 2151(setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
092f0a38 2152
2d8b2924
MW
2153(defun eshell/e (file) (find-file file) nil)
2154(defun eshell/ee (file) (find-file-other-window file) nil)
2155(defun eshell/w3m (url) (w3m-goto-url url) nil)
415a23dd 2156
092f0a38
MW
2157(mdw-define-face eshell-prompt (t :weight bold))
2158(mdw-define-face eshell-ls-archive (t :weight bold :foreground "red"))
2159(mdw-define-face eshell-ls-backup (t :foreground "lightgrey" :slant italic))
2160(mdw-define-face eshell-ls-product (t :foreground "lightgrey" :slant italic))
2161(mdw-define-face eshell-ls-clutter (t :foreground "lightgrey" :slant italic))
2162(mdw-define-face eshell-ls-executable (t :weight bold))
2163(mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
2164(mdw-define-face eshell-ls-readonly (t nil))
2165(mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
2166
6132bc01
MW
2167;;;--------------------------------------------------------------------------
2168;;; Messages-file mode.
f617db13 2169
4bb22eea 2170(defun messages-mode-guts ()
f617db13
MW
2171 (setq messages-mode-syntax-table (make-syntax-table))
2172 (set-syntax-table messages-mode-syntax-table)
f617db13
MW
2173 (modify-syntax-entry ?0 "w" messages-mode-syntax-table)
2174 (modify-syntax-entry ?1 "w" messages-mode-syntax-table)
2175 (modify-syntax-entry ?2 "w" messages-mode-syntax-table)
2176 (modify-syntax-entry ?3 "w" messages-mode-syntax-table)
2177 (modify-syntax-entry ?4 "w" messages-mode-syntax-table)
2178 (modify-syntax-entry ?5 "w" messages-mode-syntax-table)
2179 (modify-syntax-entry ?6 "w" messages-mode-syntax-table)
2180 (modify-syntax-entry ?7 "w" messages-mode-syntax-table)
2181 (modify-syntax-entry ?8 "w" messages-mode-syntax-table)
2182 (modify-syntax-entry ?9 "w" messages-mode-syntax-table)
2183 (make-local-variable 'comment-start)
2184 (make-local-variable 'comment-end)
2185 (make-local-variable 'indent-line-function)
2186 (setq indent-line-function 'indent-relative)
2187 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
2188 (make-local-variable 'font-lock-defaults)
4bb22eea 2189 (make-local-variable 'messages-mode-keywords)
f617db13 2190 (let ((keywords
8d6d55b9
MW
2191 (mdw-regexps "array" "bitmap" "callback" "docs[ \t]+enum"
2192 "export" "enum" "fixed-octetstring" "flags"
2193 "harmless" "map" "nested" "optional"
2194 "optional-tagged" "package" "primitive"
2195 "primitive-nullfree" "relaxed[ \t]+enum"
2196 "set" "table" "tagged-optional" "union"
2197 "variadic" "vector" "version" "version-tag")))
4bb22eea 2198 (setq messages-mode-keywords
f617db13
MW
2199 (list
2200 (list (concat "\\<\\(" keywords "\\)\\>:")
2201 '(0 font-lock-keyword-face))
2202 '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
2203 '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
2204 (0 font-lock-variable-name-face))
2205 '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
2206 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2207 (0 mdw-punct-face)))))
2208 (setq font-lock-defaults
4bb22eea 2209 '(messages-mode-keywords nil nil nil nil))
f617db13
MW
2210 (run-hooks 'messages-file-hook))
2211
2212(defun messages-mode ()
2213 (interactive)
2214 (fundamental-mode)
2215 (setq major-mode 'messages-mode)
2216 (setq mode-name "Messages")
4bb22eea 2217 (messages-mode-guts)
f617db13
MW
2218 (modify-syntax-entry ?# "<" messages-mode-syntax-table)
2219 (modify-syntax-entry ?\n ">" messages-mode-syntax-table)
2220 (setq comment-start "# ")
2221 (setq comment-end "")
f617db13
MW
2222 (run-hooks 'messages-mode-hook))
2223
2224(defun cpp-messages-mode ()
2225 (interactive)
2226 (fundamental-mode)
2227 (setq major-mode 'cpp-messages-mode)
2228 (setq mode-name "CPP Messages")
4bb22eea 2229 (messages-mode-guts)
f617db13
MW
2230 (modify-syntax-entry ?* ". 23" messages-mode-syntax-table)
2231 (modify-syntax-entry ?/ ". 14" messages-mode-syntax-table)
2232 (setq comment-start "/* ")
2233 (setq comment-end " */")
2234 (let ((preprocessor-keywords
8d6d55b9
MW
2235 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
2236 "ident" "if" "ifdef" "ifndef" "import" "include"
2237 "line" "pragma" "unassert" "undef" "warning")))
4bb22eea 2238 (setq messages-mode-keywords
f617db13
MW
2239 (append (list (list (concat "^[ \t]*\\#[ \t]*"
2240 "\\(include\\|import\\)"
2241 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
2242 '(2 font-lock-string-face))
2243 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
2244 preprocessor-keywords
852cd5fb 2245 "\\)\\>\\|[0-9]+\\|$\\)\\)")
f617db13 2246 '(1 font-lock-keyword-face)))
4bb22eea 2247 messages-mode-keywords)))
297d60aa 2248 (run-hooks 'cpp-messages-mode-hook))
f617db13 2249
297d60aa
MW
2250(add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
2251(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
f617db13
MW
2252; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
2253
6132bc01
MW
2254;;;--------------------------------------------------------------------------
2255;;; Messages-file mode.
f617db13
MW
2256
2257(defvar mallow-driver-substitution-face 'mallow-driver-substitution-face
2258 "Face to use for subsittution directives.")
2259(make-face 'mallow-driver-substitution-face)
2260(defvar mallow-driver-text-face 'mallow-driver-text-face
2261 "Face to use for body text.")
2262(make-face 'mallow-driver-text-face)
2263
2264(defun mallow-driver-mode ()
2265 (interactive)
2266 (fundamental-mode)
2267 (setq major-mode 'mallow-driver-mode)
2268 (setq mode-name "Mallow driver")
2269 (setq mallow-driver-mode-syntax-table (make-syntax-table))
2270 (set-syntax-table mallow-driver-mode-syntax-table)
2271 (make-local-variable 'comment-start)
2272 (make-local-variable 'comment-end)
2273 (make-local-variable 'indent-line-function)
2274 (setq indent-line-function 'indent-relative)
2275 (mdw-standard-fill-prefix "\\([ \t]*\\(;\\|/?\\*\\)+[ \t]*\\)")
2276 (make-local-variable 'font-lock-defaults)
2277 (make-local-variable 'mallow-driver-mode-keywords)
2278 (let ((keywords
8d6d55b9
MW
2279 (mdw-regexps "each" "divert" "file" "if"
2280 "perl" "set" "string" "type" "write")))
f617db13
MW
2281 (setq mallow-driver-mode-keywords
2282 (list
2283 (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
2284 '(0 font-lock-keyword-face))
2285 (list "^%\\s *\\(#.*\\|\\)$"
2286 '(0 font-lock-comment-face))
2287 (list "^%"
2288 '(0 font-lock-keyword-face))
2289 (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
2290 (list "\\${[^}]*}"
2291 '(0 mallow-driver-substitution-face t)))))
2292 (setq font-lock-defaults
2293 '(mallow-driver-mode-keywords nil nil nil nil))
2294 (modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
2295 (modify-syntax-entry ?\n ">" mallow-driver-mode-syntax-table)
2296 (setq comment-start "%# ")
2297 (setq comment-end "")
f617db13
MW
2298 (run-hooks 'mallow-driver-mode-hook))
2299
2300(add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
2301
6132bc01
MW
2302;;;--------------------------------------------------------------------------
2303;;; NFast debugs.
f617db13
MW
2304
2305(defun nfast-debug-mode ()
2306 (interactive)
2307 (fundamental-mode)
2308 (setq major-mode 'nfast-debug-mode)
2309 (setq mode-name "NFast debug")
2310 (setq messages-mode-syntax-table (make-syntax-table))
2311 (set-syntax-table messages-mode-syntax-table)
2312 (make-local-variable 'font-lock-defaults)
2313 (make-local-variable 'nfast-debug-mode-keywords)
2314 (setq truncate-lines t)
2315 (setq nfast-debug-mode-keywords
2316 (list
2317 '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
2318 (0 font-lock-keyword-face))
2319 (list (concat "^[ \t]+\\(\\("
2320 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
2321 "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
2322 "[ \t]+\\)*"
2323 "[0-9a-fA-F]+\\)[ \t]*$")
2324 '(0 mdw-number-face))
2325 '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
2326 (1 font-lock-keyword-face))
2327 '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
2328 (1 font-lock-warning-face))
2329 '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
2330 (1 nil))
2331 (list (concat "^[ \t]+\\.cmd=[ \t]+"
2332 "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
2333 '(1 font-lock-keyword-face))
2334 '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
2335 '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
2336 '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
2337 '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
2338 (setq font-lock-defaults
2339 '(nfast-debug-mode-keywords nil nil nil nil))
f617db13
MW
2340 (run-hooks 'nfast-debug-mode-hook))
2341
6132bc01
MW
2342;;;--------------------------------------------------------------------------
2343;;; Other languages.
f617db13 2344
6132bc01 2345;; Smalltalk.
f617db13
MW
2346
2347(defun mdw-setup-smalltalk ()
2348 (and mdw-auto-indent
2349 (local-set-key "\C-m" 'smalltalk-newline-and-indent))
8a425bd7 2350 (make-local-variable 'mdw-auto-indent)
f617db13
MW
2351 (setq mdw-auto-indent nil)
2352 (local-set-key "\C-i" 'smalltalk-reindent))
2353
2354(defun mdw-fontify-smalltalk ()
02109a0d 2355 (make-local-variable 'font-lock-keywords)
f617db13
MW
2356 (setq font-lock-keywords
2357 (list
f617db13
MW
2358 (list "\\<[A-Z][a-zA-Z0-9]*\\>"
2359 '(0 font-lock-keyword-face))
2360 (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2361 "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2362 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
2363 '(0 mdw-number-face))
2364 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
2365 '(0 mdw-punct-face))))
2366 (mdw-post-config-mode-hack))
f617db13 2367
6132bc01 2368;; Lispy languages.
f617db13 2369
873d87df
MW
2370;; Unpleasant bodge.
2371(unless (boundp 'slime-repl-mode-map)
2372 (setq slime-repl-mode-map (make-sparse-keymap)))
2373
f617db13
MW
2374(defun mdw-indent-newline-and-indent ()
2375 (interactive)
2376 (indent-for-tab-command)
2377 (newline-and-indent))
2378
2379(eval-after-load "cl-indent"
2380 '(progn
2381 (mapc #'(lambda (pair)
2382 (put (car pair)
2383 'common-lisp-indent-function
2384 (cdr pair)))
2385 '((destructuring-bind . ((&whole 4 &rest 1) 4 &body))
2386 (multiple-value-bind . ((&whole 4 &rest 1) 4 &body))))))
2387
2388(defun mdw-common-lisp-indent ()
8a425bd7 2389 (make-local-variable 'lisp-indent-function)
f617db13
MW
2390 (setq lisp-indent-function 'common-lisp-indent-function))
2391
037be6de 2392(setq lisp-simple-loop-indentation 2
95575d1f
MW
2393 lisp-loop-keyword-indentation 6
2394 lisp-loop-forms-indentation 6)
2395
f617db13
MW
2396(defun mdw-fontify-lispy ()
2397
6132bc01 2398 ;; Set fill prefix.
f617db13
MW
2399 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
2400
6132bc01 2401 ;; Not much fontification needed.
02109a0d 2402 (make-local-variable 'font-lock-keywords)
f617db13
MW
2403 (setq font-lock-keywords
2404 (list
f617db13 2405 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
ed7b46b9
MW
2406 '(0 mdw-punct-face))))
2407
2408 (mdw-post-config-mode-hack))
f617db13
MW
2409
2410(defun comint-send-and-indent ()
2411 (interactive)
2412 (comint-send-input)
2413 (and mdw-auto-indent
2414 (indent-for-tab-command)))
2415
ec007bea
MW
2416(defun mdw-setup-m4 ()
2417 (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
2418
6132bc01
MW
2419;;;--------------------------------------------------------------------------
2420;;; Text mode.
f617db13
MW
2421
2422(defun mdw-text-mode ()
2423 (setq fill-column 72)
2424 (flyspell-mode t)
2425 (mdw-standard-fill-prefix
c7a8da49 2426 "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
f617db13
MW
2427 (auto-fill-mode 1))
2428
6132bc01 2429;;;--------------------------------------------------------------------------
faf2cef7 2430;;; Outline and hide/show modes.
5de5db48
MW
2431
2432(defun mdw-outline-collapse-all ()
2433 "Completely collapse everything in the entire buffer."
2434 (interactive)
2435 (save-excursion
2436 (goto-char (point-min))
2437 (while (< (point) (point-max))
2438 (hide-subtree)
2439 (forward-line))))
2440
faf2cef7
MW
2441(setq hs-hide-comments-when-hiding-all nil)
2442
b200af26 2443(defadvice hs-hide-all (after hide-first-comment activate)
941c29ba 2444 (save-excursion (hs-hide-initial-comment-block)))
b200af26 2445
6132bc01
MW
2446;;;--------------------------------------------------------------------------
2447;;; Shell mode.
f617db13
MW
2448
2449(defun mdw-sh-mode-setup ()
2450 (local-set-key [?\C-a] 'comint-bol)
2451 (add-hook 'comint-output-filter-functions
2452 'comint-watch-for-password-prompt))
2453
2454(defun mdw-term-mode-setup ()
3d9147ea 2455 (setq term-prompt-regexp shell-prompt-pattern)
f617db13
MW
2456 (make-local-variable 'mouse-yank-at-point)
2457 (make-local-variable 'transient-mark-mode)
2458 (setq mouse-yank-at-point t)
f617db13
MW
2459 (auto-fill-mode -1)
2460 (setq tab-width 8))
2461
3d9147ea
MW
2462(defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
2463(defun term-send-meta-left () (interactive) (term-send-raw-string "\e\e[D"))
2464(defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
2465(defun term-send-meta-meta-something ()
2466 (interactive)
2467 (term-send-raw-string "\e\e")
2468 (term-send-raw))
2469(eval-after-load 'term
2470 '(progn
2471 (define-key term-raw-map [?\e ?\e] nil)
2472 (define-key term-raw-map [?\e ?\e t] 'term-send-meta-meta-something)
2473 (define-key term-raw-map [?\C-/] 'term-send-ctrl-uscore)
2474 (define-key term-raw-map [M-right] 'term-send-meta-right)
2475 (define-key term-raw-map [?\e ?\M-O ?C] 'term-send-meta-right)
2476 (define-key term-raw-map [M-left] 'term-send-meta-left)
2477 (define-key term-raw-map [?\e ?\M-O ?D] 'term-send-meta-left)))
2478
c4434c20
MW
2479(defadvice term-exec (before program-args-list compile activate)
2480 "If the PROGRAM argument is a list, interpret it as (PROGRAM . SWITCHES).
2481This allows you to pass a list of arguments through `ansi-term'."
2482 (let ((program (ad-get-arg 2)))
2483 (if (listp program)
2484 (progn
2485 (ad-set-arg 2 (car program))
2486 (ad-set-arg 4 (cdr program))))))
2487
2488(defun ssh (host)
2489 "Open a terminal containing an ssh session to the HOST."
2490 (interactive "sHost: ")
2491 (ansi-term (list "ssh" host) (format "ssh@%s" host)))
2492
e07e3320
MW
2493;;;--------------------------------------------------------------------------
2494;;; Inferior Emacs Lisp.
2495
2496(setq comint-prompt-read-only t)
2497
2498(eval-after-load "comint"
2499 '(progn
2500 (define-key comint-mode-map "\C-w" 'comint-kill-region)
2501 (define-key comint-mode-map [C-S-backspace] 'comint-kill-whole-line)))
2502
2503(eval-after-load "ielm"
2504 '(progn
2505 (define-key ielm-map "\C-w" 'comint-kill-region)
2506 (define-key ielm-map [C-S-backspace] 'comint-kill-whole-line)))
2507
f617db13
MW
2508;;;----- That's all, folks --------------------------------------------------
2509
2510(provide 'dot-emacs)