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