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