el/dot-emacs.el: Move `mdw-compile' into its own section.
[profile] / el / dot-emacs.el
1 ;;; -*- mode: emacs-lisp; coding: utf-8 -*-
2 ;;;
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.
14 ;;;
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.
19 ;;;
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
24 ;;;--------------------------------------------------------------------------
25 ;;; Check command-line.
26
27 (defvar mdw-fast-startup nil
28 "Whether .emacs should optimize for rapid startup.
29 This may be at the expense of cool features.")
30 (let ((probe nil) (next command-line-args))
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
41 ;;;--------------------------------------------------------------------------
42 ;;; Some general utilities.
43
44 (eval-when-compile
45 (unless (fboundp 'make-regexp)
46 (load "make-regexp"))
47 (require 'cl))
48
49 (defmacro mdw-regexps (&rest list)
50 "Turn a LIST of strings into a single regular expression at compile-time."
51 (declare (indent nil)
52 (debug 0))
53 `',(make-regexp list))
54
55 (defun mdw-wrong ()
56 "This is not the key sequence you're looking for."
57 (interactive)
58 (error "wrong button"))
59
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
66 ;; Some error trapping.
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."
73 (declare (indent 0)
74 (debug t))
75 `(condition-case err
76 ,(if (cdr forms) (cons 'progn forms) (car forms))
77 (error (message "Error (trapped): %s in %s"
78 (error-message-string err)
79 ',forms))))
80
81 ;; Configuration reading.
82
83 (defvar mdw-config nil)
84 (defun mdw-config (sym)
85 "Read the configuration variable named SYM."
86 (unless mdw-config
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) ")")))))))
103 (cdr (assq sym mdw-config)))
104
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
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
122 ;; Set up the load path convincingly.
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
133 ;; Is an Emacs library available?
134
135 (defun library-exists-p (name)
136 "Return non-nil if NAME is an available library.
137 Return non-nil if NAME.el (or NAME.elc) somewhere on the Emacs
138 load path. The non-nil value is the filename we found for the
139 library."
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
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
163 ;; Splitting windows.
164
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
176 (defun mdw-horizontal-window-overhead ()
177 "Computes the horizontal window overhead.
178 This is the number of columns used by fringes, scroll bars and other such
179 cruft."
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.
191 Without a numeric argument, split the window approximately in
192 half. With a numeric argument WIDTH, allocate WIDTH columns to
193 the left-hand window (if positive) or -WIDTH columns to the
194 right-hand window (if negative). Space for scroll bars and
195 fringes 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
203 (defun mdw-divvy-window (&optional width)
204 "Split a wide window into appropriate widths."
205 (interactive "P")
206 (setq width (cond (width (prefix-numeric-value width))
207 ((and window-system (mdw-emacs-version-p 22))
208 mdw-column-width)
209 (t (1+ mdw-column-width))))
210 (let* ((win (selected-window))
211 (sb-width (mdw-horizontal-window-overhead))
212 (c (/ (+ (window-width) sb-width)
213 (+ width sb-width))))
214 (while (> c 1)
215 (setq c (1- c))
216 (split-window-horizontally (+ width sb-width))
217 (other-window 1))
218 (select-window win)))
219
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
228 frame 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)
242 (mdw-advise-to-inhibit-raise-frame appt-disp-window)
243
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
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
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.
282 If `transient-mark-mode' is on and the mark is inactive, then
283 just activate it. A non-trivial prefix argument will force the
284 usual behaviour. A trivial prefix argument (i.e., just C-u) will
285 activate the mark and temporarily enable `transient-mark-mode' if
286 it'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
296 ;; Functions for sexp diary entries.
297
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
303 (defun mdw-weekday (l)
304 "Return non-nil if `date' falls on one of the days of the week in L.
305 L is a list of day numbers (from 0 to 6 for Sunday through to
306 Saturday) or symbols `sunday', `monday', etc. (or a mixture). If
307 the date stored in `date' falls on a listed day, then the
308 function returns non-nil."
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
314 (defun mdw-discordian-date (date)
315 "Return the Discordian calendar date corresponding to DATE.
316
317 The return value is (YOLD . st-tibs-day) or (YOLD SEASON DAYNUM DOW).
318
319 The original is by David Pearson. I modified it to produce date components
320 as 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
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
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
383 (defadvice diary-add-to-list (before mdw-trim-leading-space compile activate)
384 "Trim leading space from the diary entry string."
385 (save-match-data
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))
393 ((and mdw-diary-for-org-mode-p
394 (string-match (concat
395 "\\(^\\|\n\\)"
396 "\\(" diary-time-regexp
397 "\\(-" diary-time-regexp "\\)?"
398 "\\)"
399 "\\(\t[ \t]*\\| [ \t]+\\)")
400 str))
401 (replace-match "\\1\\2 " nil nil str))
402 ((and (not mdw-diary-for-org-mode-p)
403 (string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]"
404 str))
405 (replace-match "\\1" nil nil str))
406 (t str)))
407 (if (equal str old) (setq done t)))
408 (ad-set-arg 1 str))))
409
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
423 ;; Fighting with Org-mode's evil key maps.
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'.
435 The value is an alist mapping evil keys (as a list, or singleton)
436 to good keys (in the same form).")
437
438 (defun mdw-clobber-evil-keymap (keymap)
439 "Replace evil key bindings in the KEYMAP.
440 Evil 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
460 (eval-after-load "org-latex"
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
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
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.
498 This is used by advice on `switch-to-buffer-other-frame' to inhibit finding
499 buffers 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.
509 Even 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.
514 Pretend they don't exist. They might be on other display devices."
515 (ad-set-arg 2 nil))
516
517 ;;;--------------------------------------------------------------------------
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.
540 The DIRECTORY may be nil to not change. If COMINT is t, then
541 start an interactive compilation.
542
543 Interactively, prompt for the command if the variable
544 `compilation-read-command' is non-nil, or if requested through
545 the prefix argument. Prompt for the directory, and run
546 interactively, if requested through the prefix.
547
548 Use a prefix of 4, 6, 12, or 14, or type C-u between one and three times, to
549 force prompting for a directory.
550
551 Use a prefix of 2, 6, 10, or 14, or type C-u three times, to force
552 prompting for the command.
553
554 Use a prefix of 8, 10, 12, or 14, or type C-u twice or three times,
555 to 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 ;;;--------------------------------------------------------------------------
571 ;;; Mail and news hacking.
572
573 (define-derived-mode mdwmail-mode mail-mode "[mdw] mail"
574 "Major mode for editing news and mail messages from external programs.
575 Not 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
594 ;; How to encrypt in mdwmail.
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
605 ;; How to sign in mdwmail.
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
616 ;; Some signature mangling.
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
625 ;; Insert my login name into message-ids, so I can score replies.
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,
629 so that it can be used for convenient filtering."
630 (setq ad-return-value (concat ad-return-value "." (user-login-name))))
631
632 ;; Tell my movemail hack where movemail is.
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
643 ;; AUTHINFO GENERIC kludge.
644
645 (defvar nntp-authinfo-generic nil
646 "Set to the `NNTPAUTH' string to pass on to `authinfo-kludge'.
647
648 Use 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
664 (eval-after-load "erc"
665 '(load "~/.ercrc.el"))
666
667 ;;;--------------------------------------------------------------------------
668 ;;; Utility functions.
669
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))))))))
682
683 (defun mdw-uniquify-alist (&rest alists)
684 "Return the concatenation of the ALISTS with duplicate elements removed.
685 The first association with a given key prevails; others are
686 ignored. The input lists are not modified, although they'll
687 probably become garbage."
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
695 (defun mdw-do-uniquify (done end l rest)
696 "A helper function for mdw-uniquify-alist.
697 The DONE argument is a list whose first element is `nil'. It
698 contains the uniquified alist built so far. The leading `nil' is
699 stripped off at the end of the operation; it's only there so that
700 DONE always references a cons cell. END refers to the final cons
701 cell in the DONE list; it is modified in place each time to avoid
702 the overheads of `append'ing all the time. The L argument is the
703 alist we're currently processing; the remaining alists are given
704 in REST."
705
706 ;; There are several different cases to deal with here.
707 (cond
708
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.
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
717 ;; The list we were working on is empty. Shunt the next list into the
718 ;; current list position and go round again.
719 (rest (mdw-do-uniquify done end (car rest) (cdr rest)))
720
721 ;; Everything's done. Remove the leading `nil' from the DONE list and
722 ;; return it. Finished!
723 (t (cdr done))))
724
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
738 (defun uuencode (file &optional name)
739 "UUencodes a file, maybe calling it NAME, into the current buffer."
740 (interactive "fInput file name: ")
741
742 ;; If NAME isn't specified, then guess from the filename.
743 (if (not name)
744 (setq name
745 (substring file
746 (or (string-match "[^/]*$" file) 0))))
747 (print (format "uuencode `%s' `%s'" file name))
748
749 ;; Now actually do the thing.
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
760 (goto-char (point-max))
761 (insert "\nNP: ")
762 (insert-file-contents np-file)))))
763
764 (defun mdw-version-< (ver-a ver-b)
765 "Answer whether VER-A is strictly earlier than VER-B.
766 VER-A and VER-B are version numbers, which are strings containing digit
767 sequences 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))
777 ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb)))
778 (t (throw 'done nil)))))))
779
780 (defun mdw-check-autorevert ()
781 "Sets global-auto-revert-ignore-buffer appropriately for this buffer.
782 This takes into consideration whether it's been found using
783 tramp, which seems to get itself into a twist."
784 (cond ((not (boundp 'global-auto-revert-ignore-buffer))
785 nil)
786 ((and (buffer-file-name)
787 (fboundp 'tramp-tramp-file-p)
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)
797 (mdw-check-autorevert))
798
799 ;;;--------------------------------------------------------------------------
800 ;;; Dired hacking.
801
802 (defadvice dired-maybe-insert-subdir
803 (around mdw-marked-insertion first activate)
804 "The DIRNAME may be a list of directory names to insert.
805 Interactively, if files are marked, then insert all of them.
806 With a numeric prefix argument, select that many entries near
807 point; with a non-numeric prefix argument, prompt for listing
808 options."
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
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
835 ;;;--------------------------------------------------------------------------
836 ;;; URL viewing.
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.
840 If NEW-SESSION-P, start a new session."
841 (interactive "sURL: \nP")
842 (save-excursion
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)))))
853
854 (defvar mdw-good-url-browsers
855 '(browse-url-mozilla
856 browse-url-generic
857 (w3m . mdw-w3m-browse-url)
858 browse-url-w3)
859 "List of good browsers for mdw-good-url-browsers.
860 Each item is a browser function name, or a cons (CHECK . FUNC).
861 A symbol FOO stands for (FOO . FOO).")
862
863 (defun mdw-good-url-browser ()
864 "Return a good URL browser.
865 Trundle the list of such things, finding the first item for which
866 CHECK is fboundp, and returning the correponding FUNC."
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
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
914 ;;;--------------------------------------------------------------------------
915 ;;; Paragraph filling.
916
917 ;; Useful variables.
918
919 (defvar mdw-fill-prefix nil
920 "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
921 If there's no fill prefix currently set (by the `fill-prefix'
922 variable) and there's a match from one of the regexps here, it
923 gets used to set the fill-prefix for the current operation.
924
925 The variable is a list of items of the form `REGEXP . PREFIX'; if
926 the REGEXP matches, the PREFIX is used to set the fill prefix.
927 It in turn is a list of things:
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
937 (concat "\\(\\("
938 "\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
939 "[ \t]+"
940 "\\)?\\)")
941 "*Standard regexp matching parts of a hanging indent.
942 This is mainly useful in `auto-fill-mode'.")
943
944 ;; Setting things up.
945
946 (fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
947
948 ;; Utility functions.
949
950 (defun mdw-maybe-tabify (s)
951 "Tabify or untabify the string S, according to `indent-tabs-mode'."
952 (let ((tabfun (if indent-tabs-mode #'tabify #'untabify)))
953 (with-temp-buffer
954 (save-match-data
955 (insert s "\n")
956 (let ((start (point-min)) (end (point-max)))
957 (funcall tabfun (point-min) (point-max))
958 (setq s (buffer-substring (point-min) (1- (point-max)))))))))
959
960 (defun mdw-examine-fill-prefixes (l)
961 "Given a list of dynamic fill prefixes, pick one which matches
962 context and return the static fill prefix to use. Point must be
963 at the start of a line, and match data must be saved."
964 (cond ((not l) nil)
965 ((looking-at (car (car l)))
966 (mdw-maybe-tabify (apply #'concat
967 (mapcar #'mdw-do-prefix-match
968 (cdr (car l))))))
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)
985 "Expand a dynamic prefix match element.
986 See `mdw-fill-prefix' for details."
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 ()
1004 "Handle auto-filling, working out a dynamic fill prefix in the
1005 case where there isn't a sensible static one."
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.
1017 This is just a short-cut for setting the thing by hand, and by
1018 design it doesn't cope with anything approximating a complicated
1019 case."
1020 (setq mdw-fill-prefix
1021 `((,(concat rx mdw-hanging-indents)
1022 (match . 1)
1023 (pad . ,(or mat 2))))))
1024
1025 ;;;--------------------------------------------------------------------------
1026 ;;; Other common declarations.
1027
1028 ;; Common mode settings.
1029
1030 (defvar mdw-auto-indent t
1031 "Whether to indent automatically after a newline.")
1032
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)))
1039 (whitespace-mode arg))
1040 (setq show-trailing-whitespace whitespace-mode)))
1041
1042 (defvar mdw-do-misc-mode-hacking nil)
1043
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))
1048 ((or (eq major-mode 'slime-repl-mode)
1049 (eq major-mode 'asm-mode))
1050 nil)
1051 (t
1052 (local-set-key "\C-m" 'newline-and-indent))))
1053 (set (make-local-variable 'mdw-do-misc-mode-hacking) t)
1054 (local-set-key [C-return] 'newline)
1055 (make-local-variable 'page-delimiter)
1056 (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
1057 (setq comment-column 40)
1058 (auto-fill-mode 1)
1059 (setq fill-column mdw-text-width)
1060 (and (fboundp 'gtags-mode)
1061 (gtags-mode))
1062 (if (fboundp 'hs-minor-mode)
1063 (trap (hs-minor-mode t))
1064 (outline-minor-mode t))
1065 (reveal-mode t)
1066 (trap (turn-on-font-lock)))
1067
1068 (defun mdw-post-local-vars-misc-mode-config ()
1069 (setq whitespace-line-column mdw-text-width)
1070 (when (and mdw-do-misc-mode-hacking
1071 (not buffer-read-only))
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)
1075
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)
1090
1091 (eval-after-load 'gtags
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))))
1100
1101 ;; Backup file handling.
1102
1103 (defvar mdw-backup-disable-regexps nil
1104 "*List of regular expressions: if a file name matches any of
1105 these then the file is not backed up.")
1106
1107 (defun mdw-backup-enable-predicate (name)
1108 "[mdw]'s default backup predicate.
1109 Allows a backup if the standard predicate would allow it, and it
1110 doesn't match any of the regular expressions in
1111 `mdw-backup-disable-regexps'."
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
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)
1130 (and (not (eq fr frame))
1131 (string= (frame-parameter fr 'display)
1132 frame-display)))
1133 (frame-list))))
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
1137 ;;;--------------------------------------------------------------------------
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 ;;;--------------------------------------------------------------------------
1173 ;;; General fontification.
1174
1175 (make-face 'mdw-virgin-face)
1176
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
1182 (copy-face 'mdw-virgin-face ',name)
1183 (defvar ,name ',name)
1184 (put ',name 'face-defface-spec ',body)
1185 (face-spec-set ',name ',body nil)))
1186
1187 (mdw-define-face default
1188 (((type w32)) :family "courier new" :height 85)
1189 (((type x)) :family "6x13" :foundry "trad" :height 130)
1190 (((type color)) :foreground "white" :background "black")
1191 (t nil))
1192 (mdw-define-face fixed-pitch
1193 (((type w32)) :family "courier new" :height 85)
1194 (((type x)) :family "6x13" :foundry "trad" :height 130)
1195 (t :foreground "white" :background "black"))
1196 (if (mdw-emacs-version-p 23)
1197 (mdw-define-face variable-pitch
1198 (((type x)) :family "sans" :height 100))
1199 (mdw-define-face variable-pitch
1200 (((type x)) :family "helvetica" :height 90)))
1201 (mdw-define-face region
1202 (((min-colors 64)) :background "grey30")
1203 (((class color)) :background "blue")
1204 (t :inverse-video t))
1205 (mdw-define-face match
1206 (((class color)) :background "blue")
1207 (t :inverse-video t))
1208 (mdw-define-face mc/cursor-face
1209 (((class color)) :background "red")
1210 (t :inverse-video t))
1211 (mdw-define-face minibuffer-prompt
1212 (t :weight bold))
1213 (mdw-define-face mode-line
1214 (((class color)) :foreground "blue" :background "yellow"
1215 :box (:line-width 1 :style released-button))
1216 (t :inverse-video t))
1217 (mdw-define-face mode-line-inactive
1218 (((class color)) :foreground "yellow" :background "blue"
1219 :box (:line-width 1 :style released-button))
1220 (t :inverse-video t))
1221 (mdw-define-face nobreak-space
1222 (((type tty)))
1223 (t :inherit escape-glyph :underline t))
1224 (mdw-define-face scroll-bar
1225 (t :foreground "black" :background "lightgrey"))
1226 (mdw-define-face fringe
1227 (t :foreground "yellow"))
1228 (mdw-define-face show-paren-match
1229 (((min-colors 64)) :background "darkgreen")
1230 (((class color)) :background "green")
1231 (t :underline t))
1232 (mdw-define-face show-paren-mismatch
1233 (((class color)) :background "red")
1234 (t :inverse-video t))
1235 (mdw-define-face highlight
1236 (((min-colors 64)) :background "DarkSeaGreen4")
1237 (((class color)) :background "cyan")
1238 (t :inverse-video t))
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))
1247 (mdw-define-face comint-highlight-input
1248 (t nil))
1249
1250 (mdw-define-face ido-subdir
1251 (t :foreground "cyan" :weight bold))
1252
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
1260 (mdw-define-face trailing-whitespace
1261 (((class color)) :background "red")
1262 (t :inverse-video t))
1263 (mdw-define-face whitespace-line
1264 (((class color)) :background "darkred")
1265 (t :inverse-video t))
1266 (mdw-define-face mdw-punct-face
1267 (((min-colors 64)) :foreground "burlywood2")
1268 (((class color)) :foreground "yellow"))
1269 (mdw-define-face mdw-number-face
1270 (t :foreground "yellow"))
1271 (mdw-define-face mdw-trivial-face)
1272 (mdw-define-face font-lock-function-name-face
1273 (t :slant italic))
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))
1280 (mdw-define-face font-lock-type-face
1281 (t :weight bold :slant italic))
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
1287 (((min-colors 64)) :slant italic :foreground "SeaGreen1")
1288 (((class color)) :foreground "green")
1289 (t :weight bold))
1290 (mdw-define-face font-lock-comment-face
1291 (((min-colors 64)) :slant italic :foreground "SeaGreen1")
1292 (((class color)) :foreground "green")
1293 (t :weight bold))
1294 (mdw-define-face font-lock-string-face
1295 (((min-colors 64)) :foreground "SkyBlue1")
1296 (((class color)) :foreground "cyan")
1297 (t :weight bold))
1298
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)
1303 (((min-colors 64)) :foreground "SkyBlue1")
1304 (((class color)) :foreground "cyan"))
1305 (mdw-define-face message-header-cc
1306 (default :slant italic)
1307 (((min-colors 64)) :foreground "SeaGreen1")
1308 (((class color)) :foreground "green"))
1309 (mdw-define-face message-header-newsgroups
1310 (default :slant italic)
1311 (((min-colors 64)) :foreground "SeaGreen1")
1312 (((class color)) :foreground "green"))
1313 (mdw-define-face message-header-subject
1314 (((min-colors 64)) :foreground "SeaGreen1")
1315 (((class color)) :foreground "green"))
1316 (mdw-define-face message-header-to
1317 (((min-colors 64)) :foreground "SeaGreen1")
1318 (((class color)) :foreground "green"))
1319 (mdw-define-face message-header-xheader
1320 (default :slant italic)
1321 (((min-colors 64)) :foreground "SeaGreen1")
1322 (((class color)) :foreground "green"))
1323 (mdw-define-face message-header-other
1324 (default :slant italic)
1325 (((min-colors 64)) :foreground "SeaGreen1")
1326 (((class color)) :foreground "green"))
1327 (mdw-define-face message-header-name
1328 (default :weight bold)
1329 (((min-colors 64)) :foreground "SeaGreen1")
1330 (((class color)) :foreground "green"))
1331
1332 (mdw-define-face which-func
1333 (t nil))
1334
1335 (mdw-define-face gnus-header-name
1336 (default :weight bold)
1337 (((min-colors 64)) :foreground "SeaGreen1")
1338 (((class color)) :foreground "green"))
1339 (mdw-define-face gnus-header-subject
1340 (((min-colors 64)) :foreground "SeaGreen1")
1341 (((class color)) :foreground "green"))
1342 (mdw-define-face gnus-header-from
1343 (((min-colors 64)) :foreground "SeaGreen1")
1344 (((class color)) :foreground "green"))
1345 (mdw-define-face gnus-header-to
1346 (((min-colors 64)) :foreground "SeaGreen1")
1347 (((class color)) :foreground "green"))
1348 (mdw-define-face gnus-header-content
1349 (default :slant italic)
1350 (((min-colors 64)) :foreground "SeaGreen1")
1351 (((class color)) :foreground "green"))
1352
1353 (mdw-define-face gnus-cite-1
1354 (((min-colors 64)) :foreground "SkyBlue1")
1355 (((class color)) :foreground "cyan"))
1356 (mdw-define-face gnus-cite-2
1357 (((min-colors 64)) :foreground "RoyalBlue2")
1358 (((class color)) :foreground "blue"))
1359 (mdw-define-face gnus-cite-3
1360 (((min-colors 64)) :foreground "MediumOrchid")
1361 (((class color)) :foreground "magenta"))
1362 (mdw-define-face gnus-cite-4
1363 (((min-colors 64)) :foreground "firebrick2")
1364 (((class color)) :foreground "red"))
1365 (mdw-define-face gnus-cite-5
1366 (((min-colors 64)) :foreground "burlywood2")
1367 (((class color)) :foreground "yellow"))
1368 (mdw-define-face gnus-cite-6
1369 (((min-colors 64)) :foreground "SeaGreen1")
1370 (((class color)) :foreground "green"))
1371 (mdw-define-face gnus-cite-7
1372 (((min-colors 64)) :foreground "SlateBlue1")
1373 (((class color)) :foreground "cyan"))
1374 (mdw-define-face gnus-cite-8
1375 (((min-colors 64)) :foreground "RoyalBlue2")
1376 (((class color)) :foreground "blue"))
1377 (mdw-define-face gnus-cite-9
1378 (((min-colors 64)) :foreground "purple2")
1379 (((class color)) :foreground "magenta"))
1380 (mdw-define-face gnus-cite-10
1381 (((min-colors 64)) :foreground "DarkOrange2")
1382 (((class color)) :foreground "red"))
1383 (mdw-define-face gnus-cite-11
1384 (t :foreground "grey"))
1385
1386 (mdw-define-face diff-header
1387 (t nil))
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
1393 (((min-colors 64)) :foreground "SkyBlue1")
1394 (((class color)) :foreground "cyan"))
1395 (mdw-define-face diff-function
1396 (default :weight bold)
1397 (((min-colors 64)) :foreground "SkyBlue1")
1398 (((class color)) :foreground "cyan"))
1399 (mdw-define-face diff-header
1400 (((min-colors 64)) :background "grey10"))
1401 (mdw-define-face diff-added
1402 (((class color)) :foreground "green"))
1403 (mdw-define-face diff-removed
1404 (((class color)) :foreground "red"))
1405 (mdw-define-face diff-context
1406 (t nil))
1407 (mdw-define-face diff-refine-change
1408 (((min-colors 64)) :background "RoyalBlue4")
1409 (t :underline t))
1410 (mdw-define-face diff-refine-removed
1411 (((min-colors 64)) :background "#500")
1412 (t :underline t))
1413 (mdw-define-face diff-refine-added
1414 (((min-colors 64)) :background "#050")
1415 (t :underline t))
1416
1417 (setq ediff-force-faces t)
1418 (mdw-define-face ediff-current-diff-A
1419 (((min-colors 64)) :background "darkred")
1420 (((class color)) :background "red")
1421 (t :inverse-video t))
1422 (mdw-define-face ediff-fine-diff-A
1423 (((min-colors 64)) :background "red3")
1424 (((class color)) :inverse-video t)
1425 (t :inverse-video nil))
1426 (mdw-define-face ediff-even-diff-A
1427 (((min-colors 64)) :background "#300"))
1428 (mdw-define-face ediff-odd-diff-A
1429 (((min-colors 64)) :background "#300"))
1430 (mdw-define-face ediff-current-diff-B
1431 (((min-colors 64)) :background "darkgreen")
1432 (((class color)) :background "magenta")
1433 (t :inverse-video t))
1434 (mdw-define-face ediff-fine-diff-B
1435 (((min-colors 64)) :background "green4")
1436 (((class color)) :inverse-video t)
1437 (t :inverse-video nil))
1438 (mdw-define-face ediff-even-diff-B
1439 (((min-colors 64)) :background "#020"))
1440 (mdw-define-face ediff-odd-diff-B
1441 (((min-colors 64)) :background "#020"))
1442 (mdw-define-face ediff-current-diff-C
1443 (((min-colors 64)) :background "darkblue")
1444 (((class color)) :background "blue")
1445 (t :inverse-video t))
1446 (mdw-define-face ediff-fine-diff-C
1447 (((min-colors 64)) :background "blue1")
1448 (((class color)) :inverse-video t)
1449 (t :inverse-video nil))
1450 (mdw-define-face ediff-even-diff-C
1451 (((min-colors 64)) :background "#004"))
1452 (mdw-define-face ediff-odd-diff-C
1453 (((min-colors 64)) :background "#004"))
1454 (mdw-define-face ediff-current-diff-Ancestor
1455 (((min-colors 64)) :background "#630")
1456 (((class color)) :background "blue")
1457 (t :inverse-video t))
1458 (mdw-define-face ediff-even-diff-Ancestor
1459 (((min-colors 64)) :background "#320"))
1460 (mdw-define-face ediff-odd-diff-Ancestor
1461 (((min-colors 64)) :background "#320"))
1462
1463 (mdw-define-face magit-hash
1464 (((min-colors 64)) :foreground "grey40")
1465 (((class color)) :foreground "blue"))
1466 (mdw-define-face magit-diff-hunk-heading
1467 (((min-colors 64)) :foreground "grey70" :background "grey25")
1468 (((class color)) :foreground "yellow"))
1469 (mdw-define-face magit-diff-hunk-heading-highlight
1470 (((min-colors 64)) :foreground "grey70" :background "grey35")
1471 (((class color)) :foreground "yellow" :background "blue"))
1472 (mdw-define-face magit-diff-added
1473 (((min-colors 64)) :foreground "#ddffdd" :background "#335533")
1474 (((class color)) :foreground "green"))
1475 (mdw-define-face magit-diff-added-highlight
1476 (((min-colors 64)) :foreground "#cceecc" :background "#336633")
1477 (((class color)) :foreground "green" :background "blue"))
1478 (mdw-define-face magit-diff-removed
1479 (((min-colors 64)) :foreground "#ffdddd" :background "#553333")
1480 (((class color)) :foreground "red"))
1481 (mdw-define-face magit-diff-removed-highlight
1482 (((min-colors 64)) :foreground "#eecccc" :background "#663333")
1483 (((class color)) :foreground "red" :background "blue"))
1484
1485 (mdw-define-face dylan-header-background
1486 (((min-colors 64)) :background "NavyBlue")
1487 (((class color)) :background "blue"))
1488
1489 (mdw-define-face erc-input-face
1490 (t :foreground "red"))
1491
1492 (mdw-define-face woman-bold
1493 (t :weight bold))
1494 (mdw-define-face woman-italic
1495 (t :slant italic))
1496
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 ())))
1511
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
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
1536 (mdw-define-face whizzy-slice-face
1537 (t :background "grey10"))
1538 (mdw-define-face whizzy-error-face
1539 (t :background "darkred"))
1540
1541 ;; Ellipses used to indicate hidden text (and similar).
1542 (mdw-define-face mdw-ellipsis-face
1543 (((type tty)) :foreground "blue") (t :foreground "grey60"))
1544 (let ((dollar (make-glyph-code ?$ 'mdw-ellipsis-face))
1545 (backslash (make-glyph-code ?\\ 'mdw-ellipsis-face))
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)
1550 (set-display-table-slot standard-display-table 4
1551 (vector dot dot dot))
1552 (set-display-table-slot standard-display-table 5 bar))
1553
1554 ;;;--------------------------------------------------------------------------
1555 ;;; Where is point?
1556
1557 (mdw-define-face mdw-point-overlay-face
1558 (((type graphic)))
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)))
1581 (overlay-put ov 'face 'mdw-point-overlay-face)
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 ;;;--------------------------------------------------------------------------
1633 ;;; C programming configuration.
1634
1635 ;; Make C indentation nice.
1636
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
1653 (defun mdw-c-indent-arglist-nested (langelem)
1654 "Indent continued argument lists.
1655 If we've nested more than one argument list, then only introduce a single
1656 indentation 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
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.
1674 A function, named `mdw-define-c-style/NAME', is defined to actually install
1675 the 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
1677 set."
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
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 . +)
1709 (access-label . -2)
1710 (inclass . +)
1711 (inline-open . ++)
1712 (statement-cont . +)
1713 (statement-case-intro . +)))
1714
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
1739 MODES may be a list of major mode names or a singleton. STYLE is a style
1740 name, 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)
1755
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
1765 (defun mdw-fontify-c-and-c++ ()
1766
1767 ;; Fiddle with some syntax codes.
1768 (modify-syntax-entry ?* ". 23")
1769 (modify-syntax-entry ?/ ". 124b")
1770 (modify-syntax-entry ?\n "> b")
1771
1772 ;; Other stuff.
1773 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1774
1775 ;; Now define things to be fontified.
1776 (make-local-variable 'font-lock-keywords)
1777 (let ((c-keywords
1778 (mdw-regexps "alignas" ;C11 macro, C++11
1779 "alignof" ;C++11
1780 "and" ;C++, C95 macro
1781 "and_eq" ;C++, C95 macro
1782 "asm" ;K&R, C++, GCC
1783 "atomic" ;C11 macro, C++11 template type
1784 "auto" ;K&R, C89
1785 "bitand" ;C++, C95 macro
1786 "bitor" ;C++, C95 macro
1787 "bool" ;C++, C99 macro
1788 "break" ;K&R, C89
1789 "case" ;K&R, C89
1790 "catch" ;C++
1791 "char" ;K&R, C89
1792 "char16_t" ;C++11, C11 library type
1793 "char32_t" ;C++11, C11 library type
1794 "class" ;C++
1795 "complex" ;C99 macro, C++ template type
1796 "compl" ;C++, C95 macro
1797 "const" ;C89
1798 "constexpr" ;C++11
1799 "const_cast" ;C++
1800 "continue" ;K&R, C89
1801 "decltype" ;C++11
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
1820 "imaginary" ;C99 macro
1821 "inline" ;C++, C99, GCC
1822 "int" ;K&R, C89
1823 "long" ;K&R, C89
1824 "mutable" ;C++
1825 "namespace" ;C++
1826 "new" ;C++
1827 "noexcept" ;C++11
1828 "noreturn" ;C11 macro
1829 "not" ;C++, C95 macro
1830 "not_eq" ;C++, C95 macro
1831 "nullptr" ;C++11
1832 "operator" ;C++
1833 "or" ;C++, C95 macro
1834 "or_eq" ;C++, C95 macro
1835 "private" ;C++
1836 "protected" ;C++
1837 "public" ;C++
1838 "register" ;K&R, C89
1839 "reinterpret_cast" ;C++
1840 "restrict" ;C99
1841 "return" ;K&R, C89
1842 "short" ;K&R, C89
1843 "signed" ;C89
1844 "sizeof" ;K&R, C89
1845 "static" ;K&R, C89
1846 "static_assert" ;C11 macro, C++11
1847 "static_cast" ;C++
1848 "struct" ;K&R, C89
1849 "switch" ;K&R, C89
1850 "template" ;C++
1851 "throw" ;C++
1852 "try" ;C++
1853 "thread_local" ;C11 macro, C++11
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
1866 "xor" ;C++, C95 macro
1867 "xor_eq" ;C++, C95 macro
1868 "_Alignas" ;C11
1869 "_Alignof" ;C11
1870 "_Atomic" ;C11
1871 "_Bool" ;C99
1872 "_Complex" ;C99
1873 "_Generic" ;C11
1874 "_Imaginary" ;C99
1875 "_Noreturn" ;C11
1876 "_Pragma" ;C99 preprocessor
1877 "_Static_assert" ;C11
1878 "_Thread_local" ;C11
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 ))
1893 (c-constants
1894 (mdw-regexps "false" ;C++, C99 macro
1895 "this" ;C++
1896 "true" ;C++, C99 macro
1897 ))
1898 (preprocessor-keywords
1899 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
1900 "ident" "if" "ifdef" "ifndef" "import" "include"
1901 "line" "pragma" "unassert" "undef" "warning"))
1902 (objc-keywords
1903 (mdw-regexps "class" "defs" "encode" "end" "implementation"
1904 "interface" "private" "protected" "protocol" "public"
1905 "selector")))
1906
1907 (setq font-lock-keywords
1908 (list
1909
1910 ;; Fontify include files as strings.
1911 (list (concat "^[ \t]*\\#[ \t]*"
1912 "\\(include\\|import\\)"
1913 "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
1914 '(2 font-lock-string-face))
1915
1916 ;; Preprocessor directives are `references'?.
1917 (list (concat "^\\([ \t]*#[ \t]*\\(\\("
1918 preprocessor-keywords
1919 "\\)\\>\\|[0-9]+\\|$\\)\\)")
1920 '(1 font-lock-keyword-face))
1921
1922 ;; Handle the keywords defined above.
1923 (list (concat "@\\<\\(" objc-keywords "\\)\\>")
1924 '(0 font-lock-keyword-face))
1925
1926 (list (concat "\\<\\(" c-keywords "\\)\\>")
1927 '(0 font-lock-keyword-face))
1928
1929 (list (concat "\\<\\(" c-constants "\\)\\>")
1930 '(0 font-lock-variable-name-face))
1931
1932 ;; Handle numbers too.
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.
1937 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1938 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1939 '(0 mdw-number-face))
1940
1941 ;; And anything else is punctuation.
1942 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1943 '(0 mdw-punct-face))))))
1944
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
1949 ;;;--------------------------------------------------------------------------
1950 ;;; AP calc mode.
1951
1952 (define-derived-mode apcalc-mode c-mode "AP Calc"
1953 "Major mode for editing Calc code.")
1954
1955 (defun mdw-fontify-apcalc ()
1956
1957 ;; Fiddle with some syntax codes.
1958 (modify-syntax-entry ?* ". 23")
1959 (modify-syntax-entry ?/ ". 14")
1960
1961 ;; Other stuff.
1962 (setq comment-start "/* ")
1963 (setq comment-end " */")
1964 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
1965
1966 ;; Now define things to be fontified.
1967 (make-local-variable 'font-lock-keywords)
1968 (let ((c-keywords
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")))
1973
1974 (setq font-lock-keywords
1975 (list
1976
1977 ;; Handle the keywords defined above.
1978 (list (concat "\\<\\(" c-keywords "\\)\\>")
1979 '(0 font-lock-keyword-face))
1980
1981 ;; Handle numbers too.
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.
1986 (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
1987 "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
1988 '(0 mdw-number-face))
1989
1990 ;; And anything else is punctuation.
1991 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
1992 '(0 mdw-punct-face))))))
1993
1994 ;;;--------------------------------------------------------------------------
1995 ;;; Java programming configuration.
1996
1997 ;; Make indentation nice.
1998
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)
2009
2010 ;; Declare Java fontification style.
2011
2012 (defun mdw-fontify-java ()
2013
2014 ;; Other stuff.
2015 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
2016
2017 ;; Now define things to be fontified.
2018 (make-local-variable 'font-lock-keywords)
2019 (let ((java-keywords
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"
2026 "static" "switch" "synchronized" "throw" "throws"
2027 "transient" "try" "void" "volatile" "while"))
2028
2029 (java-constants
2030 (mdw-regexps "false" "null" "super" "this" "true")))
2031
2032 (setq font-lock-keywords
2033 (list
2034
2035 ;; Handle the keywords defined above.
2036 (list (concat "\\<\\(" java-keywords "\\)\\>")
2037 '(0 font-lock-keyword-face))
2038
2039 ;; Handle the magic constants defined above.
2040 (list (concat "\\<\\(" java-constants "\\)\\>")
2041 '(0 font-lock-variable-name-face))
2042
2043 ;; Handle numbers too.
2044 ;;
2045 ;; The following isn't quite right, but it's close enough.
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
2053 ;; And anything else is punctuation.
2054 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2055 '(0 mdw-punct-face))))))
2056
2057 ;;;--------------------------------------------------------------------------
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.
2094 (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
2095 '(0 font-lock-keyword-face))
2096
2097 ;; Handle the predefined constants defined above.
2098 (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
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.
2104 (list (concat "\\_<\\("
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/\\)"
2113 '(0 mdw-punct-face))))))
2114
2115 ;;;--------------------------------------------------------------------------
2116 ;;; Scala programming configuration.
2117
2118 (defun mdw-fontify-scala ()
2119
2120 ;; Comment filling.
2121 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
2122
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"
2129 "override" "package" "private" "protected" "return"
2130 "sealed" "throw" "trait" "try" "type" "val"
2131 "var" "while" "with" "yield"))
2132 (scala-constants
2133 (mdw-regexps "false" "null" "super" "this" "true"))
2134 (punctuation "[-!%^&*=+:@#~/?\\|`]"))
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 "\"")
2186 '(4 "\""))))))
2187
2188 ;;;--------------------------------------------------------------------------
2189 ;;; C# programming configuration.
2190
2191 ;; Make indentation nice.
2192
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)
2203
2204 ;; Declare C# fontification style.
2205
2206 (defun mdw-fontify-csharp ()
2207
2208 ;; Other stuff.
2209 (setq mdw-fill-prefix mdw-c-comment-fill-prefix)
2210
2211 ;; Now define things to be fontified.
2212 (make-local-variable 'font-lock-keywords)
2213 (let ((csharp-keywords
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")))
2230
2231 (setq font-lock-keywords
2232 (list
2233
2234 ;; Handle the keywords defined above.
2235 (list (concat "\\<\\(" csharp-keywords "\\)\\>")
2236 '(0 font-lock-keyword-face))
2237
2238 ;; Handle the magic constants defined above.
2239 (list (concat "\\<\\(" csharp-constants "\\)\\>")
2240 '(0 font-lock-variable-name-face))
2241
2242 ;; Handle numbers too.
2243 ;;
2244 ;; The following isn't quite right, but it's close enough.
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
2252 ;; And anything else is punctuation.
2253 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2254 '(0 mdw-punct-face))))))
2255
2256 (define-derived-mode csharp-mode java-mode "C#"
2257 "Major mode for editing C# code.")
2258
2259 ;;;--------------------------------------------------------------------------
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"
2279 "begin" "break"
2280 "checked" "class" "component" "const" "constraint"
2281 "constructor" "continue"
2282 "default" "delegate" "do" "done" "downcast" "downto"
2283 "eager" "elif" "else" "end" "exception" "extern"
2284 "finally" "fixed" "for" "fori" "fun" "function"
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"
2292 "namespace" "new"
2293 "object" "of" "open" "or" "override"
2294 "parallel" "params" "private" "process" "protected"
2295 "public" "pure"
2296 "rec" "recursive" "return"
2297 "sealed" "sig" "static" "struct"
2298 "tailcall" "then" "to" "trait" "try" "type"
2299 "upcast" "use"
2300 "val" "virtual" "void" "volatile"
2301 "when" "while" "with"
2302 "yield"))
2303
2304 (fsharp-builtins
2305 (mdw-regexps "asr" "land" "lor" "lsl" "lsr" "lxor" "mod"
2306 "base" "false" "null" "true"))
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/\\)"
2369 '(0 mdw-punct-face))))))
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 ;;;--------------------------------------------------------------------------
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"
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")))
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))
2406 (list (concat "\\<\\(" go-intrinsics "\\)\\>")
2407 '(0 font-lock-variable-name-face))
2408
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
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/\\)"
2438 '(0 mdw-punct-face))))))
2439
2440 ;;;--------------------------------------------------------------------------
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.
2487 (list (concat "\\_<\\(" rust-keywords "\\)\\_>")
2488 '(0 font-lock-keyword-face))
2489 (list (concat "\\_<\\(" rust-builtins "\\)\\_>")
2490 '(0 font-lock-variable-name-face))
2491
2492 ;; Handle numbers too.
2493 (list (concat "\\_<\\("
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\\)\\)?"
2505 "\\)\\_>")
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.
2513 (local-set-key [?{] 'mdw-self-insert-and-indent)
2514 (local-set-key [?}] 'mdw-self-insert-and-indent))
2515
2516 ;;;--------------------------------------------------------------------------
2517 ;;; Awk programming configuration.
2518
2519 ;; Make Awk indentation nice.
2520
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)
2528
2529 ;; Declare Awk fontification style.
2530
2531 (defun mdw-fontify-awk ()
2532
2533 ;; Miscellaneous fiddling.
2534 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2535
2536 ;; Now define things to be fontified.
2537 (make-local-variable 'font-lock-keywords)
2538 (let ((c-keywords
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")))
2550
2551 (setq font-lock-keywords
2552 (list
2553
2554 ;; Handle the keywords defined above.
2555 (list (concat "\\<\\(" c-keywords "\\)\\>")
2556 '(0 font-lock-keyword-face))
2557
2558 ;; Handle numbers too.
2559 ;;
2560 ;; The following isn't quite right, but it's close enough.
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
2568 ;; And anything else is punctuation.
2569 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2570 '(0 mdw-punct-face))))))
2571
2572 ;;;--------------------------------------------------------------------------
2573 ;;; Perl programming style.
2574
2575 ;; Perl indentation style.
2576
2577 (setq perl-indent-level 2)
2578
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
2586 ;; Define perl fontification style.
2587
2588 (defun mdw-fontify-perl ()
2589
2590 ;; Miscellaneous fiddling.
2591 (modify-syntax-entry ?$ "\\")
2592 (modify-syntax-entry ?$ "\\" font-lock-syntax-table)
2593 (modify-syntax-entry ?: "." font-lock-syntax-table)
2594 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2595
2596 ;; Now define fontification things.
2597 (make-local-variable 'font-lock-keywords)
2598 (let ((perl-keywords
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")))
2616
2617 (setq font-lock-keywords
2618 (list
2619
2620 ;; Set up the keywords defined above.
2621 (list (concat "\\<\\(" perl-keywords "\\)\\>")
2622 '(0 font-lock-keyword-face))
2623
2624 ;; At least numbers are simpler than C.
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
2630 ;; And anything else is punctuation.
2631 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2632 '(0 mdw-punct-face))))))
2633
2634 (defun perl-number-tests (&optional arg)
2635 "Assign consecutive numbers to lines containing `#t'. With ARG,
2636 strip 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
2649 ;;;--------------------------------------------------------------------------
2650 ;;; Python programming style.
2651
2652 (defun mdw-fontify-pythonic (keywords)
2653
2654 ;; Miscellaneous fiddling.
2655 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2656 (setq indent-tabs-mode nil)
2657
2658 ;; Now define fontification things.
2659 (make-local-variable 'font-lock-keywords)
2660 (setq font-lock-keywords
2661 (list
2662
2663 ;; Set up the keywords defined above.
2664 (list (concat "\\_<\\(" keywords "\\)\\_>")
2665 '(0 font-lock-keyword-face))
2666
2667 ;; At least numbers are simpler than C.
2668 (list (concat "\\_<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
2669 "\\_<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
2670 "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
2671 '(0 mdw-number-face))
2672
2673 ;; And anything else is punctuation.
2674 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2675 '(0 mdw-punct-face)))))
2676
2677 ;; Define Python fontification styles.
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"
2690 "ctypedef" "def" "del" "elif" "else" "enum" "except" "exec"
2691 "extern" "finally" "for" "from" "global" "if"
2692 "import" "in" "is" "lambda" "not" "or" "pass" "print"
2693 "property" "raise" "return" "struct" "try" "while" "with"
2694 "yield")))
2695
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
2704 ;;;--------------------------------------------------------------------------
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 ;;;--------------------------------------------------------------------------
2748 ;;; Icon programming style.
2749
2750 ;; Icon indentation style.
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
2757 ;; Define Icon fontification style.
2758
2759 (defun mdw-fontify-icon ()
2760
2761 ;; Miscellaneous fiddling.
2762 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2763
2764 ;; Now define fontification things.
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
2778 ;; Set up the keywords defined above.
2779 (list (concat "\\<\\(" icon-keywords "\\)\\>")
2780 '(0 font-lock-keyword-face))
2781
2782 ;; The things that Icon calls keywords.
2783 (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
2784
2785 ;; At least numbers are simpler than C.
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
2792 ;; Preprocessor.
2793 (list (concat "^[ \t]*$[ \t]*\\<\\("
2794 preprocessor-keywords
2795 "\\)\\>")
2796 '(0 font-lock-keyword-face))
2797
2798 ;; And anything else is punctuation.
2799 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
2800 '(0 mdw-punct-face))))))
2801
2802 ;;;--------------------------------------------------------------------------
2803 ;;; Assembler mode.
2804
2805 (defun mdw-fontify-asm ()
2806 (modify-syntax-entry ?' "\"")
2807 (modify-syntax-entry ?. "w")
2808 (modify-syntax-entry ?\n ">")
2809 (setf fill-prefix nil)
2810 (local-set-key ";" 'self-insert-command)
2811 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
2812
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)
2820
2821 ;;;--------------------------------------------------------------------------
2822 ;;; TCL configuration.
2823
2824 (defun mdw-fontify-tcl ()
2825 (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
2826 (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
2827 (make-local-variable 'font-lock-keywords)
2828 (setq font-lock-keywords
2829 (list
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/\\)"
2835 '(0 mdw-punct-face)))))
2836
2837 ;;;--------------------------------------------------------------------------
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
2880 "\\|" "with\\(out\\)?-" word
2881 "\\)\\>")
2882 '(0 font-lock-keyword-face))
2883 (list (concat "\\<" word ":" "\\|"
2884 "#\\(" sharp-keywords "\\)\\>")
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 "\\)")
2901 '(0 mdw-punct-face))))))
2902
2903 ;;;--------------------------------------------------------------------------
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/"
2943 '(0 mdw-punct-face))))))
2944
2945 ;;;--------------------------------------------------------------------------
2946 ;;; REXX configuration.
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
2961 ;; Various bits of fiddling.
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"))
2966 '(?! ?? ?# ?@ ?$))
2967 (mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
2968
2969 ;; Set up keywords and things for fontification.
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)
2975 (setq rexx-cont-indent rexx-indent)
2976
2977 (make-local-variable 'font-lock-keywords)
2978 (let ((rexx-keywords
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")))
3001
3002 (setq font-lock-keywords
3003 (list
3004
3005 ;; Set up the keywords defined above.
3006 (list (concat "\\<\\(" rexx-keywords "\\)\\>")
3007 '(0 font-lock-keyword-face))
3008
3009 ;; Fontify all symbols the same way.
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
3014 ;; And everything else is punctuation.
3015 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3016 '(0 mdw-punct-face))))))
3017
3018 ;;;--------------------------------------------------------------------------
3019 ;;; Standard ML programming style.
3020
3021 (defun mdw-fontify-sml ()
3022
3023 ;; Make underscore an honorary letter.
3024 (modify-syntax-entry ?' "w")
3025
3026 ;; Set fill prefix.
3027 (mdw-standard-fill-prefix "\\([ \t]*(\*[ \t]*\\)")
3028
3029 ;; Now define fontification things.
3030 (make-local-variable 'font-lock-keywords)
3031 (let ((sml-keywords
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")))
3047
3048 (setq font-lock-keywords
3049 (list
3050
3051 ;; Set up the keywords defined above.
3052 (list (concat "\\<\\(" sml-keywords "\\)\\>")
3053 '(0 font-lock-keyword-face))
3054
3055 ;; At least numbers are simpler than C.
3056 (list (concat "\\<\\(\\~\\|\\)"
3057 "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
3058 "[wW][0-9]+\\)\\|"
3059 "\\([0-9]+\\(\\.[0-9]+\\|\\)"
3060 "\\([eE]\\(\\~\\|\\)"
3061 "[0-9]+\\|\\)\\)\\)")
3062 '(0 mdw-number-face))
3063
3064 ;; And anything else is punctuation.
3065 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3066 '(0 mdw-punct-face))))))
3067
3068 ;;;--------------------------------------------------------------------------
3069 ;;; Haskell configuration.
3070
3071 (defun mdw-fontify-haskell ()
3072
3073 ;; Fiddle with syntax table to get comments right.
3074 (modify-syntax-entry ?' "_")
3075 (modify-syntax-entry ?- ". 12")
3076 (modify-syntax-entry ?\n ">")
3077
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
3084 ;; Set fill prefix.
3085 (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)")
3086
3087 ;; Fiddle with fontification.
3088 (make-local-variable 'font-lock-keywords)
3089 (let ((haskell-keywords
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")))
3113
3114 (setq font-lock-keywords
3115 (list
3116 (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
3117 "\\(-+}\\|-*\\'\\)"
3118 "\\|"
3119 "--.*$")
3120 '(0 font-lock-comment-face))
3121 (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
3122 '(0 font-lock-keyword-face))
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]*\\|\\)"
3141 "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
3142 '(0 mdw-number-face))
3143 (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
3144 '(0 mdw-punct-face))))))
3145
3146 ;;;--------------------------------------------------------------------------
3147 ;;; Erlang configuration.
3148
3149 (setq erlang-electric-commands nil)
3150
3151 (defun mdw-fontify-erlang ()
3152
3153 ;; Set fill prefix.
3154 (mdw-standard-fill-prefix "\\([ \t]*{?%*[ \t]*\\)")
3155
3156 ;; Fiddle with fontification.
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/\\)"
3177 '(0 mdw-punct-face))))))
3178
3179 ;;;--------------------------------------------------------------------------
3180 ;;; Texinfo configuration.
3181
3182 (defun mdw-fontify-texinfo ()
3183
3184 ;; Set fill prefix.
3185 (mdw-standard-fill-prefix "\\([ \t]*@c[ \t]+\\)")
3186
3187 ;; Real fontification things.
3188 (make-local-variable 'font-lock-keywords)
3189 (setq font-lock-keywords
3190 (list
3191
3192 ;; Environment names are keywords.
3193 (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
3194 '(2 font-lock-keyword-face))
3195
3196 ;; Unmark escaped magic characters.
3197 (list "\\(@\\)\\([@{}]\\)"
3198 '(1 font-lock-keyword-face)
3199 '(2 font-lock-variable-name-face))
3200
3201 ;; Make sure we get comments properly.
3202 (list "@c\\(\\|omment\\)\\( .*\\)?$"
3203 '(0 font-lock-comment-face))
3204
3205 ;; Command names are keywords.
3206 (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
3207 '(0 font-lock-keyword-face))
3208
3209 ;; Fontify TeX special characters as punctuation.
3210 (list "[{}]+"
3211 '(0 mdw-punct-face)))))
3212
3213 ;;;--------------------------------------------------------------------------
3214 ;;; TeX and LaTeX configuration.
3215
3216 (defun mdw-fontify-tex ()
3217 (setq ispell-parser 'tex)
3218 (turn-on-reftex)
3219
3220 ;; Don't make maths into a string.
3221 (modify-syntax-entry ?$ ".")
3222 (modify-syntax-entry ?$ "." font-lock-syntax-table)
3223 (local-set-key [?$] 'self-insert-command)
3224
3225 ;; Make `tab' be useful, given that tab stops in TeX don't work well.
3226 (local-set-key "\C-\M-i" 'indent-relative)
3227 (setq indent-tabs-mode nil)
3228
3229 ;; Set fill prefix.
3230 (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")
3231
3232 ;; Real fontification things.
3233 (make-local-variable 'font-lock-keywords)
3234 (setq font-lock-keywords
3235 (list
3236
3237 ;; Environment names are keywords.
3238 (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
3239 "{\\([^}\n]*\\)}")
3240 '(2 font-lock-keyword-face))
3241
3242 ;; Suspended environment names are keywords too.
3243 (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
3244 "{\\([^}\n]*\\)}")
3245 '(3 font-lock-keyword-face))
3246
3247 ;; Command names are keywords.
3248 (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
3249 '(0 font-lock-keyword-face))
3250
3251 ;; Handle @/.../ for italics.
3252 ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
3253 ;; '(1 font-lock-keyword-face)
3254 ;; '(3 font-lock-keyword-face))
3255
3256 ;; Handle @*...* for boldness.
3257 ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
3258 ;; '(1 font-lock-keyword-face)
3259 ;; '(3 font-lock-keyword-face))
3260
3261 ;; Handle @`...' for literal syntax things.
3262 ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
3263 ;; '(1 font-lock-keyword-face)
3264 ;; '(3 font-lock-keyword-face))
3265
3266 ;; Handle @<...> for nonterminals.
3267 ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
3268 ;; '(1 font-lock-keyword-face)
3269 ;; '(3 font-lock-keyword-face))
3270
3271 ;; Handle other @-commands.
3272 ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
3273 ;; '(0 font-lock-keyword-face))
3274
3275 ;; Make sure we get comments properly.
3276 (list "%.*"
3277 '(0 font-lock-comment-face))
3278
3279 ;; Fontify TeX special characters as punctuation.
3280 (list "[$^_{}#&]"
3281 '(0 mdw-punct-face)))))
3282
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
3302 ;;;--------------------------------------------------------------------------
3303 ;;; SGML hacking.
3304
3305 (defun mdw-sgml-mode ()
3306 (interactive)
3307 (sgml-mode)
3308 (mdw-standard-fill-prefix "")
3309 (make-local-variable 'sgml-delimiters)
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))
3322
3323 ;;;--------------------------------------------------------------------------
3324 ;;; Configuration files.
3325
3326 (defvar mdw-conf-quote-normal nil
3327 "*Control syntax category of quote characters `\"' and `''.
3328 If this is `t', consider quote characters to be normal
3329 punctuation, as for `conf-quote-normal'. If this is `nil' then
3330 leave quote characters as quotes. If this is a list, then
3331 consider the quote characters in the list to be normal
3332 punctuation. If this is a single quote character, then consider
3333 that 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)))))
3339 (put 'mdw-conf-quote-normal 'safe-local-variable
3340 'mdw-conf-quote-normal-acceptable-value-p)
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)))))))
3355 (add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t)
3356
3357 ;;;--------------------------------------------------------------------------
3358 ;;; Shell scripts.
3359
3360 (defun mdw-setup-sh-script-mode ()
3361
3362 ;; Fetch the shell interpreter's name.
3363 (let ((shell-name sh-shell-file))
3364
3365 ;; Try reading the hash-bang line.
3366 (save-excursion
3367 (goto-char (point-min))
3368 (if (looking-at "#![ \t]*\\([^ \t\n]*\\)")
3369 (setq shell-name (match-string 1))))
3370
3371 ;; Now try to set the shell.
3372 ;;
3373 ;; Don't let `sh-set-shell' bugger up my script.
3374 (let ((executable-set-magic #'(lambda (s &rest r) s)))
3375 (sh-set-shell shell-name)))
3376
3377 ;; Don't insert here-document scaffolding automatically.
3378 (local-set-key "<" 'self-insert-command)
3379
3380 ;; Now enable my keys and the fontification.
3381 (mdw-misc-mode-config)
3382
3383 ;; Set the indentation level correctly.
3384 (setq sh-indentation 2)
3385 (setq sh-basic-offset 2))
3386
3387 (setq sh-shell-file "/bin/sh")
3388
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
3425 ;;;--------------------------------------------------------------------------
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 " "
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)
3440 (= (elt pwd nhome) ?/))
3441 (string= (substring pwd 0 nhome) home))
3442 (concat "~" (substring pwd (length home)))
3443 pwd))
3444 right)))
3445 (setq eshell-prompt-function 'mdw-eshell-prompt)
3446 (setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
3447
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)
3451
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 ;;;--------------------------------------------------------------------------
3463 ;;; Messages-file mode.
3464
3465 (defun messages-mode-guts ()
3466 (setq messages-mode-syntax-table (make-syntax-table))
3467 (set-syntax-table messages-mode-syntax-table)
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)
3484 (make-local-variable 'messages-mode-keywords)
3485 (let ((keywords
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")))
3493 (setq messages-mode-keywords
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
3504 '(messages-mode-keywords nil nil nil nil))
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")
3512 (messages-mode-guts)
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 "")
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")
3524 (messages-mode-guts)
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
3530 (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
3531 "ident" "if" "ifdef" "ifndef" "import" "include"
3532 "line" "pragma" "unassert" "undef" "warning")))
3533 (setq messages-mode-keywords
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
3540 "\\)\\>\\|[0-9]+\\|$\\)\\)")
3541 '(1 font-lock-keyword-face)))
3542 messages-mode-keywords)))
3543 (run-hooks 'cpp-messages-mode-hook))
3544
3545 (add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
3546 (add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
3547 ; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
3548
3549 ;;;--------------------------------------------------------------------------
3550 ;;; Messages-file mode.
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
3574 (mdw-regexps "each" "divert" "file" "if"
3575 "perl" "set" "string" "type" "write")))
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 "")
3593 (run-hooks 'mallow-driver-mode-hook))
3594
3595 (add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
3596
3597 ;;;--------------------------------------------------------------------------
3598 ;;; NFast debugs.
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))
3635 (run-hooks 'nfast-debug-mode-hook))
3636
3637 ;;;--------------------------------------------------------------------------
3638 ;;; Other languages.
3639
3640 ;; Smalltalk.
3641
3642 (defun mdw-setup-smalltalk ()
3643 (and mdw-auto-indent
3644 (local-set-key "\C-m" 'smalltalk-newline-and-indent))
3645 (make-local-variable 'mdw-auto-indent)
3646 (setq mdw-auto-indent nil)
3647 (local-set-key "\C-i" 'smalltalk-reindent))
3648
3649 (defun mdw-fontify-smalltalk ()
3650 (make-local-variable 'font-lock-keywords)
3651 (setq font-lock-keywords
3652 (list
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/\\)"
3660 '(0 mdw-punct-face)))))
3661
3662 ;; Lispy languages.
3663
3664 ;; Unpleasant bodge.
3665 (unless (boundp 'slime-repl-mode-map)
3666 (setq slime-repl-mode-map (make-sparse-keymap)))
3667
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 ()
3683 (make-local-variable 'lisp-indent-function)
3684 (setq lisp-indent-function 'common-lisp-indent-function))
3685
3686 (setq lisp-simple-loop-indentation 2
3687 lisp-loop-keyword-indentation 6
3688 lisp-loop-forms-indentation 6)
3689
3690 (defun mdw-fontify-lispy ()
3691
3692 ;; Set fill prefix.
3693 (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")
3694
3695 ;; Not much fontification needed.
3696 (make-local-variable 'font-lock-keywords)
3697 (setq font-lock-keywords
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/\\)"
3717 '(0 mdw-punct-face)))))
3718
3719 (defun comint-send-and-indent ()
3720 (interactive)
3721 (comint-send-input)
3722 (and mdw-auto-indent
3723 (indent-for-tab-command)))
3724
3725 (defun mdw-setup-m4 ()
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.
3733 (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
3734
3735 ;;;--------------------------------------------------------------------------
3736 ;;; Text mode.
3737
3738 (defun mdw-text-mode ()
3739 (setq fill-column 72)
3740 (flyspell-mode t)
3741 (mdw-standard-fill-prefix
3742 "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
3743 (auto-fill-mode 1))
3744
3745 (eval-after-load "flyspell"
3746 '(define-key flyspell-mode-map "\C-\M-i" nil))
3747
3748 ;;;--------------------------------------------------------------------------
3749 ;;; Outline and hide/show modes.
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
3760 (setq hs-hide-comments-when-hiding-all nil)
3761
3762 (defadvice hs-hide-all (after hide-first-comment activate)
3763 (save-excursion (hs-hide-initial-comment-block)))
3764
3765 ;;;--------------------------------------------------------------------------
3766 ;;; Shell mode.
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 ()
3774 (setq term-prompt-regexp shell-prompt-pattern)
3775 (make-local-variable 'mouse-yank-at-point)
3776 (make-local-variable 'transient-mark-mode)
3777 (setq mouse-yank-at-point t)
3778 (auto-fill-mode -1)
3779 (setq tab-width 8))
3780
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
3798 (defadvice term-exec (before program-args-list compile activate)
3799 "If the PROGRAM argument is a list, interpret it as (PROGRAM . SWITCHES).
3800 This 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
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
3825 ;;;--------------------------------------------------------------------------
3826 ;;; Magit configuration.
3827
3828 (setq magit-diff-refine-hunk 'all
3829 magit-view-git-manual-method 'man
3830 magit-log-margin '(nil age magit-log-margin-width t 18)
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)
3839 (add-to-list 'magit-no-confirm 'safe-with-wip)
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)
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"))))
3853
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.
3867 Otherwise child processes get started in the wrong directory and
3868 there 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
3887 ;;;--------------------------------------------------------------------------
3888 ;;; MPC configuration.
3889
3890 (eval-when-compile (trap (require 'mpc)))
3891
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
3911 (string-to-number
3912 (if (string-match ":" time-string)
3913 (substring time-string
3914 0 (match-beginning 0))
3915 (time-string)))))
3916 (duration (and duration-string
3917 (string-to-number duration-string)))
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
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))
3951
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
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 ()
3992 (when (and (get-char-property (point) 'mpc-file)
3993 (not (get-char-property (point) 'mpc-select)))
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))
4002 (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one))
4003
4004 (defun mdw-mpc-unselect (&optional arg interactivep)
4005 (interactive (list current-prefix-arg t))
4006 (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-unselect-one))
4007
4008 (defun mdw-mpc-unselect-backwards (arg)
4009 (interactive "p")
4010 (mdw-mpc-hack-lines (- arg) t 'mdw-mpc-unselect-one))
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
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
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
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
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)
4078 (define-key mpc-mode-map "/" 'mpc-songs-search)
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)
4082 (define-key mpc-songs-mode-map "+" 'mdw-mpc-playlist-add)
4083 (define-key mpc-songs-mode-map "-" 'mdw-mpc-playlist-delete)
4084 (define-key mpc-songs-mode-map "\r" 'mpc-songs-jump-to)))
4085
4086 ;;;--------------------------------------------------------------------------
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
4101 ;;;----- That's all, folks --------------------------------------------------
4102
4103 (provide 'dot-emacs)