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