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