(replace-match with t))))
(with-temp-buffer
(insert-file-contents "~/.mdw.conf")
- (replace "^[ \t]*\\(#.*\\|\\)\n" "")
+ (replace "^[ \t]*\\(#.*\\)?\n" "")
(replace (concat "^[ \t]*"
"\\([-a-zA-Z0-9_.]*\\)"
"[ \t]*=[ \t]*"
- "\\(.*[^ \t\n]\\|\\)"
+ "\\(.*[^ \t\n]\\)?"
"[ \t]**\\(\n\\|$\\)")
"(\\1 . \"\\2\")\n")
(car (read-from-string
(set-frame-parameter frame 'menu-bar-lines 0)
(set-frame-parameter frame 'menu-bar-lines old)))
+;; Page motion.
+
+(defun mdw-fixup-page-position ()
+ (unless (eq (char-before (point)) ?\f)
+ (forward-line 0)))
+
+(defadvice backward-page (after mdw-fixup compile activate)
+ (mdw-fixup-page-position))
+(defadvice forward-page (after mdw-fixup compile activate)
+ (mdw-fixup-page-position))
+
;; Splitting windows.
(unless (fboundp 'scroll-bar-columns)
sb-width))
(mdw-divvy-window width)))
+(defvar mdw-frame-width-fudge
+ (cond ((<= emacs-major-version 20) 1)
+ ((= emacs-major-version 26) 3)
+ (t 0))
+ "The number of extra columns to add to the desired frame width.
+
+This is sadly necessary because Emacs 26 is broken in this regard.")
+
;; Don't raise windows unless I say so.
(defvar mdw-inhibit-raise-frame nil
(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)))
+ (year (- (calendar-extract-year date) 1900))
+ (month (1- (calendar-extract-month date)))
+ (day (1- (calendar-extract-day date)))
(julian (+ (aref day-count month) day))
(dyear (+ year 3066)))
(if (and (= month 1) (= day 28))
(let ((mdw-diary-for-org-mode-p t))
ad-do-it))
+(defvar diary-time-regexp nil)
+
(defadvice diary-add-to-list (before mdw-trim-leading-space compile activate)
"Trim leading space from the diary entry string."
(save-match-data
Pretend they don't exist. They might be on other display devices."
(ad-set-arg 2 nil))
+(setq even-window-sizes nil
+ even-window-heights nil)
+
+;; Rename buffers along with files.
+
+(defvar mdw-inhibit-rename-buffer nil
+ "If non-nil, `rename-file' won't rename the buffer visiting the file.")
+
+(defmacro mdw-advise-to-inhibit-rename-buffer (function)
+ "Advise FUNCTION to set `mdw-inhibit-rename-buffer' while it runs.
+
+This will prevent `rename-file' from renaming the buffer."
+ `(defadvice ,function (around mdw-inhibit-rename-buffer compile activate)
+ "Don't rename the buffer when renaming the underlying file."
+ (let ((mdw-inhibit-rename-buffer t))
+ ad-do-it)))
+(mdw-advise-to-inhibit-rename-buffer recode-file-name)
+(mdw-advise-to-inhibit-rename-buffer set-visited-file-name)
+(mdw-advise-to-inhibit-rename-buffer backup-buffer)
+
+(defadvice rename-file (after mdw-rename-buffers (from to &optional forcep)
+ compile activate)
+ "If a buffer is visiting the file, rename it to match the new name.
+
+Don't do this if `mdw-inhibit-rename-buffer' is non-nil."
+ (unless mdw-inhibit-rename-buffer
+ (let ((buffer (get-file-buffer from)))
+ (when buffer
+ (with-current-buffer buffer
+ (set-visited-file-name to nil t))))))
+
;;;--------------------------------------------------------------------------
;;; Improved compilation machinery.
(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)))
+ (insert (format "%S" (subst-char-in-string ?\n ?\s string)))
;; [mdw] missing from upstream
(backward-char 1))
(beginning-of-line)
'(defalias 'nnimap-transform-headers
(symbol-function 'mdw-nnimap-transform-headers)))
+(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))))
+ ad-do-it))
+
+;; Preferred programs.
+
+(setq mailcap-user-mime-data
+ '(((type . "application/pdf") (viewer . "mupdf %s"))))
+
;;;--------------------------------------------------------------------------
;;; Utility functions.
variable) and there's a match from one of the regexps here, it
gets used to set the fill-prefix for the current operation.
-The variable is a list of items of the form `REGEXP . PREFIX'; if
-the REGEXP matches, the PREFIX is used to set the fill prefix.
-It in turn is a list of things:
+The variable is a list of items of the form `PATTERN . PREFIX'; if
+the PATTERN matches, the PREFIX is used to set the fill prefix.
+
+A PATTERN is one of the following.
+
+ * STRING -- a regular expression, expected to match at point
+ * (eval . FORM) -- a Lisp form which must evaluate non-nil
+ * (if COND CONSEQ-PAT ALT-PAT) -- if COND evaluates non-nil, must match
+ CONSEQ-PAT; otherwise must match ALT-PAT
+ * (and PATTERN ...) -- must match all of the PATTERNs
+ * (or PATTERN ...) -- must match at least one PATTERN
+ * (not PATTERN) -- mustn't match (probably not useful)
- STRING -- insert a literal string
- (match . N) -- insert the thing matched by bracketed subexpression N
- (pad . N) -- a string of whitespace the same width as subexpression N
- (expr . FORM) -- the result of evaluating FORM")
+A PREFIX is a list of the following kinds of things:
+
+ * STRING -- insert a literal string
+ * (match . N) -- insert the thing matched by bracketed subexpression N
+ * (pad . N) -- a string of whitespace the same width as subexpression N
+ * (expr . FORM) -- the result of evaluating FORM
+
+Information about `bracketed subexpressions' comes from the match data,
+as modified during matching.")
(make-variable-buffer-local 'mdw-fill-prefix)
(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
-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)))))
+(defun mdw-fill-prefix-match-p (pat)
+ "Return non-nil if PAT matches at the current position."
+ (cond ((stringp pat) (looking-at pat))
+ ((not (consp pat)) (error "Unknown pattern item `%S'" pat))
+ ((eq (car pat) 'eval) (eval (cdr pat)))
+ ((eq (car pat) 'if)
+ (if (or (null (cdr pat))
+ (null (cddr pat))
+ (null (cdddr pat))
+ (cddddr pat))
+ (error "Invalid `if' pattern `%S'" pat))
+ (mdw-fill-prefix-match-p (if (eval (cadr pat))
+ (caddr pat)
+ (cadddr pat))))
+ ((eq (car pat) 'and)
+ (let ((pats (cdr pat))
+ (ok t))
+ (while (and pats
+ (or (mdw-fill-prefix-match-p (car pats))
+ (setq ok nil)))
+ (setq pats (cdr pats)))
+ ok))
+ ((eq (car pat) 'or)
+ (let ((pats (cdr pat))
+ (ok nil))
+ (while (and pats
+ (or (not (mdw-fill-prefix-match-p (car pats)))
+ (progn (setq ok t) nil)))
+ (setq pats (cdr pats)))
+ ok))
+ ((eq (car pat) 'not)
+ (if (or (null (cdr pat)) (cddr pat))
+ (error "Invalid `not' pattern `%S'" pat))
+ (not (mdw-fill-prefix-match-p (car pats))))
+ (t (error "Unknown pattern form `%S'" pat))))
(defun mdw-maybe-car (p)
"If P is a pair, return (car P), otherwise just return P."
((eq (car m) 'eval) (eval (cdr m)))
(t "")))
+(defun mdw-examine-fill-prefixes (l)
+ "Given a list of dynamic fill prefixes, pick one which matches
+context and return the static fill prefix to use. Point must be
+at the start of a line, and match data must be saved."
+ (let ((prefix nil))
+ (while (cond ((null l) nil)
+ ((mdw-fill-prefix-match-p (caar l))
+ (setq prefix
+ (mdw-maybe-tabify
+ (apply #'concat
+ (mapcar #'mdw-do-prefix-match
+ (cdr (car l))))))
+ nil))
+ (setq l (cdr l)))
+ prefix))
+
(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)
(let ((fill-prefix (mdw-choose-dynamic-fill-prefix)))
(fill-paragraph nil)))
+(defun mdw-point-within-string-p ()
+ "Return non-nil if point is within a string."
+ (let ((state (syntax-ppss)))
+ (elt state 3)))
+
(defun mdw-standard-fill-prefix (rx &optional mat)
"Set the dynamic fill prefix, handling standard hanging indents and stuff.
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)
+ `(((if (mdw-point-within-string-p)
+ ,(concat "\\(\\s-*\\)" mdw-hanging-indents)
+ ,(concat rx mdw-hanging-indents))
(match . 1)
(pad . ,(or mat 2))))))
(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 page-delimiter (concat "^" "\f"
+ "\\|" "^"
+ ".\\{0,4\\}"
+ "-\\{5\\}"
+ "\\(" " " ".*" " " "\\)?"
+ "-+"
+ ".\\{0,2\\}"
+ "$"))
(setq comment-column 40)
(auto-fill-mode 1)
(setq fill-column mdw-text-width)
+ (flyspell-prog-mode)
(and (fboundp 'gtags-mode)
(gtags-mode))
(if (fboundp 'hs-minor-mode)
(((type w32)) :family "courier new" :height 85)
(((type x)) :family "6x13" :foundry "trad" :height 130)
(t :foreground "white" :background "black"))
-(if (mdw-emacs-version-p 23)
- (mdw-define-face variable-pitch
- (((type x)) :family "sans" :height 100))
- (mdw-define-face variable-pitch
- (((type x)) :family "helvetica" :height 90)))
+(mdw-define-face fixed-pitch-serif
+ (((type w32)) :family "courier new" :height 85 :weight bold)
+ (((type x)) :family "6x13" :foundry "trad" :height 130 :weight bold)
+ (t :foreground "white" :background "black" :weight bold))
+(mdw-define-face variable-pitch
+ (((type x)) :family "helvetica" :height 120))
(mdw-define-face region
(((min-colors 64)) :background "grey30")
(((class color)) :background "blue")
(mdw-define-face gnus-cite-11
(t :foreground "grey"))
+(mdw-define-face gnus-emphasis-underline
+ (((type tty)) :underline t)
+ (t :slant italic))
+
(mdw-define-face diff-header
(t nil))
(mdw-define-face diff-index
mdw-point-overlay-mode
(lambda () (if (not (minibufferp)) (mdw-point-overlay-mode t))))
+(defvar mdw-terminal-title-alist nil)
+(defun mdw-update-terminal-title ()
+ (when (let ((term (frame-parameter nil 'tty-type)))
+ (and term (string-match "^xterm" term)))
+ (let* ((tty (frame-parameter nil 'tty))
+ (old (assoc tty mdw-terminal-title-alist))
+ (new (format-mode-line frame-title-format)))
+ (unless (and old (equal (cdr old) new))
+ (if old (rplacd old new)
+ (setq mdw-terminal-title-alist
+ (cons (cons tty new) mdw-terminal-title-alist)))
+ (send-string-to-terminal (concat "\e]2;" new "\e\\"))))))
+
+(add-hook 'post-command-hook 'mdw-update-terminal-title)
+
;;;--------------------------------------------------------------------------
;;; C programming configuration.
(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.
+(defun mdw-merge-style-alists (first second)
+ (let ((output nil))
+ (dolist (item first)
+ (let ((key (car item)) (value (cdr item)))
+ (if (string-suffix-p "-alist" (symbol-name key))
+ (push (cons key
+ (mdw-merge-style-alists value
+ (cdr (assoc key second))))
+ output)
+ (push item output))))
+ (dolist (item second)
+ (unless (assoc (car item) first)
+ (push item output)))
+ (nreverse output)))
+
+(cl-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
`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))
+ (var (intern (concat "mdw-c-style/" name-string)))
(func (intern (concat "mdw-define-c-style/" name-string))))
`(progn
- (defun ,func () (c-add-style ,name-string ',assocs))
+ (setq ,var
+ ,(if (null parent)
+ `',assocs
+ (let ((parent-list (intern (concat "mdw-c-style/"
+ (symbol-name parent)))))
+ `(mdw-merge-style-alists ',assocs ,parent-list))))
+ (defun ,func () (c-add-style ,name-string ,var))
(and (featurep 'cc-mode) (,func))
- (add-hook 'mdw-define-c-styles-hook ',func))))
+ (add-hook 'mdw-define-c-styles-hook ',func)
+ ',name)))
(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 . -2)
- (inclass . +)
- (inline-open . ++)
- (statement-cont . +)
- (statement-case-intro . +)))
-
-(mdw-define-c-style mdw-c
+(mdw-define-c-style mdw-c ()
(c-basic-offset . 2)
(comment-column . 40)
(c-class-key . "class")
(statement-cont . +)
(statement-case-intro . +)))
+(mdw-define-c-style mdw-trustonic-basic-c (mdw-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-offsets-alist (access-label . -2)))
+
+(mdw-define-c-style mdw-trustonic-c (mdw-trustonic-basic-c)
+ (c-offsets-alist (arglist-cont-nonempty . mdw-c-indent-arglist-nested)))
+
(defun mdw-set-default-c-style (modes style)
"Update the default CC Mode style for MODES to be STYLE.
;; Fontify include files as strings.
(list (concat "^[ \t]*\\#[ \t]*"
"\\(include\\|import\\)"
- "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
+ "[ \t]*\\(<[^>]+>?\\)")
'(2 font-lock-string-face))
;; Preprocessor directives are `references'?.
;; Make indentation nice.
-(mdw-define-c-style mdw-java
+(mdw-define-c-style mdw-java ()
(c-basic-offset . 2)
(c-backslash-column . 72)
(c-offsets-alist (substatement-open . 0)
;; The following isn't quite right, but it's close enough.
(list (concat "\\<\\("
"0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
"[lLfFdD]?")
'(0 mdw-number-face))
;; The following isn't quite right, but it's close enough.
(list (concat "\\_<\\("
"0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
"[lLfFdD]?")
'(0 mdw-number-face))
;; As usual, not quite right.
(list (concat "\\_<\\("
"0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
"[lLfFdD]?")
'(0 mdw-number-face))
;; Make indentation nice.
-(mdw-define-c-style mdw-csharp
+(mdw-define-c-style mdw-csharp ()
(c-basic-offset . 2)
(c-backslash-column . 72)
(c-offsets-alist (substatement-open . 0)
;; The following isn't quite right, but it's close enough.
(list (concat "\\<\\("
"0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
"[lLfFdD]?")
'(0 mdw-number-face))
;; The following isn't quite right, but it's close enough.
(list (concat "\\<\\("
"0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)")
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)")
'(0 mdw-number-face))
;; And anything else is punctuation.
;; Make Awk indentation nice.
-(mdw-define-c-style mdw-awk
+(mdw-define-c-style mdw-awk ()
(c-basic-offset . 2)
(c-offsets-alist (substatement-open . 0)
(c-backslash-column . 72)
;; The following isn't quite right, but it's close enough.
(list (concat "\\<\\("
"0\\([xX][0-9a-fA-F]+\\|[0-7]+\\)\\|"
- "[0-9]+\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|\\)\\)"
+ "[0-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?\\)"
"[uUlL]*")
'(0 mdw-number-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_]+\\|\\)")
+ "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+ "\\([eE][-+]?[0-9_]+\\)?")
'(0 mdw-number-face))
;; And anything else is punctuation.
;; At least numbers are simpler than C.
(list (concat "\\_<0\\([xX][0-9a-fA-F]+\\|[oO]?[0-7]+\\|[bB][01]+\\)\\|"
- "\\_<[0-9][0-9]*\\(\\.[0-9]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9]+\\|[lL]\\|\\)")
+ "\\_<[0-9][0-9]*\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\|[lL]\\)?")
'(0 mdw-number-face))
;; And anything else is punctuation.
(setq font-lock-keywords
(list
(list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
- "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
+ "\\<[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+ "\\([eE][-+]?[0-9_]+\\)?")
'(0 mdw-number-face))
(list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
'(0 mdw-punct-face)))))
'(0 font-lock-keyword-face))
;; At least numbers are simpler than C.
- (list (concat "\\<\\(\\~\\|\\)"
- "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|"
+ (list (concat "\\<\\~?"
+ "\\(0\\([wW]?[xX][0-9a-fA-F]+\\|"
"[wW][0-9]+\\)\\|"
- "\\([0-9]+\\(\\.[0-9]+\\|\\)"
- "\\([eE]\\(\\~\\|\\)"
- "[0-9]+\\|\\)\\)\\)")
+ "\\([0-9]+\\(\\.[0-9]+\\)?"
+ "\\([eE]\\~?"
+ "[0-9]+\\)?\\)\\)")
'(0 mdw-number-face))
;; And anything else is punctuation.
(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-9]+\\(\\.[0-9]*\\)?"
+ "\\([eE][-+]?[0-9]+\\)?")
'(0 mdw-number-face))
(list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
'(0 mdw-punct-face))))))
'(0 font-lock-keyword-face))
(list (concat "^-\\sw+\\>")
'(0 font-lock-keyword-face))
- (list "\\<[0-9]+\\(\\|#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)\\>"
+ (list "\\<[0-9]+\\(#[0-9a-zA-Z]+\\|[eE][+-]?[0-9]+\\)?\\>"
'(0 mdw-number-face))
(list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
'(0 mdw-punct-face))))))
'(2 font-lock-variable-name-face))
;; Make sure we get comments properly.
- (list "@c\\(\\|omment\\)\\( .*\\)?$"
+ (list "@c\\(omment\\)?\\( .*\\)?$"
'(0 font-lock-comment-face))
;; Command names are keywords.
(setq messages-mode-keywords
(append (list (list (concat "^[ \t]*\\#[ \t]*"
"\\(include\\|import\\)"
- "[ \t]*\\(<[^>]+\\(>\\|\\)\\)")
+ "[ \t]*\\(<[^>]+\\(>\\)?\\)")
'(2 font-lock-string-face))
(list (concat "^\\([ \t]*#[ \t]*\\(\\("
preprocessor-keywords
(list
(list (concat "^%\\s *\\(}\\|\\(" keywords "\\)\\>\\).*$")
'(0 font-lock-keyword-face))
- (list "^%\\s *\\(#.*\\|\\)$"
+ (list "^%\\s *\\(#.*\\)?$"
'(0 font-lock-comment-face))
(list "^%"
'(0 font-lock-keyword-face))
(make-local-variable 'lisp-indent-function)
(setq lisp-indent-function 'common-lisp-indent-function))
-(setq-default lisp-simple-loop-indentation 2
- lisp-loop-keyword-indentation 6
- lisp-loop-forms-indentation 6)
-
(defmacro mdw-advise-hyperspec-lookup (func args)
`(defadvice ,func (around mdw-browse-w3m ,args activate compile)
(if (fboundp 'w3m)
(list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
'(0 mdw-punct-face)))))
+;; Special indentation.
+
+(defvar mdw-lisp-loop-default-indent 2)
+
+(setq lisp-simple-loop-indentation 0
+ lisp-loop-keyword-indentation 0
+ lisp-loop-forms-indentation 2
+ lisp-lambda-list-keyword-parameter-alignment t)
+
+(defun mdw-indent-funcall (path state indent-point sexp-column normal-indent)
+ "Indent `funcall' more usefully.
+Essentially, treat `funcall foo' as a function name, and align the arguments
+to `foo'."
+ (and (null (cdr path))
+ (save-excursion
+ (goto-char (cadr state))
+ (forward-char 1)
+ (let ((start-line (line-number-at-pos)))
+ (and (condition-case nil (progn (forward-sexp 3) t)
+ (scan-error nil))
+ (progn
+ (forward-sexp -1)
+ (and (= start-line (line-number-at-pos))
+ (current-column))))))))
+(put 'funcall 'common-lisp-indent-function 'mdw-indent-funcall)
+
+(defadvice common-lisp-loop-part-indentation
+ (around mdw-fix-loop-indentation (indent-point state) activate compile)
+ "Improve `loop' indentation.
+If the first subform is on the same line as the `loop' keyword, then
+align the other subforms beneath it. Otherwise, indent them
+`mdw-lisp-loop-default-indent' columns in from the opening parenthesis."
+
+ (let* ((loop-indentation (save-excursion
+ (goto-char (elt state 1))
+ (current-column))))
+
+ ;; Don't really care about this.
+ (when (and (eq lisp-indent-backquote-substitution-mode 'corrected))
+ (save-excursion
+ (goto-char (elt state 1))
+ (cl-incf loop-indentation
+ (cond ((eq (char-before) ?,) -1)
+ ((and (eq (char-before) ?@)
+ (progn (backward-char)
+ (eq (char-before) ?,)))
+ -2)
+ (t 0)))))
+
+ ;; If the first loop item is on the same line as the `loop' itself then
+ ;; use that as the baseline. Otherwise advance by the default indent.
+ (goto-char (cadr state))
+ (forward-char 1)
+ (let ((baseline-indent
+ (if (= (line-number-at-pos)
+ (if (condition-case nil (progn (forward-sexp 2) t)
+ (scan-error nil))
+ (progn (forward-sexp -1) (line-number-at-pos))
+ -1))
+ (current-column)
+ (+ loop-indentation mdw-lisp-loop-default-indent))))
+
+ (goto-char indent-point)
+ (beginning-of-line)
+
+ (setq ad-return-value
+ (list
+ (cond ((not (lisp-extended-loop-p (elt state 1)))
+ (+ baseline-indent lisp-simple-loop-indentation))
+ ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)")
+ (+ baseline-indent lisp-loop-keyword-indentation))
+ (t
+ (+ baseline-indent lisp-loop-forms-indentation)))
+
+ ;; Tell the caller that the next line needs recomputation, even
+ ;; though it doesn't start a sexp.
+ loop-indentation)))))
+
;; SLIME setup.
+(defvar mdw-friendly-name "[mdw]"
+ "How I want to be addressed.")
+(defadvice slime-user-first-name
+ (around mdw-use-friendly-name compile activate)
+ (if mdw-friendly-name (setq ad-return-value mdw-friendly-name)
+ ad-do-it))
+
(trap
(if (not mdw-fast-startup)
(progn
(list "\\<[A-Z][a-zA-Z0-9]*\\>"
'(0 font-lock-keyword-face))
(list (concat "\\<0\\([xX][0-9a-fA-F_]+\\|[0-7_]+\\)\\|"
- "[0-9][0-9_]*\\(\\.[0-9_]*\\|\\)"
- "\\([eE]\\([-+]\\|\\)[0-9_]+\\|\\)")
+ "[0-9][0-9_]*\\(\\.[0-9_]*\\)?"
+ "\\([eE][-+]?[0-9_]+\\)?")
'(0 mdw-number-face))
(list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)"
'(0 mdw-punct-face)))))
(set-window-dedicated-p (or window (selected-window)) nil))
;;;--------------------------------------------------------------------------
+;;; Man pages.
+
+;; Turn off `noip' when running `man': it interferes with `man-db''s own
+;; seccomp(2)-based sandboxing, which is (in this case, at least) strictly
+;; better.
+(defadvice Man-getpage-in-background
+ (around mdw-inhibit-noip (topic) compile activate)
+ "Inhibit the `noip' preload hack when invoking `man'."
+ (let* ((old-preload (getenv "LD_PRELOAD"))
+ (preloads (and old-preload
+ (save-match-data (split-string old-preload ":"))))
+ (any nil)
+ (filtered nil))
+ (save-match-data
+ (while preloads
+ (let ((item (pop preloads)))
+ (if (string-match "\\(/\\|^\\)noip\.so\\(:\\|$\\)" item)
+ (setq any t)
+ (push item filtered)))))
+ (if any
+ (unwind-protect
+ (progn
+ (setenv "LD_PRELOAD"
+ (and filtered
+ (with-output-to-string
+ (setq filtered (nreverse filtered))
+ (let ((first t))
+ (while filtered
+ (if first (setq first nil)
+ (write-char ?:))
+ (write-string (pop filtered)))))))
+ ad-do-it)
+ (setenv "LD_PRELOAD" old-preload))
+ ad-do-it)))
+
+;;;--------------------------------------------------------------------------
;;; MPC configuration.
(eval-when-compile (trap (require 'mpc)))