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