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