chiark / gitweb /
Merge remote-tracking branch 'staging'
[profile] / el / dot-emacs.el
index 769686c0f261662f8f83b3b896a50b1e6ba21178..001fa2947f96129ee1ec14f238fa220b015ae338 100644 (file)
@@ -200,13 +200,16 @@ (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))
-                    mdw-column-width)
-                   (t (1+ mdw-column-width))))
+  (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)
@@ -217,6 +220,17 @@ (defun mdw-divvy-window (&optional width)
       (other-window 1))
     (select-window win)))
 
+(defun mdw-set-frame-width (columns &optional width)
+  (interactive "nColumns: 
+P")
+  (setq width (if width (prefix-numeric-value width)
+               (mdw-preferred-column-width)))
+  (let ((sb-width (mdw-horizontal-window-overhead)))
+    (set-frame-width (selected-frame)
+                    (- (* columns (+ width sb-width))
+                       sb-width))
+    (mdw-divvy-window width)))
+
 ;; Don't raise windows unless I say so.
 
 (defvar mdw-inhibit-raise-frame nil
@@ -457,20 +471,40 @@     (define-key keymap key nil))
        (dolist (key replacements)
          (define-key keymap key binding))))))
 
-(eval-after-load "org-latex"
-  '(progn
-     (push '("strayman"
-            "\\documentclass{strayman}
+(defvar 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}"))))
+
+(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-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"
@@ -514,6 +548,114 @@ (defadvice display-buffer (before mdw-inhibit-other-frames activate)
 Pretend they don't exist.  They might be on other display devices."
   (ad-set-arg 2 nil))
 
+;;;--------------------------------------------------------------------------
+;;; 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 "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 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 (plusp (logand prefix #x54))
+                   (read-directory-name "Compile in directory: "))))
+     (list (if (or compilation-read-command
+                  (plusp (logand prefix #x42)))
+              (compilation-read-command command)
+            command)
+          dir
+          (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))
+      (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
+           (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.
 
@@ -609,7 +751,79 @@ (defun nntp-open-authinfo-kludge (buffer)
     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)
+    (block nil
+      (while (not (eobp))
+       (while (not (looking-at "\\* [0-9]+ FETCH"))
+         (delete-region (point) (progn (forward-line 1) (point)))
+         (when (eobp)
+           (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" (mm-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)))
 
 ;;;--------------------------------------------------------------------------
 ;;; Utility functions.
@@ -798,8 +1012,12 @@ (defun mdw-w3m-browse-url (url &optional new-session-p)
            (w3m-browse-url url new-session-p))
        (select-window window)))))
 
+(eval-after-load 'w3m
+  '(define-key w3m-mode-map [?\e ?\r] 'w3m-view-this-url-new-session))
+
 (defvar mdw-good-url-browsers
-  '(browse-url-mozilla
+  '(browse-url-chromium
+    browse-url-mozilla
     browse-url-generic
     (w3m . mdw-w3m-browse-url)
     browse-url-w3)
@@ -888,10 +1106,6 @@ (defvar mdw-hanging-indents
   "*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))
-
 ;; Utility functions.
 
 (defun mdw-maybe-tabify (s)
@@ -909,11 +1123,11 @@ (defun mdw-examine-fill-prefixes (l)
 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)))))
+       ((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-maybe-car (p)
   "If P is a pair, return (car P), otherwise just return P."
@@ -932,26 +1146,26 @@ (defun mdw-do-prefix-match (m)
   "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-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."
@@ -965,9 +1179,9 @@ (defun mdw-standard-fill-prefix (rx &optional mat)
 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))))))
+       `((,(concat rx mdw-hanging-indents)
+          (match . 1)
+          (pad . ,(or mat 2))))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Other common declarations.
@@ -992,8 +1206,7 @@ (defun mdw-misc-mode-config ()
   (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))))
@@ -1081,62 +1294,6 @@ (defun mdw-last-one-out-turn-off-the-lights (frame)
       (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.
 
@@ -1202,16 +1359,15 @@ (if (mdw-emacs-version-p 23)
   (mdw-define-face variable-pitch
     (((type x)) :family "helvetica" :height 90)))
 (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 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
@@ -1230,14 +1386,15 @@ (mdw-define-face scroll-bar
 (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 holiday-face
@@ -1267,7 +1424,8 @@ (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)
@@ -1286,78 +1444,102 @@ (mdw-define-face font-lock-reference-face
 (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"))
+  (((min-colors 64)) :slant italic :foreground "SeaGreen1")
+  (((class color)) :foreground "green")
+  (t :weight bold))
 (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-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 message-separator
   (t :background "red" :foreground "white" :weight bold))
 (mdw-define-face message-cited-text
   (default :slant italic)
-  (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
+  (((min-colors 64)) :foreground "SkyBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face message-header-cc
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-newsgroups
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-subject
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-to
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-xheader
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-other
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face message-header-name
   (default :weight bold)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((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)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-subject
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-from
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-to
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-header-content
   (default :slant italic)
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 
 (mdw-define-face gnus-cite-1
-  (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1"))
+  (((min-colors 64)) :foreground "SkyBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face gnus-cite-2
-  (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
+  (((min-colors 64)) :foreground "RoyalBlue2")
+  (((class color)) :foreground "blue"))
 (mdw-define-face gnus-cite-3
-  (((type tty)) :foreground "magenta") (t :foreground "MediumOrchid"))
+  (((min-colors 64)) :foreground "MediumOrchid")
+  (((class color)) :foreground "magenta"))
 (mdw-define-face gnus-cite-4
-  (((type tty)) :foreground "red") (t :foreground "firebrick2"))
+  (((min-colors 64)) :foreground "firebrick2")
+  (((class color)) :foreground "red"))
 (mdw-define-face gnus-cite-5
-  (((type tty)) :foreground "yellow") (t :foreground "burlywood2"))
+  (((min-colors 64)) :foreground "burlywood2")
+  (((class color)) :foreground "yellow"))
 (mdw-define-face gnus-cite-6
-  (((type tty)) :foreground "green") (t :foreground "SeaGreen1"))
+  (((min-colors 64)) :foreground "SeaGreen1")
+  (((class color)) :foreground "green"))
 (mdw-define-face gnus-cite-7
-  (((type tty)) :foreground "cyan") (t :foreground "SlateBlue1"))
+  (((min-colors 64)) :foreground "SlateBlue1")
+  (((class color)) :foreground "cyan"))
 (mdw-define-face gnus-cite-8
-  (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2"))
+  (((min-colors 64)) :foreground "RoyalBlue2")
+  (((class color)) :foreground "blue"))
 (mdw-define-face gnus-cite-9
-  (((type tty)) :foreground "magenta") (t :foreground "purple2"))
+  (((min-colors 64)) :foreground "purple2")
+  (((class color)) :foreground "magenta"))
 (mdw-define-face gnus-cite-10
-  (((type tty)) :foreground "red") (t :foreground "DarkOrange2"))
+  (((min-colors 64)) :foreground "DarkOrange2")
+  (((class color)) :foreground "red"))
 (mdw-define-face gnus-cite-11
   (t :foreground "grey"))
 
@@ -1368,98 +1550,113 @@ (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
-  (((class color) (type x)) :background "#500")
+  (((min-colors 64)) :background "#500")
   (t :underline t))
 (mdw-define-face diff-refine-added
-  (((class color) (type x)) :background "#050")
+  (((min-colors 64)) :background "#050")
   (t :underline t))
 
 (setq ediff-force-faces t)
 (mdw-define-face ediff-current-diff-A
-  (((class color) (type x)) :background "darkred")
-  (((class color) (type tty)) :background "red")
+  (((min-colors 64)) :background "darkred")
+  (((class color)) :background "red")
   (t :inverse-video t))
 (mdw-define-face ediff-fine-diff-A
-  (((class color) (type x)) :background "red3")
-  (((class color) (type tty)) :inverse-video t)
+  (((min-colors 64)) :background "red3")
+  (((class color)) :inverse-video t)
   (t :inverse-video nil))
 (mdw-define-face ediff-even-diff-A
-  (((class color) (type x)) :background "#300"))
+  (((min-colors 64)) :background "#300"))
 (mdw-define-face ediff-odd-diff-A
-  (((class color) (type x)) :background "#300"))
+  (((min-colors 64)) :background "#300"))
 (mdw-define-face ediff-current-diff-B
-  (((class color) (type x)) :background "darkgreen")
-  (((class color) (type tty)) :background "magenta")
+  (((min-colors 64)) :background "darkgreen")
+  (((class color)) :background "magenta")
   (t :inverse-video t))
 (mdw-define-face ediff-fine-diff-B
-  (((class color) (type x)) :background "green4")
-  (((class color) (type tty)) :inverse-video t)
+  (((min-colors 64)) :background "green4")
+  (((class color)) :inverse-video t)
   (t :inverse-video nil))
 (mdw-define-face ediff-even-diff-B
-  (((class color) (type x)) :background "#020"))
+  (((min-colors 64)) :background "#020"))
 (mdw-define-face ediff-odd-diff-B
-  (((class color) (type x)) :background "#020"))
+  (((min-colors 64)) :background "#020"))
 (mdw-define-face ediff-current-diff-C
-  (((class color) (type x)) :background "darkblue")
-  (((class color) (type tty)) :background "blue")
+  (((min-colors 64)) :background "darkblue")
+  (((class color)) :background "blue")
   (t :inverse-video t))
 (mdw-define-face ediff-fine-diff-C
-  (((class color) (type x)) :background "blue1")
-  (((class color) (type tty)) :inverse-video t)
+  (((min-colors 64)) :background "blue1")
+  (((class color)) :inverse-video t)
   (t :inverse-video nil))
 (mdw-define-face ediff-even-diff-C
-  (((class color) (type x)) :background "#004"))
+  (((min-colors 64)) :background "#004"))
 (mdw-define-face ediff-odd-diff-C
-  (((class color) (type x)) :background "#004"))
+  (((min-colors 64)) :background "#004"))
 (mdw-define-face ediff-current-diff-Ancestor
-  (((class color) (type x)) :background "#630")
-  (((class color) (type tty)) :background "blue")
+  (((min-colors 64)) :background "#630")
+  (((class color)) :background "blue")
   (t :inverse-video t))
 (mdw-define-face ediff-even-diff-Ancestor
-  (((class color) (type x)) :background "#320"))
+  (((min-colors 64)) :background "#320"))
 (mdw-define-face ediff-odd-diff-Ancestor
-  (((class color) (type x)) :background "#320"))
+  (((min-colors 64)) :background "#320"))
 
 (mdw-define-face magit-hash
-  (((class color) (type x)) :foreground "grey40")
-  (((class color) (type tty)) :foreground "blue"))
+  (((min-colors 64)) :foreground "grey40")
+  (((class color)) :foreground "blue"))
 (mdw-define-face magit-diff-hunk-heading
-  (((class color) (type x)) :foreground "grey70" :background "grey25")
-  (((class color) (type tty)) :foreground "yellow"))
+  (((min-colors 64)) :foreground "grey70" :background "grey25")
+  (((class color)) :foreground "yellow"))
 (mdw-define-face magit-diff-hunk-heading-highlight
-  (((class color) (type x)) :foreground "grey70" :background "grey35")
-  (((class color) (type tty)) :foreground "yellow" :background "blue"))
+  (((min-colors 64)) :foreground "grey70" :background "grey35")
+  (((class color)) :foreground "yellow" :background "blue"))
 (mdw-define-face magit-diff-added
-  (((class color) (type x)) :foreground "#ddffdd" :background "#335533")
-  (((class color) (type tty)) :foreground "green"))
+  (((min-colors 64)) :foreground "#ddffdd" :background "#335533")
+  (((class color)) :foreground "green"))
 (mdw-define-face magit-diff-added-highlight
-  (((class color) (type x)) :foreground "#cceecc" :background "#336633")
-  (((class color) (type tty)) :foreground "green" :background "blue"))
+  (((min-colors 64)) :foreground "#cceecc" :background "#336633")
+  (((class color)) :foreground "green" :background "blue"))
 (mdw-define-face magit-diff-removed
-  (((class color) (type x)) :foreground "#ffdddd" :background "#553333")
-  (((class color) (type tty)) :foreground "red"))
+  (((min-colors 64)) :foreground "#ffdddd" :background "#553333")
+  (((class color)) :foreground "red"))
 (mdw-define-face magit-diff-removed-highlight
-  (((class color) (type x)) :foreground "#eecccc" :background "#663333")
-  (((class color) (type tty)) :foreground "red" :background "blue"))
+  (((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
-  (((class color) (type x)) :background "NavyBlue")
-  (t :background "blue"))
+  (((min-colors 64)) :background "NavyBlue")
+  (((class color)) :background "blue"))
 
 (mdw-define-face erc-input-face
   (t :foreground "red"))
@@ -1526,6 +1723,84 @@ (let ((dollar (make-glyph-code ?$ 'mdw-ellipsis-face))
                          (vector dot dot dot))
   (set-display-table-slot standard-display-table 5 bar))
 
+;;;--------------------------------------------------------------------------
+;;; Where is point?
+
+(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))
+
+(defvar mdw-point-overlay-fringe-display '(vertical-bar . vertical-bar))
+
+(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))
+
+(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)
+  (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
+         (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))))
+
 ;;;--------------------------------------------------------------------------
 ;;; C programming configuration.
 
@@ -1839,6 +2114,10 @@ (defun mdw-fontify-c-and-c++ ()
           (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)
+
 ;;;--------------------------------------------------------------------------
 ;;; AP calc mode.
 
@@ -2377,13 +2656,13 @@ (defun mdw-fontify-rust ()
          (list
 
           ;; Handle the keywords defined above.
-          (list (concat "\\<\\(" rust-keywords "\\)\\>")
+          (list (concat "\\_<\\(" rust-keywords "\\)\\_>")
                 '(0 font-lock-keyword-face))
-          (list (concat "\\<\\(" rust-builtins "\\)\\>")
+          (list (concat "\\_<\\(" rust-builtins "\\)\\_>")
                 '(0 font-lock-variable-name-face))
 
           ;; Handle numbers too.
-          (list (concat "\\<\\("
+          (list (concat "\\_<\\("
                               "[0-9][0-9_]*"
                               "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+"
                               "\\|" "\\.[0-9_]+"
@@ -2395,7 +2674,7 @@ (defun mdw-fontify-rust ()
                               "\\|" "0b[01_]+"
                               "\\)"
                               "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?"
-                        "\\)\\>")
+                        "\\)\\_>")
                 '(0 mdw-number-face))
 
           ;; And anything else is punctuation.
@@ -2580,12 +2859,20 @@ (defun mdw-fontify-python ()
 (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"
+               "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))
+
 ;;;--------------------------------------------------------------------------
 ;;; Lua programming style.
 
@@ -3108,7 +3395,7 @@ (defun mdw-fontify-tex ()
   (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.
@@ -3184,6 +3471,9 @@ (eval-after-load 'font-latex
           (unless modified
             (restore-buffer-modified-p nil)))))))
 
+(setq LaTeX-syntactic-comments nil
+      LaTeX-fill-break-at-separators '(\\\[))
+
 ;;;--------------------------------------------------------------------------
 ;;; SGML hacking.
 
@@ -3344,6 +3634,9 @@ (mdw-define-face eshell-ls-directory (t :foreground "cyan" :weight bold))
 (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.
 
@@ -3607,6 +3900,15 @@ (defun comint-send-and-indent ()
   (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 mdw-setup-m4 ()
 
   ;; Inexplicably, Emacs doesn't match braces in m4 mode.  This is very
@@ -3627,6 +3929,9 @@ (defun mdw-text-mode ()
    "\\([ \t]*\\([>#|:] ?\\)*[ \t]*\\)" 3)
   (auto-fill-mode 1))
 
+(eval-after-load "flyspell"
+  '(define-key flyspell-mode-map "\C-\M-i" nil))
+
 ;;;--------------------------------------------------------------------------
 ;;; Outline and hide/show modes.
 
@@ -3686,13 +3991,25 @@ (defadvice term-exec (before program-args-list compile activate)
          (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 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 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 "
+  "env GIT_PAGER=cat git grep --no-color -nH -e "
   "*The default command for \\[git-grep].")
 
 (defvar git-grep-history nil)
@@ -3702,7 +4019,8 @@ (defun git-grep (command-args)
   (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.
@@ -3733,6 +4051,10 @@ (eval-after-load "magit"
                           magit-revision-mode-refresh-popup))
            (magit-define-popup-switch popup ?R "Reverse diff" "-R"))))
 
+(defadvice magit-wip-commit-buffer-file
+    (around mdw-just-this-buffer activate compile)
+  (let ((magit-save-repository-buffers nil)) ad-do-it))
+
 (setq magit-repolist-columns
       '(("Name" 16 magit-repolist-column-ident nil)
        ("Version" 18 magit-repolist-column-version nil)
@@ -3766,15 +4088,17 @@ (defun mdw-repolist-column-unpushed-to-upstream (_id)
           (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)
+
 ;;;--------------------------------------------------------------------------
 ;;; MPC configuration.
 
-(defun mdw-mpc-play-or-pause ()
-  (interactive)
-  (require 'mpc)
-  (if (member (cdr (assq 'state (mpc-cmd-status))) '("play"))
-      (mpc-pause)
-    (mpc-play)))
+(eval-when-compile (trap (require 'mpc)))
 
 (setq mpc-browser-tags '(Artist|Composer|Performer Album|Playlist))
 
@@ -3820,9 +4144,33 @@ (defun mdw-mpc-now-playing ()
          (t
           (message "mpd in unknown state `%s'" state)))))
 
-(autoload 'mpc-pause "mpc")
-(autoload 'mpc-next "mpc")
-(autoload 'mpc-prev "mpc")
+(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))
@@ -3852,7 +4200,8 @@ (defun mdw-mpc-hack-lines (arg interactivep func)
               (decf n)))))))
 
 (defun mdw-mpc-select-one ()
-  (unless (get-char-property (point) 'mpc-select)
+  (when (and (get-char-property (point) 'mpc-file)
+            (not (get-char-property (point) 'mpc-select)))
     (mpc-select-toggle)))
 
 (defun mdw-mpc-unselect-one ()
@@ -3861,18 +4210,15 @@ (defun mdw-mpc-unselect-one ()
 
 (defun mdw-mpc-select (&optional arg interactivep)
   (interactive (list current-prefix-arg t))
-  (mdw-mpc-hack-lines arg interactivep 'mdw-mpc-select-one)
-  (mpc-selection-refresh))
+  (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)
-  (mpc-selection-refresh))
+  (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)
-  (mpc-selection-refresh))
+  (mdw-mpc-hack-lines (- arg) t 'mdw-mpc-unselect-one))
 
 (defun mdw-mpc-unselect-all ()
   (interactive)
@@ -3889,6 +4235,49 @@ (defun mdw-mpc-previous-line (arg)
   (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)
@@ -3897,11 +4286,13 @@      (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 "+" 'mpc-playlist-add)
-     (define-key mpc-songs-mode-map "-" 'mpc-playlist-delete)))
+     (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.