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