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