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