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