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