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