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