;;;--------------------------------------------------------------------------
;;; Check command-line.
+(defgroup mdw nil
+ "Customization for mdw's Emacs configuration."
+ :prefix "mdw-")
+
+(defun mdw-check-command-line-switch (switch)
+ (let ((probe nil) (next command-line-args) (found nil))
+ (while next
+ (cond ((string= (car next) switch)
+ (setq found t)
+ (if probe (rplacd probe (cdr next))
+ (setq command-line-args (cdr next))))
+ (t
+ (setq probe next)))
+ (setq next (cdr next)))
+ found))
+
(defvar mdw-fast-startup nil
"Whether .emacs should optimize for rapid startup.
This may be at the expense of cool features.")
-(let ((probe nil) (next command-line-args))
- (while next
- (cond ((string= (car next) "--mdw-fast-startup")
- (setq mdw-fast-startup t)
- (if probe
- (rplacd probe (cdr next))
- (setq command-line-args (cdr next))))
- (t
- (setq probe next)))
- (setq next (cdr next))))
+(setq mdw-fast-startup
+ (mdw-check-command-line-switch "--mdw-fast-startup"))
+
+(defvar mdw-splashy-startup nil
+ "Whether to show a splash screen and related frippery.")
+(setq mdw-splashy-startup
+ (mdw-check-command-line-switch "--mdw-splashy-startup"))
;;;--------------------------------------------------------------------------
;;; Some general utilities.
(eval-when-compile
- (unless (fboundp 'make-regexp)
- (load "make-regexp"))
- (require 'cl))
+ (unless (fboundp 'make-regexp) (load "make-regexp"))
+ (require 'cl-lib))
(defmacro mdw-regexps (&rest list)
"Turn a LIST of strings into a single regular expression at compile-time."
(declare (indent nil)
(debug 0))
- `',(make-regexp list))
+ `',(make-regexp (sort (cl-copy-list list) #'string<)))
(defun mdw-wrong ()
"This is not the key sequence you're looking for."
(and (= emacs-major-version major)
(>= emacs-minor-version (or minor 0)))))
+(defun mdw-submode-p (mode parent)
+ "Return non-nil if MODE is indirectly derived from PARENT."
+ (let ((answer nil))
+ (while (cond ((eq mode parent) (setq answer t) nil)
+ (t (setq mode (get mode 'derived-mode-parent)))))
+ answer))
+
;; Some error trapping.
;;
;; If individual bits of this file go tits-up, we don't particularly want
;; the whole lot to stop right there and then, because it's bloody annoying.
-(defmacro trap (&rest forms)
- "Execute FORMS without allowing errors to propagate outside."
- (declare (indent 0)
- (debug t))
- `(condition-case err
- ,(if (cdr forms) (cons 'progn forms) (car forms))
- (error (message "Error (trapped): %s in %s"
- (error-message-string err)
- ',forms))))
+(eval-and-compile
+ (defmacro trap (&rest forms)
+ "Execute FORMS without allowing errors to propagate outside."
+ (declare (indent 0)
+ (debug t))
+ `(condition-case err
+ ,(if (cdr forms) (cons 'progn forms) (car forms))
+ (error (message "Error (trapped): %s in %s"
+ (error-message-string err)
+ ',forms)))))
;; Configuration reading.
"Read the configuration variable named SYM."
(unless mdw-config
(setq mdw-config
- (flet ((replace (what with)
- (goto-char (point-min))
- (while (re-search-forward what nil t)
- (replace-match with t))))
- (with-temp-buffer
- (insert-file-contents "~/.mdw.conf")
- (replace "^[ \t]*\\(#.*\\|\\)\n" "")
- (replace (concat "^[ \t]*"
- "\\([-a-zA-Z0-9_.]*\\)"
- "[ \t]*=[ \t]*"
- "\\(.*[^ \t\n]\\|\\)"
- "[ \t]**\\(\n\\|$\\)")
- "(\\1 . \"\\2\")\n")
- (car (read-from-string
- (concat "(" (buffer-string) ")")))))))
+ (cl-flet ((replace (what with)
+ (goto-char (point-min))
+ (while (re-search-forward what nil t)
+ (replace-match with t))))
+ (with-temp-buffer
+ (insert-file-contents "~/.mdw.conf")
+ (replace "^[ \t]*\\(#.*\\)?\n" "")
+ (replace (concat "^[ \t]*"
+ "\\([-a-zA-Z0-9_.]*\\)"
+ "[ \t]*=[ \t]*"
+ "\\(.*[^ \t\n]\\)?"
+ "[ \t]**\\(\n\\|$\\)")
+ "(\\1 . \"\\2\")\n")
+ (car (read-from-string
+ (concat "(" (buffer-string) ")")))))))
(cdr (assq sym mdw-config)))
+;; Width configuration.
+
+(defcustom mdw-column-width
+ (string-to-number (or (mdw-config 'emacs-width) "77"))
+ "Width of Emacs columns."
+ :type 'integer)
+(defcustom mdw-text-width mdw-column-width
+ "Expected width of text within columns."
+ :type 'integer
+ :safe 'integerp)
+
;; Local variables hacking.
(defun run-local-vars-mode-hook ()
(set-frame-parameter frame 'menu-bar-lines 0)
(set-frame-parameter frame 'menu-bar-lines old)))
+;; Page motion.
+
+(defun mdw-fixup-page-position ()
+ (unless (eq (char-before (point)) ?\f)
+ (forward-line 0)))
+
+(defadvice backward-page (after mdw-fixup compile activate)
+ (mdw-fixup-page-position))
+(defadvice forward-page (after mdw-fixup compile activate)
+ (mdw-fixup-page-position))
+
;; Splitting windows.
(unless (fboundp 'scroll-bar-columns)
(let ((tot 0))
(dolist (what '(scroll-bar fringe))
(dolist (side '(left right))
- (incf tot (funcall (intern (concat (symbol-name what) "-columns"))
- side))))
+ (cl-incf tot
+ (funcall (intern (concat (symbol-name what) "-columns"))
+ side))))
tot)))
(defun mdw-split-window-horizontally (&optional width)
((>= width 0) (+ width (mdw-horizontal-window-overhead)))
((< width 0) width))))
+(defun mdw-preferred-column-width ()
+ "Return the preferred column width."
+ (if (and window-system (mdw-emacs-version-p 22)) mdw-column-width
+ (1+ mdw-column-width)))
+
(defun mdw-divvy-window (&optional width)
"Split a wide window into appropriate widths."
(interactive "P")
- (setq width (cond (width (prefix-numeric-value width))
- ((and window-system (mdw-emacs-version-p 22))
- 77)
- (t 78)))
+ (setq width (if width (prefix-numeric-value width)
+ (mdw-preferred-column-width)))
(let* ((win (selected-window))
(sb-width (mdw-horizontal-window-overhead))
(c (/ (+ (window-width) sb-width)
(other-window 1))
(select-window win)))
+(defun mdw-frame-width-quantized-p (frame-width column-width)
+ "Return whether the FRAME-WIDTH was chosen specifically for COLUMN-WIDTH."
+ (let ((sb-width (mdw-horizontal-window-overhead)))
+ (zerop (mod (+ frame-width sb-width)
+ (+ column-width sb-width)))))
+
+(defun mdw-frame-width-for-columns (columns width)
+ "Return the preferred width for a frame with so many COLUMNS of WIDTH."
+ (let ((sb-width (mdw-horizontal-window-overhead)))
+ (- (* columns (+ width sb-width))
+ sb-width)))
+
+(defun mdw-set-frame-width (columns &optional width)
+ "Set the current frame to be the correct width for COLUMNS columns.
+
+If WIDTH is non-nil, then it provides the width for the new columns. (This
+can be set interactively with a prefix argument.)"
+ (interactive "nColumns:
+P")
+ (setq width (if width (prefix-numeric-value width)
+ (mdw-preferred-column-width)))
+ (set-frame-width (selected-frame)
+ (mdw-frame-width-for-columns columns width))
+ (mdw-divvy-window width))
+
+(defcustom mdw-frame-width-fudge
+ (cond ((<= emacs-major-version 20) 1)
+ ((= emacs-major-version 26) 3)
+ (t 0))
+ "The number of extra columns to add to the desired frame width.
+
+This is sadly necessary because Emacs 26 is broken in this regard."
+ :type 'integer)
+
+(defcustom mdw-frame-colour-alist
+ '((black . ("#000000" . "#ffffff"))
+ (red . ("#2a0000" . "#ffffff"))
+ (green . ("#002a00" . "#ffffff"))
+ (blue . ("#00002a" . "#ffffff")))
+ "Alist mapping symbol names to (FOREGROUND . BACKGROUND) colour pairs."
+ :type '(alist :key-type symbol :value-type (cons color color)))
+
+(defun mdw-set-frame-colour (colour &optional frame)
+ (interactive "xColour name or (FOREGROUND . BACKGROUND) pair:
+")
+ (when (and colour (symbolp colour))
+ (let ((entry (assq colour mdw-frame-colour-alist)))
+ (unless entry (error "Unknown colour `%s'" colour))
+ (setf colour (cdr entry))))
+ (set-frame-parameter frame 'background-color (car colour))
+ (set-frame-parameter frame 'foreground-color (cdr colour)))
+
+;; Window configuration switching.
+
+(defvar mdw-current-window-configuration nil
+ "The current window configuration register name, or `nil'.")
+
+(defun mdw-switch-window-configuration (register &optional no-save)
+ "Switch make REGISTER be the new current window configuration.
+If a current window configuration register is established, and
+NO-SAVE is nil, then save the current window configuration to
+that register first.
+
+Signal an error if the new register contains something other than
+a window configuration. If the register is unset then save the
+current window configuration to it immediately.
+
+With one or three C-u, or an odd numeric prefix argument, set
+NO-SAVE, so the previous window configuration register is left
+unchanged.
+
+With two or three C-u, or a prefix argument which is an odd
+multiple of 2, just clear the record of the current window
+configuration register, so that the next switch doesn't save the
+prevailing configuration."
+ (interactive
+ (let ((arg current-prefix-arg))
+ (list (if (or (and (consp arg) (= (car arg) 16) (= (car arg) 64))
+ (and (integerp arg) (not (zerop (logand arg 2)))))
+ nil
+ (register-read-with-preview "Switch to window configuration: "))
+ (or (and (consp arg) (= (car arg) 4) (= (car arg) 64))
+ (and (integerp arg) (not (zerop (logand arg 1))))))))
+
+ (let ((previous mdw-current-window-configuration)
+ (current-windows (list (current-window-configuration)
+ (point-marker)))
+ (register-value (and register (get-register register))))
+ (when (and mdw-current-window-configuration (not no-save))
+ (set-register mdw-current-window-configuration current-windows))
+ (cond ((null register)
+ (setq mdw-current-window-configuration nil)
+ (if previous
+ (message "Left window configuration `%c'." previous)
+ (message "Nothing to do!")))
+ ((not (or (null register-value)
+ (and (consp register-value)
+ (window-configuration-p (car register-value))
+ (integer-or-marker-p (cadr register-value))
+ (null (cl-caddr register-value)))))
+ (error "Register `%c' is not a window configuration" register))
+ (t
+ (cond ((null register-value)
+ (set-register register current-windows)
+ (message "Started new window configuration `%c'."
+ register))
+ (t
+ (set-window-configuration (car register-value))
+ (goto-char (cadr register-value))
+ (message "Switched to window configuration `%c'."
+ register)))
+ (setq mdw-current-window-configuration register)))))
+
;; Don't raise windows unless I say so.
-(defvar mdw-inhibit-raise-frame nil
- "*Whether `raise-frame' should do nothing when the frame is mapped.")
+(defcustom mdw-inhibit-raise-frame nil
+ "Whether `raise-frame' should do nothing when the frame is mapped."
+ :type 'boolean)
(defadvice raise-frame
(around mdw-inhibit (&optional frame) activate compile)
ad-do-it)))
(mdw-advise-to-inhibit-raise-frame select-frame-set-input-focus)
+(mdw-advise-to-inhibit-raise-frame appt-disp-window)
+(mdw-advise-to-inhibit-raise-frame mouse-select-window)
;; Bug fix for markdown-mode, which breaks point positioning during
;; `query-replace'.
;; Functions for sexp diary entries.
+(defvar mdw-diary-for-org-mode-p nil
+ "Display diary along with the agenda?")
+
(defun mdw-not-org-mode (form)
"As FORM, but not in Org mode agenda."
(and (not mdw-diary-for-org-mode-p)
(months ["Chaos" "Discord" "Confusion"
"Bureaucracy" "Aftermath"])
(day-count [0 31 59 90 120 151 181 212 243 273 304 334])
- (year (- (extract-calendar-year date) 1900))
- (month (1- (extract-calendar-month date)))
- (day (1- (extract-calendar-day date)))
+ (year (- (calendar-extract-year date) 1900))
+ (month (1- (calendar-extract-month date)))
+ (day (1- (calendar-extract-day date)))
(julian (+ (aref day-count month) day))
(dyear (+ year 3066)))
(if (and (= month 1) (= day 28))
(if (eq (cdr ddate) 'st-tibs-day)
(format "St Tib's Day %s" tail)
(let ((season (cadr ddate))
- (daynum (caddr ddate))
- (dayname (cadddr ddate)))
+ (daynum (cl-caddr ddate))
+ (dayname (cl-cadddr ddate)))
(format "%s, the %d%s day of %s %s"
dayname
daynum
(nth 2 when))))))))
(eq w d)))
-(defvar mdw-diary-for-org-mode-p nil)
-
(defadvice org-agenda-list (around mdw-preserve-links activate)
(let ((mdw-diary-for-org-mode-p t))
ad-do-it))
-(defadvice diary-add-to-list (before mdw-trim-leading-space activate)
+(defcustom diary-time-regexp nil
+ "Regexp matching times in the diary buffer."
+ :type 'regexp)
+
+(defadvice diary-add-to-list (before mdw-trim-leading-space compile activate)
"Trim leading space from the diary entry string."
(save-match-data
- (let ((str (ad-get-arg 1)))
- (ad-set-arg 1
- (cond ((null str) nil)
+ (let ((str (ad-get-arg 1))
+ (done nil) old)
+ (while (not done)
+ (setq old str)
+ (setq str (cond ((null str) nil)
+ ((string-match "\\(^\\|\n\\)[ \t]+" str)
+ (replace-match "\\1" nil nil str))
((and mdw-diary-for-org-mode-p
(string-match (concat
- "^[ \t]*"
+ "\\(^\\|\n\\)"
"\\(" diary-time-regexp
"\\(-" diary-time-regexp "\\)?"
- "\\)[ \t]+")
+ "\\)"
+ "\\(\t[ \t]*\\| [ \t]+\\)")
str))
- (replace-match "\\1 " nil nil str))
- ((string-match "^[ \t]+" str)
- (replace-match "" nil nil str))
+ (replace-match "\\1\\2 " nil nil str))
((and (not mdw-diary-for-org-mode-p)
(string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]"
str))
(replace-match "\\1" nil nil str))
- (t str))))))
+ (t str)))
+ (if (equal str old) (setq done t)))
+ (ad-set-arg 1 str))))
+
+(defadvice org-bbdb-anniversaries (after mdw-fixup-list compile activate)
+ "Return a string rather than a list."
+ (with-temp-buffer
+ (let ((anyp nil))
+ (dolist (e (let ((ee ad-return-value))
+ (if (atom ee) (list ee) ee)))
+ (when e
+ (when anyp (insert ?\n))
+ (insert e)
+ (setq anyp t)))
+ (setq ad-return-value
+ (and anyp (buffer-string))))))
;; Fighting with Org-mode's evil key maps.
-(defvar mdw-evil-keymap-keys
+(defcustom mdw-evil-keymap-keys
'(([S-up] . [?\C-c up])
([S-down] . [?\C-c down])
([S-left] . [?\C-c left])
(([M-right] [?\e right]) . [C-right]))
"Defines evil keybindings to clobber in `mdw-clobber-evil-keymap'.
The value is an alist mapping evil keys (as a list, or singleton)
-to good keys (in the same form).")
+to good keys (in the same form)."
+ :type '(alist :key-type (choice key-sequence (repeat key-sequence))
+ :value-type key-sequence))
(defun mdw-clobber-evil-keymap (keymap)
"Replace evil key bindings in the KEYMAP.
(dolist (key replacements)
(define-key keymap key binding))))))
-(eval-after-load "org-latex"
- '(progn
- (push '("strayman"
- "\\documentclass{strayman}
+(defcustom mdw-org-latex-defs
+ '(("strayman"
+ "\\documentclass{strayman}
\\usepackage[utf8]{inputenc}
\\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
-\\usepackage[T1]{fontenc}
\\usepackage{graphicx, tikz, mdwtab, mdwmath, crypto, longtable}"
- ("\\section{%s}" . "\\section*{%s}")
- ("\\subsection{%s}" . "\\subsection*{%s}")
- ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
- ("\\paragraph{%s}" . "\\paragraph*{%s}")
- ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
- org-export-latex-classes)))
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
+ ("\\paragraph{%s}" . "\\paragraph*{%s}")
+ ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
+ "Additional LaTeX class definitions."
+ :type '(alist :key-type string
+ :value-type (list string
+ (alist :inline t
+ :key-type string
+ :value-type string))))
+
+(setq org-emphasis-regexp-components
+ '("- \t('\"{}" ; prematch
+ "- \t.,:!?;'\")}\\[" ; postmatch
+ " \t\r\n" ; /forbidden/ as border
+ "." ; body regexp
+ 1)) ; maximum newlines
+
+(setq org-entities-user
+ ;; NAME LATEX MATHP HTML ASCII LATIN1 UTF8
+ '(("relax" "" nil "" "" "" "")))
+
+(eval-after-load "org-latex"
+ '(setq org-export-latex-classes
+ (append mdw-org-latex-defs org-export-latex-classes)))
+
+(eval-after-load "ox-latex"
+ '(setq org-latex-classes (append mdw-org-latex-defs org-latex-classes)
+ org-latex-caption-above nil
+ org-latex-default-packages-alist '(("AUTO" "inputenc" t)
+ ("T1" "fontenc" t)
+ ("" "fixltx2e" nil)
+ ("" "graphicx" t)
+ ("" "longtable" nil)
+ ("" "float" nil)
+ ("" "wrapfig" nil)
+ ("" "rotating" nil)
+ ("normalem" "ulem" t)
+ ("" "textcomp" t)
+ ("" "marvosym" t)
+ ("" "wasysym" t)
+ ("" "amssymb" t)
+ ("" "hyperref" nil)
+ "\\tolerance=1000")))
(setq org-export-docbook-xslt-proc-command "xsltproc --output %o %s %i"
org-export-docbook-xsl-fo-proc-command "fop %i.safe %o"
org-export-docbook-xslt-stylesheet
- "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl")
+ "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl")
+
+;; Glasses.
+
+(setq glasses-separator "-"
+ glasses-separate-parentheses-p nil
+ glasses-uncapitalize-p t)
;; Some hacks to do with window placement.
+(defvar mdw-designated-window nil
+ "The window chosen by `mdw-designate-window', or nil.")
+
+(defun mdw-designated-window-display-buffer-function (buffer not-this-window)
+ "Display buffer function to use the designated window."
+ (unless mdw-designated-window (error "No designated window!"))
+ (prog1 mdw-designated-window
+ (with-selected-window mdw-designated-window (switch-to-buffer buffer))
+ (setq mdw-designated-window nil
+ display-buffer-function nil)))
+
+(defun mdw-display-buffer-in-designated-window (buffer alist)
+ "Display function to use the designated window."
+ (prog1 mdw-designated-window
+ (when mdw-designated-window
+ (with-selected-window mdw-designated-window
+ (switch-to-buffer buffer nil t)))
+ (setq mdw-designated-window nil)))
+
+(defun mdw-designate-window (cancel)
+ "Use the selected window for the next pop-up buffer.
+With a prefix argument, clear the designated window."
+ (interactive "P")
+ (let ((window (selected-window)))
+ (cond (cancel
+ (cond (mdw-designated-window
+ (setq mdw-designated-window nil)
+ (unless (mdw-emacs-version-p 24)
+ (setq display-buffer-function nil))
+ (message "Window designation cleared."))
+ (t
+ (message "No designated window active."))))
+ ((window-dedicated-p window)
+ (error "Window is dedicated to its buffer."))
+ (t
+ (setq mdw-designated-window window)
+ (unless (mdw-emacs-version-p 24)
+ (setq display-buffer-function
+ #'mdw-designated-window-display-buffer-function))
+ (message "Window designated.")))))
+
+(when (mdw-emacs-version-p 24)
+ (setq display-buffer-base-action
+ (let* ((action display-buffer-base-action)
+ (funcs (car action))
+ (alist (cdr action)))
+ (cons (cons 'mdw-display-buffer-in-designated-window funcs)
+ alist))))
+
(defun mdw-clobber-other-windows-showing-buffer (buffer-or-name)
"Arrange that no windows on other frames are showing BUFFER-OR-NAME."
(interactive "bBuffer: ")
(let ((home-frame (selected-frame))
(buffer (get-buffer buffer-or-name))
(safe-buffer (get-buffer "*scratch*")))
- (mapc (lambda (frame)
- (or (eq frame home-frame)
- (mapc (lambda (window)
- (and (eq (window-buffer window) buffer)
- (set-window-buffer window safe-buffer)))
- (window-list frame))))
- (frame-list))))
+ (dolist (frame (frame-list))
+ (unless (eq frame home-frame)
+ (dolist (window (window-list frame))
+ (when (eq (window-buffer window) buffer)
+ (set-window-buffer window safe-buffer)))))))
(defvar mdw-inhibit-walk-windows nil
"If non-nil, then `walk-windows' does nothing.
This is used by advice on `switch-to-buffer-other-frame' to inhibit finding
buffers in random frames.")
+(setq display-buffer--other-frame-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame)
+ (reusable-frames . nil)
+ (inhibit-same-window . t)))
+
(defadvice walk-windows (around mdw-inhibit activate)
"If `mdw-inhibit-walk-windows' is non-nil, then do nothing."
(and (not mdw-inhibit-walk-windows)
Pretend they don't exist. They might be on other display devices."
(ad-set-arg 2 nil))
+(setq even-window-sizes nil
+ even-window-heights nil
+ display-buffer-reuse-frames nil)
+
+(defvar mdw-fallback-window-alist nil
+ "Alist mapping frames to fallback windows.")
+
+(defun mdw-cleanup-fallback-window-alist ()
+ "Remove entries for dead frames and windows from the fallback alist."
+ (let ((prev nil)
+ (cursor mdw-fallback-window-alist))
+ (while cursor
+ (let* ((assoc (car cursor))
+ (tail (cdr cursor)))
+ (cond ((and (frame-live-p (car assoc))
+ (window-live-p (cdr assoc)))
+ (setq prev cursor))
+ ((null prev)
+ (setq mdw-fallback-window-alist tail))
+ (t
+ (setcdr prev tail)))
+ (setq cursor tail)))))
+
+(defun mdw-set-fallback-window (cancel)
+ "Prefer the selected window for pop-up buffers in this frame.
+With a prefix argument, clear the fallback window."
+ (interactive "P")
+ (let* ((frame (selected-frame)) (window (selected-window))
+ (assoc (assq (selected-frame) mdw-fallback-window-alist)))
+ (cond (cancel
+ (cond (assoc
+ (setcdr assoc nil)
+ (message "Fallback window cleared."))
+ (t
+ (message "No fallback window active in this frame."))))
+ ((window-dedicated-p window)
+ (error "Window is dedicated to its buffer."))
+ (t
+ (if assoc (setcdr assoc window)
+ (push (cons frame window) mdw-fallback-window-alist))
+ (message "Fallback window set.")))
+ (mdw-cleanup-fallback-window-alist)))
+
+(defun mdw-last-window-in-frame-p (window)
+ "Return whether WINDOW is the last in its frame."
+ (catch 'done
+ (while window
+ (let ((next (window-next-sibling window)))
+ (while (and next (window-minibuffer-p next))
+ (setq next (window-next-sibling next)))
+ (if next (throw 'done nil)))
+ (setq window (window-parent window)))
+ t))
+
+(defun mdw-display-buffer-in-tolerable-window (buffer alist)
+ "Try finding a tolerable window in which to display BUFFER.
+Begone, foul DWIMmerlaik!
+
+This is all totally subject to arbitrary change in the future, but the
+emphasis is on predictability rather than crazy DWIMmery."
+ (let* ((selected (selected-window)) chosen
+ (fallback (assq (selected-frame) mdw-fallback-window-alist))
+ (full-height-p (window-full-height-p selected))
+ (full-width-p (window-full-width-p selected)))
+ (cond
+
+ ((and fallback (window-live-p (cdr fallback)))
+ ;; There's a fallback window set for this frame. Use it.
+
+ (setq chosen (cdr fallback)
+ selected nil)
+ (display-buffer-record-window 'window chosen buffer))
+
+ ((and full-height-p full-width-p)
+ ;; We're basically the only window in the frame. If we want to get
+ ;; anywhere, we'll have to split the window.
+
+ (let ((width (window-width selected))
+ (preferred-width (mdw-preferred-column-width)))
+ (if (and (>= width (mdw-frame-width-for-columns 2 preferred-width))
+ (mdw-frame-width-quantized-p width preferred-width))
+ (setq chosen (split-window-right preferred-width))
+ (setq chosen (split-window-below)))
+ (display-buffer-record-window 'window chosen buffer)))
+
+ ((mdw-last-window-in-frame-p selected)
+ ;; This is the last window in the frame. I don't think I want to
+ ;; clobber the first window, so rebound and clobber the previous one
+ ;; instead. (This obviously has the same effect if there are only two
+ ;; windows, but seems more useful if there are three.)
+
+ (setq chosen (previous-window selected 'never nil))
+ (display-buffer-record-window 'reuse chosen buffer))
+
+ (t
+ ;; There's another window in front of us. Let's use that one.
+ (setq chosen (next-window selected 'never nil)))
+ (display-buffer-record-window 'reuse chosen buffer))
+
+ (if (eq chosen selected)
+ (error "Failed to select a different window!"))
+
+ (when chosen
+ (with-selected-window chosen (switch-to-buffer buffer)))
+ chosen))
+
+;; Hack the display actions so that they do something sensible.
+(setq display-buffer-fallback-action
+ '((display-buffer--maybe-same-window
+ display-buffer-reuse-window
+ display-buffer-pop-up-window
+ mdw-display-buffer-in-tolerable-window)))
+
+;; Rename buffers along with files.
+
+(defvar mdw-inhibit-rename-buffer nil
+ "If non-nil, `rename-file' won't rename the buffer visiting the file.")
+
+(defmacro mdw-advise-to-inhibit-rename-buffer (function)
+ "Advise FUNCTION to set `mdw-inhibit-rename-buffer' while it runs.
+
+This will prevent `rename-file' from renaming the buffer."
+ `(defadvice ,function (around mdw-inhibit-rename-buffer compile activate)
+ "Don't rename the buffer when renaming the underlying file."
+ (let ((mdw-inhibit-rename-buffer t))
+ ad-do-it)))
+(mdw-advise-to-inhibit-rename-buffer recode-file-name)
+(mdw-advise-to-inhibit-rename-buffer set-visited-file-name)
+(mdw-advise-to-inhibit-rename-buffer backup-buffer)
+
+(defadvice rename-file (after mdw-rename-buffers (from to &optional forcep)
+ compile activate)
+ "If a buffer is visiting the file, rename it to match the new name.
+
+Don't do this if `mdw-inhibit-rename-buffer' is non-nil."
+ (unless mdw-inhibit-rename-buffer
+ (let ((buffer (get-file-buffer from)))
+ (when buffer
+ (let ((to (if (not (string= (file-name-nondirectory to) "")) to
+ (concat to (file-name-nondirectory from)))))
+ (with-current-buffer buffer
+ (set-visited-file-name to nil t)))))))
+
+;;;--------------------------------------------------------------------------
+;;; Improved compilation machinery.
+
+;; Uprated version of M-x compile.
+
+(setq compile-command
+ (let ((ncpu (with-temp-buffer
+ (insert-file-contents "/proc/cpuinfo")
+ (buffer-string)
+ (count-matches "^processor\\s-*:"))))
+ (format "nice make -j%d -k" (* 2 ncpu))))
+
+(defun mdw-compilation-buffer-name (mode)
+ (concat "*" (downcase mode) ": "
+ (abbreviate-file-name default-directory) "*"))
+(setq compilation-buffer-name-function 'mdw-compilation-buffer-name)
+
+(eval-after-load "compile"
+ '(progn
+ (define-key compilation-shell-minor-mode-map "\C-c\M-g" 'recompile)))
+
+(defadvice compile (around hack-environment compile activate)
+ "Hack the environment inherited by inferiors in the compilation."
+ (let ((process-environment (copy-tree process-environment)))
+ (setenv "LD_PRELOAD" nil)
+ ad-do-it))
+
+(defun mdw-compile (command &optional directory comint)
+ "Initiate a compilation COMMAND, maybe in a different DIRECTORY.
+The DIRECTORY may be nil to not change. If COMINT is t, then
+start an interactive compilation.
+
+Interactively, prompt for the command if the variable
+`compilation-read-command' is non-nil, or if requested through
+the prefix argument. Prompt for the directory, and run
+interactively, if requested through the prefix.
+
+Use a prefix of 4, 6, 12, or 14, or type C-u between one and three times, to
+force prompting for a directory.
+
+Use a prefix of 2, 6, 10, or 14, or type C-u three times, to force
+prompting for the command.
+
+Use a prefix of 8, 10, 12, or 14, or type C-u twice or three times,
+to force interactive compilation."
+ (interactive
+ (let* ((prefix (prefix-numeric-value current-prefix-arg))
+ (command (eval compile-command))
+ (dir (and (cl-plusp (logand prefix #x54))
+ (read-directory-name "Compile in directory: "))))
+ (list (if (or compilation-read-command
+ (cl-plusp (logand prefix #x42)))
+ (compilation-read-command command)
+ command)
+ dir
+ (cl-plusp (logand prefix #x58)))))
+ (let ((default-directory (or directory default-directory)))
+ (compile command comint)))
+
+;; Flymake support.
+
+(defun mdw-find-build-dir (build-file)
+ (catch 'found
+ (let* ((src-dir (file-name-as-directory (expand-file-name ".")))
+ (dir src-dir))
+ (cl-loop
+ (when (file-exists-p (concat dir build-file))
+ (throw 'found dir))
+ (let ((sub (expand-file-name (file-relative-name src-dir dir)
+ (concat dir "build/"))))
+ (catch 'give-up
+ (cl-loop
+ (when (file-exists-p (concat sub build-file))
+ (throw 'found sub))
+ (when (string= sub dir) (throw 'give-up nil))
+ (setq sub (file-name-directory (directory-file-name sub))))))
+ (when (string= dir
+ (setq dir (file-name-directory
+ (directory-file-name dir))))
+ (throw 'found nil))))))
+
+(defun mdw-flymake-make-init ()
+ (let ((build-dir (mdw-find-build-dir "Makefile")))
+ (and build-dir
+ (let ((tmp-src (flymake-init-create-temp-buffer-copy
+ #'flymake-create-temp-inplace)))
+ (flymake-get-syntax-check-program-args
+ tmp-src build-dir t t
+ #'flymake-get-make-cmdline)))))
+
+(setq flymake-allowed-file-name-masks
+ '(("\\.\\(?:[cC]\\|cc\\|cpp\\|cxx\\|c\\+\\+\\)\\'"
+ mdw-flymake-make-init)
+ ("\\.\\(?:[hH]\\|hh\\|hpp\\|hxx\\|h\\+\\+\\)\\'"
+ mdw-flymake-master-make-init)
+ ("\\.p[lm]" flymake-perl-init)))
+
+(setq flymake-mode-map
+ (let ((map (if (boundp 'flymake-mode-map)
+ flymake-mode-map
+ (make-sparse-keymap))))
+ (define-key map [?\C-c ?\C-f ?\C-p] 'flymake-goto-prev-error)
+ (define-key map [?\C-c ?\C-f ?\C-n] 'flymake-goto-next-error)
+ (define-key map [?\C-c ?\C-f ?\C-c] 'flymake-compile)
+ (define-key map [?\C-c ?\C-f ?\C-k] 'flymake-stop-all-syntax-checks)
+ (define-key map [?\C-c ?\C-f ?\C-e] 'flymake-popup-current-error-menu)
+ map))
+
;;;--------------------------------------------------------------------------
;;; Mail and news hacking.
(make-local-variable 'paragraph-separate)
(make-local-variable 'paragraph-start)
(setq paragraph-start
- (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
- paragraph-start))
+ (concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
+ paragraph-start))
(setq paragraph-separate
(concat "[ \t]*[-_][-_][-_]+$\\|^-- \\|-----\\|"
paragraph-separate))))
;; AUTHINFO GENERIC kludge.
-(defvar nntp-authinfo-generic nil
+(defcustom nntp-authinfo-generic nil
"Set to the `NNTPAUTH' string to pass on to `authinfo-kludge'.
-Use this to arrange for per-server settings.")
+Use this to arrange for per-server settings."
+ :type '(choice (const :tag "Use `NNTPAUTH' environment variable" nil)
+ string)
+ :safe 'stringp)
(defun nntp-open-authinfo-kludge (buffer)
"Open a connection to SERVER using `authinfo-kludge'."
proc))
(eval-after-load "erc"
- '(load "~/.ercrc.el"))
+ '(load "~/.ercrc.el"))
+
+;; Heavy-duty Gnus patching.
+
+(defun mdw-nnimap-transform-headers ()
+ (goto-char (point-min))
+ (let (article lines size string)
+ (cl-block nil
+ (while (not (eobp))
+ (while (not (looking-at "\\* [0-9]+ FETCH"))
+ (delete-region (point) (progn (forward-line 1) (point)))
+ (when (eobp)
+ (cl-return)))
+ (goto-char (match-end 0))
+ ;; Unfold quoted {number} strings.
+ (while (re-search-forward
+ "[^]][ (]{\\([0-9]+\\)}\r?\n"
+ (save-excursion
+ ;; Start of the header section.
+ (or (re-search-forward "] {[0-9]+}\r?\n" nil t)
+ ;; Start of the next FETCH.
+ (re-search-forward "\\* [0-9]+ FETCH" nil t)
+ (point-max)))
+ t)
+ (setq size (string-to-number (match-string 1)))
+ (delete-region (+ (match-beginning 0) 2) (point))
+ (setq string (buffer-substring (point) (+ (point) size)))
+ (delete-region (point) (+ (point) size))
+ (insert (format "%S" (subst-char-in-string ?\n ?\s string)))
+ ;; [mdw] missing from upstream
+ (backward-char 1))
+ (beginning-of-line)
+ (setq article
+ (and (re-search-forward "UID \\([0-9]+\\)"
+ (line-end-position)
+ t)
+ (match-string 1)))
+ (setq lines nil)
+ (setq size
+ (and (re-search-forward "RFC822.SIZE \\([0-9]+\\)"
+ (line-end-position)
+ t)
+ (match-string 1)))
+ (beginning-of-line)
+ (when (search-forward "BODYSTRUCTURE" (line-end-position) t)
+ (let ((structure (ignore-errors
+ (read (current-buffer)))))
+ (while (and (consp structure)
+ (not (atom (car structure))))
+ (setq structure (car structure)))
+ (setq lines (if (and
+ (stringp (car structure))
+ (equal (upcase (nth 0 structure)) "MESSAGE")
+ (equal (upcase (nth 1 structure)) "RFC822"))
+ (nth 9 structure)
+ (nth 7 structure)))))
+ (delete-region (line-beginning-position) (line-end-position))
+ (insert (format "211 %s Article retrieved." article))
+ (forward-line 1)
+ (when size
+ (insert (format "Chars: %s\n" size)))
+ (when lines
+ (insert (format "Lines: %s\n" lines)))
+ ;; Most servers have a blank line after the headers, but
+ ;; Davmail doesn't.
+ (unless (re-search-forward "^\r$\\|^)\r?$" nil t)
+ (goto-char (point-max)))
+ (delete-region (line-beginning-position) (line-end-position))
+ (insert ".")
+ (forward-line 1)))))
+
+(eval-after-load 'nnimap
+ '(defalias 'nnimap-transform-headers
+ (symbol-function 'mdw-nnimap-transform-headers)))
+
+(defadvice gnus-other-frame (around mdw-hack-frame-width compile activate)
+ "Always arrange for mail/news frames to be 80 columns wide."
+ (let ((default-frame-alist (cons `(width . ,(+ 80 mdw-frame-width-fudge))
+ (delete* 'width default-frame-alist
+ :key #'car))))
+ ad-do-it))
+
+;; Preferred programs.
+
+(setq mailcap-user-mime-data
+ '(((type . "application/pdf") (viewer . "mupdf %s"))))
;;;--------------------------------------------------------------------------
;;; Utility functions.
(erase-buffer)
(shell-command "date +%Y-%m-%d" t)
(goto-char (mark))
- (delete-backward-char 1)
+ (delete-char -1)
(buffer-string))
(kill-buffer buffer))))))
;; Now actually do the thing.
(call-process "uuencode" file t nil name))
-(defvar np-file "~/.np"
- "*Where the `now-playing' file is.")
+(defcustom np-file "~/.np"
+ "Where the `now-playing' file is."
+ :type 'file
+ :safe 'stringp)
(defun np (&optional arg)
"Grabs a `now-playing' string."
(cond ((null la) (throw 'done lb))
((null lb) (throw 'done nil))
((< (car la) (car lb)) (throw 'done t))
- ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb))))))))
+ ((= (car la) (car lb)) (setq la (cdr la) lb (cdr lb)))
+ (t (throw 'done nil)))))))
(defun mdw-check-autorevert ()
"Sets global-auto-revert-ignore-buffer appropriately for this buffer.
(defadvice write-file (after mdw-autorevert activate)
(mdw-check-autorevert))
+(defun mdw-auto-revert ()
+ "Recheck all of the autorevertable buffers, and update VC modelines."
+ (interactive)
+ (let ((auto-revert-check-vc-info t))
+ (auto-revert-buffers)))
+
;;;--------------------------------------------------------------------------
;;; Dired hacking.
(ad-set-arg 0 dir)
ad-do-it)))
+(defun mdw-dired-run (args &optional syncp)
+ (interactive (let ((file (dired-get-filename t)))
+ (list (read-string (format "Arguments for %s: " file))
+ current-prefix-arg)))
+ (funcall (if syncp 'shell-command 'async-shell-command)
+ (concat (shell-quote-argument (dired-get-filename nil))
+ " " args)))
+
+(defadvice dired-do-flagged-delete
+ (around mdw-delete-if-prefix-argument activate compile)
+ (let ((delete-by-moving-to-trash (and (null current-prefix-arg)
+ delete-by-moving-to-trash)))
+ ad-do-it))
+
+(eval-after-load "dired"
+ '(define-key dired-mode-map "X" 'mdw-dired-run))
+
;;;--------------------------------------------------------------------------
;;; URL viewing.
(w3m-browse-url url new-session-p))
(select-window window)))))
-(defvar mdw-good-url-browsers
- '(browse-url-mozilla
+(eval-after-load 'w3m
+ '(define-key w3m-mode-map [?\e ?\r] 'w3m-view-this-url-new-session))
+
+(defcustom mdw-good-url-browsers
+ '(browse-url-firefox
+ browse-url-mozilla
browse-url-generic
(w3m . mdw-w3m-browse-url)
browse-url-w3)
"List of good browsers for mdw-good-url-browsers.
Each item is a browser function name, or a cons (CHECK . FUNC).
-A symbol FOO stands for (FOO . FOO).")
+A symbol FOO stands for (FOO . FOO)."
+ :type '(repeat (choice function (cons function function))))
(defun mdw-good-url-browser ()
"Return a good URL browser.
"http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=%s")
("ljlogin" "LJ login" "http://www.livejournal.com/login.bml")))
(add-to-list 'w3m-search-engine-alist
- (list (cadr item) (caddr item) nil))
+ (list (cadr item) (cl-caddr item) nil))
(add-to-list 'w3m-uri-replace-alist
(list (concat "\\`" (car item) ":")
'w3m-search-uri-replace
;; Useful variables.
-(defvar mdw-fill-prefix nil
- "*Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
+(defcustom mdw-fill-prefix nil
+ "Used by `mdw-line-prefix' and `mdw-fill-paragraph'.
If there's no fill prefix currently set (by the `fill-prefix'
variable) and there's a match from one of the regexps here, it
gets used to set the fill-prefix for the current operation.
-The variable is a list of items of the form `REGEXP . PREFIX'; if
-the REGEXP matches, the PREFIX is used to set the fill prefix.
-It in turn is a list of things:
+The variable is a list of items of the form `PATTERN . PREFIX'; if
+the PATTERN matches, the PREFIX is used to set the fill prefix.
+
+A PATTERN is one of the following.
+
+ * STRING -- a regular expression, expected to match at point
+ * (eval . FORM) -- a Lisp form which must evaluate non-nil
+ * (if COND CONSEQ-PAT ALT-PAT) -- if COND evaluates non-nil, must match
+ CONSEQ-PAT; otherwise must match ALT-PAT
+ * (and PATTERN ...) -- must match all of the PATTERNs
+ * (or PATTERN ...) -- must match at least one PATTERN
+ * (not PATTERN) -- mustn't match (probably not useful)
+
+A PREFIX is a list of the following kinds of things:
- STRING -- insert a literal string
- (match . N) -- insert the thing matched by bracketed subexpression N
- (pad . N) -- a string of whitespace the same width as subexpression N
- (expr . FORM) -- the result of evaluating FORM")
+ * STRING -- insert a literal string
+ * (match . N) -- insert the thing matched by bracketed subexpression N
+ * (pad . N) -- a string of whitespace the same width as subexpression N
+ * (expr . FORM) -- the result of evaluating FORM
+
+Information about `bracketed subexpressions' comes from the match data,
+as modified during matching.")
(make-variable-buffer-local 'mdw-fill-prefix)
-(defvar mdw-hanging-indents
+(defcustom mdw-hanging-indents
(concat "\\(\\("
"\\([*o+]\\|-[-#]?\\|[0-9]+\\.\\|\\[[0-9]+\\]\\|([a-zA-Z])\\)"
"[ \t]+"
"\\)?\\)")
- "*Standard regexp matching parts of a hanging indent.
-This is mainly useful in `auto-fill-mode'.")
-
-;; Setting things up.
-
-(fset 'mdw-do-auto-fill (symbol-function 'do-auto-fill))
+ "Standard regexp matching parts of a hanging indent.
+This is mainly useful in `auto-fill-mode'."
+ :type 'regexp)
;; Utility functions.
(funcall tabfun (point-min) (point-max))
(setq s (buffer-substring (point-min) (1- (point-max)))))))))
-(defun mdw-examine-fill-prefixes (l)
- "Given a list of dynamic fill prefixes, pick one which matches
-context and return the static fill prefix to use. Point must be
-at the start of a line, and match data must be saved."
- (cond ((not l) nil)
- ((looking-at (car (car l)))
- (mdw-maybe-tabify (apply #'concat
- (mapcar #'mdw-do-prefix-match
- (cdr (car l))))))
- (t (mdw-examine-fill-prefixes (cdr l)))))
+(defun mdw-fill-prefix-match-p (pat)
+ "Return non-nil if PAT matches at the current position."
+ (cond ((stringp pat) (looking-at pat))
+ ((not (consp pat)) (error "Unknown pattern item `%S'" pat))
+ ((eq (car pat) 'eval) (eval (cdr pat)))
+ ((eq (car pat) 'if)
+ (if (or (null (cdr pat))
+ (null (cddr pat))
+ (null (cl-cdddr pat))
+ (cl-cddddr pat))
+ (error "Invalid `if' pattern `%S'" pat))
+ (mdw-fill-prefix-match-p (if (eval (cadr pat))
+ (cl-caddr pat)
+ (cl-cadddr pat))))
+ ((eq (car pat) 'and)
+ (let ((pats (cdr pat))
+ (ok t))
+ (while (and pats
+ (or (mdw-fill-prefix-match-p (car pats))
+ (setq ok nil)))
+ (setq pats (cdr pats)))
+ ok))
+ ((eq (car pat) 'or)
+ (let ((pats (cdr pat))
+ (ok nil))
+ (while (and pats
+ (or (not (mdw-fill-prefix-match-p (car pats)))
+ (progn (setq ok t) nil)))
+ (setq pats (cdr pats)))
+ ok))
+ ((eq (car pat) 'not)
+ (if (or (null (cdr pat)) (cddr pat))
+ (error "Invalid `not' pattern `%S'" pat))
+ (not (mdw-fill-prefix-match-p (car pats))))
+ (t (error "Unknown pattern form `%S'" pat))))
(defun mdw-maybe-car (p)
"If P is a pair, return (car P), otherwise just return P."
"Expand a dynamic prefix match element.
See `mdw-fill-prefix' for details."
(cond ((not (consp m)) (format "%s" m))
- ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
- ((eq (car m) 'pad) (mdw-padding (match-string
- (mdw-maybe-car (cdr m)))))
- ((eq (car m) 'eval) (eval (cdr m)))
- (t "")))
+ ((eq (car m) 'match) (match-string (mdw-maybe-car (cdr m))))
+ ((eq (car m) 'pad) (mdw-padding (match-string
+ (mdw-maybe-car (cdr m)))))
+ ((eq (car m) 'eval) (eval (cdr m)))
+ (t "")))
+
+(defun mdw-examine-fill-prefixes (l)
+ "Given a list of dynamic fill prefixes, pick one which matches
+context and return the static fill prefix to use. Point must be
+at the start of a line, and match data must be saved."
+ (let ((prefix nil))
+ (while (cond ((null l) nil)
+ ((mdw-fill-prefix-match-p (caar l))
+ (setq prefix
+ (mdw-maybe-tabify
+ (apply #'concat
+ (mapcar #'mdw-do-prefix-match
+ (cdr (car l))))))
+ nil))
+ (setq l (cdr l)))
+ prefix))
(defun mdw-choose-dynamic-fill-prefix ()
"Work out the dynamic fill prefix based on the variable `mdw-fill-prefix'."
(cond ((and fill-prefix (not (string= fill-prefix ""))) fill-prefix)
- ((not mdw-fill-prefix) fill-prefix)
- (t (save-excursion
- (beginning-of-line)
- (save-match-data
- (mdw-examine-fill-prefixes mdw-fill-prefix))))))
+ ((not mdw-fill-prefix) fill-prefix)
+ (t (save-excursion
+ (beginning-of-line)
+ (save-match-data
+ (mdw-examine-fill-prefixes mdw-fill-prefix))))))
-(defun do-auto-fill ()
+(defadvice do-auto-fill (around mdw-dynamic-fill-prefix () activate compile)
"Handle auto-filling, working out a dynamic fill prefix in the
case where there isn't a sensible static one."
(let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
- (mdw-do-auto-fill)))
+ ad-do-it))
(defun mdw-fill-paragraph ()
"Fill paragraph, getting a dynamic fill prefix."
(let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
(fill-paragraph nil)))
+(defun mdw-point-within-string-p ()
+ "Return non-nil if point is within a string."
+ (let ((state (syntax-ppss)))
+ (elt state 3)))
+
(defun mdw-standard-fill-prefix (rx &optional mat)
"Set the dynamic fill prefix, handling standard hanging indents and stuff.
This is just a short-cut for setting the thing by hand, and by
design it doesn't cope with anything approximating a complicated
case."
(setq mdw-fill-prefix
- `((,(concat rx mdw-hanging-indents)
- (match . 1)
- (pad . ,(or mat 2))))))
+ `(((if (mdw-point-within-string-p)
+ ,(concat "\\(\\s-*\\)" mdw-hanging-indents)
+ ,(concat rx mdw-hanging-indents))
+ (match . 1)
+ (pad . ,(or mat 2))))))
+
+;;;--------------------------------------------------------------------------
+;;; Printing.
+
+;; Teach PostScript about a condensed variant of Courier. I'm using 85% of
+;; the usual width, which happens to match `mdwfonts', and David Carlisle's
+;; `pslatex'. (Once upon a time, I used 80%, but decided consistency with
+;; `pslatex' was useful.)
+(setq ps-user-defined-prologue "
+/CourierCondensed /Courier
+/CourierCondensed-Bold /Courier-Bold
+/CourierCondensed-Oblique /Courier-Oblique
+/CourierCondensed-BoldOblique /Courier-BoldOblique
+ 4 { findfont [0.85 0 0 1 0 0] makefont definefont pop } repeat
+")
+
+;; Hack `ps-print''s settings.
+(eval-after-load 'ps-print
+ '(progn
+
+ ;; Notice that the comment-delimiters should be in italics too.
+ (cl-pushnew 'font-lock-comment-delimiter-face ps-italic-faces)
+
+ ;; Select more suitable colours for the main kinds of tokens. The
+ ;; colours set on the Emacs faces are chosen for use against a dark
+ ;; background, and work very badly on white paper.
+ (ps-extend-face '(font-lock-comment-face "darkgreen" nil italic))
+ (ps-extend-face '(font-lock-comment-delimiter-face "darkgreen" nil italic))
+ (ps-extend-face '(font-lock-string-face "RoyalBlue4" nil))
+ (ps-extend-face '(mdw-punct-face "sienna" nil))
+ (ps-extend-face '(mdw-number-face "OrangeRed3" nil))
+
+ ;; Teach `ps-print' about my condensed varsions of Courier.
+ (setq ps-font-info-database
+ (append '((CourierCondensed
+ (fonts (normal . "CourierCondensed")
+ (bold . "CourierCondensed-Bold")
+ (italic . "CourierCondensed-Oblique")
+ (bold-italic . "CourierCondensed-BoldOblique"))
+ (size . 10.0)
+ (line-height . 10.55)
+ (space-width . 5.1)
+ (avg-char-width . 5.1)))
+ (cl-remove 'CourierCondensed ps-font-info-database
+ :key #'car)))))
+
+;; Arrange to strip overlays from the buffer before we print . This will
+;; prevent `flyspell' from interfering with the printout. (It would be less
+;; bad if `ps-print' could merge the `flyspell' overlay face with the
+;; underlying `font-lock' face, but it can't (and that seems hard). So
+;; instead we have this hack.
+;;
+;; The basic trick is to copy the relevant text from the buffer being printed
+;; into a temporary buffer and... just print that. The text properties come
+;; with the text and end up in the new buffer, and the overlays get lost
+;; along the way. Only problem is that the headers identifying the file
+;; being printed get confused, so remember the original buffer and reinstate
+;; it when constructing the headers.
+(defvar mdw-printing-buffer)
+
+(defadvice ps-generate-header
+ (around mdw-use-correct-buffer () activate compile)
+ "Print the correct name of the buffer being printed."
+ (with-current-buffer mdw-printing-buffer
+ ad-do-it))
+
+(defadvice ps-generate
+ (around mdw-strip-overlays (buffer from to genfunc) activate compile)
+ "Strip overlays -- in particular, from `flyspell' -- before printout."
+ (with-temp-buffer
+ (let ((mdw-printing-buffer buffer))
+ (insert-buffer-substring buffer from to)
+ (ad-set-arg 0 (current-buffer))
+ (ad-set-arg 1 (point-min))
+ (ad-set-arg 2 (point-max))
+ ad-do-it)))
;;;--------------------------------------------------------------------------
;;; Other common declarations.
;; Common mode settings.
-(defvar mdw-auto-indent t
- "Whether to indent automatically after a newline.")
+(defcustom mdw-auto-indent t
+ "Whether to indent automatically after a newline."
+ :type 'boolean
+ :safe 'booleanp)
(defun mdw-whitespace-mode (&optional arg)
"Turn on/off whitespace mode, but don't highlight trailing space."
(and mdw-auto-indent
(cond ((eq major-mode 'lisp-mode)
(local-set-key "\C-m" 'mdw-indent-newline-and-indent))
- ((or (eq major-mode 'slime-repl-mode)
- (eq major-mode 'asm-mode))
+ ((derived-mode-p 'slime-repl-mode 'asm-mode 'comint-mode)
nil)
(t
(local-set-key "\C-m" 'newline-and-indent))))
(set (make-local-variable 'mdw-do-misc-mode-hacking) t)
(local-set-key [C-return] 'newline)
(make-local-variable 'page-delimiter)
- (setq page-delimiter "\f\\|^.*-\\{6\\}.*$")
+ (setq page-delimiter (concat "^" "\f"
+ "\\|" "^"
+ ".\\{0,4\\}"
+ "-\\{5\\}"
+ "\\(" " " ".*" " " "\\)?"
+ "-+"
+ ".\\{0,2\\}"
+ "$"))
(setq comment-column 40)
(auto-fill-mode 1)
- (setq fill-column 77)
+ (setq fill-column mdw-text-width)
+ (flyspell-prog-mode)
(and (fboundp 'gtags-mode)
(gtags-mode))
(if (fboundp 'hs-minor-mode)
(trap (turn-on-font-lock)))
(defun mdw-post-local-vars-misc-mode-config ()
+ (setq whitespace-line-column mdw-text-width)
(when (and mdw-do-misc-mode-hacking
(not buffer-read-only))
(setq show-trailing-whitespace t)
(mdw-whitespace-mode 1)))
(add-hook 'hack-local-variables-hook 'mdw-post-local-vars-misc-mode-config)
-(defadvice toggle-read-only (after mdw-angry-fruit-salad activate)
- (when mdw-do-misc-mode-hacking
- (setq show-trailing-whitespace (not buffer-read-only))
- (mdw-whitespace-mode (if buffer-read-only 0 1))))
+(defmacro mdw-advise-update-angry-fruit-salad (&rest funcs)
+ `(progn ,@(mapcar (lambda (func)
+ `(defadvice ,func
+ (after mdw-angry-fruit-salad activate)
+ (when mdw-do-misc-mode-hacking
+ (setq show-trailing-whitespace
+ (not buffer-read-only))
+ (mdw-whitespace-mode (if buffer-read-only 0 1)))))
+ funcs)))
+(mdw-advise-update-angry-fruit-salad toggle-read-only
+ read-only-mode
+ view-mode
+ view-mode-enable
+ view-mode-disable)
(eval-after-load 'gtags
'(progn
;; Backup file handling.
-(defvar mdw-backup-disable-regexps nil
- "*List of regular expressions: if a file name matches any of
-these then the file is not backed up.")
+(defcustom mdw-backup-disable-regexps nil
+ "List of regular expressions: if a file name matches any of
+these then the file is not backed up."
+ :type '(repeat regexp))
(defun mdw-backup-enable-predicate (name)
"[mdw]'s default backup predicate.
(let ((frame-display (frame-parameter frame 'display)))
(when (and frame-display
(eq window-system 'x)
- (not (some (lambda (fr)
- (and (not (eq fr frame))
- (string= (frame-parameter fr 'display)
- frame-display)))
- (frame-list))))
+ (not (cl-some (lambda (fr)
+ (and (not (eq fr frame))
+ (string= (frame-parameter fr 'display)
+ frame-display)))
+ (frame-list))))
(run-with-idle-timer 0 nil #'x-close-connection frame-display))))
(add-hook 'delete-frame-functions 'mdw-last-one-out-turn-off-the-lights)
;;;--------------------------------------------------------------------------
-;;; Where is point?
-
-(defvar mdw-point-overlay
- (let ((ov (make-overlay 0 0))
- (s "."))
- (overlay-put ov 'priority 2)
- (put-text-property 0 1 'display '(left-fringe vertical-bar) s)
- (overlay-put ov 'before-string s)
- (delete-overlay ov)
- ov)
- "An overlay used for showing where point is in the selected window.")
-
-(defun mdw-remove-point-overlay ()
- "Remove the current-point overlay."
- (delete-overlay mdw-point-overlay))
-
-(defun mdw-update-point-overlay ()
- "Mark the current point position with an overlay."
- (if (not mdw-point-overlay-mode)
- (mdw-remove-point-overlay)
- (overlay-put mdw-point-overlay 'window (selected-window))
- (if (bolp)
- (move-overlay mdw-point-overlay
- (point) (1+ (point)) (current-buffer))
- (move-overlay mdw-point-overlay
- (1- (point)) (point) (current-buffer)))))
-
-(defvar mdw-point-overlay-buffers nil
- "List of buffers using `mdw-point-overlay-mode'.")
-
-(define-minor-mode mdw-point-overlay-mode
- "Indicate current line with an overlay."
- :global nil
- (let ((buffer (current-buffer)))
- (setq mdw-point-overlay-buffers
- (mapcan (lambda (buf)
- (if (and (buffer-live-p buf)
- (not (eq buf buffer)))
- (list buf)))
- mdw-point-overlay-buffers))
- (if mdw-point-overlay-mode
- (setq mdw-point-overlay-buffers
- (cons buffer mdw-point-overlay-buffers))))
- (cond (mdw-point-overlay-buffers
- (add-hook 'pre-command-hook 'mdw-remove-point-overlay)
- (add-hook 'post-command-hook 'mdw-update-point-overlay))
- (t
- (mdw-remove-point-overlay)
- (remove-hook 'pre-command-hook 'mdw-remove-point-overlay)
- (remove-hook 'post-command-hook 'mdw-update-point-overlay))))
-
-(define-globalized-minor-mode mdw-global-point-overlay-mode
- mdw-point-overlay-mode
- (lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
-
-;;;--------------------------------------------------------------------------
;;; Fullscreen-ness.
-(defvar mdw-full-screen-parameters
+(defcustom mdw-full-screen-parameters
'((menu-bar-lines . 0)
- ;(vertical-scroll-bars . nil)
+ ;;(vertical-scroll-bars . nil)
)
- "Frame parameters to set when making a frame fullscreen.")
+ "Frame parameters to set when making a frame fullscreen."
+ :type '(alist :key-type symbol))
-(defvar mdw-full-screen-save
+(defcustom mdw-full-screen-save
'(width height)
- "Extra frame parameters to save when setting fullscreen.")
+ "Extra frame parameters to save when setting fullscreen."
+ :type '(repeat symbol))
(defun mdw-toggle-full-screen (&optional frame)
"Show the FRAME fullscreen."
;;;--------------------------------------------------------------------------
;;; General fontification.
+(make-face 'mdw-virgin-face)
+
(defmacro mdw-define-face (name &rest body)
"Define a face, and make sure it's actually set as the definition."
(declare (indent 1)
(debug 0))
`(progn
- (make-face ',name)
+ (copy-face 'mdw-virgin-face ',name)
(defvar ,name ',name)
(put ',name 'face-defface-spec ',body)
(face-spec-set ',name ',body nil)))
(((type w32)) :family "courier new" :height 85)
(((type x)) :family "6x13" :foundry "trad" :height 130)
(t :foreground "white" :background "black"))
-(if (mdw-emacs-version-p 23)
- (mdw-define-face variable-pitch
- (((type x)) :family "sans" :height 100))
- (mdw-define-face variable-pitch
- (((type x)) :family "helvetica" :height 90)))
+(mdw-define-face fixed-pitch-serif
+ (((type w32)) :family "courier new" :height 85 :weight bold)
+ (((type x)) :family "6x13" :foundry "trad" :height 130 :weight bold)
+ (t :foreground "white" :background "black" :weight bold))
+(mdw-define-face variable-pitch
+ (((type x)) :family "helvetica" :height 120))
(mdw-define-face region
- (((type tty) (class color)) :background "blue")
- (((type tty) (class mono)) :inverse-video t)
- (t :background "grey30"))
+ (((min-colors 64)) :background "grey30")
+ (((class color)) :background "blue")
+ (t :inverse-video t))
+(mdw-define-face error
+ (((class color)) :background "red")
+ (t :inverse-video t))
(mdw-define-face match
- (((type tty) (class color)) :background "blue")
- (((type tty) (class mono)) :inverse-video t)
- (t :background "blue"))
+ (((class color)) :background "blue")
+ (t :inverse-video t))
(mdw-define-face mc/cursor-face
- (((type tty) (class mono)) :inverse-video t)
- (t :background "red"))
+ (((class color)) :background "red")
+ (t :inverse-video t))
(mdw-define-face minibuffer-prompt
(t :weight bold))
(mdw-define-face mode-line
(mdw-define-face fringe
(t :foreground "yellow"))
(mdw-define-face show-paren-match
- (((class color)) :background "darkgreen")
+ (((min-colors 64)) :background "darkgreen")
+ (((class color)) :background "green")
(t :underline t))
(mdw-define-face show-paren-mismatch
(((class color)) :background "red")
(t :inverse-video t))
(mdw-define-face highlight
- (((type x) (class color)) :background "DarkSeaGreen4")
- (((type tty) (class color)) :background "cyan")
+ (((min-colors 64)) :background "DarkSeaGreen4")
+ (((class color)) :background "cyan")
(t :inverse-video t))
+(mdw-define-face viper-minibuffer-emacs (t nil))
+(mdw-define-face viper-minibuffer-insert (t nil))
+(mdw-define-face viper-minibuffer-vi (t nil))
+(mdw-define-face viper-replace-overlay
+ (((min-colors 64)) :background "darkred")
+ (((class color)) :background "red")
+ (t :inverse-video t))
+(mdw-define-face viper-search (t :inherit isearch))
+
+(mdw-define-face compilation-error
+ (((class color)) :foreground "red" :weight bold)
+ (t :weight bold))
+(mdw-define-face compilation-warning
+ (((class color)) :foreground "orange" :weight bold)
+ (t :weight bold))
+(mdw-define-face compilation-info
+ (((class color)) :foreground "green" :weight bold)
+ (t :weight bold))
+(mdw-define-face compilation-line-number
+ (t :weight bold))
+(mdw-define-face compilation-column-number
+ (((min-colors 64)) :foreground "lightgrey"))
+(setq compilation-message-face 'mdw-virgin-face)
+(setq compilation-enter-directory-face 'font-lock-comment-face)
+(setq compilation-leave-directory-face 'font-lock-comment-face)
+
(mdw-define-face holiday-face
(t :background "red"))
(mdw-define-face calendar-today-face
(t :foreground "yellow" :weight bold))
+(mdw-define-face flyspell-incorrect
+ (((type x)) :underline (:color "red" :style wave))
+ (((class color)) :foreground "red" :underline t)
+ (t :underline t))
+(mdw-define-face flyspell-duplicate
+ (((type x)) :underline (:color "orange" :style wave))
+ (((class color)) :foreground "orange" :underline t)
+ (t :underline t))
+
(mdw-define-face comint-highlight-prompt
(t :weight bold))
(mdw-define-face comint-highlight-input
(t nil))
+(mdw-define-face Man-underline
+ (((type tty)) :underline t)
+ (t :slant italic))
+
+(mdw-define-face ido-subdir
+ (t :foreground "cyan" :weight bold))
+
(mdw-define-face dired-directory
(t :foreground "cyan" :weight bold))
(mdw-define-face dired-symlink
(mdw-define-face trailing-whitespace
(((class color)) :background "red")
(t :inverse-video t))
+(mdw-define-face whitespace-line
+ (((class color)) :background "darkred")
+ (t :inverse-video t))
(mdw-define-face mdw-punct-face
- (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
+ (((min-colors 64)) :foreground "burlywood2")
+ (((class color)) :foreground "yellow"))
(mdw-define-face mdw-number-face
(t :foreground "yellow"))
(mdw-define-face mdw-trivial-face)
(t :weight bold))
(mdw-define-face font-lock-variable-name-face
(t :slant italic))
-(mdw-define-face font-lock-comment-delimiter-face
- (((class mono)) :weight bold)
- (((type tty) (class color)) :foreground "green")
- (t :slant italic :foreground "SeaGreen1"))
(mdw-define-face font-lock-comment-face
- (((class mono)) :weight bold)
- (((type tty) (class color)) :foreground "green")
- (t :slant italic :foreground "SeaGreen1"))
+ (((min-colors 64)) :slant italic :foreground "SeaGreen1")
+ (((class color)) :foreground "green")
+ (t :weight bold))
+(mdw-define-face font-lock-comment-delimiter-face
+ (t :inherit font-lock-comment-face))
(mdw-define-face font-lock-string-face
- (((class mono)) :weight bold)
- (((class color)) :foreground "SkyBlue1"))
+ (((min-colors 64)) :foreground "SkyBlue1")
+ (((class color)) :foreground "cyan")
+ (t :weight bold))
+(mdw-define-face font-lock-doc-face
+ (t :inherit font-lock-string-face))
(mdw-define-face message-separator
(t :background "red" :foreground "white" :weight bold))
(mdw-define-face message-cited-text
(default :slant italic)
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (((min-colors 64)) :foreground "SkyBlue1")
+ (((class color)) :foreground "cyan"))
(mdw-define-face message-header-cc
- (default :weight bold)
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (default :slant italic)
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
(mdw-define-face message-header-newsgroups
- (default :weight bold)
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (default :slant italic)
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
(mdw-define-face message-header-subject
- (default :weight bold)
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
(mdw-define-face message-header-to
- (default :weight bold)
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
(mdw-define-face message-header-xheader
- (default :weight bold)
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (default :slant italic)
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
(mdw-define-face message-header-other
- (default :weight bold)
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (default :slant italic)
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
(mdw-define-face message-header-name
- (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+ (default :weight bold)
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
+
(mdw-define-face which-func
(t nil))
+(mdw-define-face gnus-header-name
+ (default :weight bold)
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
+(mdw-define-face gnus-header-subject
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
+(mdw-define-face gnus-header-from
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
+(mdw-define-face gnus-header-to
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
+(mdw-define-face gnus-header-content
+ (default :slant italic)
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
+
+(mdw-define-face gnus-cite-1
+ (((min-colors 64)) :foreground "SkyBlue1")
+ (((class color)) :foreground "cyan"))
+(mdw-define-face gnus-cite-2
+ (((min-colors 64)) :foreground "RoyalBlue2")
+ (((class color)) :foreground "blue"))
+(mdw-define-face gnus-cite-3
+ (((min-colors 64)) :foreground "MediumOrchid")
+ (((class color)) :foreground "magenta"))
+(mdw-define-face gnus-cite-4
+ (((min-colors 64)) :foreground "firebrick2")
+ (((class color)) :foreground "red"))
+(mdw-define-face gnus-cite-5
+ (((min-colors 64)) :foreground "burlywood2")
+ (((class color)) :foreground "yellow"))
+(mdw-define-face gnus-cite-6
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green"))
+(mdw-define-face gnus-cite-7
+ (((min-colors 64)) :foreground "SlateBlue1")
+ (((class color)) :foreground "cyan"))
+(mdw-define-face gnus-cite-8
+ (((min-colors 64)) :foreground "RoyalBlue2")
+ (((class color)) :foreground "blue"))
+(mdw-define-face gnus-cite-9
+ (((min-colors 64)) :foreground "purple2")
+ (((class color)) :foreground "magenta"))
+(mdw-define-face gnus-cite-10
+ (((min-colors 64)) :foreground "DarkOrange2")
+ (((class color)) :foreground "red"))
+(mdw-define-face gnus-cite-11
+ (t :foreground "grey"))
+
+(mdw-define-face gnus-emphasis-underline
+ (((type tty)) :underline t)
+ (t :slant italic))
+
(mdw-define-face diff-header
(t nil))
(mdw-define-face diff-index
(mdw-define-face diff-file-header
(t :weight bold))
(mdw-define-face diff-hunk-header
- (t :foreground "SkyBlue1"))
+ (((min-colors 64)) :foreground "SkyBlue1")
+ (((class color)) :foreground "cyan"))
(mdw-define-face diff-function
- (t :foreground "SkyBlue1" :weight bold))
+ (default :weight bold)
+ (((min-colors 64)) :foreground "SkyBlue1")
+ (((class color)) :foreground "cyan"))
(mdw-define-face diff-header
- (t :background "grey10"))
+ (((min-colors 64)) :background "grey10"))
(mdw-define-face diff-added
- (t :foreground "green"))
+ (((class color)) :foreground "green"))
(mdw-define-face diff-removed
- (t :foreground "red"))
+ (((class color)) :foreground "red"))
(mdw-define-face diff-context
(t nil))
(mdw-define-face diff-refine-change
- (((class color) (type x)) :background "RoyalBlue4")
+ (((min-colors 64)) :background "RoyalBlue4")
+ (t :underline t))
+(mdw-define-face diff-refine-removed
+ (((min-colors 64)) :background "#500")
+ (t :underline t))
+(mdw-define-face diff-refine-added
+ (((min-colors 64)) :background "#050")
(t :underline t))
-(mdw-define-face dylan-header-background
- (((class color) (type x)) :background "NavyBlue")
- (t :background "blue"))
-
-(mdw-define-face magit-diff-add
- (t :foreground "green"))
-(mdw-define-face magit-diff-del
- (t :foreground "red"))
-(mdw-define-face magit-diff-file-header
+(setq ediff-force-faces t)
+(mdw-define-face ediff-current-diff-A
+ (((min-colors 64)) :background "darkred")
+ (((class color)) :background "red")
+ (t :inverse-video t))
+(mdw-define-face ediff-fine-diff-A
+ (((min-colors 64)) :background "red3")
+ (((class color)) :inverse-video t)
+ (t :inverse-video nil))
+(mdw-define-face ediff-even-diff-A
+ (((min-colors 64)) :background "#300"))
+(mdw-define-face ediff-odd-diff-A
+ (((min-colors 64)) :background "#300"))
+(mdw-define-face ediff-current-diff-B
+ (((min-colors 64)) :background "darkgreen")
+ (((class color)) :background "magenta")
+ (t :inverse-video t))
+(mdw-define-face ediff-fine-diff-B
+ (((min-colors 64)) :background "green4")
+ (((class color)) :inverse-video t)
+ (t :inverse-video nil))
+(mdw-define-face ediff-even-diff-B
+ (((min-colors 64)) :background "#020"))
+(mdw-define-face ediff-odd-diff-B
+ (((min-colors 64)) :background "#020"))
+(mdw-define-face ediff-current-diff-C
+ (((min-colors 64)) :background "darkblue")
+ (((class color)) :background "blue")
+ (t :inverse-video t))
+(mdw-define-face ediff-fine-diff-C
+ (((min-colors 64)) :background "blue1")
+ (((class color)) :inverse-video t)
+ (t :inverse-video nil))
+(mdw-define-face ediff-even-diff-C
+ (((min-colors 64)) :background "#004"))
+(mdw-define-face ediff-odd-diff-C
+ (((min-colors 64)) :background "#004"))
+(mdw-define-face ediff-current-diff-Ancestor
+ (((min-colors 64)) :background "#630")
+ (((class color)) :background "blue")
+ (t :inverse-video t))
+(mdw-define-face ediff-even-diff-Ancestor
+ (((min-colors 64)) :background "#320"))
+(mdw-define-face ediff-odd-diff-Ancestor
+ (((min-colors 64)) :background "#320"))
+
+(mdw-define-face magit-hash
+ (((min-colors 64)) :foreground "grey40")
+ (((class color)) :foreground "blue"))
+(mdw-define-face magit-popup-argument
+ (((min-colors 64)) :foreground "SeaGreen1")
+ (((class color)) :foreground "green")
(t :weight bold))
-(mdw-define-face magit-diff-hunk-header
- (t :foreground "SkyBlue1"))
-(mdw-define-face magit-item-highlight
- (((type tty)) :background "blue")
- (t :background "grey11"))
-(mdw-define-face magit-log-head-label-remote
- (((type tty)) :background "cyan" :foreground "green")
- (t :background "grey11" :foreground "DarkSeaGreen2" :box t))
-(mdw-define-face magit-log-head-label-local
- (((type tty)) :background "cyan" :foreground "yellow")
- (t :background "grey11" :foreground "LightSkyBlue1" :box t))
-(mdw-define-face magit-log-head-label-tags
- (((type tty)) :background "red" :foreground "yellow")
- (t :background "LemonChiffon1" :foreground "goldenrod4" :box t))
-(mdw-define-face magit-log-graph
- (((type tty)) :foreground "magenta")
- (t :foreground "grey80"))
+(mdw-define-face magit-diff-hunk-heading
+ (((min-colors 64)) :foreground "grey70" :background "grey25")
+ (((class color)) :foreground "yellow"))
+(mdw-define-face magit-diff-hunk-heading-highlight
+ (((min-colors 64)) :foreground "grey70" :background "grey35")
+ (((class color)) :foreground "yellow" :background "blue"))
+(mdw-define-face magit-diff-added
+ (((min-colors 64)) :foreground "#ddffdd" :background "#335533")
+ (((class color)) :foreground "green"))
+(mdw-define-face magit-diff-added-highlight
+ (((min-colors 64)) :foreground "#cceecc" :background "#336633")
+ (((class color)) :foreground "green" :background "blue"))
+(mdw-define-face magit-diff-removed
+ (((min-colors 64)) :foreground "#ffdddd" :background "#553333")
+ (((class color)) :foreground "red"))
+(mdw-define-face magit-diff-removed-highlight
+ (((min-colors 64)) :foreground "#eecccc" :background "#663333")
+ (((class color)) :foreground "red" :background "blue"))
+(mdw-define-face magit-blame-heading
+ (((min-colors 64)) :foreground "white" :background "grey25"
+ :weight normal :slant normal)
+ (((class color)) :foreground "white" :background "blue"
+ :weight normal :slant normal))
+(mdw-define-face magit-blame-name
+ (t :inherit magit-blame-heading :slant italic))
+(mdw-define-face magit-blame-date
+ (((min-colors 64)) :inherit magit-blame-heading :foreground "grey60")
+ (((class color)) :inherit magit-blame-heading :foreground "cyan"))
+(mdw-define-face magit-blame-summary
+ (t :inherit magit-blame-heading :weight bold))
+
+(mdw-define-face dylan-header-background
+ (((min-colors 64)) :background "NavyBlue")
+ (((class color)) :background "blue"))
+(mdw-define-face erc-my-nick-face
+ (t :foreground "yellow" :weight bold))
+(mdw-define-face erc-current-nick-face
+ (t :foreground "yellow" :weight bold))
(mdw-define-face erc-input-face
- (t :foreground "red"))
+ (t :foreground "yellow"))
+(mdw-define-face erc-action-face
+ ())
+(mdw-define-face erc-button
+ (t :foreground "cyan" :underline t :weight semi-bold))
(mdw-define-face woman-bold
(t :weight bold))
(set-display-table-slot standard-display-table 5 bar))
;;;--------------------------------------------------------------------------
-;;; C programming configuration.
-
-;; Linux kernel hacking.
+;;; Where is point?
-(defvar linux-c-mode-hook)
+(mdw-define-face mdw-point-overlay-face
+ (((type graphic)))
+ (((min-colors 64)) :background "darkblue")
+ (((class color)) :background "blue")
+ (((type tty) (class mono)) :inverse-video t))
+
+(defcustom mdw-point-overlay-fringe-display '(vertical-bar . vertical-bar)
+ "Bitmaps to display in the left and right fringes in the current line."
+ :type '(cons symbol symbol))
+
+(defun mdw-configure-point-overlay ()
+ (let ((ov (make-overlay 0 0)))
+ (overlay-put ov 'priority 0)
+ (let* ((fringe (or mdw-point-overlay-fringe-display (cons nil nil)))
+ (left (car fringe)) (right (cdr fringe))
+ (s ""))
+ (when left
+ (let ((ss "."))
+ (put-text-property 0 1 'display `(left-fringe ,left) ss)
+ (setq s (concat s ss))))
+ (when right
+ (let ((ss "."))
+ (put-text-property 0 1 'display `(right-fringe ,right) ss)
+ (setq s (concat s ss))))
+ (when (or left right)
+ (overlay-put ov 'before-string s)))
+ (overlay-put ov 'face 'mdw-point-overlay-face)
+ (delete-overlay ov)
+ ov))
-(defun linux-c-mode ()
+(defvar mdw-point-overlay (mdw-configure-point-overlay)
+ "An overlay used for showing where point is in the selected window.")
+(defun mdw-reconfigure-point-overlay ()
(interactive)
- (c-mode)
- (setq major-mode 'linux-c-mode)
- (setq mode-name "Linux C")
- (run-hooks 'linux-c-mode-hook))
+ (setq mdw-point-overlay (mdw-configure-point-overlay)))
+
+(defun mdw-remove-point-overlay ()
+ "Remove the current-point overlay."
+ (delete-overlay mdw-point-overlay))
+
+(defun mdw-update-point-overlay ()
+ "Mark the current point position with an overlay."
+ (if (not mdw-point-overlay-mode)
+ (mdw-remove-point-overlay)
+ (overlay-put mdw-point-overlay 'window (selected-window))
+ (move-overlay mdw-point-overlay
+ (line-beginning-position)
+ (+ (line-end-position) 1))))
+
+(defvar mdw-point-overlay-buffers nil
+ "List of buffers using `mdw-point-overlay-mode'.")
+
+(define-minor-mode mdw-point-overlay-mode
+ "Indicate current line with an overlay."
+ :global nil
+ (let ((buffer (current-buffer)))
+ (setq mdw-point-overlay-buffers
+ (cl-mapcan (lambda (buf)
+ (if (and (buffer-live-p buf)
+ (not (eq buf buffer)))
+ (list buf)))
+ mdw-point-overlay-buffers))
+ (if mdw-point-overlay-mode
+ (setq mdw-point-overlay-buffers
+ (cons buffer mdw-point-overlay-buffers))))
+ (cond (mdw-point-overlay-buffers
+ (add-hook 'pre-command-hook 'mdw-remove-point-overlay)
+ (add-hook 'post-command-hook 'mdw-update-point-overlay))
+ (t
+ (mdw-remove-point-overlay)
+ (remove-hook 'pre-command-hook 'mdw-remove-point-overlay)
+ (remove-hook 'post-command-hook 'mdw-update-point-overlay))))
+
+(define-globalized-minor-mode mdw-global-point-overlay-mode
+ mdw-point-overlay-mode
+ (lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
+
+(defvar mdw-terminal-title-alist nil)
+(defun mdw-update-terminal-title ()
+ (when (let ((term (frame-parameter nil 'tty-type)))
+ (and term (string-match "^xterm" term)))
+ (let* ((tty (frame-parameter nil 'tty))
+ (old (assoc tty mdw-terminal-title-alist))
+ (new (format-mode-line frame-title-format)))
+ (unless (and old (equal (cdr old) new))
+ (if old (rplacd old new)
+ (setq mdw-terminal-title-alist
+ (cons (cons tty new) mdw-terminal-title-alist)))
+ (send-string-to-terminal (concat "\e]2;" new "\e\\"))))))
+
+(add-hook 'post-command-hook 'mdw-update-terminal-title)
+
+;;;--------------------------------------------------------------------------
+;;; Ediff hacking.
+
+(defvar mdw-ediff-previous-windows)
+(defun mdw-ediff-setup ()
+ (setq mdw-ediff-previous-windows (current-window-configuration)))
+(defun mdw-ediff-suspend-or-quit ()
+ (set-window-configuration mdw-ediff-previous-windows))
+(add-hook 'ediff-before-setup-hook 'mdw-ediff-setup)
+(add-hook 'ediff-quit-hook 'mdw-ediff-suspend-or-quit t)
+(add-hook 'ediff-suspend-hook 'mdw-ediff-suspend-or-quit t)
+
+;;;--------------------------------------------------------------------------
+;;; C programming configuration.
;; Make C indentation nice.
c-basic-offset
nil)))
-(defun mdw-c-style ()
- (c-add-style "[mdw] C and C++ style"
- '((c-basic-offset . 2)
- (comment-column . 40)
- (c-class-key . "class")
- (c-backslash-column . 72)
- (c-offsets-alist
- (substatement-open . (add 0 c-indent-one-line-block))
- (defun-open . (add 0 c-indent-one-line-block))
- (arglist-cont-nonempty . mdw-c-lineup-arglist)
- (topmost-intro . mdw-c-indent-extern-mumble)
- (cpp-define-intro . 0)
- (knr-argdecl . 0)
- (inextern-lang . [0])
- (label . 0)
- (case-label . +)
- (access-label . -)
- (inclass . +)
- (inline-open . ++)
- (statement-cont . +)
- (statement-case-intro . +)))
- t))
+(defun mdw-c-indent-arglist-nested (langelem)
+ "Indent continued argument lists.
+If we've nested more than one argument list, then only introduce a single
+indentation anyway."
+ (let ((context c-syntactic-context)
+ (pos (c-langelem-2nd-pos c-syntactic-element))
+ (should-indent-p t))
+ (while (and context
+ (eq (caar context) 'arglist-cont-nonempty))
+ (when (and (= (cl-caddr (pop context)) pos)
+ context
+ (memq (caar context) '(arglist-intro
+ arglist-cont-nonempty)))
+ (setq should-indent-p nil)))
+ (if should-indent-p '+ 0)))
+
+(defvar mdw-define-c-styles-hook nil
+ "Hook run when `cc-mode' starts up to define styles.")
+
+(defun mdw-merge-style-alists (first second)
+ (let ((output nil))
+ (dolist (item first)
+ (let ((key (car item)) (value (cdr item)))
+ (if (let* ((key-name (symbol-name key))
+ (key-len (length key-name)))
+ (and (>= key-len 6)
+ (string= (substring key-name (- key-len 6)) "-alist")))
+ (push (cons key
+ (mdw-merge-style-alists value
+ (cdr (assoc key second))))
+ output)
+ (push item output))))
+ (dolist (item second)
+ (unless (assoc (car item) first)
+ (push item output)))
+ (nreverse output)))
+
+(cl-defmacro mdw-define-c-style (name (&optional parent) &rest assocs)
+ "Define a C style, called NAME (a symbol) based on PARENT, setting ASSOCs.
+A function, named `mdw-define-c-style/NAME', is defined to actually install
+the style using `c-add-style', and added to the hook
+`mdw-define-c-styles-hook'. If CC Mode is already loaded, then the style is
+set."
+ (declare (indent defun))
+ (let* ((name-string (symbol-name name))
+ (var (intern (concat "mdw-c-style/" name-string)))
+ (func (intern (concat "mdw-define-c-style/" name-string))))
+ `(progn
+ (setq ,var
+ ,(if (null parent)
+ `',assocs
+ (let ((parent-list (intern (concat "mdw-c-style/"
+ (symbol-name parent)))))
+ `(mdw-merge-style-alists ',assocs ,parent-list))))
+ (defun ,func () (c-add-style ,name-string ,var))
+ (and (featurep 'cc-mode) (,func))
+ (add-hook 'mdw-define-c-styles-hook ',func)
+ ',name)))
+
+(eval-after-load "cc-mode"
+ '(run-hooks 'mdw-define-c-styles-hook))
+
+(mdw-define-c-style mdw-c ()
+ (c-basic-offset . 2)
+ (comment-column . 40)
+ (c-class-key . "class")
+ (c-backslash-column . 72)
+ (c-label-minimum-indentation . 0)
+ (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block))
+ (defun-open . (add 0 c-indent-one-line-block))
+ (arglist-cont-nonempty . mdw-c-lineup-arglist)
+ (topmost-intro . mdw-c-indent-extern-mumble)
+ (cpp-define-intro . 0)
+ (knr-argdecl . 0)
+ (inextern-lang . [0])
+ (label . 0)
+ (case-label . +)
+ (access-label . -)
+ (inclass . +)
+ (inline-open . ++)
+ (statement-cont . +)
+ (statement-case-intro . +)))
+
+(mdw-define-c-style mdw-trustonic-c (mdw-c)
+ (c-basic-offset . 4)
+ (c-offsets-alist (access-label . -2)))
+
+(mdw-define-c-style mdw-trustonic-alec-c (mdw-trustonic-c)
+ (comment-column . 0)
+ (c-indent-comment-alist (anchored-comment . (column . 0))
+ (end-block . (space . 1))
+ (cpp-end-block . (space . 1))
+ (other . (space . 1)))
+ (c-offsets-alist (arglist-cont-nonempty . mdw-c-indent-arglist-nested)))
+
+(defun mdw-set-default-c-style (modes style)
+ "Update the default CC Mode style for MODES to be STYLE.
+
+MODES may be a list of major mode names or a singleton. STYLE is a style
+name, as a symbol."
+ (let ((modes (if (listp modes) modes (list modes)))
+ (style (symbol-name style)))
+ (setq c-default-style
+ (append (mapcar (lambda (mode)
+ (cons mode style))
+ modes)
+ (cl-remove-if (lambda (assoc)
+ (memq (car assoc) modes))
+ (if (listp c-default-style)
+ c-default-style
+ (list (cons 'other
+ c-default-style))))))))
+(setq c-default-style "mdw-c")
+
+(mdw-set-default-c-style '(c-mode c++-mode) 'mdw-c)
(defvar mdw-c-comment-fill-prefix
`((,(concat "\\([ \t]*/?\\)"
- "\\(\*\\|//]\\)"
+ "\\(\\*\\|//\\)"
"\\([ \t]*\\)"
"\\([A-Za-z]+:[ \t]*\\)?"
mdw-hanging-indents)
(modify-syntax-entry ?\n "> b")
;; Other stuff.
- (mdw-c-style)
- (setq c-hanging-comment-ender-p nil)
- (setq c-backslash-column 72)
- (setq c-label-minimum-indentation 0)
(setq mdw-fill-prefix mdw-c-comment-fill-prefix)
;; Now define things to be fontified.
"__typeof__" ;GCC
"__volatile__" ;GCC
))
- (c-constants
+ (c-builtins
(mdw-regexps "false" ;C++, C99 macro
"this" ;C++
"true" ;C++, C99 macro
"selector")))
(setq font-lock-keywords
- (list
-
- ;; Fontify include files as strings.
- (list (concat "^[ \t]*\\#[ \t]*"
- "\\(include\\|import\\)"
- "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
- '(2 font-lock-string-face))
-
- ;; Preprocessor directives are `references'?.
- (list (concat "^\\([ \t]*#[ \t]*\\(\\("
- preprocessor-keywords
- "\\)\\>\\|[0-9]+\\|$\\)\\)")
- '(1 font-lock-keyword-face))
-
- ;; Handle the keywords defined above.
- (list (concat "@\\<\\(" objc-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
-
- (list (concat "\\<\\(" c-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
-
- (list (concat "\\<\\(" c-constants "\\)\\>")
- '(0 font-lock-variable-name-face))
-
- ;; Handle numbers too.
- ;;
- ;; This looks strange, I know. It corresponds to the
- ;; preprocessor's idea of what a number looks like, rather than
- ;; anything sensible.
- (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
- "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
- '(0 mdw-number-face))
-
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+
+ ;; Fontify include files as strings.
+ (list (concat "^[ \t]*\\#[ \t]*"
+ "\\(include\\|import\\)"
+ "[ \t]*\\(<[^>]+>?\\)")
+ '(2 font-lock-string-face))
+
+ ;; Preprocessor directives are `references'?.
+ (list (concat "^\\([ \t]*#[ \t]*\\(\\("
+ preprocessor-keywords
+ "\\)\\>\\|[0-9]+\\|$\\)\\)")
+ '(1 font-lock-keyword-face))
+
+ ;; Handle the keywords defined above.
+ (list (concat "@\\<\\(" objc-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+
+ (list (concat "\\<\\(" c-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+
+ (list (concat "\\<\\(" c-builtins "\\)\\>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Handle numbers too.
+ ;;
+ ;; This looks strange, I know. It corresponds to the
+ ;; preprocessor's idea of what a number looks like, rather than
+ ;; anything sensible.
+ (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
+ "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(define-derived-mode sod-mode c-mode "Sod"
+ "Major mode for editing Sod code.")
+(push '("\\.sod$" . sod-mode) auto-mode-alist)
+
+(dolist (hook '(c-mode-hook objc-mode-hook c++-mode-hook))
+ (add-hook hook 'mdw-misc-mode-config t)
+ (add-hook hook 'mdw-fontify-c-and-c++ t))
;;;--------------------------------------------------------------------------
;;; AP calc mode.
-(defun apcalc-mode ()
- (interactive)
- (c-mode)
- (setq major-mode 'apcalc-mode)
- (setq mode-name "AP Calc")
- (run-hooks 'apcalc-mode-hook))
+(define-derived-mode apcalc-mode c-mode "AP Calc"
+ "Major mode for editing Calc code.")
(defun mdw-fontify-apcalc ()
(modify-syntax-entry ?/ ". 14")
;; Other stuff.
- (mdw-c-style)
- (setq c-hanging-comment-ender-p nil)
- (setq c-backslash-column 72)
(setq comment-start "/* ")
(setq comment-end " */")
(setq mdw-fill-prefix mdw-c-comment-fill-prefix)
"show" "static" "switch" "while" "write")))
(setq font-lock-keywords
- (list
+ (list
- ;; Handle the keywords defined above.
- (list (concat "\\<\\(" c-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
+ ;; Handle the keywords defined above.
+ (list (concat "\\<\\(" c-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
- ;; Handle numbers too.
- ;;
- ;; This looks strange, I know. It corresponds to the
- ;; preprocessor's idea of what a number looks like, rather than
- ;; anything sensible.
- (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
- "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
- '(0 mdw-number-face))
+ ;; Handle numbers too.
+ ;;
+ ;; This looks strange, I know. It corresponds to the
+ ;; preprocessor's idea of what a number looks like, rather than
+ ;; anything sensible.
+ (list (concat "\\(\\<[0-9]\\|\\.[0-9]\\)"
+ "\\([Ee][+-]\\|[0-9A-Za-z_.]\\)*")
+ '(0 mdw-number-face))
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'apcalc-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'apcalc-mode-hook 'mdw-fontify-apcalc t))
;;;--------------------------------------------------------------------------
;;; Java programming configuration.
;; Make indentation nice.
-(defun mdw-java-style ()
- (c-add-style "[mdw] Java style"
- '((c-basic-offset . 2)
- (c-offsets-alist (substatement-open . 0)
- (label . +)
- (case-label . +)
- (access-label . 0)
- (inclass . +)
- (statement-case-intro . +)))
- t))
+(mdw-define-c-style mdw-java ()
+ (c-basic-offset . 2)
+ (c-backslash-column . 72)
+ (c-offsets-alist (substatement-open . 0)
+ (label . +)
+ (case-label . +)
+ (access-label . 0)
+ (inclass . +)
+ (statement-case-intro . +)))
+(mdw-set-default-c-style 'java-mode 'mdw-java)
;; Declare Java fontification style.
(defun mdw-fontify-java ()
+ ;; Fiddle with some syntax codes.
+ (modify-syntax-entry ?@ ".")
+ (modify-syntax-entry ?@ "." font-lock-syntax-table)
+
;; Other stuff.
- (mdw-java-style)
- (setq c-hanging-comment-ender-p nil)
- (setq c-backslash-column 72)
(setq mdw-fill-prefix mdw-c-comment-fill-prefix)
;; Now define things to be fontified.
(make-local-variable 'font-lock-keywords)
(let ((java-keywords
- (mdw-regexps "abstract" "boolean" "break" "byte" "case" "catch"
- "char" "class" "const" "continue" "default" "do"
- "double" "else" "extends" "final" "finally" "float"
- "for" "goto" "if" "implements" "import" "instanceof"
- "int" "interface" "long" "native" "new" "package"
- "private" "protected" "public" "return" "short"
- "static" "switch" "synchronized" "throw" "throws"
- "transient" "try" "void" "volatile" "while"))
-
- (java-constants
+ (mdw-regexps "abstract" "assert"
+ "boolean" "break" "byte"
+ "case" "catch" "char" "class" "const" "continue"
+ "default" "do" "double"
+ "else" "enum" "extends"
+ "final" "finally" "float" "for"
+ "goto"
+ "if" "implements" "import" "instanceof" "int"
+ "interface"
+ "long"
+ "native" "new"
+ "package" "private" "protected" "public"
+ "return"
+ "short" "static" "strictfp" "switch" "synchronized"
+ "throw" "throws" "transient" "try"
+ "void" "volatile"
+ "while"))
+
+ (java-builtins
(mdw-regexps "false" "null" "super" "this" "true")))
(setq font-lock-keywords
- (list
-
- ;; Handle the keywords defined above.
- (list (concat "\\<\\(" java-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
-
- ;; Handle the magic constants defined above.
- (list (concat "\\<\\(" java-constants "\\)\\>")
- '(0 font-lock-variable-name-face))
-
- ;; Handle numbers too.
- ;;
- ;; The following isn't quite right, but it's close enough.
- (list (concat "\\<\\("
- "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
- "[lLfFdD]?")
- '(0 mdw-number-face))
-
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+
+ ;; Handle the keywords defined above.
+ (list (concat "\\<\\(" java-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+
+ ;; Handle the magic builtins defined above.
+ (list (concat "\\<\\(" java-builtins "\\)\\>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Handle numbers too.
+ ;;
+ ;; The following isn't quite right, but it's close enough.
+ (list (concat "\\<\\("
+ "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
+ "[lLfFdD]?")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'java-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'java-mode-hook 'mdw-fontify-java t))
;;;--------------------------------------------------------------------------
;;; Javascript programming configuration.
"private" "protected" "public" "return" "short"
"static" "super" "switch" "synchronized" "throw"
"throws" "transient" "try" "typeof" "var" "void"
- "volatile" "while" "with" "yield"
-
- "boolean" "byte" "char" "double" "float" "int" "long"
- "short" "void"))
- (javascript-constants
+ "volatile" "while" "with" "yield"))
+ (javascript-builtins
(mdw-regexps "false" "null" "undefined" "Infinity" "NaN" "true"
"arguments" "this")))
(setq font-lock-keywords
- (list
-
- ;; Handle the keywords defined above.
- (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
- '(0 font-lock-keyword-face))
-
- ;; Handle the predefined constants defined above.
- (list (concat "\\_<\\(" javascript-constants "\\)\\_>")
- '(0 font-lock-variable-name-face))
-
- ;; Handle numbers too.
- ;;
- ;; The following isn't quite right, but it's close enough.
- (list (concat "\\_<\\("
- "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
- "[lLfFdD]?")
- '(0 mdw-number-face))
-
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+
+ ;; Handle the keywords defined above.
+ (list (concat "\\_<\\(" javascript-keywords "\\)\\_>")
+ '(0 font-lock-keyword-face))
+
+ ;; Handle the predefined builtins defined above.
+ (list (concat "\\_<\\(" javascript-builtins "\\)\\_>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Handle numbers too.
+ ;;
+ ;; The following isn't quite right, but it's close enough.
+ (list (concat "\\_<\\("
+ "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
+ "[lLfFdD]?")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'js-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'js-mode-hook 'mdw-fontify-javascript t))
;;;--------------------------------------------------------------------------
;;; Scala programming configuration.
(punctuation "[-!%^&*=+:@#~/?\\|`]"))
(setq font-lock-keywords
- (list
-
- ;; Magical identifiers between backticks.
- (list (concat "`\\([^`]+\\)`")
- '(1 font-lock-variable-name-face))
-
- ;; Handle the keywords defined above.
- (list (concat "\\_<\\(" scala-keywords "\\)\\_>")
- '(0 font-lock-keyword-face))
-
- ;; Handle the constants defined above.
- (list (concat "\\_<\\(" scala-constants "\\)\\_>")
- '(0 font-lock-variable-name-face))
-
- ;; Magical identifiers between backticks.
- (list (concat "`\\([^`]+\\)`")
- '(1 font-lock-variable-name-face))
-
- ;; Handle numbers too.
- ;;
- ;; As usual, not quite right.
- (list (concat "\\_<\\("
- "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
- "[lLfFdD]?")
- '(0 mdw-number-face))
-
- ;; Identifiers with trailing operators.
- (list (concat "_\\(" punctuation "\\)+")
- '(0 mdw-trivial-face))
-
- ;; And everything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face)))
+ (list
+
+ ;; Magical identifiers between backticks.
+ (list (concat "`\\([^`]+\\)`")
+ '(1 font-lock-variable-name-face))
+
+ ;; Handle the keywords defined above.
+ (list (concat "\\_<\\(" scala-keywords "\\)\\_>")
+ '(0 font-lock-keyword-face))
+
+ ;; Handle the constants defined above.
+ (list (concat "\\_<\\(" scala-constants "\\)\\_>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Magical identifiers between backticks.
+ (list (concat "`\\([^`]+\\)`")
+ '(1 font-lock-variable-name-face))
+
+ ;; Handle numbers too.
+ ;;
+ ;; As usual, not quite right.
+ (list (concat "\\_<\\("
+ "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
+ "[lLfFdD]?")
+ '(0 mdw-number-face))
+
+ ;; And everything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face)))
font-lock-syntactic-keywords
- (list
-
- ;; Single quotes around characters. But not when used to quote
- ;; symbol names. Ugh.
- (list (concat "\\('\\)"
- "\\(" "."
- "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*"
- "u+" "[0-9a-fA-F]\\{4\\}"
- "\\|" "\\\\" "[0-7]\\{1,3\\}"
- "\\|" "\\\\" "." "\\)"
- "\\('\\)")
- '(1 "\"")
- '(4 "\""))))))
+ (list
+
+ ;; Single quotes around characters. But not when used to quote
+ ;; symbol names. Ugh.
+ (list (concat "\\('\\)"
+ "\\(" "."
+ "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*"
+ "u+" "[0-9a-fA-F]\\{4\\}"
+ "\\|" "\\\\" "[0-7]\\{1,3\\}"
+ "\\|" "\\\\" "." "\\)"
+ "\\('\\)")
+ '(1 "\"")
+ '(4 "\""))))))
+
+(progn
+ (add-hook 'scala-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'scala-mode-hook 'mdw-fontify-scala t))
;;;--------------------------------------------------------------------------
;;; C# programming configuration.
;; Make indentation nice.
-(defun mdw-csharp-style ()
- (c-add-style "[mdw] C# style"
- '((c-basic-offset . 2)
- (c-offsets-alist (substatement-open . 0)
- (label . 0)
- (case-label . +)
- (access-label . 0)
- (inclass . +)
- (statement-case-intro . +)))
- t))
+(mdw-define-c-style mdw-csharp ()
+ (c-basic-offset . 2)
+ (c-backslash-column . 72)
+ (c-offsets-alist (substatement-open . 0)
+ (label . 0)
+ (case-label . +)
+ (access-label . 0)
+ (inclass . +)
+ (statement-case-intro . +)))
+(mdw-set-default-c-style 'csharp-mode 'mdw-csharp)
;; Declare C# fontification style.
(defun mdw-fontify-csharp ()
;; Other stuff.
- (mdw-csharp-style)
- (setq c-hanging-comment-ender-p nil)
- (setq c-backslash-column 72)
(setq mdw-fill-prefix mdw-c-comment-fill-prefix)
;; Now define things to be fontified.
"unsafe" "ushort" "using" "virtual" "void" "volatile"
"while" "yield"))
- (csharp-constants
+ (csharp-builtins
(mdw-regexps "base" "false" "null" "this" "true")))
(setq font-lock-keywords
- (list
-
- ;; Handle the keywords defined above.
- (list (concat "\\<\\(" csharp-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
-
- ;; Handle the magic constants defined above.
- (list (concat "\\<\\(" csharp-constants "\\)\\>")
- '(0 font-lock-variable-name-face))
-
- ;; Handle numbers too.
- ;;
- ;; The following isn't quite right, but it's close enough.
- (list (concat "\\<\\("
- "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
- "[lLfFdD]?")
- '(0 mdw-number-face))
-
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+
+ ;; Handle the keywords defined above.
+ (list (concat "\\<\\(" csharp-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+
+ ;; Handle the magic builtins defined above.
+ (list (concat "\\<\\(" csharp-builtins "\\)\\>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Handle numbers too.
+ ;;
+ ;; The following isn't quite right, but it's close enough.
+ (list (concat "\\<\\("
+ "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
+ "[lLfFdD]?")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
(define-derived-mode csharp-mode java-mode "C#"
"Major mode for editing C# code.")
+(add-hook 'csharp-mode-hook 'mdw-fontify-csharp t)
+
;;;--------------------------------------------------------------------------
;;; F# programming configuration.
(defun mdw-fontify-fsharp ()
(let ((punct "=<>+-*/|&%!@?"))
- (do ((i 0 (1+ i)))
+ (cl-do ((i 0 (1+ i)))
((>= i (length punct)))
(modify-syntax-entry (aref punct i) ".")))
(mdw-regexps "if" "indent" "else" "endif")))
(setq font-lock-keywords
- (list (list (concat "\\(^\\|[^\"]\\)"
- "\\(" "(\\*"
- "[^*]*\\*+"
- "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*"
- ")"
- "\\|"
- "//.*"
- "\\)")
- '(2 font-lock-comment-face))
-
- (list (concat "'" "\\("
- "\\\\"
- "\\(" "[ntbr'\\]"
- "\\|" "[0-9][0-9][0-9]"
- "\\|" "u" "[0-9a-fA-F]\\{4\\}"
- "\\|" "U" "[0-9a-fA-F]\\{8\\}"
- "\\)"
- "\\|"
- "." "\\)" "'"
- "\\|"
- "\"" "[^\"\\]*"
- "\\(" "\\\\" "\\(.\\|\n\\)"
- "[^\"\\]*" "\\)*"
- "\\(\"\\|\\'\\)")
- '(0 font-lock-string-face))
-
- (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|"
- "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>"
- "\\|"
- "\\_<\\(" fsharp-keywords "\\)\\_>")
- '(0 font-lock-keyword-face))
- (list (concat "\\<\\(" fsharp-builtins "\\)\\_>")
- '(0 font-lock-variable-name-face))
-
- (list (concat "\\_<"
- "\\(" "0[bB][01]+" "\\|"
- "0[oO][0-7]+" "\\|"
- "0[xX][0-9a-fA-F]+" "\\)"
- "\\(" "lf\\|LF" "\\|"
- "[uU]?[ysnlL]?" "\\)"
- "\\|"
- "\\_<"
- "[0-9]+" "\\("
- "[mMQRZING]"
+ (list (list (concat "\\(^\\|[^\"]\\)"
+ "\\(" "(\\*"
+ "[^*]*\\*+"
+ "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*"
+ ")"
"\\|"
- "\\(\\.[0-9]*\\)?"
- "\\([eE][-+]?[0-9]+\\)?"
- "[fFmM]?"
+ "//.*"
+ "\\)")
+ '(2 font-lock-comment-face))
+
+ (list (concat "'" "\\("
+ "\\\\"
+ "\\(" "[ntbr'\\]"
+ "\\|" "[0-9][0-9][0-9]"
+ "\\|" "u" "[0-9a-fA-F]\\{4\\}"
+ "\\|" "U" "[0-9a-fA-F]\\{8\\}"
+ "\\)"
+ "\\|"
+ "." "\\)" "'"
"\\|"
- "[uU]?[ysnlL]?"
- "\\)")
- '(0 mdw-number-face))
+ "\"" "[^\"\\]*"
+ "\\(" "\\\\" "\\(.\\|\n\\)"
+ "[^\"\\]*" "\\)*"
+ "\\(\"\\|\\'\\)")
+ '(0 font-lock-string-face))
+
+ (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|"
+ "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>"
+ "\\|"
+ "\\_<\\(" fsharp-keywords "\\)\\_>")
+ '(0 font-lock-keyword-face))
+ (list (concat "\\<\\(" fsharp-builtins "\\)\\_>")
+ '(0 font-lock-variable-name-face))
+
+ (list (concat "\\_<"
+ "\\(" "0[bB][01]+" "\\|"
+ "0[oO][0-7]+" "\\|"
+ "0[xX][0-9a-fA-F]+" "\\)"
+ "\\(" "lf\\|LF" "\\|"
+ "[uU]?[ysnlL]?" "\\)"
+ "\\|"
+ "\\_<"
+ "[0-9]+" "\\("
+ "[mMQRZING]"
+ "\\|"
+ "\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?"
+ "[fFmM]?"
+ "\\|"
+ "[uU]?[ysnlL]?"
+ "\\)")
+ '(0 mdw-number-face))
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
(defun mdw-fontify-inferior-fsharp ()
(mdw-fontify-fsharp)
(setq font-lock-keywords
- (append (list (list "^[#-]" '(0 font-lock-comment-face))
- (list "^>" '(0 font-lock-keyword-face)))
- font-lock-keywords)))
+ (append (list (list "^[#-]" '(0 font-lock-comment-face))
+ (list "^>" '(0 font-lock-keyword-face)))
+ font-lock-keywords)))
+
+(progn
+ (add-hook 'fsharp-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'fsharp-mode-hook 'mdw-fontify-fsharp t)
+ (add-hook 'inferior-fsharp-mode-hooks 'mdw-fontify-inferior-fsharp t))
;;;--------------------------------------------------------------------------
;;; Go programming configuration.
"new" "panic" "real" "recover")))
(setq font-lock-keywords
- (list
-
- ;; Handle the keywords defined above.
- (list (concat "\\<\\(" go-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
- (list (concat "\\<\\(" go-intrinsics "\\)\\>")
- '(0 font-lock-variable-name-face))
-
- ;; Strings and characters.
- (list (concat "'"
- "\\(" "[^\\']" "\\|"
- "\\\\"
- "\\(" "[abfnrtv\\'\"]" "\\|"
- "[0-7]\\{3\\}" "\\|"
- "x" "[0-9A-Fa-f]\\{2\\}" "\\|"
- "u" "[0-9A-Fa-f]\\{4\\}" "\\|"
- "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)"
- "'"
- "\\|"
- "\""
- "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*"
- "\\(\"\\|$\\)"
- "\\|"
- "`" "[^`]+" "`")
- '(0 font-lock-string-face))
-
- ;; Handle numbers too.
- ;;
- ;; The following isn't quite right, but it's close enough.
- (list (concat "\\<\\("
- "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
- '(0 mdw-number-face))
-
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+
+ ;; Handle the keywords defined above.
+ (list (concat "\\<\\(" go-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+ (list (concat "\\<\\(" go-intrinsics "\\)\\>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Strings and characters.
+ (list (concat "'"
+ "\\(" "[^\\']" "\\|"
+ "\\\\"
+ "\\(" "[abfnrtv\\'\"]" "\\|"
+ "[0-7]\\{3\\}" "\\|"
+ "x" "[0-9A-Fa-f]\\{2\\}" "\\|"
+ "u" "[0-9A-Fa-f]\\{4\\}" "\\|"
+ "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)"
+ "'"
+ "\\|"
+ "\""
+ "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*"
+ "\\(\"\\|$\\)"
+ "\\|"
+ "`" "[^`]+" "`")
+ '(0 font-lock-string-face))
+
+ ;; Handle numbers too.
+ ;;
+ ;; The following isn't quite right, but it's close enough.
+ (list (concat "\\<\\("
+ "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+(progn
+ (add-hook 'go-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'go-mode-hook 'mdw-fontify-go t))
;;;--------------------------------------------------------------------------
;;; Rust programming configuration.
(defun mdw-fontify-rust ()
;; Hack syntax categories.
+ (modify-syntax-entry ?$ ".")
+ (modify-syntax-entry ?% ".")
(modify-syntax-entry ?= ".")
;; Fontify keywords and things.
(make-local-variable 'font-lock-keywords)
(let ((rust-keywords
- (mdw-regexps "abstract" "alignof" "as"
+ (mdw-regexps "abstract" "alignof" "as" "async" "await"
"become" "box" "break"
- "const" "continue" "create"
- "do"
+ "const" "continue" "crate"
+ "do" "dyn"
"else" "enum" "extern"
- "false" "final" "fn" "for"
+ "final" "fn" "for"
"if" "impl" "in"
"let" "loop"
"macro" "match" "mod" "move" "mut"
"offsetof" "override"
- "priv" "pub" "pure"
+ "priv" "proc" "pub" "pure"
"ref" "return"
- "self" "sizeof" "static" "struct" "super"
- "true" "trait" "type" "typeof"
- "unsafe" "unsized" "use"
+ "sizeof" "static" "struct" "super"
+ "trait" "try" "type" "typeof"
+ "union" "unsafe" "unsized" "use"
"virtual"
"where" "while"
"yield"))
"f32" "f64"
"i8" "i16" "i32" "i64" "isize"
"u8" "u16" "u32" "u64" "usize"
- "char" "str")))
+ "char" "str"
+ "self" "Self")))
(setq font-lock-keywords
- (list
-
- ;; Handle the keywords defined above.
- (list (concat "\\<\\(" rust-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
- (list (concat "\\<\\(" rust-builtins "\\)\\>")
- '(0 font-lock-variable-name-face))
-
- ;; Handle numbers too.
- (list (concat "\\<\\("
- "[0-9][0-9_]*"
- "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
- "\\|" "\\.[0-9_]+"
- "\\)"
- "\\(f32\\|f64\\)?"
- "\\|" "\\(" "[0-9][0-9_]*"
- "\\|" "0x[0-9a-fA-F_]+"
- "\\|" "0o[0-7_]+"
- "\\|" "0b[01_]+"
- "\\)"
- "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?"
- "\\)\\>")
- '(0 mdw-number-face))
-
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face)))))
+ (list
+
+ ;; Handle the keywords defined above.
+ (list (concat "\\_<\\(" rust-keywords "\\)\\_>")
+ '(0 font-lock-keyword-face))
+ (list (concat "\\_<\\(" rust-builtins "\\)\\_>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Handle numbers too.
+ (list (concat "\\_<\\("
+ "[0-9][0-9_]*"
+ "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
+ "\\|" "\\.[0-9_]+"
+ "\\)"
+ "\\(f32\\|f64\\)?"
+ "\\|" "\\(" "[0-9][0-9_]*"
+ "\\|" "0x[0-9a-fA-F_]+"
+ "\\|" "0o[0-7_]+"
+ "\\|" "0b[01_]+"
+ "\\)"
+ "\\([ui]\\(8\\|16\\|32\\|64\\|size\\)\\)?"
+ "\\)\\_>")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face)))
+ font-lock-syntactic-face-function nil))
;; Hack key bindings.
(local-set-key [?{] 'mdw-self-insert-and-indent)
(local-set-key [?}] 'mdw-self-insert-and-indent))
+(progn
+ (add-hook 'rust-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'rust-mode-hook 'mdw-fontify-rust t))
+
;;;--------------------------------------------------------------------------
;;; Awk programming configuration.
;; Make Awk indentation nice.
-(defun mdw-awk-style ()
- (c-add-style "[mdw] Awk style"
- '((c-basic-offset . 2)
- (c-offsets-alist (substatement-open . 0)
- (statement-cont . 0)
- (statement-case-intro . +)))
- t))
+(mdw-define-c-style mdw-awk ()
+ (c-basic-offset . 2)
+ (c-offsets-alist (substatement-open . 0)
+ (c-backslash-column . 72)
+ (statement-cont . 0)
+ (statement-case-intro . +)))
+(mdw-set-default-c-style 'awk-mode 'mdw-awk)
;; Declare Awk fontification style.
(defun mdw-fontify-awk ()
;; Miscellaneous fiddling.
- (mdw-awk-style)
- (setq c-backslash-column 72)
(mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
;; Now define things to be fontified.
"systime" "tolower" "toupper" "while")))
(setq font-lock-keywords
- (list
-
- ;; Handle the keywords defined above.
- (list (concat "\\<\\(" c-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
-
- ;; Handle numbers too.
- ;;
- ;; The following isn't quite right, but it's close enough.
- (list (concat "\\<\\("
- "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
- "[uUlL]*")
- '(0 mdw-number-face))
-
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+
+ ;; Handle the keywords defined above.
+ (list (concat "\\<\\(" c-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+
+ ;; Handle numbers too.
+ ;;
+ ;; The following isn't quite right, but it's close enough.
+ (list (concat "\\<\\("
+ "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
+ "[uUlL]*")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'awk-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'awk-mode-hook 'mdw-fontify-awk t))
;;;--------------------------------------------------------------------------
;;; Perl programming style.
;; Perl indentation style.
-(setq perl-indent-level 2)
+(setq-default perl-indent-level 2)
-(setq cperl-indent-level 2)
-(setq cperl-continued-statement-offset 2)
-(setq cperl-continued-brace-offset 0)
-(setq cperl-brace-offset -2)
-(setq cperl-brace-imaginary-offset 0)
-(setq cperl-label-offset 0)
+(setq-default cperl-indent-level 2
+ cperl-continued-statement-offset 2
+ cperl-indent-region-fix-constructs nil
+ cperl-continued-brace-offset 0
+ cperl-brace-offset -2
+ cperl-brace-imaginary-offset 0
+ cperl-label-offset 0)
;; Define perl fontification style.
(modify-syntax-entry ?$ "\\" font-lock-syntax-table)
(modify-syntax-entry ?: "." font-lock-syntax-table)
(mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
+ (setq auto-fill-function #'do-auto-fill)
;; Now define fontification things.
(make-local-variable 'font-lock-keywords)
"when" "while")))
(setq font-lock-keywords
- (list
+ (list
- ;; Set up the keywords defined above.
- (list (concat "\\<\\(" perl-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
+ ;; Set up the keywords defined above.
+ (list (concat "\\<\\(" perl-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
- ;; At least numbers are simpler than C.
- (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
- "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
- '(0 mdw-number-face))
+ ;; At least numbers are simpler than C.
+ (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
+ "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+ "\\([eE][-+]?[0-9_]+\\)?")
+ '(0 mdw-number-face))
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
(defun perl-number-tests (&optional arg)
"Assign consecutive numbers to lines containing `#t'. With ARG,
(if (re-search-forward "\\(tests\\s-*=>\\s-*\\)\\w*" nil t)
(replace-match (format "\\1%d" i))))))
+(dolist (hook '(perl-mode-hook cperl-mode-hook))
+ (add-hook hook 'mdw-misc-mode-config t)
+ (add-hook hook 'mdw-fontify-perl t))
+
;;;--------------------------------------------------------------------------
;;; Python programming style.
-(defun mdw-fontify-pythonic (keywords)
+(setq-default py-indent-offset 2
+ python-indent 2
+ python-indent-offset 2
+ python-fill-docstring-style 'symmetric)
+
+(defun mdw-fontify-pythonic (keywords soft-keywords builtins)
;; Miscellaneous fiddling.
(mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
(setq indent-tabs-mode nil)
+ (set (make-local-variable 'forward-sexp-function) nil)
;; Now define fontification things.
(make-local-variable 'font-lock-keywords)
(setq font-lock-keywords
- (list
+ (list
- ;; Set up the keywords defined above.
- (list (concat "\\_<\\(" keywords "\\)\\_>")
- '(0 font-lock-keyword-face))
+ ;; Set up the keywords defined above.
+ (list (concat "\\_<\\(" keywords "\\)\\_>")
+ '(0 font-lock-keyword-face))
+ (list (concat "\\(^\\|[^.]\\)\\_<\\(" soft-keywords "\\)\\_>")
+ '(2 font-lock-keyword-face))
+ (list (concat "\\(^\\|[^.]\\)\\_<\\(" builtins "\\)\\_>")
+ '(2 font-lock-variable-name-face))
+ (list (concat "\\_<\\(__\\(\\sw+\\|\\s_+\\)+__\\)\\_>")
+ '(0 font-lock-variable-name-face))
- ;; At least numbers are simpler than C.
- (list (concat "\\_<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
- "\\_<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9_]+\\|[lL]\\|\\)")
- '(0 mdw-number-face))
+ ;; At least numbers are simpler than C.
+ (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO]?[0-7]+\\|[bB][01]+\\)\\|"
+ "\\_<[0-9][0-9]*\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\|[lL]\\)?")
+ '(0 mdw-number-face))
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face)))))
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face)))))
;; Define Python fontification styles.
(defun mdw-fontify-python ()
(mdw-fontify-pythonic
- (mdw-regexps "and" "as" "assert" "break" "class" "continue" "def"
- "del" "elif" "else" "except" "exec" "finally" "for"
- "from" "global" "if" "import" "in" "is" "lambda"
- "not" "or" "pass" "print" "raise" "return" "try"
- "while" "with" "yield")))
+ (mdw-regexps "and" "as" "assert" "async" "await"
+ "break"
+ "class" "continue"
+ "def" "del"
+ "elif" "else" "except" ;"exec"
+ "finally" "for" "from"
+ "global"
+ "if" "import" "in" "is"
+ "lambda"
+ "nonlocal"
+ "not"
+ "or"
+ "pass" ;"print"
+ "raise" "return"
+ "try" ;"type"
+ "while" "with"
+ "yield")
+
+ (mdw-regexps "case"
+ "match")
+
+ (mdw-regexps "Ellipsis"
+ "False"
+ "None" "NotImplemented"
+ "True"
+ "__debug__"
+
+ "BaseException"
+ "BaseExceptionGroup"
+ "Exception"
+ "StandardError"
+ "ArithmeticError"
+ "FloatingPointError"
+ "OverflowError"
+ "ZeroDivisionError"
+ "AssertionError"
+ "AttributeError"
+ "BufferError"
+ "EnvironmentError"
+ "IOError"
+ "OSError"
+ "BlockingIOError"
+ "ChildProcessError"
+ "ConnectionError"
+ "BrokenPipeError"
+ "ConnectionAbortedError"
+ "ConnectionRefusedError"
+ "ConnectionResetError"
+ "FileExistsError"
+ "FileNotFoundError"
+ "InterruptedError"
+ "IsADirectoryError"
+ "NotADirectoryError"
+ "PermissionError"
+ "TimeoutError"
+ "EOFError"
+ "ExceptionGroup"
+ "ImportError"
+ "ModuleNotFoundError"
+ "LookupError"
+ "IndexError"
+ "KeyError"
+ "MemoryError"
+ "NameError"
+ "UnboundLocalError"
+ "ReferenceError"
+ "RuntimeError"
+ "NotImplementedError"
+ "RecursionError"
+ "SyntaxError"
+ "IndentationError"
+ "TabError"
+ "SystemError"
+ "TypeError"
+ "ValueError"
+ "UnicodeError"
+ "UnicodeDecodeError"
+ "UnicodeEncodeError"
+ "UnicodeTranslateError"
+ "StopIteration"
+ "Warning"
+ "BytesWarning"
+ "DeprecationWarning"
+ "EncodingWarning"
+ "FutureWarning"
+ "ImportWarning"
+ "PendingDeprecationWarning"
+ "ResourceWarning"
+ "RuntimeWarning"
+ "SyntaxWarning"
+ "UnicodeWarning"
+ "UserWarning"
+ "GeneratorExit"
+ "KeyboardInterrupt"
+ "SystemExit"
+
+ "abs" "absolute_import" "aiter"
+ "all" "anext" "any" "apply" "ascii"
+ "basestring" "bin" "bool" "breakpoint"
+ "buffer" "bytearray" "bytes"
+ "callable" "coerce" "chr" "classmethod"
+ "cmp" "compile" "complex"
+ "delattr" "dict" "dir" "divmod"
+ "enumerate" "eval" "exec" "execfile"
+ "file" "filter" "float" "format" "frozenset"
+ "getattr" "globals"
+ "hasattr" "hash" "help" "hex"
+ "id" "input" "int" "intern"
+ "isinstance" "issubclass" "iter"
+ "len" "list" "locals" "long"
+ "map" "max" "memoryview" "min"
+ "next"
+ "object" "oct" "open" "ord"
+ "pow" "print" "property"
+ "range" "raw_input" "reduce" "reload"
+ "repr" "reversed" "round"
+ "set" "setattr" "slice" "sorted"
+ "staticmethod" "str" "sum" "super"
+ "tuple" "type"
+ "unichr" "unicode"
+ "vars"
+ "xrange"
+ "zip"
+ "__import__")))
(defun mdw-fontify-pyrex ()
(mdw-fontify-pythonic
(mdw-regexps "and" "as" "assert" "break" "cdef" "class" "continue"
- "ctypedef" "def" "del" "elif" "else" "except" "exec"
+ "ctypedef" "def" "del" "elif" "else" "enum" "except" "exec"
"extern" "finally" "for" "from" "global" "if"
"import" "in" "is" "lambda" "not" "or" "pass" "print"
- "raise" "return" "struct" "try" "while" "with"
- "yield")))
+ "property" "raise" "return" "struct" "try" "while" "with"
+ "yield")
+ ""
+ ""))
+
+(define-derived-mode pyrex-mode python-mode "Pyrex"
+ "Major mode for editing Pyrex source code")
+(setq auto-mode-alist
+ (append '(("\\.pyx$" . pyrex-mode)
+ ("\\.pxd$" . pyrex-mode)
+ ("\\.pxi$" . pyrex-mode))
+ auto-mode-alist))
+
+(progn
+ (add-hook 'python-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'python-mode-hook 'mdw-fontify-python t)
+ (add-hook 'pyrex-mode-hook 'mdw-fontify-pyrex t))
+
+;;;--------------------------------------------------------------------------
+;;; Lua programming style.
+
+(setq-default lua-indent-level 2)
+
+(defun mdw-fontify-lua ()
+
+ ;; Miscellaneous fiddling.
+ (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
+
+ ;; Now define fontification things.
+ (make-local-variable 'font-lock-keywords)
+ (let ((lua-keywords
+ (mdw-regexps "and" "break" "do" "else" "elseif" "end"
+ "false" "for" "function" "goto" "if" "in" "local"
+ "nil" "not" "or" "repeat" "return" "then" "true"
+ "until" "while")))
+ (setq font-lock-keywords
+ (list
+
+ ;; Set up the keywords defined above.
+ (list (concat "\\_<\\(" lua-keywords "\\)\\_>")
+ '(0 font-lock-keyword-face))
+
+ ;; At least numbers are simpler than C.
+ (list (concat "\\_<\\(" "0[xX]"
+ "\\(" "[0-9a-fA-F]+"
+ "\\(\\.[0-9a-fA-F]*\\)?"
+ "\\|" "\\.[0-9a-fA-F]+"
+ "\\)"
+ "\\([pP][-+]?[0-9]+\\)?"
+ "\\|" "\\(" "[0-9]+"
+ "\\(\\.[0-9]*\\)?"
+ "\\|" "\\.[0-9]+"
+ "\\)"
+ "\\([eE][-+]?[0-9]+\\)?"
+ "\\)")
+ '(0 mdw-number-face))
+
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'lua-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'lua-mode-hook 'mdw-fontify-lua t))
;;;--------------------------------------------------------------------------
;;; Icon programming style.
;; Icon indentation style.
-(setq icon-brace-offset 0
- icon-continued-brace-offset 0
- icon-continued-statement-offset 2
- icon-indent-level 2)
+(setq-default icon-brace-offset 0
+ icon-continued-brace-offset 0
+ icon-continued-statement-offset 2
+ icon-indent-level 2)
;; Define Icon fontification style.
(mdw-regexps "define" "else" "endif" "error" "ifdef" "ifndef"
"include" "line" "undef")))
(setq font-lock-keywords
- (list
+ (list
- ;; Set up the keywords defined above.
- (list (concat "\\<\\(" icon-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
+ ;; Set up the keywords defined above.
+ (list (concat "\\<\\(" icon-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
- ;; The things that Icon calls keywords.
- (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
+ ;; The things that Icon calls keywords.
+ (list "&\\sw+\\>" '(0 font-lock-variable-name-face))
- ;; At least numbers are simpler than C.
- (list (concat "\\<[0-9]+"
- "\\([rR][0-9a-zA-Z]+\\|"
- "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
- "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
- '(0 mdw-number-face))
+ ;; At least numbers are simpler than C.
+ (list (concat "\\<[0-9]+"
+ "\\([rR][0-9a-zA-Z]+\\|"
+ "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\)\\>\\|"
+ "\\.[0-9]+\\([eE][+-]?[0-9]+\\)?\\>")
+ '(0 mdw-number-face))
- ;; Preprocessor.
- (list (concat "^[ \t]*$[ \t]*\\<\\("
- preprocessor-keywords
- "\\)\\>")
- '(0 font-lock-keyword-face))
+ ;; Preprocessor.
+ (list (concat "^[ \t]*$[ \t]*\\<\\("
+ preprocessor-keywords
+ "\\)\\>")
+ '(0 font-lock-keyword-face))
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'icon-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'icon-mode-hook 'mdw-fontify-icon t))
+
+;;;--------------------------------------------------------------------------
+;;; Fortran mode.
+
+(defun mdw-fontify-fortran-common ()
+ (let ((fortran-keywords
+ (mdw-regexps "access"
+ "assign"
+ "associate"
+ "backspace"
+ "blank"
+ "block\\s-*data"
+ "call"
+ "case"
+ "character"
+ "class"
+ "close"
+ "common"
+ "complex"
+ "continue"
+ "critical"
+ "data"
+ "dimension"
+ "do"
+ "double\\s-*precision"
+ "else" "elseif" "elsewhere"
+ "end"
+ "endblock" "endblockdata"
+ "endcritical"
+ "enddo"
+ "endinterface"
+ "endmodule"
+ "endprocedure"
+ "endprogram"
+ "endselect"
+ "endsubmodule"
+ "endsubroutine"
+ "endtype"
+ "endwhere"
+ "endenum"
+ "end\\s-*file"
+ "endforall"
+ "endfunction"
+ "endif"
+ "entry"
+ "enum"
+ "equivalence"
+ "err"
+ "external"
+ "file"
+ "fmt"
+ "forall"
+ "form"
+ "format"
+ "function"
+ "go\\s-*to"
+ "if"
+ "implicit"
+ "in" "inout"
+ "inquire"
+ "include"
+ "integer"
+ "interface"
+ "intrinsic"
+ "iostat"
+ "len"
+ "logical"
+ "module"
+ "open"
+ "out"
+ "parameter"
+ "pause"
+ "procedure"
+ "program"
+ "precision"
+ "program"
+ "read"
+ "real"
+ "rec"
+ "recl"
+ "return"
+ "rewind"
+ "save"
+ "select" "selectcase" "selecttype"
+ "status"
+ "stop"
+ "submodule"
+ "subroutine"
+ "then"
+ "to"
+ "type"
+ "unit"
+ "where"
+ "write"))
+ (fortran-operators (mdw-regexps "and"
+ "eq"
+ "eqv"
+ "false"
+ "ge"
+ "gt"
+ "le"
+ "lt"
+ "ne"
+ "neqv"
+ "not"
+ "or"
+ "true"))
+ (fortran-intrinsics (mdw-regexps "abs" "dabs" "iabs" "cabs"
+ "atan" "datan" "atan2" "datan2"
+ "cmplx"
+ "conjg"
+ "cos" "dcos" "ccos"
+ "dble"
+ "dim" "idim"
+ "exp" "dexp" "cexp"
+ "float"
+ "ifix"
+ "aimag"
+ "int" "aint" "idint"
+ "alog" "dlog" "clog"
+ "alog10" "dlog10"
+ "max"
+ "amax0" "amax1"
+ "max0" "max1"
+ "dmax1"
+ "min"
+ "amin0" "amin1"
+ "min0" "min1"
+ "dmin1"
+ "mod" "amod" "dmod"
+ "sin" "dsin" "csin"
+ "sign" "isign" "dsign"
+ "sngl"
+ "sqrt" "dsqrt" "csqrt"
+ "tanh"))
+ (preprocessor-keywords
+ (mdw-regexps "assert" "define" "elif" "else" "endif" "error"
+ "ident" "if" "ifdef" "ifndef" "import" "include"
+ "line" "pragma" "unassert" "undef" "warning")))
+ (setq font-lock-keywords-case-fold-search t
+ font-lock-keywords
+ (list
+
+ ;; Fontify include files as strings.
+ (list (concat "^[ \t]*\\#[ \t]*" "include"
+ "[ \t]*\\(<[^>]+>?\\)")
+ '(1 font-lock-string-face))
+
+ ;; Preprocessor directives are `references'?.
+ (list (concat "^\\([ \t]*#[ \t]*\\(\\("
+ preprocessor-keywords
+ "\\)\\>\\|[0-9]+\\|$\\)\\)")
+ '(1 font-lock-keyword-face))
+
+ ;; Set up the keywords defined above.
+ (list (concat "\\<\\(" fortran-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+
+ ;; Set up the `.foo.' operators.
+ (list (concat "\\.\\(" fortran-operators "\\)\\.")
+ '(0 font-lock-keyword-face))
+
+ ;; Set up the intrinsic functions.
+ (list (concat "\\<\\(" fortran-intrinsics "\\)\\>")
+ '(0 font-lock-variable-name-face))
+
+ ;; Numbers.
+ (list (concat "\\(" "\\<" "[0-9]+" "\\(\\.[0-9]*\\)?"
+ "\\|" "\\.[0-9]+"
+ "\\)"
+ "\\(" "[de]" "[+-]?" "[0-9]+" "\\)?"
+ "\\(" "_" "\\sw+" "\\)?"
+ "\\|" "b'[01]*'" "\\|" "'[01]*'b"
+ "\\|" "b\"[01]*\"" "\\|" "\"[01]*\"b"
+ "\\|" "o'[0-7]*'" "\\|" "'[0-7]*'o"
+ "\\|" "o\"[0-7]*\"" "\\|" "\"[0-7]*\"o"
+ "\\|" "[xz]'[0-9a-f]*'" "\\|" "'[0-9a-f]*'[xz]"
+ "\\|" "[xz]\"[0-9a-f]*\"" "\\|" "\"[0-9a-f]*\"[xz]")
+ '(0 mdw-number-face))
+
+ ;; Any anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))
+
+ (modify-syntax-entry ?/ "." font-lock-syntax-table)
+ (modify-syntax-entry ?< ".")
+ (modify-syntax-entry ?> ".")))
+
+(defun mdw-fontify-fortran () (mdw-fontify-fortran-common))
+(defun mdw-fontify-f90 () (mdw-fontify-fortran-common))
+
+(setq fortran-do-indent 2
+ fortran-if-indent 2
+ fortran-structure-indent 2
+ fortran-comment-line-start "*"
+ fortran-comment-indent-style 'relative
+ fortran-continuation-string "&"
+ fortran-continuation-indent 4)
+
+(setq f90-do-indent 2
+ f90-if-indent 2
+ f90-program-indent 2
+ f90-continuation-indent 4
+ f90-smart-end-names nil
+ f90-smart-end 'no-blink)
+
+(progn
+ (add-hook 'fortran-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'fortran-mode-hook 'mdw-fontify-fortran t)
+ (add-hook 'f90-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'f90-mode-hook 'mdw-fontify-f90 t))
;;;--------------------------------------------------------------------------
;;; Assembler mode.
(modify-syntax-entry ?. "w")
(modify-syntax-entry ?\n ">")
(setf fill-prefix nil)
+ (modify-syntax-entry ?. "_")
+ (modify-syntax-entry ?* ". 23")
+ (modify-syntax-entry ?/ ". 124b")
+ (modify-syntax-entry ?\n "> b")
+ (local-set-key ";" 'self-insert-command)
(mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)"))
(defun mdw-asm-set-comment ()
(modify-syntax-entry ?; "."
)
- (modify-syntax-entry asm-comment-char "<b")
+ (modify-syntax-entry asm-comment-char "< b")
(setq comment-start (string asm-comment-char ? )))
(add-hook 'asm-mode-local-variables-hook 'mdw-asm-set-comment)
(put 'asm-comment-char 'safe-local-variable 'characterp)
+(progn
+ (add-hook 'asm-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'asm-mode-hook 'mdw-fontify-asm t))
+
;;;--------------------------------------------------------------------------
;;; TCL configuration.
+(setq-default tcl-indent-level 2)
+
(defun mdw-fontify-tcl ()
- (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$))
+ (dolist (ch '(?$))
+ (modify-syntax-entry ch "."))
(mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)")
(make-local-variable 'font-lock-keywords)
(setq font-lock-keywords
- (list
- (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
- "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
- '(0 mdw-number-face))
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face)))))
+ (list
+ (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
+ "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+ "\\([eE][-+]?[0-9_]+\\)?")
+ '(0 mdw-number-face))
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face)))))
+
+(progn
+ (add-hook 'tcl-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'tcl-mode-hook 'mdw-fontify-tcl t))
;;;--------------------------------------------------------------------------
;;; Dylan programming configuration.
"all-keys" "key" "next" "rest" "include"
"t" "f")))
(setq font-lock-keywords
- (list (list (concat "\\<\\(" dylan-keywords
- "\\|" "with\\(out\\)?-" word
- "\\)\\>")
- '(0 font-lock-keyword-face))
- (list (concat "\\<" word ":" "\\|"
- "#\\(" sharp-keywords "\\)\\>")
- '(0 font-lock-variable-name-face))
- (list (concat "\\("
- "\\([-+]\\|\\<\\)[0-9]+" "\\("
- "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
- "\\|" "/[0-9]+"
- "\\)"
- "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
- "\\|" "#b[01]+"
- "\\|" "#o[0-7]+"
- "\\|" "#x[0-9a-zA-Z]+"
- "\\)\\>")
- '(0 mdw-number-face))
- (list (concat "\\("
- "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
- "\\_<[-+*/=<>:&|]+\\_>"
- "\\)")
- '(0 mdw-punct-face))))))
+ (list (list (concat "\\<\\(" dylan-keywords
+ "\\|" "with\\(out\\)?-" word
+ "\\)\\>")
+ '(0 font-lock-keyword-face))
+ (list (concat "\\<" word ":" "\\|"
+ "#\\(" sharp-keywords "\\)\\>")
+ '(0 font-lock-variable-name-face))
+ (list (concat "\\("
+ "\\([-+]\\|\\<\\)[0-9]+" "\\("
+ "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?"
+ "\\|" "/[0-9]+"
+ "\\)"
+ "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?"
+ "\\|" "#b[01]+"
+ "\\|" "#o[0-7]+"
+ "\\|" "#x[0-9a-zA-Z]+"
+ "\\)\\>")
+ '(0 mdw-number-face))
+ (list (concat "\\("
+ "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|"
+ "\\_<[-+*/=<>:&|]+\\_>"
+ "\\)")
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'dylan-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'dylan-mode-hook 'mdw-fontify-dylan t))
;;;--------------------------------------------------------------------------
;;; Algol 68 configuration.
-(setq a68-indent-step 2)
+(setq-default a68-indent-step 2)
(defun mdw-fontify-algol-68 ()
(let ((not-comment
(let ((word "COMMENT"))
- (do ((regexp (concat "[^" (substring word 0 1) "]+")
- (concat regexp "\\|"
- (substring word 0 i)
- "[^" (substring word i (1+ i)) "]"))
- (i 1 (1+ i)))
+ (cl-do ((regexp (concat "[^" (substring word 0 1) "]+")
+ (concat regexp "\\|"
+ (substring word 0 i)
+ "[^" (substring word i (1+ i)) "]"))
+ (i 1 (1+ i)))
((>= i (length word)) regexp)))))
(setq font-lock-keywords
- (list (list (concat "\\<COMMENT\\>"
- "\\(" not-comment "\\)\\{0,5\\}"
- "\\(\\'\\|\\<COMMENT\\>\\)")
- '(0 font-lock-comment-face))
- (list (concat "\\<CO\\>"
- "\\([^C]+\\|C[^O]\\)\\{0,5\\}"
- "\\($\\|\\<CO\\>\\)")
- '(0 font-lock-comment-face))
- (list "\\<[A-Z_]+\\>"
- '(0 font-lock-keyword-face))
- (list (concat "\\<"
- "[0-9]+"
- "\\(\\.[0-9]+\\)?"
- "\\([eE][-+]?[0-9]+\\)?"
- "\\>")
- '(0 mdw-number-face))
- (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/"
- '(0 mdw-punct-face))))))
+ (list (list (concat "\\<COMMENT\\>"
+ "\\(" not-comment "\\)\\{0,5\\}"
+ "\\(\\'\\|\\<COMMENT\\>\\)")
+ '(0 font-lock-comment-face))
+ (list (concat "\\<CO\\>"
+ "\\([^C]+\\|C[^O]\\)\\{0,5\\}"
+ "\\($\\|\\<CO\\>\\)")
+ '(0 font-lock-comment-face))
+ (list "\\<[A-Z_]+\\>"
+ '(0 font-lock-keyword-face))
+ (list (concat "\\<"
+ "[0-9]+"
+ "\\(\\.[0-9]+\\)?"
+ "\\([eE][-+]?[0-9]+\\)?"
+ "\\>")
+ '(0 mdw-number-face))
+ (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/"
+ '(0 mdw-punct-face))))))
+
+(dolist (hook '(a68-mode-hook a68-mode-hooks))
+ (add-hook hook 'mdw-misc-mode-config t)
+ (add-hook hook 'mdw-fontify-algol-68 t))
;;;--------------------------------------------------------------------------
;;; REXX configuration.
(setq mdw-auto-indent nil)
(local-set-key [?\C-m] 'mdw-rexx-indent-newline-indent)
(local-set-key [?*] 'mdw-rexx-electric-*)
- (mapcar #'(lambda (ch) (modify-syntax-entry ch "w"))
- '(?! ?? ?# ?@ ?$))
+ (dolist (ch '(?! ?? ?# ?@ ?$)) (modify-syntax-entry ch "w"))
+ (dolist (ch '(?¬)) (modify-syntax-entry ch "."))
(mdw-standard-fill-prefix "\\([ \t]*/?\*[ \t]*\\)")
;; Set up keywords and things for fontification.
"x2d")))
(setq font-lock-keywords
- (list
+ (list
- ;; Set up the keywords defined above.
- (list (concat "\\<\\(" rexx-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
+ ;; Set up the keywords defined above.
+ (list (concat "\\<\\(" rexx-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
- ;; Fontify all symbols the same way.
- (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
- "[A-Za-z0-9.!?_#@$]+\\)")
- '(0 font-lock-variable-name-face))
+ ;; Fontify all symbols the same way.
+ (list (concat "\\<\\([0-9.][A-Za-z0-9.!?_#@$]*[Ee][+-]?[0-9]+\\|"
+ "[A-Za-z0-9.!?_#@$]+\\)")
+ '(0 font-lock-variable-name-face))
- ;; And everything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ ;; And everything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'rexx-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'rexx-mode-hook 'mdw-fontify-rexx t))
;;;--------------------------------------------------------------------------
;;; Standard ML programming style.
+(setq-default sml-nested-if-indent t
+ sml-case-indent nil
+ sml-indent-level 4
+ sml-type-of-indent nil)
+
(defun mdw-fontify-sml ()
;; Make underscore an honorary letter.
"where" "while" "with" "withtype")))
(setq font-lock-keywords
- (list
+ (list
- ;; Set up the keywords defined above.
- (list (concat "\\<\\(" sml-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
+ ;; Set up the keywords defined above.
+ (list (concat "\\<\\(" sml-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
- ;; At least numbers are simpler than C.
- (list (concat "\\<\\(\\~\\|\\)"
- "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
- "[wW][0-9]+\\)\\|"
- "\\([0-9]+\\(\\.[0-9]+\\|\\)"
- "\\([eE]\\(\\~\\|\\)"
- "[0-9]+\\|\\)\\)\\)")
- '(0 mdw-number-face))
+ ;; At least numbers are simpler than C.
+ (list (concat "\\<\\~?"
+ "\\(0\\([wW]?[xX][0-9a-fA-F]+\\|"
+ "[wW][0-9]+\\)\\|"
+ "\\([0-9]+\\(\\.[0-9]+\\)?"
+ "\\([eE]\\~?"
+ "[0-9]+\\)?\\)\\)")
+ '(0 mdw-number-face))
- ;; And anything else is punctuation.
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ ;; And anything else is punctuation.
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'sml-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'sml-mode-hook 'mdw-fontify-sml t))
;;;--------------------------------------------------------------------------
;;; Haskell configuration.
+(setq-default haskell-indent-offset 2)
+(setq haskell-doc-prettify-types nil
+ haskell-interactive-popup-errors nil)
+
(defun mdw-fontify-haskell ()
;; Fiddle with syntax table to get comments right.
;; Make punctuation be punctuation
(let ((punct "=<>+-*/|&%!@?$.^:#`"))
- (do ((i 0 (1+ i)))
+ (cl-do ((i 0 (1+ i)))
((>= i (length punct)))
(modify-syntax-entry (aref punct i) ".")))
"SP" "STX" "SUB" "SYN" "US" "VT")))
(setq font-lock-keywords
- (list
- (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
- "\\(-+}\\|-*\\'\\)"
- "\\|"
- "--.*$")
- '(0 font-lock-comment-face))
- (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
- '(0 font-lock-keyword-face))
- (list (concat "'\\("
- "[^\\]"
- "\\|"
- "\\\\"
- "\\(" "[abfnrtv\\\"']" "\\|"
- "^" "\\(" control-sequences "\\|"
- "[]A-Z@[\\^_]" "\\)" "\\|"
- "\\|"
- "[0-9]+" "\\|"
- "[oO][0-7]+" "\\|"
- "[xX][0-9A-Fa-f]+"
- "\\)"
- "\\)'")
- '(0 font-lock-string-face))
- (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>"
- '(0 font-lock-variable-name-face))
- (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|"
- "\\_<[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)")
- '(0 mdw-number-face))
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+ (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*"
+ "\\(-+}\\|-*\\'\\)"
+ "\\|"
+ "--.*$")
+ '(0 font-lock-comment-face))
+ (list (concat "\\_<\\(" haskell-keywords "\\)\\_>")
+ '(0 font-lock-keyword-face))
+ (list (concat "'\\("
+ "[^\\]"
+ "\\|"
+ "\\\\"
+ "\\(" "[abfnrtv\\\"']" "\\|"
+ "^" "\\(" control-sequences "\\|"
+ "[]A-Z@[\\^_]" "\\)" "\\|"
+ "\\|"
+ "[0-9]+" "\\|"
+ "[oO][0-7]+" "\\|"
+ "[xX][0-9A-Fa-f]+"
+ "\\)"
+ "\\)'")
+ '(0 font-lock-string-face))
+ (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>"
+ '(0 font-lock-variable-name-face))
+ (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|"
+ "\\_<[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?")
+ '(0 mdw-number-face))
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'haskell-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'haskell-mode-hook 'mdw-fontify-haskell t))
;;;--------------------------------------------------------------------------
;;; Erlang configuration.
-(setq erlang-electric-commands nil)
+(setq-default erlang-electric-commands nil)
(defun mdw-fontify-erlang ()
"query" "receive" "rem" "try" "when" "xor")))
(setq font-lock-keywords
- (list
- (list "%.*$"
- '(0 font-lock-comment-face))
- (list (concat "\\<\\(" erlang-keywords "\\)\\>")
- '(0 font-lock-keyword-face))
- (list (concat "^-\\sw+\\>")
- '(0 font-lock-keyword-face))
- (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
- '(0 mdw-number-face))
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face))))))
+ (list
+ (list "%.*$"
+ '(0 font-lock-comment-face))
+ (list (concat "\\<\\(" erlang-keywords "\\)\\>")
+ '(0 font-lock-keyword-face))
+ (list (concat "^-\\sw+\\>")
+ '(0 font-lock-keyword-face))
+ (list "\\<[0-9]+\\(#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)?\\>"
+ '(0 mdw-number-face))
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face))))))
+
+(progn
+ (add-hook 'erlang-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'erlang-mode-hook 'mdw-fontify-erlang t))
;;;--------------------------------------------------------------------------
;;; Texinfo configuration.
;; Real fontification things.
(make-local-variable 'font-lock-keywords)
(setq font-lock-keywords
- (list
+ (list
+
+ ;; Environment names are keywords.
+ (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
+ '(2 font-lock-keyword-face))
- ;; Environment names are keywords.
- (list "@\\(end\\) *\\([a-zA-Z]*\\)?"
- '(2 font-lock-keyword-face))
+ ;; Unmark escaped magic characters.
+ (list "\\(@\\)\\([@{}]\\)"
+ '(1 font-lock-keyword-face)
+ '(2 font-lock-variable-name-face))
- ;; Unmark escaped magic characters.
- (list "\\(@\\)\\([@{}]\\)"
- '(1 font-lock-keyword-face)
- '(2 font-lock-variable-name-face))
+ ;; Make sure we get comments properly.
+ (list "@c\\(omment\\)?\\( .*\\)?$"
+ '(0 font-lock-comment-face))
- ;; Make sure we get comments properly.
- (list "@c\\(\\|omment\\)\\( .*\\)?$"
- '(0 font-lock-comment-face))
+ ;; Command names are keywords.
+ (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
+ '(0 font-lock-keyword-face))
- ;; Command names are keywords.
- (list "@\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
- '(0 font-lock-keyword-face))
+ ;; Fontify TeX special characters as punctuation.
+ (list "[{}]+"
+ '(0 mdw-punct-face)))))
- ;; Fontify TeX special characters as punctuation.
- (list "[{}]+"
- '(0 mdw-punct-face)))))
+(dolist (hook '(texinfo-mode-hook TeXinfo-mode-hook))
+ (add-hook hook 'mdw-misc-mode-config t)
+ (add-hook hook 'mdw-fontify-texinfo t))
;;;--------------------------------------------------------------------------
;;; TeX and LaTeX configuration.
+(setq-default LaTeX-table-label "tbl:"
+ TeX-auto-untabify nil
+ LaTeX-syntactic-comments nil
+ LaTeX-fill-break-at-separators '(\\\[))
+
(defun mdw-fontify-tex ()
(setq ispell-parser 'tex)
(turn-on-reftex)
(local-set-key [?$] 'self-insert-command)
;; Make `tab' be useful, given that tab stops in TeX don't work well.
- (local-set-key "\C-i" 'indent-relative)
+ (local-set-key "\C-\M-i" 'indent-relative)
(setq indent-tabs-mode nil)
;; Set fill prefix.
;; Real fontification things.
(make-local-variable 'font-lock-keywords)
(setq font-lock-keywords
- (list
-
- ;; Environment names are keywords.
- (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
- "{\\([^}\n]*\\)}")
- '(2 font-lock-keyword-face))
-
- ;; Suspended environment names are keywords too.
- (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
- "{\\([^}\n]*\\)}")
- '(3 font-lock-keyword-face))
-
- ;; Command names are keywords.
- (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
- '(0 font-lock-keyword-face))
-
- ;; Handle @/.../ for italics.
- ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
- ;; '(1 font-lock-keyword-face)
- ;; '(3 font-lock-keyword-face))
-
- ;; Handle @*...* for boldness.
- ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
- ;; '(1 font-lock-keyword-face)
- ;; '(3 font-lock-keyword-face))
-
- ;; Handle @`...' for literal syntax things.
- ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
- ;; '(1 font-lock-keyword-face)
- ;; '(3 font-lock-keyword-face))
-
- ;; Handle @<...> for nonterminals.
- ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
- ;; '(1 font-lock-keyword-face)
- ;; '(3 font-lock-keyword-face))
-
- ;; Handle other @-commands.
- ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
- ;; '(0 font-lock-keyword-face))
-
- ;; Make sure we get comments properly.
- (list "%.*"
- '(0 font-lock-comment-face))
-
- ;; Fontify TeX special characters as punctuation.
- (list "[$^_{}#&]"
- '(0 mdw-punct-face)))))
+ (list
+
+ ;; Environment names are keywords.
+ (list (concat "\\\\\\(begin\\|end\\|newenvironment\\)"
+ "{\\([^}\n]*\\)}")
+ '(2 font-lock-keyword-face))
+
+ ;; Suspended environment names are keywords too.
+ (list (concat "\\\\\\(suspend\\|resume\\)\\(\\[[^]]*\\]\\)?"
+ "{\\([^}\n]*\\)}")
+ '(3 font-lock-keyword-face))
+
+ ;; Command names are keywords.
+ (list "\\\\\\([^a-zA-Z@]\\|[a-zA-Z@]*\\)"
+ '(0 font-lock-keyword-face))
+
+ ;; Handle @/.../ for italics.
+ ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)"
+ ;; '(1 font-lock-keyword-face)
+ ;; '(3 font-lock-keyword-face))
+
+ ;; Handle @*...* for boldness.
+ ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)"
+ ;; '(1 font-lock-keyword-face)
+ ;; '(3 font-lock-keyword-face))
+
+ ;; Handle @`...' for literal syntax things.
+ ;; (list "\\(@`\\)\\([^']*\\)\\('\\)"
+ ;; '(1 font-lock-keyword-face)
+ ;; '(3 font-lock-keyword-face))
+
+ ;; Handle @<...> for nonterminals.
+ ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)"
+ ;; '(1 font-lock-keyword-face)
+ ;; '(3 font-lock-keyword-face))
+
+ ;; Handle other @-commands.
+ ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)"
+ ;; '(0 font-lock-keyword-face))
+
+ ;; Make sure we get comments properly.
+ (list "%.*"
+ '(0 font-lock-comment-face))
+
+ ;; Fontify TeX special characters as punctuation.
+ (list "[$^_{}#&]"
+ '(0 mdw-punct-face)))))
+
+(setq TeX-install-font-lock 'tex-font-setup)
+
+(eval-after-load 'font-latex
+ '(defun font-latex-jit-lock-force-redisplay (buf start end)
+ "Compatibility for Emacsen not offering `jit-lock-force-redisplay'."
+ ;; The following block is an expansion of `jit-lock-force-redisplay'
+ ;; and involved macros taken from CVS Emacs on 2007-04-28.
+ (with-current-buffer buf
+ (let ((modified (buffer-modified-p)))
+ (unwind-protect
+ (let ((buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t)
+ deactivate-mark
+ buffer-file-name
+ buffer-file-truename)
+ (put-text-property start end 'fontified t))
+ (unless modified
+ (restore-buffer-modified-p nil)))))))
+
+(setq TeX-output-view-style
+ '(("^dvi$"
+ ("^landscape$" "^pstricks$\\|^pst-\\|^psfrag$")
+ "%(o?)dvips -t landscape %d -o && xdg-open %f")
+ ("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$"
+ "%(o?)dvips %d -o && xdg-open %f")
+ ("^dvi$"
+ ("^a4\\(?:dutch\\|paper\\|wide\\)\\|sem-a4$" "^landscape$")
+ "%(o?)xdvi %dS -paper a4r -s 0 %d")
+ ("^dvi$" "^a4\\(?:dutch\\|paper\\|wide\\)\\|sem-a4$"
+ "%(o?)xdvi %dS -paper a4 %d")
+ ("^dvi$"
+ ("^a5\\(?:comb\\|paper\\)$" "^landscape$")
+ "%(o?)xdvi %dS -paper a5r -s 0 %d")
+ ("^dvi$" "^a5\\(?:comb\\|paper\\)$" "%(o?)xdvi %dS -paper a5 %d")
+ ("^dvi$" "^b5paper$" "%(o?)xdvi %dS -paper b5 %d")
+ ("^dvi$" "^letterpaper$" "%(o?)xdvi %dS -paper us %d")
+ ("^dvi$" "^legalpaper$" "%(o?)xdvi %dS -paper legal %d")
+ ("^dvi$" "^executivepaper$" "%(o?)xdvi %dS -paper 7.25x10.5in %d")
+ ("^dvi$" "." "%(o?)xdvi %dS %d")
+ ("^pdf$" "." "xdg-open %o")
+ ("^html?$" "." "sensible-browser %o")))
+
+(setq TeX-view-program-list
+ '(("mupdf" ("mupdf %o" (mode-io-correlate " %(outpage)")))))
+
+(setq TeX-view-program-selection
+ '(((output-dvi style-pstricks) "dvips and gv")
+ (output-dvi "xdvi")
+ (output-pdf "mupdf")
+ (output-html "sensible-browser")))
+
+(setq TeX-open-quote "\""
+ TeX-close-quote "\"")
+
+(setq reftex-use-external-file-finders t
+ reftex-auto-recenter-toc t)
+
+(setq reftex-label-alist
+ '(("theorem" ?T "th:" "~\\ref{%s}" t ("theorems?" "th\\.") -2)
+ ("axiom" ?A "ax:" "~\\ref{%s}" t ("axioms?" "ax\\.") -2)
+ ("definition" ?D "def:" "~\\ref{%s}" t ("definitions?" "def\\.") -2)
+ ("proposition" ?P "prop:" "~\\ref{%s}" t
+ ("propositions?" "prop\\.") -2)
+ ("lemma" ?L "lem:" "~\\ref{%s}" t ("lemmas?" "lem\\.") -2)
+ ("example" ?X "eg:" "~\\ref{%s}" t ("examples?") -2)
+ ("exercise" ?E "ex:" "~\\ref{%s}" t ("exercises?" "ex\\.") -2)
+ ("enumerate" ?i "i:" "~\\ref{%s}" item ("items?"))))
+(setq reftex-section-prefixes
+ '((0 . "part:")
+ (1 . "ch:")
+ (t . "sec:")))
+
+(setq bibtex-field-delimiters 'double-quotes
+ bibtex-align-at-equal-sign t
+ bibtex-entry-format '(realign opts-or-alts required-fields
+ numerical-fields last-comma delimiters
+ unify-case sort-fields braces)
+ bibtex-sort-ignore-string-entries nil
+ bibtex-maintain-sorted-entries 'entry-class
+ bibtex-include-OPTkey t
+ bibtex-autokey-names-stretch 1
+ bibtex-autokey-expand-strings t
+ bibtex-autokey-name-separator "-"
+ bibtex-autokey-year-length 4
+ bibtex-autokey-titleword-separator "-"
+ bibtex-autokey-name-year-separator "-"
+ bibtex-autokey-year-title-separator ":")
+
+(progn
+ (dolist (hook '(tex-mode-hook latex-mode-hook
+ TeX-mode-hook LaTeX-mode-hook))
+ (add-hook hook 'mdw-misc-mode-config t)
+ (add-hook hook 'mdw-fontify-tex t))
+ (add-hook 'bibtex-mode-hook (lambda () (setq fill-column 76))))
+
+;;;--------------------------------------------------------------------------
+;;; HTML, CSS, and other web foolishness.
+
+(setq-default css-indent-offset 8)
;;;--------------------------------------------------------------------------
;;; SGML hacking.
+(setq-default psgml-html-build-new-buffer nil)
+
(defun mdw-sgml-mode ()
(interactive)
(sgml-mode)
(mdw-standard-fill-prefix "")
(make-local-variable 'sgml-delimiters)
(setq sgml-delimiters
- '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
- "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT" "\""
- "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]" "NESTC" "{"
- "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">" "PIO" "<?"
- "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" "," "STAGO" ":"
- "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
- "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE" "/>"
- "NULL" ""))
+ '("AND" "&" "COM" "--" "CRO" "&#" "DSC" "]" "DSO" "[" "DTGC" "]"
+ "DTGO" "[" "ERO" "&" "ETAGO" ":e" "GRPC" ")" "GRPO" "(" "LIT"
+ "\"" "LITA" "'" "MDC" ">" "MDO" "<!" "MINUS" "-" "MSC" "]]"
+ "NESTC" "{" "NET" "}" "OPT" "?" "OR" "|" "PERO" "%" "PIC" ">"
+ "PIO" "<?" "PLUS" "+" "REFC" "." "REP" "*" "RNI" "#" "SEQ" ","
+ "STAGO" ":" "TAGC" "." "VI" "=" "MS-START" "<![" "MS-END" "]]>"
+ "XML-ECOM" "-->" "XML-PIC" "?>" "XML-SCOM" "<!--" "XML-TAGCE"
+ "/>" "NULL" ""))
(setq major-mode 'mdw-sgml-mode)
(setq mode-name "[mdw] SGML")
(run-hooks 'mdw-sgml-mode-hook))
;;;--------------------------------------------------------------------------
;;; Configuration files.
-(defvar mdw-conf-quote-normal nil
- "*Control syntax category of quote characters `\"' and `''.
+(defcustom mdw-conf-quote-normal nil
+ "Control syntax category of quote characters `\"' and `''.
If this is `t', consider quote characters to be normal
punctuation, as for `conf-quote-normal'. If this is `nil' then
leave quote characters as quotes. If this is a list, then
consider the quote characters in the list to be normal
punctuation. If this is a single quote character, then consider
-that character only to be normal punctuation.")
+that character only to be normal punctuation."
+ :type '(choice boolean character (repeat character))
+ :safe 'mdw-conf-quote-normal-acceptable-value-p)
(defun mdw-conf-quote-normal-acceptable-value-p (value)
"Is the VALUE is an acceptable value for `mdw-conf-quote-normal'?"
(or (booleanp value)
- (every (lambda (v) (memq v '(?\" ?')))
- (if (listp value) value (list value)))))
-(put 'mdw-conf-quote-normal 'safe-local-variable
- 'mdw-conf-quote-normal-acceptable-value-p)
+ (cl-every (lambda (v) (memq v '(?\" ?')))
+ (if (listp value) value (list value)))))
(defun mdw-fix-up-quote ()
"Apply the setting of `mdw-conf-quote-normal'."
nil)
(t
(let ((table (copy-syntax-table (syntax-table))))
- (mapc (lambda (ch) (modify-syntax-entry ch "." table))
- (if (listp flag) flag (list flag)))
+ (dolist (ch (if (listp flag) flag (list flag)))
+ (modify-syntax-entry ch "." table))
(set-syntax-table table)
(and font-lock-mode (font-lock-fontify-buffer)))))))
-(add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t)
+
+(progn
+ (add-hook 'conf-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t))
;;;--------------------------------------------------------------------------
;;; Shell scripts.
(if assoc
(rplacd assoc frag)
(setq sh-mode-syntax-table-input
- (cons (cons 'rc frag)
- sh-mode-syntax-table-input))))))
+ (cons (cons 'rc frag)
+ sh-mode-syntax-table-input))))))
+
+(progn
+ (add-hook 'sh-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'sh-mode-hook 'mdw-setup-sh-script-mode t))
;;;--------------------------------------------------------------------------
;;; Emacs shell mode.
(concat "~" (substring pwd (length home)))
pwd))
right)))
-(setq eshell-prompt-function 'mdw-eshell-prompt)
-(setq eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
+(setq-default eshell-prompt-function 'mdw-eshell-prompt)
+(setq-default eshell-prompt-regexp "^\\[[^]>]+\\(\\]\\|>>?\\)")
(defun eshell/e (file) (find-file file) nil)
(defun eshell/ee (file) (find-file-other-window file) nil)
(mdw-define-face eshell-ls-readonly (t nil))
(mdw-define-face eshell-ls-symlink (t :foreground "cyan"))
+(defun mdw-eshell-hack () (setenv "LD_PRELOAD" nil))
+(add-hook 'eshell-mode-hook 'mdw-eshell-hack)
+
;;;--------------------------------------------------------------------------
;;; Messages-file mode.
"set" "table" "tagged-optional" "union"
"variadic" "vector" "version" "version-tag")))
(setq messages-mode-keywords
- (list
- (list (concat "\\<\\(" keywords "\\)\\>:")
- '(0 font-lock-keyword-face))
- '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
- '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
- (0 font-lock-variable-name-face))
- '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
- '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- (0 mdw-punct-face)))))
+ (list
+ (list (concat "\\<\\(" keywords "\\)\\>:")
+ '(0 font-lock-keyword-face))
+ '("\\([-a-zA-Z0-9]+:\\)" (0 font-lock-warning-face))
+ '("\\(\\<[a-z][-_a-zA-Z0-9]*\\)"
+ (0 font-lock-variable-name-face))
+ '("\\<\\([0-9]+\\)\\>" (0 mdw-number-face))
+ '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ (0 mdw-punct-face)))))
(setq font-lock-defaults
- '(messages-mode-keywords nil nil nil nil))
+ '(messages-mode-keywords nil nil nil nil))
(run-hooks 'messages-file-hook))
(defun messages-mode ()
"ident" "if" "ifdef" "ifndef" "import" "include"
"line" "pragma" "unassert" "undef" "warning")))
(setq messages-mode-keywords
- (append (list (list (concat "^[ \t]*\\#[ \t]*"
- "\\(include\\|import\\)"
- "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
- '(2 font-lock-string-face))
- (list (concat "^\\([ \t]*#[ \t]*\\(\\("
- preprocessor-keywords
- "\\)\\>\\|[0-9]+\\|$\\)\\)")
- '(1 font-lock-keyword-face)))
- messages-mode-keywords)))
+ (append (list (list (concat "^[ \t]*\\#[ \t]*"
+ "\\(include\\|import\\)"
+ "[ \t]*\\(<[^>]+\\(>\\)?\\)")
+ '(2 font-lock-string-face))
+ (list (concat "^\\([ \t]*#[ \t]*\\(\\("
+ preprocessor-keywords
+ "\\)\\>\\|[0-9]+\\|$\\)\\)")
+ '(1 font-lock-keyword-face)))
+ messages-mode-keywords)))
(run-hooks 'cpp-messages-mode-hook))
-(add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
-(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
-; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
+(progn
+ (add-hook 'messages-mode-hook 'mdw-misc-mode-config t)
+ (add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t)
+ ;; (add-hook 'messages-file-hook 'mdw-fontify-messages t)
+ )
;;;--------------------------------------------------------------------------
;;; Messages-file mode.
(mdw-regexps "each" "divert" "file" "if"
"perl" "set" "string" "type" "write")))
(setq mallow-driver-mode-keywords
- (list
- (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
- '(0 font-lock-keyword-face))
- (list "^%\\s *\\(#.*\\|\\)$"
- '(0 font-lock-comment-face))
- (list "^%"
- '(0 font-lock-keyword-face))
- (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
- (list "\\${[^}]*}"
- '(0 mallow-driver-substitution-face t)))))
+ (list
+ (list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
+ '(0 font-lock-keyword-face))
+ (list "^%\\s *\\(#.*\\)?$"
+ '(0 font-lock-comment-face))
+ (list "^%"
+ '(0 font-lock-keyword-face))
+ (list "^|?\\(.+\\)$" '(1 mallow-driver-text-face))
+ (list "\\${[^}]*}"
+ '(0 mallow-driver-substitution-face t)))))
(setq font-lock-defaults
'(mallow-driver-mode-keywords nil nil nil nil))
(modify-syntax-entry ?\" "_" mallow-driver-mode-syntax-table)
(setq comment-end "")
(run-hooks 'mallow-driver-mode-hook))
-(add-hook 'mallow-driver-hook 'mdw-misc-mode-config t)
+(progn
+ (add-hook 'mallow-driver-hook 'mdw-misc-mode-config t))
;;;--------------------------------------------------------------------------
;;; NFast debugs.
(make-local-variable 'nfast-debug-mode-keywords)
(setq truncate-lines t)
(setq nfast-debug-mode-keywords
- (list
- '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
- (0 font-lock-keyword-face))
- (list (concat "^[ \t]+\\(\\("
- "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
- "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
- "[ \t]+\\)*"
- "[0-9a-fA-F]+\\)[ \t]*$")
- '(0 mdw-number-face))
- '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
- (1 font-lock-keyword-face))
- '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
- (1 font-lock-warning-face))
- '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
- (1 nil))
- (list (concat "^[ \t]+\\.cmd=[ \t]+"
- "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
- '(1 font-lock-keyword-face))
- '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
- '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
- '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
- '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
+ (list
+ '("^\\(NFast_\\(Connect\\|Disconnect\\|Submit\\|Wait\\)\\)"
+ (0 font-lock-keyword-face))
+ (list (concat "^[ \t]+\\(\\("
+ "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
+ "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"
+ "[ \t]+\\)*"
+ "[0-9a-fA-F]+\\)[ \t]*$")
+ '(0 mdw-number-face))
+ '("^[ \t]+\.status=[ \t]+\\<\\(OK\\)\\>"
+ (1 font-lock-keyword-face))
+ '("^[ \t]+\.status=[ \t]+\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>"
+ (1 font-lock-warning-face))
+ '("^[ \t]+\.status[ \t]+\\<\\(zero\\)\\>"
+ (1 nil))
+ (list (concat "^[ \t]+\\.cmd=[ \t]+"
+ "\\<\\([a-zA-Z][0-9a-zA-Z]*\\)\\>")
+ '(1 font-lock-keyword-face))
+ '("-?\\<\\([0-9]+\\|0x[0-9a-fA-F]+\\)\\>" (0 mdw-number-face))
+ '("^\\([ \t]+[a-z0-9.]+\\)" (0 font-lock-variable-name-face))
+ '("\\<\\([a-z][a-z0-9.]+\\)\\>=" (1 font-lock-variable-name-face))
+ '("\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" (0 mdw-punct-face))))
(setq font-lock-defaults
- '(nfast-debug-mode-keywords nil nil nil nil))
+ '(nfast-debug-mode-keywords nil nil nil nil))
(run-hooks 'nfast-debug-mode-hook))
;;;--------------------------------------------------------------------------
-;;; Other languages.
-
-;; Smalltalk.
-
-(defun mdw-setup-smalltalk ()
- (and mdw-auto-indent
- (local-set-key "\C-m" 'smalltalk-newline-and-indent))
- (make-local-variable 'mdw-auto-indent)
- (setq mdw-auto-indent nil)
- (local-set-key "\C-i" 'smalltalk-reindent))
-
-(defun mdw-fontify-smalltalk ()
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-keywords
- (list
- (list "\\<[A-Z][a-zA-Z0-9]*\\>"
- '(0 font-lock-keyword-face))
- (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
- "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
- '(0 mdw-number-face))
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face)))))
-
-;; Lispy languages.
+;;; Lispy languages.
;; Unpleasant bodge.
(unless (boundp 'slime-repl-mode-map)
(make-local-variable 'lisp-indent-function)
(setq lisp-indent-function 'common-lisp-indent-function))
-(setq lisp-simple-loop-indentation 2
- lisp-loop-keyword-indentation 6
- lisp-loop-forms-indentation 6)
+(defmacro mdw-advise-hyperspec-lookup (func args)
+ `(defadvice ,func (around mdw-browse-w3m ,args activate compile)
+ (if (fboundp 'w3m)
+ (let ((browse-url-browser-function #'mdw-w3m-browse-url))
+ ad-do-it)
+ ad-do-it)))
+(mdw-advise-hyperspec-lookup common-lisp-hyperspec (symbol))
+(mdw-advise-hyperspec-lookup common-lisp-hyperspec-format (char))
+(mdw-advise-hyperspec-lookup common-lisp-hyperspec-lookup-reader-macro (char))
(defun mdw-fontify-lispy ()
;; Not much fontification needed.
(make-local-variable 'font-lock-keywords)
- (setq font-lock-keywords
- (list (list (concat "\\("
- "\\_<[-+]?"
- "\\(" "[0-9]+/[0-9]+"
- "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|"
- "\\.[0-9]+" "\\)"
- "\\([dDeEfFlLsS][-+]?[0-9]+\\)?"
- "\\)"
- "\\|"
- "#"
- "\\(" "x" "[-+]?"
- "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?"
- "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?"
- "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?"
- "\\|" "[0-9]+" "r" "[-+]?"
- "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?"
- "\\)"
- "\\)\\_>")
- '(0 mdw-number-face))
- (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face)))))
+ (setq font-lock-keywords
+ (list (list (concat "\\("
+ "\\_<[-+]?"
+ "\\(" "[0-9]+/[0-9]+"
+ "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|"
+ "\\.[0-9]+" "\\)"
+ "\\([dDeEfFlLsS][-+]?[0-9]+\\)?"
+ "\\)"
+ "\\|"
+ "#"
+ "\\(" "x" "[-+]?"
+ "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?"
+ "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?"
+ "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?"
+ "\\|" "[0-9]+" "r" "[-+]?"
+ "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?"
+ "\\)"
+ "\\)\\_>")
+ '(0 mdw-number-face))
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face)))))
+
+;; Special indentation.
+
+(defcustom mdw-lisp-loop-default-indent 2
+ "Default indent for simple `loop' body."
+ :type 'integer
+ :safe 'integerp)
+(defcustom mdw-lisp-setf-value-indent 2
+ "Default extra indent for `setf' values."
+ :type 'integer :safe 'integerp)
+
+(setq lisp-simple-loop-indentation 0
+ lisp-loop-keyword-indentation 0
+ lisp-loop-forms-indentation 2
+ lisp-lambda-list-keyword-parameter-alignment t)
+
+(defun mdw-indent-funcall
+ (path state &optional indent-point sexp-column normal-indent)
+ "Indent `funcall' more usefully.
+Essentially, treat `funcall foo' as a function name, and align the arguments
+to `foo'."
+ (and (or (not (consp path)) (null (cadr path)))
+ (save-excursion
+ (goto-char (cadr state))
+ (forward-char 1)
+ (let ((start-line (line-number-at-pos)))
+ (and (condition-case nil (progn (forward-sexp 3) t)
+ (scan-error nil))
+ (progn
+ (forward-sexp -1)
+ (and (= start-line (line-number-at-pos))
+ (current-column))))))))
+(progn
+ (put 'funcall 'common-lisp-indent-function 'mdw-indent-funcall)
+ (put 'funcall 'lisp-indent-function 'mdw-indent-funcall))
+
+(defun mdw-indent-setf
+ (path state &optional indent-point sexp-column normal-indent)
+ "Indent `setf' more usefully.
+If the values aren't on the same lines as their variables then indent them
+by `mdw-lisp-setf-value-indent' spaces."
+ (and (or (not (consp path)) (null (cadr path)))
+ (let ((basic-indent (save-excursion
+ (goto-char (cadr state))
+ (forward-char 1)
+ (and (condition-case nil
+ (progn (forward-sexp 2) t)
+ (scan-error nil))
+ (progn
+ (forward-sexp -1)
+ (current-column)))))
+ (offset (if (consp path) (car path)
+ (catch 'done
+ (save-excursion
+ (let ((start path)
+ (count 0))
+ (goto-char (cadr state))
+ (forward-char 1)
+ (while (< (point) start)
+ (condition-case nil (forward-sexp 1)
+ (scan-error (throw 'done nil)))
+ (cl-incf count))
+ (1- count)))))))
+ (and basic-indent offset
+ (list (+ basic-indent
+ (if (cl-oddp offset) 0
+ mdw-lisp-setf-value-indent))
+ basic-indent)))))
+(progn
+ (put 'setf 'common-lisp-indent-functopion 'mdw-indent-setf)
+ (put 'psetf 'common-lisp-indent-function 'mdw-indent-setf)
+ (put 'setq 'common-lisp-indent-function 'mdw-indent-setf)
+ (put 'setf 'lisp-indent-function 'mdw-indent-setf)
+ (put 'setq 'lisp-indent-function 'mdw-indent-setf)
+ (put 'setq-local 'lisp-indent-function 'mdw-indent-setf)
+ (put 'setq-default 'lisp-indent-function 'mdw-indent-setf))
+
+(defadvice common-lisp-loop-part-indentation
+ (around mdw-fix-loop-indentation (indent-point state) activate compile)
+ "Improve `loop' indentation.
+If the first subform is on the same line as the `loop' keyword, then
+align the other subforms beneath it. Otherwise, indent them
+`mdw-lisp-loop-default-indent' columns in from the opening parenthesis."
+
+ (let* ((loop-indentation (save-excursion
+ (goto-char (elt state 1))
+ (current-column))))
+
+ ;; Don't really care about this.
+ (when (and (boundp 'lisp-indent-backquote-substitution-mode)
+ (eq lisp-indent-backquote-substitution-mode 'corrected))
+ (save-excursion
+ (goto-char (elt state 1))
+ (cl-incf loop-indentation
+ (cond ((eq (char-before) ?,) -1)
+ ((and (eq (char-before) ?@)
+ (progn (backward-char)
+ (eq (char-before) ?,)))
+ -2)
+ (t 0)))))
+
+ ;; If the first loop item is on the same line as the `loop' itself then
+ ;; use that as the baseline. Otherwise advance by the default indent.
+ (goto-char (cadr state))
+ (forward-char 1)
+ (let ((baseline-indent
+ (if (= (line-number-at-pos)
+ (if (condition-case nil (progn (forward-sexp 2) t)
+ (scan-error nil))
+ (progn (forward-sexp -1) (line-number-at-pos))
+ -1))
+ (current-column)
+ (+ loop-indentation mdw-lisp-loop-default-indent))))
+
+ (goto-char indent-point)
+ (beginning-of-line)
+
+ (setq ad-return-value
+ (list
+ (cond ((condition-case ()
+ (save-excursion
+ (goto-char (elt state 1))
+ (forward-char 1)
+ (forward-sexp 2)
+ (backward-sexp 1)
+ (not (looking-at "\\(:\\|\\sw\\)")))
+ (error nil))
+ (+ baseline-indent lisp-simple-loop-indentation))
+ ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)")
+ (+ baseline-indent lisp-loop-keyword-indentation))
+ (t
+ (+ baseline-indent lisp-loop-forms-indentation)))
+
+ ;; Tell the caller that the next line needs recomputation,
+ ;; even though it doesn't start a sexp.
+ loop-indentation)))))
+
+;; SLIME setup.
+
+(defcustom mdw-friendly-name "[mdw]"
+ "How I want to be addressed."
+ :type 'string
+ :safe 'stringp)
+(defadvice slime-user-first-name
+ (around mdw-use-friendly-name compile activate)
+ (if mdw-friendly-name (setq ad-return-value mdw-friendly-name)
+ ad-do-it))
-(defun comint-send-and-indent ()
- (interactive)
- (comint-send-input)
+(eval-and-compile
+ (trap
+ (if (not mdw-fast-startup)
+ (progn
+ (require 'slime-autoloads)
+ (slime-setup '(slime-autodoc slime-c-p-c))))))
+
+(let ((stuff '((cmucl ("cmucl"))
+ (sbcl ("sbcl") :coding-system utf-8-unix)
+ (clisp ("clisp") :coding-system utf-8-unix))))
+ (or (boundp 'slime-lisp-implementations)
+ (setq slime-lisp-implementations nil))
+ (while stuff
+ (let* ((head (car stuff))
+ (found (assq (car head) slime-lisp-implementations)))
+ (setq stuff (cdr stuff))
+ (if found
+ (rplacd found (cdr head))
+ (setq slime-lisp-implementations
+ (cons head slime-lisp-implementations))))))
+(setq slime-default-lisp 'sbcl)
+
+;; Hooks.
+
+(progn
+ (dolist (hook '(emacs-lisp-mode-hook
+ scheme-mode-hook
+ lisp-mode-hook
+ inferior-lisp-mode-hook
+ lisp-interaction-mode-hook
+ ielm-mode-hook
+ slime-repl-mode-hook))
+ (add-hook hook 'mdw-misc-mode-config t)
+ (add-hook hook 'mdw-fontify-lispy t))
+ (add-hook 'lisp-mode-hook 'mdw-common-lisp-indent t)
+ (add-hook 'inferior-lisp-mode-hook
+ #'(lambda () (local-set-key "\C-m" 'comint-send-and-indent)) t))
+
+;;;--------------------------------------------------------------------------
+;;; Other languages.
+
+;; Smalltalk.
+
+(defun mdw-setup-smalltalk ()
(and mdw-auto-indent
- (indent-for-tab-command)))
+ (local-set-key "\C-m" 'smalltalk-newline-and-indent))
+ (make-local-variable 'mdw-auto-indent)
+ (setq mdw-auto-indent nil)
+ (local-set-key "\C-i" 'smalltalk-reindent))
+
+(defun mdw-fontify-smalltalk ()
+ (make-local-variable 'font-lock-keywords)
+ (setq font-lock-keywords
+ (list
+ (list "\\<[A-Z][a-zA-Z0-9]*\\>"
+ '(0 font-lock-keyword-face))
+ (list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
+ "[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+ "\\([eE][-+]?[0-9_]+\\)?")
+ '(0 mdw-number-face))
+ (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
+ '(0 mdw-punct-face)))))
+
+(progn
+ (add-hook 'smalltalk-mode 'mdw-misc-mode-config t)
+ (add-hook 'smalltalk-mode 'mdw-fontify-smalltalk t))
+
+;; m4.
(defun mdw-setup-m4 ()
;; Fill prefix.
(mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\<dnl\\>\\)[ \t]*\\)"))
+(dolist (hook '(m4-mode-hook autoconf-mode-hook autotest-mode-hook))
+ (add-hook hook #'mdw-misc-mode-config t)
+ (add-hook hook #'mdw-setup-m4 t))
+
+;; Make.
+
+(progn
+ (add-hook 'makefile-mode-hook 'mdw-misc-mode-config t))
+
+;; nroff/troff.
+
+(progn
+ (add-hook 'nroff-mode-hook 'mdw-misc-mode-config t))
+
;;;--------------------------------------------------------------------------
;;; Text mode.
"\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
(auto-fill-mode 1))
+(eval-after-load "flyspell"
+ '(define-key flyspell-mode-map "\C-\M-i" nil))
+
+(progn
+ (add-hook 'text-mode-hook 'mdw-text-mode t))
+
;;;--------------------------------------------------------------------------
;;; Outline and hide/show modes.
(auto-fill-mode -1)
(setq tab-width 8))
+(defun comint-send-and-indent ()
+ (interactive)
+ (comint-send-input)
+ (and mdw-auto-indent
+ (indent-for-tab-command)))
+
+(defadvice comint-line-beginning-position
+ (around mdw-calculate-it-properly () activate compile)
+ "Calculate the actual line start for multi-line input."
+ (if (or comint-use-prompt-regexp
+ (eq (field-at-pos (point)) 'output))
+ ad-do-it
+ (setq ad-return-value
+ (constrain-to-field (line-beginning-position) (point)))))
+
(defun term-send-meta-right () (interactive) (term-send-raw-string "\e\e[C"))
(defun term-send-meta-left () (interactive) (term-send-raw-string "\e\e[D"))
(defun term-send-ctrl-uscore () (interactive) (term-send-raw-string "\C-_"))
(ad-set-arg 2 (car program))
(ad-set-arg 4 (cdr program))))))
+(defadvice term-exec-1 (around hack-environment compile activate)
+ "Hack the environment inherited by inferiors in the terminal."
+ (let ((process-environment (copy-tree process-environment)))
+ (setenv "LD_PRELOAD" nil)
+ ad-do-it))
+
+(defadvice shell (around hack-environment compile activate)
+ "Hack the environment inherited by inferiors in the shell."
+ (let ((process-environment (copy-tree process-environment)))
+ (setenv "LD_PRELOAD" nil)
+ ad-do-it))
+
(defun ssh (host)
"Open a terminal containing an ssh session to the HOST."
(interactive "sHost: ")
(ansi-term (list "ssh" host) (format "ssh@%s" host)))
-(defvar git-grep-command
- "env PAGER=cat git grep --no-color -nH -e "
- "*The default command for \\[git-grep].")
+(defcustom git-grep-command
+ "env GIT_PAGER=cat git grep --no-color -nH -e "
+ "The default command for \\[git-grep]."
+ :type 'string)
(defvar git-grep-history nil)
(interactive
(list (read-shell-command "Run git grep (like this): "
git-grep-command 'git-grep-history)))
- (grep command-args))
+ (let ((grep-use-null-device nil))
+ (grep command-args)))
+
+;;;--------------------------------------------------------------------------
+;;; Magit configuration.
+
+(setq magit-diff-refine-hunk 't
+ magit-view-git-manual-method 'man
+ magit-log-margin '(nil age magit-log-margin-width t 18)
+ magit-wip-after-save-local-mode-lighter ""
+ magit-wip-after-apply-mode-lighter ""
+ magit-wip-before-change-mode-lighter "")
+(eval-after-load "magit"
+ '(progn (global-magit-file-mode 1)
+ (magit-wip-after-save-mode 1)
+ (magit-wip-after-apply-mode 1)
+ (magit-wip-before-change-mode 1)
+ (add-to-list 'magit-no-confirm 'safe-with-wip)
+ (add-to-list 'magit-no-confirm 'trash)
+ (push '(:eval (if (or magit-wip-after-save-local-mode
+ magit-wip-after-apply-mode
+ magit-wip-before-change-mode)
+ (format " wip:%s%s%s"
+ (if magit-wip-after-apply-mode "A" "")
+ (if magit-wip-before-change-mode "C" "")
+ (if magit-wip-after-save-local-mode "S" ""))))
+ minor-mode-alist)
+ (dolist (popup '(magit-diff-popup
+ magit-diff-refresh-popup
+ magit-diff-mode-refresh-popup
+ magit-revision-mode-refresh-popup))
+ (magit-define-popup-switch popup ?R "Reverse diff" "-R"))
+ (magit-define-popup-switch 'magit-rebase-popup ?r
+ "Rebase merges" "--rebase-merges")))
+
+(defadvice magit-wip-commit-buffer-file
+ (around mdw-just-this-buffer activate compile)
+ (let ((magit-save-repository-buffers nil)) ad-do-it))
+
+(defadvice magit-discard
+ (around mdw-delete-if-prefix-argument activate compile)
+ (let ((magit-delete-by-moving-to-trash
+ (and (null current-prefix-arg)
+ magit-delete-by-moving-to-trash)))
+ ad-do-it))
+
+(setq magit-repolist-columns
+ '(("Name" 16 magit-repolist-column-ident nil)
+ ("Version" 18 magit-repolist-column-version nil)
+ ("St" 2 magit-repolist-column-dirty nil)
+ ("L<U" 3 mdw-repolist-column-unpulled-from-upstream nil)
+ ("L>U" 3 mdw-repolist-column-unpushed-to-upstream nil)
+ ("Path" 32 magit-repolist-column-path nil)))
+
+(setq magit-repository-directories '(("~/etc/profile" . 0)
+ ("~/src/" . 1)))
+
+(defadvice magit-list-repos (around mdw-dirname () activate compile)
+ "Make sure the returned names are directory names.
+Otherwise child processes get started in the wrong directory and
+there is sadness."
+ (setq ad-return-value (mapcar #'file-name-as-directory ad-do-it)))
+
+(defun mdw-repolist-column-unpulled-from-upstream (_id)
+ "Insert number of upstream commits not in the current branch."
+ (let ((upstream (magit-get-upstream-branch (magit-get-current-branch) t)))
+ (and upstream
+ (let ((n (cadr (magit-rev-diff-count "HEAD" upstream))))
+ (propertize (number-to-string n) 'face
+ (if (> n 0) 'bold 'shadow))))))
+
+(defun mdw-repolist-column-unpushed-to-upstream (_id)
+ "Insert number of commits in the current branch but not its upstream."
+ (let ((upstream (magit-get-upstream-branch (magit-get-current-branch) t)))
+ (and upstream
+ (let ((n (car (magit-rev-diff-count "HEAD" upstream))))
+ (propertize (number-to-string n) 'face
+ (if (> n 0) 'bold 'shadow))))))
+
+(defun mdw-try-smerge ()
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward "^<<<<<<< " nil t)
+ (smerge-mode 1))))
+(add-hook 'find-file-hook 'mdw-try-smerge t)
+
+(defcustom mdw-magit-new-window-modes
+ '(magit-diff-mode
+ magit-log-mode
+ magit-process-mode
+ magit-revision-mode
+ magit-stash-mode
+ magit-status-mode)
+ "Magit modes which should cause a new window to be used."
+ :type '(repeat symbol))
+
+(defun mdw-display-magit-buffer (buffer)
+ "Like `magit-display-buffer-traditional'.
+But uses `mdw-magit-new-window-modes' for its list of modes
+rather than baking the list into the function."
+ (display-buffer buffer
+ (let ((mode (with-current-buffer buffer major-mode)))
+ (if (and (not mdw-designated-window)
+ (derived-mode-p 'magit-mode)
+ (mdw-submode-p mode 'magit-mode)
+ (not (memq mode mdw-magit-new-window-modes)))
+ '(display-buffer-same-window . nil)
+ nil))))
+(setq magit-display-buffer-function 'mdw-display-magit-buffer)
+
+(defun mdw-display-magit-file-buffer (buffer)
+ "Show a file buffer from a diff."
+ (select-window (display-buffer buffer)))
+(setq magit-display-file-buffer-function 'mdw-display-magit-file-buffer)
+
+;;;--------------------------------------------------------------------------
+;;; GUD, and especially GDB.
+
+;; Inhibit window dedication. I mean, seriously, wtf?
+(defadvice gdb-display-buffer (after mdw-undedicated (buf) compile activate)
+ "Don't make windows dedicated. Seriously."
+ (set-window-dedicated-p ad-return-value nil))
+(defadvice gdb-set-window-buffer
+ (after mdw-undedicated (name &optional ignore-dedicated window)
+ compile activate)
+ "Don't make windows dedicated. Seriously."
+ (set-window-dedicated-p (or window (selected-window)) nil))
+
+(defadvice gud-find-expr
+ (around mdw-inhibit-read-only (&rest args) compile activate)
+ "Inhibit errors caused by my setting of `comint-prompt-read-only'."
+ (let ((inhibit-read-only t)) ad-do-it))
+
+;;;--------------------------------------------------------------------------
+;;; SQL stuff.
+
+(setq sql-postgres-options '("-n" "-P" "pager=off")
+ sql-postgres-login-params
+ '((user :default "mdw")
+ (database :default "mdw")
+ (server :default "db.distorted.org.uk")))
+
+;;;--------------------------------------------------------------------------
+;;; Man pages.
+
+;; Turn off `noip' when running `man': it interferes with `man-db''s own
+;; seccomp(2)-based sandboxing, which is (in this case, at least) strictly
+;; better.
+(defadvice Man-getpage-in-background
+ (around mdw-inhibit-noip (topic) compile activate)
+ "Inhibit the `noip' preload hack when invoking `man'."
+ (let* ((old-preload (getenv "LD_PRELOAD"))
+ (preloads (and old-preload
+ (save-match-data (split-string old-preload ":"))))
+ (any nil)
+ (filtered nil))
+ (save-match-data
+ (while preloads
+ (let ((item (pop preloads)))
+ (if (string-match "\\(/\\|^\\)noip\.so\\(:\\|$\\)" item)
+ (setq any t)
+ (push item filtered)))))
+ (if any
+ (unwind-protect
+ (progn
+ (setenv "LD_PRELOAD"
+ (and filtered
+ (with-output-to-string
+ (setq filtered (nreverse filtered))
+ (let ((first t))
+ (while filtered
+ (if first (setq first nil)
+ (write-char ?:))
+ (write-string (pop filtered)))))))
+ ad-do-it)
+ (setenv "LD_PRELOAD" old-preload))
+ ad-do-it)))
+
+;;;--------------------------------------------------------------------------
+;;; MPC configuration.
+
+(eval-when-compile (trap (require 'mpc)))
+
+(setq mpc-browser-tags '(Artist|Composer|Performer Album|Playlist))
+
+(defun mdw-mpc-now-playing ()
+ (interactive)
+ (require 'mpc)
+ (save-excursion
+ (set-buffer (mpc-proc-cmd (mpc-proc-cmd-list '("status" "currentsong"))))
+ (mpc--status-callback))
+ (let ((state (cdr (assq 'state mpc-status))))
+ (cond ((member state '("stop"))
+ (message "mpd stopped."))
+ ((member state '("play" "pause"))
+ (let* ((artist (cdr (assq 'Artist mpc-status)))
+ (album (cdr (assq 'Album mpc-status)))
+ (title (cdr (assq 'Title mpc-status)))
+ (file (cdr (assq 'file mpc-status)))
+ (duration-string (cdr (assq 'Time mpc-status)))
+ (time-string (cdr (assq 'time mpc-status)))
+ (time (and time-string
+ (string-to-number
+ (if (string-match ":" time-string)
+ (substring time-string
+ 0 (match-beginning 0))
+ (time-string)))))
+ (duration (and duration-string
+ (string-to-number duration-string)))
+ (pos (and time duration
+ (format " [%d:%02d/%d:%02d]"
+ (/ time 60) (mod time 60)
+ (/ duration 60) (mod duration 60))))
+ (fmt (cond ((and artist title)
+ (format "`%s' by %s%s" title artist
+ (if album (format ", from `%s'" album)
+ "")))
+ (file
+ (format "`%s' (no tags)" file))
+ (t
+ "(no idea what's playing!)"))))
+ (if (string= state "play")
+ (message "mpd playing %s%s" fmt (or pos ""))
+ (message "mpd paused in %s%s" fmt (or pos "")))))
+ (t
+ (message "mpd in unknown state `%s'" state)))))
+
+(defmacro mdw-define-mpc-wrapper (func bvl interactive &rest body)
+ `(defun ,func ,bvl
+ (interactive ,@interactive)
+ (require 'mpc)
+ ,@body
+ (mdw-mpc-now-playing)))
+
+(mdw-define-mpc-wrapper mdw-mpc-play-or-pause () nil
+ (if (member (cdr (assq 'state (mpc-cmd-status))) '("play"))
+ (mpc-pause)
+ (mpc-play)))
+
+(mdw-define-mpc-wrapper mdw-mpc-next () nil (mpc-next))
+(mdw-define-mpc-wrapper mdw-mpc-prev () nil (mpc-prev))
+(mdw-define-mpc-wrapper mdw-mpc-stop () nil (mpc-stop))
+
+(defun mdw-mpc-louder (step)
+ (interactive (list (if current-prefix-arg
+ (prefix-numeric-value current-prefix-arg)
+ +10)))
+ (mpc-proc-cmd (format "volume %+d" step)))
+
+(defun mdw-mpc-quieter (step)
+ (interactive (list (if current-prefix-arg
+ (prefix-numeric-value current-prefix-arg)
+ +10)))
+ (mpc-proc-cmd (format "volume %+d" (- step))))
+
+(defun mdw-mpc-hack-lines (arg interactivep func)
+ (if (and interactivep (use-region-p))
+ (let ((from (region-beginning)) (to (region-end)))
+ (goto-char from)
+ (beginning-of-line)
+ (funcall func)
+ (forward-line)
+ (while (< (point) to)
+ (funcall func)
+ (forward-line)))
+ (let ((n (prefix-numeric-value arg)))
+ (cond ((cl-minusp n)
+ (unless (bolp)
+ (beginning-of-line)
+ (funcall func)
+ (cl-incf n))
+ (while (cl-minusp n)
+ (forward-line -1)
+ (funcall func)
+ (cl-incf n)))
+ (t
+ (beginning-of-line)
+ (while (cl-plusp n)
+ (funcall func)
+ (forward-line)
+ (cl-decf n)))))))
+
+(defun mdw-mpc-select-one ()
+ (when (and (get-char-property (point) 'mpc-file)
+ (not (get-char-property (point) 'mpc-select)))
+ (mpc-select-toggle)))
+
+(defun mdw-mpc-unselect-one ()
+ (when (get-char-property (point) 'mpc-select)
+ (mpc-select-toggle)))
+
+(defun mdw-mpc-select (&optional arg interactivep)
+ (interactive (list current-prefix-arg t))
+ (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one))
+
+(defun mdw-mpc-unselect (&optional arg interactivep)
+ (interactive (list current-prefix-arg t))
+ (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-unselect-one))
+
+(defun mdw-mpc-unselect-backwards (arg)
+ (interactive "p")
+ (mdw-mpc-hack-lines (- arg) t 'mdw-mpc-unselect-one))
+
+(defun mdw-mpc-unselect-all ()
+ (interactive)
+ (setq mpc-select nil)
+ (mpc-selection-refresh))
+
+(defun mdw-mpc-next-line (arg)
+ (interactive "p")
+ (beginning-of-line)
+ (forward-line arg))
+
+(defun mdw-mpc-previous-line (arg)
+ (interactive "p")
+ (beginning-of-line)
+ (forward-line (- arg)))
+
+(defun mdw-mpc-playlist-add (&optional arg interactivep)
+ (interactive (list current-prefix-arg t))
+ (let ((mpc-select mpc-select))
+ (when (or arg (and interactivep (use-region-p)))
+ (setq mpc-select nil)
+ (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one))
+ (setq mpc-select (reverse mpc-select))
+ (mpc-playlist-add)))
+
+(defun mdw-mpc-playlist-delete (&optional arg interactivep)
+ (interactive (list current-prefix-arg t))
+ (setq mpc-select (nreverse mpc-select))
+ (mpc-select-save
+ (when (or arg (and interactivep (use-region-p)))
+ (setq mpc-select nil)
+ (mpc-selection-refresh)
+ (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one))
+ (mpc-playlist-delete)))
+
+(defun mdw-mpc-hack-tagbrowsers ()
+ (setq-local mode-line-format
+ '("%e"
+ mode-line-frame-identification
+ mode-line-buffer-identification)))
+(add-hook 'mpc-tagbrowser-mode-hook 'mdw-mpc-hack-tagbrowsers)
+
+(defun mdw-mpc-hack-songs ()
+ (setq-local header-line-format
+ ;; '("MPC " mpc-volume " " mpc-current-song)
+ (list (propertize " " 'display '(space :align-to 0))
+ ;; 'mpc-songs-format-description
+ '(:eval
+ (let ((deactivate-mark) (hscroll (window-hscroll)))
+ (with-temp-buffer
+ (mpc-format mpc-songs-format 'self hscroll)
+ ;; That would be simpler than the hscroll handling in
+ ;; mpc-format, but currently move-to-column does not
+ ;; recognize :space display properties.
+ ;; (move-to-column hscroll)
+ ;; (delete-region (point-min) (point))
+ (buffer-string)))))))
+(add-hook 'mpc-songs-mode-hook 'mdw-mpc-hack-songs)
+
+(eval-after-load "mpc"
+ '(progn
+ (define-key mpc-mode-map "m" 'mdw-mpc-select)
+ (define-key mpc-mode-map "u" 'mdw-mpc-unselect)
+ (define-key mpc-mode-map "\177" 'mdw-mpc-unselect-backwards)
+ (define-key mpc-mode-map "\e\177" 'mdw-mpc-unselect-all)
+ (define-key mpc-mode-map "n" 'mdw-mpc-next-line)
+ (define-key mpc-mode-map "p" 'mdw-mpc-previous-line)
+ (define-key mpc-mode-map "/" 'mpc-songs-search)
+ (setq mpc-songs-mode-map (make-sparse-keymap))
+ (set-keymap-parent mpc-songs-mode-map mpc-mode-map)
+ (define-key mpc-songs-mode-map "l" 'mpc-playlist)
+ (define-key mpc-songs-mode-map "+" 'mdw-mpc-playlist-add)
+ (define-key mpc-songs-mode-map "-" 'mdw-mpc-playlist-delete)
+ (define-key mpc-songs-mode-map "\r" 'mpc-songs-jump-to)))
;;;--------------------------------------------------------------------------
;;; Inferior Emacs Lisp.