X-Git-Url: https://git.distorted.org.uk/~mdw/profile/blobdiff_plain/28509f06a05e2a8684c65cb79d7590312e657d85..61aab3720fad74e4166c9541df43a46a25b0567f:/el/dot-emacs.el diff --git a/el/dot-emacs.el b/el/dot-emacs.el index 5314fd9..70d3b7a 100644 --- a/el/dot-emacs.el +++ b/el/dot-emacs.el @@ -24,19 +24,23 @@ ;;;-------------------------------------------------------------------------- ;;; Check command-line. +(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")) ;;;-------------------------------------------------------------------------- ;;; Some general utilities. @@ -200,13 +204,16 @@ fringes is not taken out of the allowance for WIDTH, unlike ((>= 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 +224,17 @@ 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 (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 @@ -240,6 +258,7 @@ frame is actually mapped on the screen." (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'. @@ -457,26 +476,52 @@ 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" org-export-docbook-xslt-stylesheet "/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. (defun mdw-clobber-other-windows-showing-buffer (buffer-or-name) @@ -537,7 +582,7 @@ Pretend they don't exist. They might be on other display devices." (defadvice compile (around hack-environment compile activate) "Hack the environment inherited by inferiors in the compilation." - (let ((process-environment process-environment)) + (let ((process-environment (copy-tree process-environment))) (setenv "LD_PRELOAD" nil) ad-do-it)) @@ -717,7 +762,79 @@ Use this to arrange for per-server settings.") 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. @@ -851,6 +968,12 @@ tramp, which seems to get itself into a twist." (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. @@ -884,6 +1007,12 @@ options." (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)) @@ -906,6 +1035,9 @@ If NEW-SESSION-P, start a new session." (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-generic @@ -996,10 +1128,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) @@ -1017,11 +1145,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." @@ -1040,26 +1168,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." @@ -1073,9 +1201,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. @@ -1535,6 +1663,18 @@ doesn't match any of the regular expressions in (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") @@ -1809,7 +1949,7 @@ name, as a symbol." (defvar mdw-c-comment-fill-prefix `((,(concat "\\([ \t]*/?\\)" - "\\(\*\\|//]\\)" + "\\(\\*\\|//\\)" "\\([ \t]*\\)" "\\([A-Za-z]+:[ \t]*\\)?" mdw-hanging-indents) @@ -1944,7 +2084,7 @@ name, as a symbol." "__typeof__" ;GCC "__volatile__" ;GCC )) - (c-constants + (c-builtins (mdw-regexps "false" ;C++, C99 macro "this" ;C++ "true" ;C++, C99 macro @@ -1980,7 +2120,7 @@ name, as a symbol." (list (concat "\\<\\(" c-keywords "\\)\\>") '(0 font-lock-keyword-face)) - (list (concat "\\<\\(" c-constants "\\)\\>") + (list (concat "\\<\\(" c-builtins "\\)\\>") '(0 font-lock-variable-name-face)) ;; Handle numbers too. @@ -2065,22 +2205,35 @@ name, as a symbol." (defun mdw-fontify-java () + ;; Fiddle with some syntax codes. + (modify-syntax-entry ?@ ".") + (modify-syntax-entry ?@ "." font-lock-syntax-table) + ;; Other stuff. (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 @@ -2090,8 +2243,8 @@ name, as a symbol." (list (concat "\\<\\(" java-keywords "\\)\\>") '(0 font-lock-keyword-face)) - ;; Handle the magic constants defined above. - (list (concat "\\<\\(" java-constants "\\)\\>") + ;; Handle the magic builtins defined above. + (list (concat "\\<\\(" java-builtins "\\)\\>") '(0 font-lock-variable-name-face)) ;; Handle numbers too. @@ -2133,11 +2286,8 @@ name, as a symbol." "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"))) @@ -2148,8 +2298,8 @@ name, as a symbol." (list (concat "\\_<\\(" javascript-keywords "\\)\\_>") '(0 font-lock-keyword-face)) - ;; Handle the predefined constants defined above. - (list (concat "\\_<\\(" javascript-constants "\\)\\_>") + ;; Handle the predefined builtins defined above. + (list (concat "\\_<\\(" javascript-builtins "\\)\\_>") '(0 font-lock-variable-name-face)) ;; Handle numbers too. @@ -2216,10 +2366,6 @@ name, as a symbol." "[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))) @@ -2279,7 +2425,7 @@ name, as a symbol." "unsafe" "ushort" "using" "virtual" "void" "volatile" "while" "yield")) - (csharp-constants + (csharp-builtins (mdw-regexps "base" "false" "null" "this" "true"))) (setq font-lock-keywords @@ -2289,8 +2435,8 @@ name, as a symbol." (list (concat "\\<\\(" csharp-keywords "\\)\\>") '(0 font-lock-keyword-face)) - ;; Handle the magic constants defined above. - (list (concat "\\<\\(" csharp-constants "\\)\\>") + ;; Handle the magic builtins defined above. + (list (concat "\\<\\(" csharp-builtins "\\)\\>") '(0 font-lock-variable-name-face)) ;; Handle numbers too. @@ -2504,26 +2650,28 @@ name, as a symbol." (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")) @@ -2533,7 +2681,8 @@ name, as a symbol." "f32" "f64" "i8" "i16" "i32" "i64" "isize" "u8" "u16" "u32" "u64" "usize" - "char" "str"))) + "char" "str" + "self" "Self"))) (setq font-lock-keywords (list @@ -2555,7 +2704,7 @@ name, as a symbol." "\\|" "0o[0-7_]+" "\\|" "0b[01_]+" "\\)" - "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?" + "\\([ui]\\(8\\|16\\|32\\|64\\|size\\)\\)?" "\\)\\_>") '(0 mdw-number-face)) @@ -2719,9 +2868,9 @@ strip numbers instead." '(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_]+\\|[lL]\\|\\)") + (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. @@ -2861,13 +3010,17 @@ strip numbers instead." (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 " 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) + +;;;-------------------------------------------------------------------------- +;;; 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)) + ;;;-------------------------------------------------------------------------- ;;; MPC configuration.