X-Git-Url: https://git.distorted.org.uk/~mdw/profile/blobdiff_plain/a8a7976a2e808307de201c7f14be012d241614a4..bc149706bc4815de68df7401987e75999ae4dcd7:/el/dot-emacs.el diff --git a/el/dot-emacs.el b/el/dot-emacs.el index e898597..a1cba54 100644 --- a/el/dot-emacs.el +++ b/el/dot-emacs.el @@ -57,6 +57,12 @@ This may be at the expense of cool features.") (interactive) (error "wrong button")) +(defun mdw-emacs-version-p (major &optional minor) + "Return non-nil if the running Emacs is at least version MAJOR.MINOR." + (or (> emacs-major-version major) + (and (= emacs-major-version major) + (>= emacs-minor-version (or minor 0))))) + ;; Some error trapping. ;; ;; If individual bits of this file go tits-up, we don't particularly want @@ -189,8 +195,7 @@ fringes is not taken out of the allowance for WIDTH, unlike "Split a wide window into appropriate widths." (interactive "P") (setq width (cond (width (prefix-numeric-value width)) - ((and window-system - (>= emacs-major-version 22)) + ((and window-system (mdw-emacs-version-p 22)) 77) (t 78))) (let* ((win (selected-window)) @@ -226,6 +231,13 @@ frame is actually mapped on the screen." (mdw-advise-to-inhibit-raise-frame select-frame-set-input-focus) +;; Bug fix for markdown-mode, which breaks point positioning during +;; `query-replace'. +(defadvice markdown-check-change-for-wiki-link + (around mdw-save-match activate compile) + "Save match data around the `markdown-mode' `after-change-functions' hook." + (save-match-data ad-do-it)) + ;; Transient mark mode hacks. (defadvice exchange-point-and-mark @@ -247,6 +259,11 @@ it's currently off." ;; Functions for sexp diary entries. +(defun mdw-not-org-mode (form) + "As FORM, but not in Org mode agenda." + (and (not mdw-diary-for-org-mode-p) + (eval form))) + (defun mdw-weekday (l) "Return non-nil if `date' falls on one of the days of the week in L. L is a list of day numbers (from 0 to 6 for Sunday through to @@ -258,6 +275,50 @@ function returns non-nil." (memq (nth d '(sunday monday tuesday wednesday thursday friday saturday)) l)))) +(defun mdw-discordian-date (date) + "Return the Discordian calendar date corresponding to DATE. + +The return value is (YOLD . st-tibs-day) or (YOLD SEASON DAYNUM DOW). + +The original is by David Pearson. I modified it to produce date components +as output rather than a string." + (let* ((days ["Sweetmorn" "Boomtime" "Pungenday" + "Prickle-Prickle" "Setting Orange"]) + (months ["Chaos" "Discord" "Confusion" + "Bureaucracy" "Aftermath"]) + (day-count [0 31 59 90 120 151 181 212 243 273 304 334]) + (year (- (extract-calendar-year date) 1900)) + (month (1- (extract-calendar-month date))) + (day (1- (extract-calendar-day date))) + (julian (+ (aref day-count month) day)) + (dyear (+ year 3066))) + (if (and (= month 1) (= day 28)) + (cons dyear 'st-tibs-day) + (list dyear + (aref months (floor (/ julian 73))) + (1+ (mod julian 73)) + (aref days (mod julian 5)))))) + +(defun mdw-diary-discordian-date () + "Convert the date in `date' to a string giving the Discordian date." + (let* ((ddate (mdw-discordian-date date)) + (tail (format "in the YOLD %d" (car ddate)))) + (if (eq (cdr ddate) 'st-tibs-day) + (format "St Tib's Day %s" tail) + (let ((season (cadr ddate)) + (daynum (caddr ddate)) + (dayname (cadddr ddate))) + (format "%s, the %d%s day of %s %s" + dayname + daynum + (let ((ldig (mod daynum 10))) + (cond ((= ldig 1) "st") + ((= ldig 2) "nd") + ((= ldig 3) "rd") + (t "th"))) + season + tail))))) + (defun mdw-todo (&optional when) "Return non-nil today, or on WHEN, whichever is later." (let ((w (calendar-absolute-from-gregorian (calendar-current-date))) @@ -277,6 +338,34 @@ function returns non-nil." (nth 2 when)))))))) (eq w d))) +(defvar mdw-diary-for-org-mode-p nil) + +(defadvice org-agenda-list (around mdw-preserve-links activate) + (let ((mdw-diary-for-org-mode-p t)) + ad-do-it)) + +(defadvice diary-add-to-list (before mdw-trim-leading-space activate) + "Trim leading space from the diary entry string." + (save-match-data + (let ((str (ad-get-arg 1))) + (ad-set-arg 1 + (cond ((null str) nil) + ((and mdw-diary-for-org-mode-p + (string-match (concat + "^[ \t]*" + "\\(" diary-time-regexp + "\\(-" diary-time-regexp "\\)?" + "\\)[ \t]+") + str)) + (replace-match "\\1 " nil nil str)) + ((string-match "^[ \t]+" str) + (replace-match "" nil nil str)) + ((and (not mdw-diary-for-org-mode-p) + (string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]" + str)) + (replace-match "\\1" nil nil str)) + (t str)))))) + ;; Fighting with Org-mode's evil key maps. (defvar mdw-evil-keymap-keys @@ -444,6 +533,27 @@ so that it can be used for convenient filtering." (setenv "REAL_MOVEMAIL" try)) (setq path (cdr path))))) +;; AUTHINFO GENERIC kludge. + +(defvar nntp-authinfo-generic nil + "Set to the `NNTPAUTH' string to pass on to `authinfo-kludge'. + +Use this to arrange for per-server settings.") + +(defun nntp-open-authinfo-kludge (buffer) + "Open a connection to SERVER using `authinfo-kludge'." + (let ((proc (start-process "nntpd" buffer + "env" (concat "NNTPAUTH=" + (or nntp-authinfo-generic + (getenv "NNTPAUTH") + (error "NNTPAUTH unset"))) + "authinfo-kludge" nntp-address))) + (set-buffer buffer) + (nntp-wait-for-string "^\r*200") + (beginning-of-line) + (delete-region (point-min) (point)) + proc)) + (eval-after-load "erc" '(load "~/.ercrc.el")) @@ -837,11 +947,17 @@ case." (trap (turn-on-font-lock))) (defun mdw-post-local-vars-misc-mode-config () - (when mdw-do-misc-mode-hacking + (when (and mdw-do-misc-mode-hacking + (not buffer-read-only)) (setq show-trailing-whitespace t) (mdw-whitespace-mode 1))) (add-hook 'hack-local-variables-hook 'mdw-post-local-vars-misc-mode-config) +(defadvice toggle-read-only (after mdw-angry-fruit-salad activate) + (when mdw-do-misc-mode-hacking + (setq show-trailing-whitespace (not buffer-read-only)) + (mdw-whitespace-mode (if buffer-read-only 0 1)))) + (eval-after-load 'gtags '(progn (dolist (key '([mouse-2] [mouse-3])) @@ -982,12 +1098,14 @@ doesn't match any of the regular expressions in ;;;-------------------------------------------------------------------------- ;;; General fontification. +(make-face 'mdw-virgin-face) + (defmacro mdw-define-face (name &rest body) "Define a face, and make sure it's actually set as the definition." (declare (indent 1) (debug 0)) `(progn - (make-face ',name) + (copy-face 'mdw-virgin-face ',name) (defvar ,name ',name) (put ',name 'face-defface-spec ',body) (face-spec-set ',name ',body nil))) @@ -1001,7 +1119,7 @@ doesn't match any of the regular expressions in (((type w32)) :family "courier new" :height 85) (((type x)) :family "6x13" :foundry "trad" :height 130) (t :foreground "white" :background "black")) -(if (>= emacs-major-version 23) +(if (mdw-emacs-version-p 23) (mdw-define-face variable-pitch (((type x)) :family "sans" :height 100)) (mdw-define-face variable-pitch @@ -1160,7 +1278,7 @@ doesn't match any of the regular expressions in (t :foreground "SkyBlue1")) (mdw-define-face magit-item-highlight (((type tty)) :background "blue") - (t :background "DarkSeaGreen4")) + (t :background "grey11")) (mdw-define-face magit-log-head-label-remote (((type tty)) :background "cyan" :foreground "green") (t :background "grey11" :foreground "DarkSeaGreen2" :box t)) @@ -1320,69 +1438,82 @@ doesn't match any of the regular expressions in ;; Now define things to be fontified. (make-local-variable 'font-lock-keywords) (let ((c-keywords - (mdw-regexps "and" ;C++ - "and_eq" ;C++ - "asm" ;K&R, GCC - "auto" ;K&R, C89 - "bitand" ;C++ - "bitor" ;C++ - "bool" ;C++, C9X macro - "break" ;K&R, C89 - "case" ;K&R, C89 - "catch" ;C++ - "char" ;K&R, C89 - "class" ;C++ - "complex" ;C9X macro, C++ template type - "compl" ;C++ - "const" ;C89 - "const_cast" ;C++ - "continue" ;K&R, C89 - "defined" ;C89 preprocessor - "default" ;K&R, C89 - "delete" ;C++ - "do" ;K&R, C89 - "double" ;K&R, C89 - "dynamic_cast" ;C++ - "else" ;K&R, C89 - ;; "entry" ;K&R -- never used - "enum" ;C89 - "explicit" ;C++ - "export" ;C++ - "extern" ;K&R, C89 - "float" ;K&R, C89 - "for" ;K&R, C89 - ;; "fortran" ;K&R - "friend" ;C++ - "goto" ;K&R, C89 - "if" ;K&R, C89 - "imaginary" ;C9X macro - "inline" ;C++, C9X, GCC - "int" ;K&R, C89 - "long" ;K&R, C89 - "mutable" ;C++ - "namespace" ;C++ - "new" ;C++ - "operator" ;C++ - "or" ;C++ - "or_eq" ;C++ - "private" ;C++ - "protected" ;C++ - "public" ;C++ - "register" ;K&R, C89 + (mdw-regexps "alignas" ;C11 macro, C++11 + "alignof" ;C++11 + "and" ;C++, C95 macro + "and_eq" ;C++, C95 macro + "asm" ;K&R, C++, GCC + "atomic" ;C11 macro, C++11 template type + "auto" ;K&R, C89 + "bitand" ;C++, C95 macro + "bitor" ;C++, C95 macro + "bool" ;C++, C99 macro + "break" ;K&R, C89 + "case" ;K&R, C89 + "catch" ;C++ + "char" ;K&R, C89 + "char16_t" ;C++11, C11 library type + "char32_t" ;C++11, C11 library type + "class" ;C++ + "complex" ;C99 macro, C++ template type + "compl" ;C++, C95 macro + "const" ;C89 + "constexpr" ;C++11 + "const_cast" ;C++ + "continue" ;K&R, C89 + "decltype" ;C++11 + "defined" ;C89 preprocessor + "default" ;K&R, C89 + "delete" ;C++ + "do" ;K&R, C89 + "double" ;K&R, C89 + "dynamic_cast" ;C++ + "else" ;K&R, C89 + ;; "entry" ;K&R -- never used + "enum" ;C89 + "explicit" ;C++ + "export" ;C++ + "extern" ;K&R, C89 + "float" ;K&R, C89 + "for" ;K&R, C89 + ;; "fortran" ;K&R + "friend" ;C++ + "goto" ;K&R, C89 + "if" ;K&R, C89 + "imaginary" ;C99 macro + "inline" ;C++, C99, GCC + "int" ;K&R, C89 + "long" ;K&R, C89 + "mutable" ;C++ + "namespace" ;C++ + "new" ;C++ + "noexcept" ;C++11 + "noreturn" ;C11 macro + "not" ;C++, C95 macro + "not_eq" ;C++, C95 macro + "nullptr" ;C++11 + "operator" ;C++ + "or" ;C++, C95 macro + "or_eq" ;C++, C95 macro + "private" ;C++ + "protected" ;C++ + "public" ;C++ + "register" ;K&R, C89 "reinterpret_cast" ;C++ - "restrict" ;C9X + "restrict" ;C99 "return" ;K&R, C89 "short" ;K&R, C89 "signed" ;C89 "sizeof" ;K&R, C89 "static" ;K&R, C89 + "static_assert" ;C11 macro, C++11 "static_cast" ;C++ "struct" ;K&R, C89 "switch" ;K&R, C89 "template" ;C++ "throw" ;C++ "try" ;C++ - "this" ;C++ + "thread_local" ;C11 macro, C++11 "typedef" ;C89 "typeid" ;C++ "typeof" ;GCC @@ -1395,12 +1526,19 @@ doesn't match any of the regular expressions in "volatile" ;C89 "wchar_t" ;C++, C89 library type "while" ;K&R, C89 - "xor" ;C++ - "xor_eq" ;C++ - "_Bool" ;C9X - "_Complex" ;C9X - "_Imaginary" ;C9X - "_Pragma" ;C9X preprocessor + "xor" ;C++, C95 macro + "xor_eq" ;C++, C95 macro + "_Alignas" ;C11 + "_Alignof" ;C11 + "_Atomic" ;C11 + "_Bool" ;C99 + "_Complex" ;C99 + "_Generic" ;C11 + "_Imaginary" ;C99 + "_Noreturn" ;C11 + "_Pragma" ;C99 preprocessor + "_Static_assert" ;C11 + "_Thread_local" ;C11 "__alignof__" ;GCC "__asm__" ;GCC "__attribute__" ;GCC @@ -1416,9 +1554,9 @@ doesn't match any of the regular expressions in "__volatile__" ;GCC )) (c-constants - (mdw-regexps "false" ;C++, C9X macro + (mdw-regexps "false" ;C++, C99 macro "this" ;C++ - "true" ;C++, C9X macro + "true" ;C++, C99 macro )) (preprocessor-keywords (mdw-regexps "assert" "define" "elif" "else" "endif" "error" @@ -2110,6 +2248,8 @@ doesn't match any of the regular expressions in ;; Perl indentation style. +(setq perl-indent-level 2) + (setq cperl-indent-level 2) (setq cperl-continued-statement-offset 2) (setq cperl-continued-brace-offset 0) @@ -2704,6 +2844,10 @@ strip numbers instead." (modify-syntax-entry ?$ "." font-lock-syntax-table) (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) + (setq indent-tabs-mode nil) + ;; Set fill prefix. (mdw-standard-fill-prefix "\\([ \t]*%+[ \t]*\\)")