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