(and (= emacs-major-version major)
(>= emacs-minor-version (or minor 0)))))
+(defun mdw-submode-p (mode parent)
+ "Return non-nil if MODE is indirectly derived from PARENT."
+ (let ((answer nil))
+ (while (cond ((eq mode parent) (setq answer t) nil)
+ (t (setq mode (get mode 'derived-mode-parent)))))
+ answer))
+
;; Some error trapping.
;;
;; If individual bits of this file go tits-up, we don't particularly want
;; the whole lot to stop right there and then, because it's bloody annoying.
-(defmacro trap (&rest forms)
- "Execute FORMS without allowing errors to propagate outside."
- (declare (indent 0)
- (debug t))
- `(condition-case err
- ,(if (cdr forms) (cons 'progn forms) (car forms))
- (error (message "Error (trapped): %s in %s"
- (error-message-string err)
- ',forms))))
+(eval-and-compile
+ (defmacro trap (&rest forms)
+ "Execute FORMS without allowing errors to propagate outside."
+ (declare (indent 0)
+ (debug t))
+ `(condition-case err
+ ,(if (cdr forms) (cons 'progn forms) (car forms))
+ (error (message "Error (trapped): %s in %s"
+ (error-message-string err)
+ ',forms)))))
;; Configuration reading.
(set-frame-parameter frame 'background-color (car colour))
(set-frame-parameter frame 'foreground-color (cdr colour)))
+;; Window configuration switching.
+
+(defvar mdw-current-window-configuration nil
+ "The current window configuration register name, or `nil'.")
+
+(defun mdw-switch-window-configuration (register &optional no-save)
+ "Switch make REGISTER be the new current window configuration.
+If a current window configuration register is established, and
+NO-SAVE is nil, then save the current window configuration to
+that register first.
+
+Signal an error if the new register contains something other than
+a window configuration. If the register is unset then save the
+current window configuration to it immediately.
+
+With one or three C-u, or an odd numeric prefix argument, set
+NO-SAVE, so the previous window configuration register is left
+unchanged.
+
+With two or three C-u, or a prefix argument which is an odd
+multiple of 2, just clear the record of the current window
+configuration register, so that the next switch doesn't save the
+prevailing configuration."
+ (interactive
+ (let ((arg current-prefix-arg))
+ (list (if (or (and (consp arg) (= (car arg) 16) (= (car arg) 64))
+ (and (integerp arg) (not (zerop (logand arg 2)))))
+ nil
+ (register-read-with-preview "Switch to window configuration: "))
+ (or (and (consp arg) (= (car arg) 4) (= (car arg) 64))
+ (and (integerp arg) (not (zerop (logand arg 1))))))))
+
+ (let ((previous mdw-current-window-configuration)
+ (current-windows (list (current-window-configuration)
+ (point-marker)))
+ (register-value (and register (get-register register))))
+ (when (and mdw-current-window-configuration (not no-save))
+ (set-register mdw-current-window-configuration current-windows))
+ (cond ((null register)
+ (setq mdw-current-window-configuration nil)
+ (if previous
+ (message "Left window configuration `%c'." previous)
+ (message "Nothing to do!")))
+ ((not (or (null register-value)
+ (and (consp register-value)
+ (window-configuration-p (car register-value))
+ (integer-or-marker-p (cadr register-value))
+ (null (caddr register-value)))))
+ (error "Register `%c' is not a window configuration" register))
+ (t
+ (cond ((null register-value)
+ (set-register register current-windows)
+ (message "Started new window configuration `%c'."
+ register))
+ (t
+ (set-window-configuration (car register-value))
+ (goto-char (cadr register-value))
+ (message "Switched to window configuration `%c'."
+ register)))
+ (setq mdw-current-window-configuration register)))))
+
;; Don't raise windows unless I say so.
(defcustom mdw-inhibit-raise-frame nil
;; Some hacks to do with window placement.
+(defvar mdw-designated-window nil
+ "The window chosen by `mdw-designate-window', or nil.")
+
+(defun mdw-designated-window-display-buffer-function (buffer not-this-window)
+ "Display buffer function to use the designated window."
+ (unless mdw-designated-window (error "No designated window!"))
+ (prog1 mdw-designated-window
+ (with-selected-window mdw-designated-window (switch-to-buffer buffer))
+ (setq mdw-designated-window nil
+ display-buffer-function nil)))
+
+(defun mdw-display-buffer-in-designated-window (buffer alist)
+ "Display function to use the designated window."
+ (prog1 mdw-designated-window
+ (when mdw-designated-window
+ (with-selected-window mdw-designated-window
+ (switch-to-buffer buffer nil t)))
+ (setq mdw-designated-window nil)))
+
+(defun mdw-designate-window (cancel)
+ "Use the selected window for the next pop-up buffer.
+With a prefix argument, clear the designated window."
+ (interactive "P")
+ (let ((window (selected-window)))
+ (cond (cancel
+ (setq mdw-designated-window nil)
+ (unless (mdw-emacs-version-p 24)
+ (setq display-buffer-function nil))
+ (message "Window designation cleared."))
+ ((window-dedicated-p window)
+ (error "Window is dedicated to its buffer."))
+ (t
+ (setq mdw-designated-window window)
+ (unless (mdw-emacs-version-p 24)
+ (setq display-buffer-function
+ #'mdw-designated-window-display-buffer-function))
+ (message "Window designated.")))))
+
+(when (mdw-emacs-version-p 24)
+ (setq display-buffer-base-action
+ (let* ((action display-buffer-base-action)
+ (funcs (car action))
+ (alist (cdr action)))
+ (cons (cons 'mdw-display-buffer-in-designated-window funcs)
+ alist))))
+
(defun mdw-clobber-other-windows-showing-buffer (buffer-or-name)
"Arrange that no windows on other frames are showing BUFFER-OR-NAME."
(interactive "bBuffer: ")
(defadvice gnus-other-frame (around mdw-hack-frame-width compile activate)
"Always arrange for mail/news frames to be 80 columns wide."
(let ((default-frame-alist (cons `(width . ,(+ 80 mdw-frame-width-fudge))
- (cl-delete 'width default-frame-alist
- :key #'car))))
+ (delete* 'width default-frame-alist
+ :key #'car))))
ad-do-it))
;; Preferred programs.
(line-height . 10.55)
(space-width . 5.1)
(avg-char-width . 5.1)))
- (cl-remove 'CourierCondensed ps-font-info-database
- :key #'car)))))
+ (remove* 'CourierCondensed ps-font-info-database
+ :key #'car)))))
;; Arrange to strip overlays from the buffer before we print . This will
;; prevent `flyspell' from interfering with the printout. (It would be less
(t :weight bold))
(mdw-define-face font-lock-variable-name-face
(t :slant italic))
-(mdw-define-face font-lock-comment-delimiter-face
- (((min-colors 64)) :slant italic :foreground "SeaGreen1")
- (((class color)) :foreground "green")
- (t :weight bold))
(mdw-define-face font-lock-comment-face
(((min-colors 64)) :slant italic :foreground "SeaGreen1")
(((class color)) :foreground "green")
(t :weight bold))
+(mdw-define-face font-lock-comment-delimiter-face
+ (t :inherit font-lock-comment-face))
(mdw-define-face font-lock-string-face
(((min-colors 64)) :foreground "SkyBlue1")
(((class color)) :foreground "cyan")
(t :weight bold))
+(mdw-define-face font-lock-doc-face
+ (t :inherit font-lock-string-face))
(mdw-define-face message-separator
(t :background "red" :foreground "white" :weight bold))
(add-hook 'post-command-hook 'mdw-update-terminal-title)
;;;--------------------------------------------------------------------------
+;;; Ediff hacking.
+
+(defvar mdw-ediff-previous-windows)
+(defun mdw-ediff-setup ()
+ (setq mdw-ediff-previous-windows (current-window-configuration)))
+(defun mdw-ediff-suspend-or-quit ()
+ (set-window-configuration mdw-ediff-previous-windows))
+(add-hook 'ediff-before-setup-hook 'mdw-ediff-setup)
+(add-hook 'ediff-quit-hook 'mdw-ediff-suspend-or-quit t)
+(add-hook 'ediff-suspend-hook 'mdw-ediff-suspend-or-quit t)
+
+;;;--------------------------------------------------------------------------
;;; C programming configuration.
;; Make C indentation nice.
(let ((output nil))
(dolist (item first)
(let ((key (car item)) (value (cdr item)))
- (if (string-suffix-p "-alist" (symbol-name key))
+ (if (let* ((key-name (symbol-name key))
+ (key-len (length key-name)))
+ (and (>= key-len 5)
+ (string= (subseq key-name (- key-len 5)) "-alist")))
(push (cons key
(mdw-merge-style-alists value
(cdr (assoc key second))))
(push item output)))
(nreverse output)))
-(cl-defmacro mdw-define-c-style (name (&optional parent) &rest assocs)
+(defmacro* mdw-define-c-style (name (&optional parent) &rest assocs)
"Define a C style, called NAME (a symbol) based on PARENT, 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
;; And anything else is punctuation.
(list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
- '(0 mdw-punct-face)))))
+ '(0 mdw-punct-face)))
+ font-lock-syntactic-face-function . nil))
;; Hack key bindings.
(local-set-key [?{] 'mdw-self-insert-and-indent)
(setq-default cperl-indent-level 2
cperl-continued-statement-offset 2
+ cperl-indent-region-fix-constructs nil
cperl-continued-brace-offset 0
cperl-brace-offset -2
cperl-brace-imaginary-offset 0
;;;--------------------------------------------------------------------------
;;; HTML, CSS, and other web foolishness.
-(setq-default css-indent-offset 2)
+(setq-default css-indent-offset 8)
;;;--------------------------------------------------------------------------
;;; SGML hacking.
(eq lisp-indent-backquote-substitution-mode 'corrected))
(save-excursion
(goto-char (elt state 1))
- (cl-incf loop-indentation
+ (incf loop-indentation
(cond ((eq (char-before) ?,) -1)
((and (eq (char-before) ?@)
(progn (backward-char)
(smerge-mode 1))))
(add-hook 'find-file-hook 'mdw-try-smerge t)
+(defcustom mdw-magit-new-window-modes
+ '(magit-diff-mode
+ magit-log-mode
+ magit-process-mode
+ magit-revision-mode
+ magit-stash-mode
+ magit-status-mode)
+ "Magit modes which should cause a new window to be used."
+ :type '(repeat symbol))
+
+(defun mdw-display-magit-buffer (buffer)
+ "Like `magit-display-buffer-traditional'.
+But uses `mdw-magit-new-window-modes' for its list of modes
+rather than baking the list into the function."
+ (display-buffer buffer
+ (let ((mode (with-current-buffer buffer major-mode)))
+ (if (and (not mdw-designated-window)
+ (derived-mode-p 'magit-mode)
+ (mdw-submode-p mode 'magit-mode)
+ (not (memq mode mdw-magit-new-window-modes)))
+ '(display-buffer-same-window . nil)
+ nil))))
+(setq magit-display-buffer-function 'mdw-display-magit-buffer)
+
+(defun mdw-display-magit-file-buffer (buffer)
+ "Show a file buffer from a diff."
+ (select-window (display-buffer buffer)))
+(setq magit-display-file-buffer-function 'mdw-display-magit-file-buffer)
+
;;;--------------------------------------------------------------------------
;;; GUD, and especially GDB.
(set-window-dedicated-p (or window (selected-window)) nil))
;;;--------------------------------------------------------------------------
+;;; SQL stuff.
+
+(setq sql-postgres-options '("-n" "-P" "pager=off")
+ sql-postgres-login-params
+ '((user :default "mdw")
+ (database :default "mdw")
+ (server :default "db.distorted.org.uk")))
+
+;;;--------------------------------------------------------------------------
;;; Man pages.
;; Turn off `noip' when running `man': it interferes with `man-db''s own