X-Git-Url: https://git.distorted.org.uk/~mdw/profile/blobdiff_plain/60c22e1bb67d984e0c897e0970aca35620e6ceb8..fbc946b7cb685bb47268f036e7fb4ed58ad19cbe:/el/dot-emacs.el diff --git a/el/dot-emacs.el b/el/dot-emacs.el index 80fc05a..17ca3bb 100644 --- a/el/dot-emacs.el +++ b/el/dot-emacs.el @@ -217,6 +217,19 @@ fringes is not taken out of the allowance for WIDTH, unlike (other-window 1)) (select-window win))) +(defun mdw-set-frame-width (columns &optional width) + (interactive "nColumns: +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)))) + (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 +470,40 @@ Evil key bindings are defined in `mdw-evil-keymap-keys'." (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" @@ -515,6 +548,114 @@ 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. (define-derived-mode mdwmail-mode mail-mode "[mdw] mail" @@ -609,7 +750,7 @@ Use this to arrange for per-server settings.") proc)) (eval-after-load "erc" - '(load "~/.ercrc.el")) + '(load "~/.ercrc.el")) ;;;-------------------------------------------------------------------------- ;;; Utility functions. @@ -768,6 +909,17 @@ options." (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))) + +(eval-after-load "dired" + '(define-key dired-mode-map "X" 'mdw-dired-run)) + ;;;-------------------------------------------------------------------------- ;;; URL viewing. @@ -788,7 +940,8 @@ If NEW-SESSION-P, start a new session." (select-window window))))) (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) @@ -877,10 +1030,6 @@ It in turn is a list of things: "*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) @@ -898,11 +1047,11 @@ This is mainly useful in `auto-fill-mode'.") 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." @@ -921,26 +1070,26 @@ at the start of a line, and match data must be saved." "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." @@ -954,9 +1103,9 @@ 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)))))) + `((,(concat rx mdw-hanging-indents) + (match . 1) + (pad . ,(or mat 2)))))) ;;;-------------------------------------------------------------------------- ;;; Other common declarations. @@ -981,8 +1130,7 @@ case." (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)))) @@ -1071,62 +1219,6 @@ doesn't match any of the regular expressions in (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 @@ -1191,16 +1283,15 @@ doesn't match any of the regular expressions in (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 @@ -1219,14 +1310,15 @@ doesn't match any of the regular expressions in (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 @@ -1239,6 +1331,9 @@ doesn't match any of the regular expressions in (mdw-define-face comint-highlight-input (t nil)) +(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 @@ -1253,7 +1348,8 @@ doesn't match any of the regular expressions in (((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) @@ -1272,78 +1368,102 @@ doesn't match any of the regular expressions in (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")) @@ -1354,76 +1474,113 @@ doesn't match any of the regular expressions in (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 + (((min-colors 64)) :foreground "grey40") + (((class color)) :foreground "blue")) +(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 - (((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")) @@ -1491,6 +1648,84 @@ doesn't match any of the regular expressions in (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. ;; Make C indentation nice. @@ -1803,6 +2038,10 @@ name, as a symbol." (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. @@ -2341,13 +2580,13 @@ name, as a symbol." (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_]+" @@ -2359,7 +2598,7 @@ name, as a symbol." "\\|" "0b[01_]+" "\\)" "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?" - "\\)\\>") + "\\)\\_>") '(0 mdw-number-face)) ;; And anything else is punctuation. @@ -2544,12 +2783,20 @@ strip numbers instead." (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. @@ -3072,7 +3319,7 @@ strip numbers instead." (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. @@ -3148,6 +3395,9 @@ strip numbers instead." (unless modified (restore-buffer-modified-p nil))))))) +(setq LaTeX-syntactic-comments nil + LaTeX-fill-break-at-separators '(\\\[)) + ;;;-------------------------------------------------------------------------- ;;; SGML hacking. @@ -3308,6 +3558,9 @@ that character only to be normal punctuation.") (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. @@ -3571,6 +3824,15 @@ that character only to be normal punctuation.") (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 @@ -3591,6 +3853,9 @@ that character only to be normal punctuation.") "\\([ \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. @@ -3650,6 +3915,18 @@ This allows you to pass a list of arguments through `ansi-term'." (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: ") @@ -3668,8 +3945,12 @@ This allows you to pass a list of arguments through `ansi-term'." git-grep-command 'git-grep-history))) (grep command-args)) +;;;-------------------------------------------------------------------------- +;;; Magit configuration. + (setq magit-diff-refine-hunk 'all 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 "") @@ -3679,12 +3960,24 @@ This allows you to pass a list of arguments through `ansi-term'." (magit-wip-after-apply-mode 1) (magit-wip-before-change-mode 1) (add-to-list 'magit-no-confirm 'safe-with-wip) + (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")))) +(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) @@ -3718,6 +4011,212 @@ there is sadness." (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. + +(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 ((minusp n) + (unless (bolp) + (beginning-of-line) + (funcall func) + (incf n)) + (while (minusp n) + (forward-line -1) + (funcall func) + (incf n))) + (t + (beginning-of-line) + (while (plusp n) + (funcall func) + (forward-line) + (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.