X-Git-Url: https://git.distorted.org.uk/~mdw/profile/blobdiff_plain/cd07f97f522053f9adf2901967e2b7f5596f1cf5..22e3f2873ee1856f0416f777cf2c625c5e4ddd2d:/el/dot-emacs.el diff --git a/el/dot-emacs.el b/el/dot-emacs.el index 2909fdd..d883666 100644 --- a/el/dot-emacs.el +++ b/el/dot-emacs.el @@ -52,6 +52,17 @@ This may be at the expense of cool features.") (debug 0)) `',(make-regexp list)) +(defun mdw-wrong () + "This is not the key sequence you're looking for." + (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 @@ -91,6 +102,14 @@ This may be at the expense of cool features.") (concat "(" (buffer-string) ")"))))))) (cdr (assq sym mdw-config))) +;; Local variables hacking. + +(defun run-local-vars-mode-hook () + "Run a hook for the major-mode after local variables have been processed." + (run-hooks (intern (concat (symbol-name major-mode) + "-local-variables-hook")))) +(add-hook 'hack-local-variables-hook 'run-local-vars-mode-hook) + ;; Set up the load path convincingly. (dolist (dir (append (and (boundp 'debian-emacs-flavor) @@ -176,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)) @@ -190,6 +208,62 @@ fringes is not taken out of the allowance for WIDTH, unlike (other-window 1)) (select-window win))) +;; Don't raise windows unless I say so. + +(defvar mdw-inhibit-raise-frame nil + "*Whether `raise-frame' should do nothing when the frame is mapped.") + +(defadvice raise-frame + (around mdw-inhibit (&optional frame) activate compile) + "Don't actually do anything if `mdw-inhibit-raise-frame' is true, and the +frame is actually mapped on the screen." + (if mdw-inhibit-raise-frame + (make-frame-visible frame) + ad-do-it)) + +(defmacro mdw-advise-to-inhibit-raise-frame (function) + "Advise the FUNCTION not to raise frames, even if it wants to." + `(defadvice ,function + (around mdw-inhibit-raise (&rest hunoz) activate compile) + "Don't raise the window unless you have to." + (let ((mdw-inhibit-raise-frame t)) + ad-do-it))) + +(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)) + +;; Bug fix for `bbdb-canonicalize-address': on Emacs 24, `run-hook-with-args' +;; always returns nil, with the result that all email addresses are lost. +;; Replace the function entirely. +(defadvice bbdb-canonicalize-address + (around mdw-bug-fix activate compile) + "Don't use `run-hook-with-args', because that doesn't work." + (let ((net (ad-get-arg 0))) + + ;; Make sure this is a proper hook list. + (if (functionp bbdb-canonicalize-net-hook) + (setq bbdb-canonicalize-net-hook (list bbdb-canonicalize-net-hook))) + + ;; Iterate over the hooks until things converge. + (let ((donep nil)) + (while (not donep) + (let (next (changep nil) + hook (hooks bbdb-canonicalize-net-hook)) + (while hooks + (setq hook (pop hooks)) + (setq next (funcall hook net)) + (if (not (equal next net)) + (setq changep t + net next))) + (setq donep (not changep))))) + (setq ad-return-value net))) + ;; Transient mark mode hacks. (defadvice exchange-point-and-mark @@ -211,6 +285,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 @@ -222,6 +301,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))) @@ -241,6 +364,52 @@ 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 compile activate) + "Trim leading space from the diary entry string." + (save-match-data + (let ((str (ad-get-arg 1)) + (done nil) old) + (while (not done) + (setq old str) + (setq str (cond ((null str) nil) + ((string-match "\\(^\\|\n\\)[ \t]+" str) + (replace-match "\\1" nil nil str)) + ((and mdw-diary-for-org-mode-p + (string-match (concat + "\\(^\\|\n\\)" + "\\(" diary-time-regexp + "\\(-" diary-time-regexp "\\)?" + "\\)" + "\\(\t[ \t]*\\| [ \t]+\\)") + str)) + (replace-match "\\1\\2 " nil nil str)) + ((and (not mdw-diary-for-org-mode-p) + (string-match "\\[\\[[^][]*]\\[\\([^][]*\\)]]" + str)) + (replace-match "\\1" nil nil str)) + (t str))) + (if (equal str old) (setq done t))) + (ad-set-arg 1 str)))) + +(defadvice org-bbdb-anniversaries (after mdw-fixup-list compile activate) + "Return a string rather than a list." + (with-temp-buffer + (let ((anyp nil)) + (dolist (e (let ((ee ad-return-value)) + (if (atom ee) (list ee) ee))) + (when e + (when anyp (insert ?\n)) + (insert e) + (setq anyp t))) + (setq ad-return-value + (and anyp (buffer-string)))))) + ;; Fighting with Org-mode's evil key maps. (defvar mdw-evil-keymap-keys @@ -298,6 +467,43 @@ Evil key bindings are defined in `mdw-evil-keymap-keys'." org-export-docbook-xslt-stylesheet "/usr/share/xml/docbook/stylesheet/docbook-xsl/fo/docbook.xsl") +;; Some hacks to do with window placement. + +(defun mdw-clobber-other-windows-showing-buffer (buffer-or-name) + "Arrange that no windows on other frames are showing BUFFER-OR-NAME." + (interactive "bBuffer: ") + (let ((home-frame (selected-frame)) + (buffer (get-buffer buffer-or-name)) + (safe-buffer (get-buffer "*scratch*"))) + (mapc (lambda (frame) + (or (eq frame home-frame) + (mapc (lambda (window) + (and (eq (window-buffer window) buffer) + (set-window-buffer window safe-buffer))) + (window-list frame)))) + (frame-list)))) + +(defvar mdw-inhibit-walk-windows nil + "If non-nil, then `walk-windows' does nothing. +This is used by advice on `switch-to-buffer-other-frame' to inhibit finding +buffers in random frames.") + +(defadvice walk-windows (around mdw-inhibit activate) + "If `mdw-inhibit-walk-windows' is non-nil, then do nothing." + (and (not mdw-inhibit-walk-windows) + ad-do-it)) + +(defadvice switch-to-buffer-other-frame + (around mdw-always-new-frame activate) + "Always make a new frame. +Even if an existing window in some random frame looks tempting." + (let ((mdw-inhibit-walk-windows t)) ad-do-it)) + +(defadvice display-buffer (before mdw-inhibit-other-frames activate) + "Don't try to do anything fancy with other frames. +Pretend they don't exist. They might be on other display devices." + (ad-set-arg 2 nil)) + ;;;-------------------------------------------------------------------------- ;;; Mail and news hacking. @@ -371,6 +577,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")) @@ -550,10 +777,10 @@ If NEW-SESSION-P, start a new session." (select-window window))))) (defvar mdw-good-url-browsers - '(browse-url-generic + '(browse-url-mozilla + browse-url-generic (w3m . mdw-w3m-browse-url) - browse-url-w3 - browse-url-mozilla) + browse-url-w3) "List of good browsers for mdw-good-url-browsers. Each item is a browser function name, or a cons (CHECK . FUNC). A symbol FOO stands for (FOO . FOO).") @@ -647,13 +874,13 @@ This is mainly useful in `auto-fill-mode'.") (defun mdw-maybe-tabify (s) "Tabify or untabify the string S, according to `indent-tabs-mode'." - (with-temp-buffer - (save-match-data - (let ((tabfun (if indent-tabs-mode #'tabify #'untabify))) + (let ((tabfun (if indent-tabs-mode #'tabify #'untabify))) + (with-temp-buffer + (save-match-data (insert s "\n") (let ((start (point-min)) (end (point-max))) - (funcall tabfun start end) - (setq s (buffer-substring start (1- end)))))))) + (funcall tabfun (point-min) (point-max)) + (setq s (buffer-substring (point-min) (1- (point-max))))))))) (defun mdw-examine-fill-prefixes (l) "Given a list of dynamic fill prefixes, pick one which matches @@ -737,6 +964,8 @@ case." (whitespace-mode arg)) (setq show-trailing-whitespace whitespace-mode))) +(defvar mdw-do-misc-mode-hacking nil) + (defun mdw-misc-mode-config () (and mdw-auto-indent (cond ((eq major-mode 'lisp-mode) @@ -746,24 +975,42 @@ case." nil) (t (local-set-key "\C-m" 'newline-and-indent)))) + (set (make-local-variable 'mdw-do-misc-mode-hacking) t) (local-set-key [C-return] 'newline) (make-local-variable 'page-delimiter) (setq page-delimiter "\f\\|^.*-\\{6\\}.*$") (setq comment-column 40) (auto-fill-mode 1) (setq fill-column 77) - (setq show-trailing-whitespace t) - (mdw-whitespace-mode 1) (and (fboundp 'gtags-mode) (gtags-mode)) (if (fboundp 'hs-minor-mode) - (hs-minor-mode t) + (trap (hs-minor-mode t)) (outline-minor-mode t)) (reveal-mode t) (trap (turn-on-font-lock))) -(defun mdw-post-config-mode-hack () - (mdw-whitespace-mode 1)) +(defun mdw-post-local-vars-misc-mode-config () + (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) + +(defmacro mdw-advise-update-angry-fruit-salad (&rest funcs) + `(progn ,@(mapcar (lambda (func) + `(defadvice ,func + (after mdw-angry-fruit-salad activate) + (when mdw-do-misc-mode-hacking + (setq show-trailing-whitespace + (not buffer-read-only)) + (mdw-whitespace-mode (if buffer-read-only 0 1))))) + funcs))) +(mdw-advise-update-angry-fruit-salad toggle-read-only + read-only-mode + view-mode + view-mode-enable + view-mode-disable) (eval-after-load 'gtags '(progn @@ -812,14 +1059,107 @@ 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 + '((menu-bar-lines . 0) + ;(vertical-scroll-bars . nil) + ) + "Frame parameters to set when making a frame fullscreen.") + +(defvar mdw-full-screen-save + '(width height) + "Extra frame parameters to save when setting fullscreen.") + +(defun mdw-toggle-full-screen (&optional frame) + "Show the FRAME fullscreen." + (interactive) + (when window-system + (cond ((frame-parameter frame 'fullscreen) + (set-frame-parameter frame 'fullscreen nil) + (modify-frame-parameters + nil + (or (frame-parameter frame 'mdw-full-screen-saved) + (mapcar (lambda (assoc) + (assq (car assoc) default-frame-alist)) + mdw-full-screen-parameters)))) + (t + (let ((saved (mapcar (lambda (param) + (cons param (frame-parameter frame param))) + (append (mapcar #'car + mdw-full-screen-parameters) + mdw-full-screen-save)))) + (set-frame-parameter frame 'mdw-full-screen-saved saved)) + (modify-frame-parameters frame mdw-full-screen-parameters) + (set-frame-parameter frame 'fullscreen 'fullboth))))) + +;;;-------------------------------------------------------------------------- ;;; 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))) @@ -833,7 +1173,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 @@ -842,6 +1182,13 @@ doesn't match any of the regular expressions in (((type tty) (class color)) :background "blue") (((type tty) (class mono)) :inverse-video t) (t :background "grey30")) +(mdw-define-face match + (((type tty) (class color)) :background "blue") + (((type tty) (class mono)) :inverse-video t) + (t :background "blue")) +(mdw-define-face mc/cursor-face + (((type tty) (class mono)) :inverse-video t) + (t :background "red")) (mdw-define-face minibuffer-prompt (t :weight bold)) (mdw-define-face mode-line @@ -852,6 +1199,9 @@ doesn't match any of the regular expressions in (((class color)) :foreground "yellow" :background "blue" :box (:line-width 1 :style released-button)) (t :inverse-video t)) +(mdw-define-face nobreak-space + (((type tty))) + (t :inherit escape-glyph :underline t)) (mdw-define-face scroll-bar (t :foreground "black" :background "lightgrey")) (mdw-define-face fringe @@ -887,10 +1237,14 @@ doesn't match any of the regular expressions in (mdw-define-face trailing-whitespace (((class color)) :background "red") (t :inverse-video t)) +(mdw-define-face whitespace-line + (((class color)) :background "darkred") + (t :inverse-video :t)) (mdw-define-face mdw-punct-face (((type tty)) :foreground "yellow") (t :foreground "burlywood2")) (mdw-define-face mdw-number-face (t :foreground "yellow")) +(mdw-define-face mdw-trivial-face) (mdw-define-face font-lock-function-name-face (t :slant italic)) (mdw-define-face font-lock-keyword-face @@ -916,34 +1270,71 @@ doesn't match any of the regular expressions in (mdw-define-face font-lock-string-face (((class mono)) :weight bold) (((class color)) :foreground "SkyBlue1")) + (mdw-define-face message-separator (t :background "red" :foreground "white" :weight bold)) (mdw-define-face message-cited-text (default :slant italic) - (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) + (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1")) (mdw-define-face message-header-cc - (default :weight bold) + (default :slant italic) (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) (mdw-define-face message-header-newsgroups - (default :weight bold) + (default :slant italic) (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) (mdw-define-face message-header-subject - (default :weight bold) (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) (mdw-define-face message-header-to - (default :weight bold) (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) (mdw-define-face message-header-xheader - (default :weight bold) + (default :slant italic) (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) (mdw-define-face message-header-other - (default :weight bold) + (default :slant italic) (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) (mdw-define-face message-header-name + (default :weight bold) (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) + (mdw-define-face which-func (t nil)) +(mdw-define-face gnus-header-name + (default :weight bold) + (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) +(mdw-define-face gnus-header-subject + (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) +(mdw-define-face gnus-header-from + (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) +(mdw-define-face gnus-header-to + (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) +(mdw-define-face gnus-header-content + (default :slant italic) + (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) + +(mdw-define-face gnus-cite-1 + (((type tty)) :foreground "cyan") (t :foreground "SkyBlue1")) +(mdw-define-face gnus-cite-2 + (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2")) +(mdw-define-face gnus-cite-3 + (((type tty)) :foreground "magenta") (t :foreground "MediumOrchid")) +(mdw-define-face gnus-cite-4 + (((type tty)) :foreground "red") (t :foreground "firebrick2")) +(mdw-define-face gnus-cite-5 + (((type tty)) :foreground "yellow") (t :foreground "burlywood2")) +(mdw-define-face gnus-cite-6 + (((type tty)) :foreground "green") (t :foreground "SeaGreen1")) +(mdw-define-face gnus-cite-7 + (((type tty)) :foreground "cyan") (t :foreground "SlateBlue1")) +(mdw-define-face gnus-cite-8 + (((type tty)) :foreground "blue") (t :foreground "RoyalBlue2")) +(mdw-define-face gnus-cite-9 + (((type tty)) :foreground "magenta") (t :foreground "purple2")) +(mdw-define-face gnus-cite-10 + (((type tty)) :foreground "red") (t :foreground "DarkOrange2")) +(mdw-define-face gnus-cite-11 + (t :foreground "grey")) + (mdw-define-face diff-header (t nil)) (mdw-define-face diff-index @@ -965,6 +1356,16 @@ doesn't match any of the regular expressions in (mdw-define-face diff-refine-change (((class color) (type x)) :background "RoyalBlue4") (t :underline t)) +(mdw-define-face diff-refine-removed + (((class color) (type x)) :background "#500") + (t :underline t)) +(mdw-define-face diff-refine-added + (((class color) (type x)) :background "#050") + (t :underline t)) + +(mdw-define-face dylan-header-background + (((class color) (type x)) :background "NavyBlue") + (t :background "blue")) (mdw-define-face magit-diff-add (t :foreground "green")) @@ -974,6 +1375,21 @@ doesn't match any of the regular expressions in (t :weight bold)) (mdw-define-face magit-diff-hunk-header (t :foreground "SkyBlue1")) +(mdw-define-face magit-item-highlight + (((type tty)) :background "blue") + (t :background "grey11")) +(mdw-define-face magit-log-head-label-remote + (((type tty)) :background "cyan" :foreground "green") + (t :background "grey11" :foreground "DarkSeaGreen2" :box t)) +(mdw-define-face magit-log-head-label-local + (((type tty)) :background "cyan" :foreground "yellow") + (t :background "grey11" :foreground "LightSkyBlue1" :box t)) +(mdw-define-face magit-log-head-label-tags + (((type tty)) :background "red" :foreground "yellow") + (t :background "LemonChiffon1" :foreground "goldenrod4" :box t)) +(mdw-define-face magit-log-graph + (((type tty)) :foreground "magenta") + (t :foreground "grey80")) (mdw-define-face erc-input-face (t :foreground "red")) @@ -1031,7 +1447,7 @@ doesn't match any of the regular expressions in (mdw-define-face mdw-ellipsis-face (((type tty)) :foreground "blue") (t :foreground "grey60")) (let ((dollar (make-glyph-code ?$ 'mdw-ellipsis-face)) - (backslash (make-glyph-code ?\ 'mdw-ellipsis-face)) + (backslash (make-glyph-code ?\\ 'mdw-ellipsis-face)) (dot (make-glyph-code ?. 'mdw-ellipsis-face)) (bar (make-glyph-code ?| mdw-ellipsis-face))) (set-display-table-slot standard-display-table 0 dollar) @@ -1043,17 +1459,6 @@ doesn't match any of the regular expressions in ;;;-------------------------------------------------------------------------- ;;; C programming configuration. -;; Linux kernel hacking. - -(defvar linux-c-mode-hook) - -(defun linux-c-mode () - (interactive) - (c-mode) - (setq major-mode 'linux-c-mode) - (setq mode-name "Linux C") - (run-hooks 'linux-c-mode-hook)) - ;; Make C indentation nice. (defun mdw-c-lineup-arglist (langelem) @@ -1072,28 +1477,108 @@ doesn't match any of the regular expressions in c-basic-offset nil))) -(defun mdw-c-style () - (c-add-style "[mdw] C and C++ style" - '((c-basic-offset . 2) - (comment-column . 40) - (c-class-key . "class") - (c-backslash-column . 72) - (c-offsets-alist - (substatement-open . (add 0 c-indent-one-line-block)) - (defun-open . (add 0 c-indent-one-line-block)) - (arglist-cont-nonempty . mdw-c-lineup-arglist) - (topmost-intro . mdw-c-indent-extern-mumble) - (cpp-define-intro . 0) - (knr-argdecl . 0) - (inextern-lang . [0]) - (label . 0) - (case-label . +) - (access-label . -) - (inclass . +) - (inline-open . ++) - (statement-cont . +) - (statement-case-intro . +))) - t)) +(defun mdw-c-indent-arglist-nested (langelem) + "Indent continued argument lists. +If we've nested more than one argument list, then only introduce a single +indentation anyway." + (let ((context c-syntactic-context) + (pos (c-langelem-2nd-pos c-syntactic-element)) + (should-indent-p t)) + (while (and context + (eq (caar context) 'arglist-cont-nonempty)) + (when (and (= (caddr (pop context)) pos) + context + (memq (caar context) '(arglist-intro + arglist-cont-nonempty))) + (setq should-indent-p nil))) + (if should-indent-p '+ 0))) + +(defvar mdw-define-c-styles-hook nil + "Hook run when `cc-mode' starts up to define styles.") + +(defmacro mdw-define-c-style (name &rest assocs) + "Define a C style, called NAME (a symbol), setting ASSOCs. +A function, named `mdw-define-c-style/NAME', is defined to actually install +the style using `c-add-style', and added to the hook +`mdw-define-c-styles-hook'. If CC Mode is already loaded, then the style is +set." + (declare (indent defun)) + (let* ((name-string (symbol-name name)) + (func (intern (concat "mdw-define-c-style/" name-string)))) + `(progn + (defun ,func () (c-add-style ,name-string ',assocs)) + (and (featurep 'cc-mode) (,func)) + (add-hook 'mdw-define-c-styles-hook ',func)))) + +(eval-after-load "cc-mode" + '(run-hooks 'mdw-define-c-styles-hook)) + +(mdw-define-c-style mdw-trustonic-c + (c-basic-offset . 4) + (comment-column . 0) + (c-indent-comment-alist (anchored-comment . (column . 0)) + (end-block . (space . 1)) + (cpp-end-block . (space . 1)) + (other . (space . 1))) + (c-class-key . "class") + (c-backslash-column . 0) + (c-auto-align-backslashes . nil) + (c-label-minimum-indentation . 0) + (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block)) + (defun-open . (add 0 c-indent-one-line-block)) + (arglist-cont-nonempty . mdw-c-indent-arglist-nested) + (topmost-intro . mdw-c-indent-extern-mumble) + (cpp-define-intro . 0) + (knr-argdecl . 0) + (inextern-lang . [0]) + (label . 0) + (case-label . +) + (access-label . -) + (inclass . +) + (inline-open . ++) + (statement-cont . +) + (statement-case-intro . +))) + +(mdw-define-c-style mdw-c + (c-basic-offset . 2) + (comment-column . 40) + (c-class-key . "class") + (c-backslash-column . 72) + (c-label-minimum-indentation . 0) + (c-offsets-alist (substatement-open . (add 0 c-indent-one-line-block)) + (defun-open . (add 0 c-indent-one-line-block)) + (arglist-cont-nonempty . mdw-c-lineup-arglist) + (topmost-intro . mdw-c-indent-extern-mumble) + (cpp-define-intro . 0) + (knr-argdecl . 0) + (inextern-lang . [0]) + (label . 0) + (case-label . +) + (access-label . -) + (inclass . +) + (inline-open . ++) + (statement-cont . +) + (statement-case-intro . +))) + +(defun mdw-set-default-c-style (modes style) + "Update the default CC Mode style for MODES to be STYLE. + +MODES may be a list of major mode names or a singleton. STYLE is a style +name, as a symbol." + (let ((modes (if (listp modes) modes (list modes))) + (style (symbol-name style))) + (setq c-default-style + (append (mapcar (lambda (mode) + (cons mode style)) + modes) + (remove-if (lambda (assoc) + (memq (car assoc) modes)) + (if (listp c-default-style) + c-default-style + (list (cons 'other c-default-style)))))))) +(setq c-default-style "mdw-c") + +(mdw-set-default-c-style '(c-mode c++-mode) 'mdw-c) (defvar mdw-c-comment-fill-prefix `((,(concat "\\([ \t]*/?\\)" @@ -1112,81 +1597,87 @@ doesn't match any of the regular expressions in (modify-syntax-entry ?\n "> b") ;; Other stuff. - (mdw-c-style) - (setq c-hanging-comment-ender-p nil) - (setq c-backslash-column 72) - (setq c-label-minimum-indentation 0) (setq mdw-fill-prefix mdw-c-comment-fill-prefix) ;; Now define things to be fontified. (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 - "false" ;C++, C9X macro - "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++ - "this" ;C++ "throw" ;C++ - "true" ;C++, C9X macro "try" ;C++ - "this" ;C++ + "thread_local" ;C11 macro, C++11 "typedef" ;C89 "typeid" ;C++ "typeof" ;GCC @@ -1199,12 +1690,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 @@ -1219,6 +1717,11 @@ doesn't match any of the regular expressions in "__typeof__" ;GCC "__volatile__" ;GCC )) + (c-constants + (mdw-regexps "false" ;C++, C99 macro + "this" ;C++ + "true" ;C++, C99 macro + )) (preprocessor-keywords (mdw-regexps "assert" "define" "elif" "else" "endif" "error" "ident" "if" "ifdef" "ifndef" "import" "include" @@ -1250,6 +1753,9 @@ doesn't match any of the regular expressions in (list (concat "\\<\\(" c-keywords "\\)\\>") '(0 font-lock-keyword-face)) + (list (concat "\\<\\(" c-constants "\\)\\>") + '(0 font-lock-variable-name-face)) + ;; Handle numbers too. ;; ;; This looks strange, I know. It corresponds to the @@ -1261,19 +1767,13 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face)))) - - (mdw-post-config-mode-hack))) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; AP calc mode. -(defun apcalc-mode () - (interactive) - (c-mode) - (setq major-mode 'apcalc-mode) - (setq mode-name "AP Calc") - (run-hooks 'apcalc-mode-hook)) +(define-derived-mode apcalc-mode c-mode "AP Calc" + "Major mode for editing Calc code.") (defun mdw-fontify-apcalc () @@ -1282,9 +1782,6 @@ doesn't match any of the regular expressions in (modify-syntax-entry ?/ ". 14") ;; Other stuff. - (mdw-c-style) - (setq c-hanging-comment-ender-p nil) - (setq c-backslash-column 72) (setq comment-start "/* ") (setq comment-end " */") (setq mdw-fill-prefix mdw-c-comment-fill-prefix) @@ -1315,34 +1812,29 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Java programming configuration. ;; Make indentation nice. -(defun mdw-java-style () - (c-add-style "[mdw] Java style" - '((c-basic-offset . 2) - (c-offsets-alist (substatement-open . 0) - (label . +) - (case-label . +) - (access-label . 0) - (inclass . +) - (statement-case-intro . +))) - t)) +(mdw-define-c-style mdw-java + (c-basic-offset . 2) + (c-backslash-column . 72) + (c-offsets-alist (substatement-open . 0) + (label . +) + (case-label . +) + (access-label . 0) + (inclass . +) + (statement-case-intro . +))) +(mdw-set-default-c-style 'java-mode 'mdw-java) ;; Declare Java fontification style. (defun mdw-fontify-java () ;; Other stuff. - (mdw-java-style) - (setq c-hanging-comment-ender-p nil) - (setq c-backslash-column 72) (setq mdw-fill-prefix mdw-c-comment-fill-prefix) ;; Now define things to be fontified. @@ -1354,11 +1846,11 @@ doesn't match any of the regular expressions in "for" "goto" "if" "implements" "import" "instanceof" "int" "interface" "long" "native" "new" "package" "private" "protected" "public" "return" "short" - "static" "super" "switch" "synchronized" "this" - "throw" "throws" "transient" "try" "void" "volatile" - "while" + "static" "switch" "synchronized" "throw" "throws" + "transient" "try" "void" "volatile" "while")) - "false" "null" "true"))) + (java-constants + (mdw-regexps "false" "null" "super" "this" "true"))) (setq font-lock-keywords (list @@ -1367,6 +1859,10 @@ doesn't match any of the regular expressions in (list (concat "\\<\\(" java-keywords "\\)\\>") '(0 font-lock-keyword-face)) + ;; Handle the magic constants defined above. + (list (concat "\\<\\(" java-constants "\\)\\>") + '(0 font-lock-variable-name-face)) + ;; Handle numbers too. ;; ;; The following isn't quite right, but it's close enough. @@ -1379,9 +1875,7 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Javascript programming configuration. @@ -1420,17 +1914,17 @@ doesn't match any of the regular expressions in (list ;; Handle the keywords defined above. - (list (concat "\\<\\(" javascript-keywords "\\)\\>") + (list (concat "\\_<\\(" javascript-keywords "\\)\\_>") '(0 font-lock-keyword-face)) ;; Handle the predefined constants defined above. - (list (concat "\\<\\(" javascript-constants "\\)\\>") + (list (concat "\\_<\\(" javascript-constants "\\)\\_>") '(0 font-lock-variable-name-face)) ;; Handle numbers too. ;; ;; The following isn't quite right, but it's close enough. - (list (concat "\\<\\(" + (list (concat "\\_<\\(" "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|" "[0-9]+\\(\\.[0-9]*\\|\\)" "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)" @@ -1439,55 +1933,123 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) + '(0 mdw-punct-face)))))) + +;;;-------------------------------------------------------------------------- +;;; Scala programming configuration. + +(defun mdw-fontify-scala () + + ;; Comment filling. + (setq mdw-fill-prefix mdw-c-comment-fill-prefix) + + ;; Define things to be fontified. + (make-local-variable 'font-lock-keywords) + (let ((scala-keywords + (mdw-regexps "abstract" "case" "catch" "class" "def" "do" "else" + "extends" "final" "finally" "for" "forSome" "if" + "implicit" "import" "lazy" "match" "new" "object" + "override" "package" "private" "protected" "return" + "sealed" "throw" "trait" "try" "type" "val" + "var" "while" "with" "yield")) + (scala-constants + (mdw-regexps "false" "null" "super" "this" "true")) + (punctuation "[-!%^&*=+:@#~/?\\|`]")) + + (setq font-lock-keywords + (list + + ;; Magical identifiers between backticks. + (list (concat "`\\([^`]+\\)`") + '(1 font-lock-variable-name-face)) + + ;; Handle the keywords defined above. + (list (concat "\\_<\\(" scala-keywords "\\)\\_>") + '(0 font-lock-keyword-face)) + + ;; Handle the constants defined above. + (list (concat "\\_<\\(" scala-constants "\\)\\_>") + '(0 font-lock-variable-name-face)) + + ;; Magical identifiers between backticks. + (list (concat "`\\([^`]+\\)`") + '(1 font-lock-variable-name-face)) + + ;; Handle numbers too. + ;; + ;; As usual, not quite right. + (list (concat "\\_<\\(" + "0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|" + "[0-9]+\\(\\.[0-9]*\\|\\)" + "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)" + "[lLfFdD]?") + '(0 mdw-number-face)) + + ;; Identifiers with trailing operators. + (list (concat "_\\(" punctuation "\\)+") + '(0 mdw-trivial-face)) + + ;; And everything else is punctuation. + (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" + '(0 mdw-punct-face))) + + font-lock-syntactic-keywords + (list - (mdw-post-config-mode-hack)) + ;; Single quotes around characters. But not when used to quote + ;; symbol names. Ugh. + (list (concat "\\('\\)" + "\\(" "." + "\\|" "\\\\" "\\(" "\\\\\\\\" "\\)*" + "u+" "[0-9a-fA-F]\\{4\\}" + "\\|" "\\\\" "[0-7]\\{1,3\\}" + "\\|" "\\\\" "." "\\)" + "\\('\\)") + '(1 "\"") + '(4 "\"")))))) ;;;-------------------------------------------------------------------------- ;;; C# programming configuration. ;; Make indentation nice. -(defun mdw-csharp-style () - (c-add-style "[mdw] C# style" - '((c-basic-offset . 2) - (c-offsets-alist (substatement-open . 0) - (label . 0) - (case-label . +) - (access-label . 0) - (inclass . +) - (statement-case-intro . +))) - t)) +(mdw-define-c-style mdw-csharp + (c-basic-offset . 2) + (c-backslash-column . 72) + (c-offsets-alist (substatement-open . 0) + (label . 0) + (case-label . +) + (access-label . 0) + (inclass . +) + (statement-case-intro . +))) +(mdw-set-default-c-style 'csharp-mode 'mdw-csharp) ;; Declare C# fontification style. (defun mdw-fontify-csharp () ;; Other stuff. - (mdw-csharp-style) - (setq c-hanging-comment-ender-p nil) - (setq c-backslash-column 72) (setq mdw-fill-prefix mdw-c-comment-fill-prefix) ;; Now define things to be fontified. (make-local-variable 'font-lock-keywords) (let ((csharp-keywords - (mdw-regexps "abstract" "as" "base" "bool" "break" - "byte" "case" "catch" "char" "checked" - "class" "const" "continue" "decimal" "default" - "delegate" "do" "double" "else" "enum" - "event" "explicit" "extern" "false" "finally" - "fixed" "float" "for" "foreach" "goto" - "if" "implicit" "in" "int" "interface" - "internal" "is" "lock" "long" "namespace" - "new" "null" "object" "operator" "out" - "override" "params" "private" "protected" "public" - "readonly" "ref" "return" "sbyte" "sealed" - "short" "sizeof" "stackalloc" "static" "string" - "struct" "switch" "this" "throw" "true" - "try" "typeof" "uint" "ulong" "unchecked" - "unsafe" "ushort" "using" "virtual" "void" - "volatile" "while" "yield"))) + (mdw-regexps "abstract" "as" "bool" "break" "byte" "case" "catch" + "char" "checked" "class" "const" "continue" "decimal" + "default" "delegate" "do" "double" "else" "enum" + "event" "explicit" "extern" "finally" "fixed" "float" + "for" "foreach" "goto" "if" "implicit" "in" "int" + "interface" "internal" "is" "lock" "long" "namespace" + "new" "object" "operator" "out" "override" "params" + "private" "protected" "public" "readonly" "ref" + "return" "sbyte" "sealed" "short" "sizeof" + "stackalloc" "static" "string" "struct" "switch" + "throw" "try" "typeof" "uint" "ulong" "unchecked" + "unsafe" "ushort" "using" "virtual" "void" "volatile" + "while" "yield")) + + (csharp-constants + (mdw-regexps "base" "false" "null" "this" "true"))) (setq font-lock-keywords (list @@ -1496,6 +2058,10 @@ doesn't match any of the regular expressions in (list (concat "\\<\\(" csharp-keywords "\\)\\>") '(0 font-lock-keyword-face)) + ;; Handle the magic constants defined above. + (list (concat "\\<\\(" csharp-constants "\\)\\>") + '(0 font-lock-variable-name-face)) + ;; Handle numbers too. ;; ;; The following isn't quite right, but it's close enough. @@ -1508,14 +2074,131 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) (define-derived-mode csharp-mode java-mode "C#" "Major mode for editing C# code.") ;;;-------------------------------------------------------------------------- +;;; F# programming configuration. + +(setq fsharp-indent-offset 2) + +(defun mdw-fontify-fsharp () + + (let ((punct "=<>+-*/|&%!@?")) + (do ((i 0 (1+ i))) + ((>= i (length punct))) + (modify-syntax-entry (aref punct i) "."))) + + (modify-syntax-entry ?_ "_") + (modify-syntax-entry ?( "(") + (modify-syntax-entry ?) ")") + + (setq indent-tabs-mode nil) + + (let ((fsharp-keywords + (mdw-regexps "abstract" "and" "as" "assert" "atomic" + "begin" "break" + "checked" "class" "component" "const" "constraint" + "constructor" "continue" + "default" "delegate" "do" "done" "downcast" "downto" + "eager" "elif" "else" "end" "exception" "extern" + "finally" "fixed" "for" "fori" "fun" "function" + "functor" + "global" + "if" "in" "include" "inherit" "inline" "interface" + "internal" + "lazy" "let" + "match" "measure" "member" "method" "mixin" "module" + "mutable" + "namespace" "new" + "object" "of" "open" "or" "override" + "parallel" "params" "private" "process" "protected" + "public" "pure" + "rec" "recursive" "return" + "sealed" "sig" "static" "struct" + "tailcall" "then" "to" "trait" "try" "type" + "upcast" "use" + "val" "virtual" "void" "volatile" + "when" "while" "with" + "yield")) + + (fsharp-builtins + (mdw-regexps "asr" "land" "lor" "lsl" "lsr" "lxor" "mod" + "base" "false" "null" "true")) + + (bang-keywords + (mdw-regexps "do" "let" "return" "use" "yield")) + + (preprocessor-keywords + (mdw-regexps "if" "indent" "else" "endif"))) + + (setq font-lock-keywords + (list (list (concat "\\(^\\|[^\"]\\)" + "\\(" "(\\*" + "[^*]*\\*+" + "\\(" "[^)*]" "[^*]*" "\\*+" "\\)*" + ")" + "\\|" + "//.*" + "\\)") + '(2 font-lock-comment-face)) + + (list (concat "'" "\\(" + "\\\\" + "\\(" "[ntbr'\\]" + "\\|" "[0-9][0-9][0-9]" + "\\|" "u" "[0-9a-fA-F]\\{4\\}" + "\\|" "U" "[0-9a-fA-F]\\{8\\}" + "\\)" + "\\|" + "." "\\)" "'" + "\\|" + "\"" "[^\"\\]*" + "\\(" "\\\\" "\\(.\\|\n\\)" + "[^\"\\]*" "\\)*" + "\\(\"\\|\\'\\)") + '(0 font-lock-string-face)) + + (list (concat "\\_<\\(" bang-keywords "\\)!" "\\|" + "^#[ \t]*\\(" preprocessor-keywords "\\)\\_>" + "\\|" + "\\_<\\(" fsharp-keywords "\\)\\_>") + '(0 font-lock-keyword-face)) + (list (concat "\\<\\(" fsharp-builtins "\\)\\_>") + '(0 font-lock-variable-name-face)) + + (list (concat "\\_<" + "\\(" "0[bB][01]+" "\\|" + "0[oO][0-7]+" "\\|" + "0[xX][0-9a-fA-F]+" "\\)" + "\\(" "lf\\|LF" "\\|" + "[uU]?[ysnlL]?" "\\)" + "\\|" + "\\_<" + "[0-9]+" "\\(" + "[mMQRZING]" + "\\|" + "\\(\\.[0-9]*\\)?" + "\\([eE][-+]?[0-9]+\\)?" + "[fFmM]?" + "\\|" + "[uU]?[ysnlL]?" + "\\)") + '(0 mdw-number-face)) + + (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" + '(0 mdw-punct-face)))))) + +(defun mdw-fontify-inferior-fsharp () + (mdw-fontify-fsharp) + (setq font-lock-keywords + (append (list (list "^[#-]" '(0 font-lock-comment-face)) + (list "^>" '(0 font-lock-keyword-face))) + font-lock-keywords))) + +;;;-------------------------------------------------------------------------- ;;; Go programming configuration. (defun mdw-fontify-go () @@ -1526,7 +2209,16 @@ doesn't match any of the regular expressions in "default" "defer" "else" "fallthrough" "for" "func" "go" "goto" "if" "import" "interface" "map" "package" "range" "return" - "select" "struct" "switch" "type" "var"))) + "select" "struct" "switch" "type" "var")) + (go-intrinsics + (mdw-regexps "bool" "byte" "complex64" "complex128" "error" + "float32" "float64" "int" "uint8" "int16" "int32" + "int64" "rune" "string" "uint" "uint8" "uint16" + "uint32" "uint64" "uintptr" "void" + "false" "iota" "nil" "true" + "init" "main" + "append" "cap" "copy" "delete" "imag" "len" "make" + "new" "panic" "real" "recover"))) (setq font-lock-keywords (list @@ -1534,6 +2226,26 @@ doesn't match any of the regular expressions in ;; Handle the keywords defined above. (list (concat "\\<\\(" go-keywords "\\)\\>") '(0 font-lock-keyword-face)) + (list (concat "\\<\\(" go-intrinsics "\\)\\>") + '(0 font-lock-variable-name-face)) + + ;; Strings and characters. + (list (concat "'" + "\\(" "[^\\']" "\\|" + "\\\\" + "\\(" "[abfnrtv\\'\"]" "\\|" + "[0-7]\\{3\\}" "\\|" + "x" "[0-9A-Fa-f]\\{2\\}" "\\|" + "u" "[0-9A-Fa-f]\\{4\\}" "\\|" + "U" "[0-9A-Fa-f]\\{8\\}" "\\)" "\\)" + "'" + "\\|" + "\"" + "\\(" "[^\n\\\"]+" "\\|" "\\\\." "\\)*" + "\\(\"\\|$\\)" + "\\|" + "`" "[^`]+" "`") + '(0 font-lock-string-face)) ;; Handle numbers too. ;; @@ -1546,30 +2258,102 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" + '(0 mdw-punct-face)))))) + +;;;-------------------------------------------------------------------------- +;;; Rust programming configuration. + +(setq-default rust-indent-offset 2) + +(defun mdw-self-insert-and-indent (count) + (interactive "p") + (self-insert-command count) + (indent-according-to-mode)) + +(defun mdw-fontify-rust () + + ;; Hack syntax categories. + (modify-syntax-entry ?= ".") + + ;; Fontify keywords and things. + (make-local-variable 'font-lock-keywords) + (let ((rust-keywords + (mdw-regexps "abstract" "alignof" "as" + "become" "box" "break" + "const" "continue" "create" + "do" + "else" "enum" "extern" + "false" "final" "fn" "for" + "if" "impl" "in" + "let" "loop" + "macro" "match" "mod" "move" "mut" + "offsetof" "override" + "priv" "pub" "pure" + "ref" "return" + "self" "sizeof" "static" "struct" "super" + "true" "trait" "type" "typeof" + "unsafe" "unsized" "use" + "virtual" + "where" "while" + "yield")) + (rust-builtins + (mdw-regexps "array" "pointer" "slice" "tuple" + "bool" "true" "false" + "f32" "f64" + "i8" "i16" "i32" "i64" "isize" + "u8" "u16" "u32" "u64" "usize" + "char" "str"))) + (setq font-lock-keywords + (list + + ;; Handle the keywords defined above. + (list (concat "\\<\\(" rust-keywords "\\)\\>") + '(0 font-lock-keyword-face)) + (list (concat "\\<\\(" rust-builtins "\\)\\>") + '(0 font-lock-variable-name-face)) + + ;; Handle numbers too. + (list (concat "\\<\\(" + "[0-9][0-9_]*" + "\\(" "\\(\\.[0-9_]+\\)?[eE][-+]?[0-9_]+" + "\\|" "\\.[0-9_]+" + "\\)" + "\\(f32\\|f64\\)?" + "\\|" "\\(" "[0-9][0-9_]*" + "\\|" "0x[0-9a-fA-F_]+" + "\\|" "0o[0-7_]+" + "\\|" "0b[01_]+" + "\\)" + "\\([ui]\\(8\\|16\\|32\\|64\\|s\\|size\\)\\)?" + "\\)\\>") + '(0 mdw-number-face)) + + ;; And anything else is punctuation. + (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" '(0 mdw-punct-face))))) - (mdw-post-config-mode-hack)) + ;; Hack key bindings. + (local-set-key [?{] 'mdw-self-insert-and-indent) + (local-set-key [?}] 'mdw-self-insert-and-indent)) ;;;-------------------------------------------------------------------------- ;;; Awk programming configuration. ;; Make Awk indentation nice. -(defun mdw-awk-style () - (c-add-style "[mdw] Awk style" - '((c-basic-offset . 2) - (c-offsets-alist (substatement-open . 0) - (statement-cont . 0) - (statement-case-intro . +))) - t)) +(mdw-define-c-style mdw-awk + (c-basic-offset . 2) + (c-offsets-alist (substatement-open . 0) + (c-backslash-column . 72) + (statement-cont . 0) + (statement-case-intro . +))) +(mdw-set-default-c-style 'awk-mode 'mdw-awk) ;; Declare Awk fontification style. (defun mdw-fontify-awk () ;; Miscellaneous fiddling. - (mdw-awk-style) - (setq c-backslash-column 72) (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)") ;; Now define things to be fontified. @@ -1606,16 +2390,15 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Perl programming style. ;; Perl indentation style. -(fset 'perl-mode 'cperl-mode) +(setq perl-indent-level 2) + (setq cperl-indent-level 2) (setq cperl-continued-statement-offset 2) (setq cperl-continued-brace-offset 0) @@ -1630,16 +2413,29 @@ doesn't match any of the regular expressions in ;; Miscellaneous fiddling. (modify-syntax-entry ?$ "\\") (modify-syntax-entry ?$ "\\" font-lock-syntax-table) + (modify-syntax-entry ?: "." font-lock-syntax-table) (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)") ;; Now define fontification things. (make-local-variable 'font-lock-keywords) (let ((perl-keywords - (mdw-regexps "and" "break" "cmp" "continue" "do" "else" "elsif" "eq" - "for" "foreach" "ge" "given" "gt" "goto" "if" - "last" "le" "lt" "local" "my" "ne" "next" "or" - "our" "package" "redo" "require" "return" "sub" - "undef" "unless" "until" "use" "when" "while"))) + (mdw-regexps "and" + "break" + "cmp" "continue" + "default" "do" + "else" "elsif" "eq" + "for" "foreach" + "ge" "given" "gt" "goto" + "if" + "last" "le" "local" "lt" + "my" + "ne" "next" + "or" "our" + "package" + "redo" "require" "return" + "sub" + "undef" "unless" "until" "use" + "when" "while"))) (setq font-lock-keywords (list @@ -1656,9 +2452,7 @@ doesn't match any of the regular expressions in ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) (defun perl-number-tests (&optional arg) "Assign consecutive numbers to lines containing `#t'. With ARG, @@ -1701,9 +2495,7 @@ strip numbers instead." ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face)))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face))))) ;; Define Python fontification styles. @@ -1777,94 +2569,7 @@ strip numbers instead." ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) - -;;;-------------------------------------------------------------------------- -;;; ARM assembler programming configuration. - -;; There doesn't appear to be an Emacs mode for this yet. -;; -;; Better do something about that, I suppose. - -(defvar arm-assembler-mode-map nil) -(defvar arm-assembler-abbrev-table nil) -(defvar arm-assembler-mode-syntax-table (make-syntax-table)) - -(or arm-assembler-mode-map - (progn - (setq arm-assembler-mode-map (make-sparse-keymap)) - (define-key arm-assembler-mode-map "\C-m" 'arm-assembler-newline) - (define-key arm-assembler-mode-map [C-return] 'newline) - (define-key arm-assembler-mode-map "\t" 'tab-to-tab-stop))) - -(defun arm-assembler-mode () - "Major mode for ARM assembler programs" - (interactive) - - ;; Do standard major mode things. - (kill-all-local-variables) - (use-local-map arm-assembler-mode-map) - (setq local-abbrev-table arm-assembler-abbrev-table) - (setq major-mode 'arm-assembler-mode) - (setq mode-name "ARM assembler") - - ;; Set up syntax table. - (set-syntax-table arm-assembler-mode-syntax-table) - (modify-syntax-entry ?; ; Nasty hack - "<" arm-assembler-mode-syntax-table) - (modify-syntax-entry ?\n ">" arm-assembler-mode-syntax-table) - (modify-syntax-entry ?_ "_" arm-assembler-mode-syntax-table) - (modify-syntax-entry ?' "\"'" arm-assembler-mode-syntax-table) - - (make-local-variable 'comment-start) - (setq comment-start ";") - (make-local-variable 'comment-end) - (setq comment-end "") - (make-local-variable 'comment-column) - (setq comment-column 48) - (make-local-variable 'comment-start-skip) - (setq comment-start-skip ";+[ \t]*") - - ;; Play with indentation. - (make-local-variable 'indent-line-function) - (setq indent-line-function 'indent-relative-maybe) - - ;; Set fill prefix. - (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)") - - ;; Fiddle with fontification. - (make-local-variable 'font-lock-keywords) - (setq font-lock-keywords - (list - - ;; Handle numbers too. - ;; - ;; The following isn't quite right, but it's close enough. - (list (concat "\\(" - "&[0-9a-fA-F]+\\|" - "\\<[0-9]+\\(\\.[0-9]*\\|_[0-9a-zA-Z]+\\|\\)" - "\\)") - '(0 mdw-number-face)) - - ;; Do something about operators. - (list "^[^ \t]*[ \t]+\\(GET\\|LNK\\)[ \t]+\\([^;\n]*\\)" - '(1 font-lock-keyword-face) - '(2 font-lock-string-face)) - (list ":[a-zA-Z]+:" - '(0 font-lock-keyword-face)) - - ;; Do menemonics and directives. - (list "^[^ \t]*[ \t]+\\([a-zA-Z]+\\)" - '(1 font-lock-keyword-face)) - - ;; And anything else is punctuation. - (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))) - - (mdw-post-config-mode-hack)) - (run-hooks 'arm-assembler-mode-hook)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Assembler mode. @@ -1872,9 +2577,18 @@ strip numbers instead." (defun mdw-fontify-asm () (modify-syntax-entry ?' "\"") (modify-syntax-entry ?. "w") + (modify-syntax-entry ?\n ">") (setf fill-prefix nil) (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")) +(defun mdw-asm-set-comment () + (modify-syntax-entry ?; "." + ) + (modify-syntax-entry asm-comment-char "$%]+") + (dylan-keywords (mdw-regexps + + "C-address" "C-callable-wrapper" "C-function" + "C-mapped-subtype" "C-pointer-type" "C-struct" + "C-subtype" "C-union" "C-variable" + + "above" "abstract" "afterwards" "all" + "begin" "below" "block" "by" + "case" "class" "cleanup" "constant" "create" + "define" "domain" + "else" "elseif" "end" "exception" "export" + "finally" "for" "from" "function" + "generic" + "handler" + "if" "in" "instance" "interface" "iterate" + "keyed-by" + "let" "library" "local" + "macro" "method" "module" + "otherwise" + "profiling" + "select" "slot" "subclass" + "table" "then" "to" + "unless" "until" "use" + "variable" "virtual" + "when" "while")) + (sharp-keywords (mdw-regexps + "all-keys" "key" "next" "rest" "include" + "t" "f"))) + (setq font-lock-keywords + (list (list (concat "\\<\\(" dylan-keywords + "\\|" "with\\(out\\)?-" word + "\\)\\>") + '(0 font-lock-keyword-face)) + (list (concat "\\<" word ":" "\\|" + "#\\(" sharp-keywords "\\)\\>") + '(0 font-lock-variable-name-face)) + (list (concat "\\(" + "\\([-+]\\|\\<\\)[0-9]+" "\\(" + "\\(\\.[0-9]+\\)?" "\\([eE][-+][0-9]+\\)?" + "\\|" "/[0-9]+" + "\\)" + "\\|" "\\.[0-9]+" "\\([eE][-+][0-9]+\\)?" + "\\|" "#b[01]+" + "\\|" "#o[0-7]+" + "\\|" "#x[0-9a-zA-Z]+" + "\\)\\>") + '(0 mdw-number-face)) + (list (concat "\\(" + "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\|" + "\\_<[-+*/=<>:&|]+\\_>" + "\\)") + '(0 mdw-punct-face)))))) + +;;;-------------------------------------------------------------------------- +;;; Algol 68 configuration. + +(setq a68-indent-step 2) + +(defun mdw-fontify-algol-68 () + + ;; Fix up the syntax table. + (modify-syntax-entry ?# "!" a68-mode-syntax-table) + (dolist (ch '(?- ?+ ?= ?< ?> ?* ?/ ?| ?&)) + (modify-syntax-entry ch "." a68-mode-syntax-table)) + + (make-local-variable 'font-lock-keywords) + + (let ((not-comment + (let ((word "COMMENT")) + (do ((regexp (concat "[^" (substring word 0 1) "]+") + (concat regexp "\\|" + (substring word 0 i) + "[^" (substring word i (1+ i)) "]")) + (i 1 (1+ i))) + ((>= i (length word)) regexp))))) + (setq font-lock-keywords + (list (list (concat "\\" + "\\(" not-comment "\\)\\{0,5\\}" + "\\(\\'\\|\\\\)") + '(0 font-lock-comment-face)) + (list (concat "\\" + "\\([^C]+\\|C[^O]\\)\\{0,5\\}" + "\\($\\|\\\\)") + '(0 font-lock-comment-face)) + (list "\\<[A-Z_]+\\>" + '(0 font-lock-keyword-face)) + (list (concat "\\<" + "[0-9]+" + "\\(\\.[0-9]+\\)?" + "\\([eE][-+]?[0-9]+\\)?" + "\\>") + '(0 mdw-number-face)) + (list "\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/" + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; REXX configuration. @@ -1963,9 +2784,7 @@ strip numbers instead." ;; And everything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Standard ML programming style. @@ -2015,9 +2834,7 @@ strip numbers instead." ;; And anything else is punctuation. (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Haskell configuration. @@ -2025,38 +2842,77 @@ strip numbers instead." (defun mdw-fontify-haskell () ;; Fiddle with syntax table to get comments right. - (modify-syntax-entry ?' "\"") - (modify-syntax-entry ?- ". 123") - (modify-syntax-entry ?{ ". 1b") - (modify-syntax-entry ?} ". 4b") + (modify-syntax-entry ?' "_") + (modify-syntax-entry ?- ". 12") (modify-syntax-entry ?\n ">") + ;; Make punctuation be punctuation + (let ((punct "=<>+-*/|&%!@?$.^:#`")) + (do ((i 0 (1+ i))) + ((>= i (length punct))) + (modify-syntax-entry (aref punct i) "."))) + ;; Set fill prefix. (mdw-standard-fill-prefix "\\([ \t]*{?--?[ \t]*\\)") ;; Fiddle with fontification. (make-local-variable 'font-lock-keywords) (let ((haskell-keywords - (mdw-regexps "as" "case" "ccall" "class" "data" "default" - "deriving" "do" "else" "foreign" "hiding" "if" - "import" "in" "infix" "infixl" "infixr" "instance" - "let" "module" "newtype" "of" "qualified" "safe" - "stdcall" "then" "type" "unsafe" "where"))) + (mdw-regexps "as" + "case" "ccall" "class" + "data" "default" "deriving" "do" + "else" "exists" + "forall" "foreign" + "hiding" + "if" "import" "in" "infix" "infixl" "infixr" "instance" + "let" + "mdo" "module" + "newtype" + "of" + "proc" + "qualified" + "rec" + "safe" "stdcall" + "then" "type" + "unsafe" + "where")) + (control-sequences + (mdw-regexps "ACK" "BEL" "BS" "CAN" "CR" "DC1" "DC2" "DC3" "DC4" + "DEL" "DLE" "EM" "ENQ" "EOT" "ESC" "ETB" "ETX" "FF" + "FS" "GS" "HT" "LF" "NAK" "NUL" "RS" "SI" "SO" "SOH" + "SP" "STX" "SUB" "SYN" "US" "VT"))) (setq font-lock-keywords (list - (list "--.*$" + (list (concat "{-" "[^-]*" "\\(-+[^-}][^-]*\\)*" + "\\(-+}\\|-*\\'\\)" + "\\|" + "--.*$") '(0 font-lock-comment-face)) - (list (concat "\\<\\(" haskell-keywords "\\)\\>") + (list (concat "\\_<\\(" haskell-keywords "\\)\\_>") '(0 font-lock-keyword-face)) - (list (concat "\\<0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|" - "\\<[0-9][0-9_]*\\(\\.[0-9]*\\|\\)" + (list (concat "'\\(" + "[^\\]" + "\\|" + "\\\\" + "\\(" "[abfnrtv\\\"']" "\\|" + "^" "\\(" control-sequences "\\|" + "[]A-Z@[\\^_]" "\\)" "\\|" + "\\|" + "[0-9]+" "\\|" + "[oO][0-7]+" "\\|" + "[xX][0-9A-Fa-f]+" + "\\)" + "\\)'") + '(0 font-lock-string-face)) + (list "\\_<[A-Z]\\(\\sw+\\|\\s_+\\)*\\_>" + '(0 font-lock-variable-name-face)) + (list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO][0-7]+\\)\\|" + "\\_<[0-9]+\\(\\.[0-9]*\\|\\)" "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)") '(0 mdw-number-face)) (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Erlang configuration. @@ -2089,9 +2945,7 @@ strip numbers instead." (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>" '(0 mdw-number-face)) (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face))))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face)))))) ;;;-------------------------------------------------------------------------- ;;; Texinfo configuration. @@ -2125,9 +2979,7 @@ strip numbers instead." ;; Fontify TeX special characters as punctuation. (list "[{}]+" - '(0 mdw-punct-face)))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face))))) ;;;-------------------------------------------------------------------------- ;;; TeX and LaTeX configuration. @@ -2141,6 +2993,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]*\\)") @@ -2193,9 +3049,7 @@ strip numbers instead." ;; Fontify TeX special characters as punctuation. (list "[$^_{}#&]" - '(0 mdw-punct-face)))) - - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face))))) ;;;-------------------------------------------------------------------------- ;;; SGML hacking. @@ -2234,8 +3088,8 @@ that character only to be normal punctuation.") (or (booleanp value) (every (lambda (v) (memq v '(?\" ?'))) (if (listp value) value (list value))))) -(put 'mdw-conf-quote-normal 'safe-local-variable ' - mdw-conf-quote-normal-acceptable-value-p) +(put 'mdw-conf-quote-normal 'safe-local-variable + 'mdw-conf-quote-normal-acceptable-value-p) (defun mdw-fix-up-quote () "Apply the setting of `mdw-conf-quote-normal'." @@ -2250,15 +3104,7 @@ that character only to be normal punctuation.") (if (listp flag) flag (list flag))) (set-syntax-table table) (and font-lock-mode (font-lock-fontify-buffer))))))) -(defun mdw-fix-up-quote-hack () - "Unpleasant hack to call `mdw-fix-up-quote' at the right time. -Annoyingly, `hack-local-variables' is done after `set-auto-mode' -so we wouldn't see a local-variable setting of -`mdw-conf-quote-normal' in `conf-mode-hook'. Instead, wire -ourselves onto `hack-local-variables-hook' here, and check the -setting once it's actually been made." - (add-hook 'hack-local-variables-hook 'mdw-fix-up-quote t t)) -(add-hook 'conf-mode-hook 'mdw-fix-up-quote-hack t) +(add-hook 'conf-mode-local-variables-hook 'mdw-fix-up-quote t t) ;;;-------------------------------------------------------------------------- ;;; Shell scripts. @@ -2280,6 +3126,9 @@ setting once it's actually been made." (let ((executable-set-magic #'(lambda (s &rest r) s))) (sh-set-shell shell-name))) + ;; Don't insert here-document scaffolding automatically. + (local-set-key "<" 'self-insert-command) + ;; Now enable my keys and the fontification. (mdw-misc-mode-config) @@ -2560,8 +3409,7 @@ setting once it's actually been made." "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)") '(0 mdw-number-face)) (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face)))) - (mdw-post-config-mode-hack)) + '(0 mdw-punct-face))))) ;; Lispy languages. @@ -2599,11 +3447,26 @@ setting once it's actually been made." ;; Not much fontification needed. (make-local-variable 'font-lock-keywords) (setq font-lock-keywords - (list - (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" - '(0 mdw-punct-face)))) - - (mdw-post-config-mode-hack)) + (list (list (concat "\\(" + "\\_<[-+]?" + "\\(" "[0-9]+/[0-9]+" + "\\|" "\\(" "[0-9]+" "\\(\\.[0-9]*\\)?" "\\|" + "\\.[0-9]+" "\\)" + "\\([dDeEfFlLsS][-+]?[0-9]+\\)?" + "\\)" + "\\|" + "#" + "\\(" "x" "[-+]?" + "[0-9A-Fa-f]+" "\\(/[0-9A-Fa-f]+\\)?" + "\\|" "o" "[-+]?" "[0-7]+" "\\(/[0-7]+\\)?" + "\\|" "b" "[-+]?" "[01]+" "\\(/[01]+\\)?" + "\\|" "[0-9]+" "r" "[-+]?" + "[0-9a-zA-Z]+" "\\(/[0-9a-zA-Z]+\\)?" + "\\)" + "\\)\\_>") + '(0 mdw-number-face)) + (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" + '(0 mdw-punct-face))))) (defun comint-send-and-indent () (interactive) @@ -2612,6 +3475,13 @@ setting once it's actually been made." (indent-for-tab-command))) (defun mdw-setup-m4 () + + ;; Inexplicably, Emacs doesn't match braces in m4 mode. This is very + ;; annoying: fix it. + (modify-syntax-entry ?{ "(") + (modify-syntax-entry ?} ")") + + ;; Fill prefix. (mdw-standard-fill-prefix "\\([ \t]*\\(?:#+\\|\\\\)[ \t]*\\)")) ;;;-------------------------------------------------------------------------- @@ -2688,6 +3558,19 @@ This allows you to pass a list of arguments through `ansi-term'." (interactive "sHost: ") (ansi-term (list "ssh" host) (format "ssh@%s" host))) +(defvar git-grep-command + "env PAGER=cat git grep --no-color -nH -e " + "*The default command for \\[git-grep].") + +(defvar git-grep-history nil) + +(defun git-grep (command-args) + "Run `git grep' with user-specified args and collect output in a buffer." + (interactive + (list (read-shell-command "Run git grep (like this): " + git-grep-command 'git-grep-history))) + (grep command-args)) + ;;;-------------------------------------------------------------------------- ;;; Inferior Emacs Lisp.