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