X-Git-Url: https://git.distorted.org.uk/~mdw/profile/blobdiff_plain/043e413bb941f99b26a976112768bf7a8de21fff..459c9fb2fc1ea83ebc141cc8b898c4e704eafa63:/dot-emacs.el diff --git a/dot-emacs.el b/dot-emacs.el index 4f55e91..0599106 100644 --- a/dot-emacs.el +++ b/dot-emacs.el @@ -13,12 +13,12 @@ ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 2 of the License, or ;;; (at your option) any later version. -;;; +;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. -;;; +;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software Foundation, ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -36,6 +36,47 @@ ,(if (cdr forms) (cons 'progn forms) (car forms)) (error (message "Error (trapped): %s" (error-message-string err))))) +;; --- Configuration reading --- + +(defvar mdw-config nil) +(defun mdw-config (sym) + "Read the configuration variable named SYM." + (unless mdw-config + (setq mdw-config (with-temp-buffer + (insert-file-contents "~/.mdw.conf") + (replace-regexp "^[ \t]*\\(#.*\\|\\)\n" "" + nil (point-min) (point-max)) + (replace-regexp (concat "^[ \t]*" + "\\([-a-zA-Z0-9_.]*\\)" + "[ \t]*=[ \t]*" + "\\(.*[^ \t\n]\\|\\)" + "[ \t]**\\(\n\\|$\\)") + "(\\1 . \"\\2\") " + nil (point-min) (point-max)) + (car (read-from-string + (concat "(" (buffer-string) ")")))))) + (cdr (assq sym mdw-config))) + +;; --- Is an Emacs library available? --- + +(defun library-exists-p (name) + "Return non-nil if NAME.el (or NAME.elc) is somewhere on the Emacs load +path. The non-nil value is the filename we found for the library." + (let ((path load-path) elt (foundp nil)) + (while (and path (not foundp)) + (setq elt (car path)) + (setq path (cdr path)) + (setq foundp (or (let ((file (concat elt "/" name ".elc"))) + (and (file-exists-p file) file)) + (let ((file (concat elt "/" name ".el"))) + (and (file-exists-p file) file))))) + foundp)) + +(defun maybe-autoload (symbol file &optional docstring interactivep type) + "Set an autoload if the file actually exists." + (and (library-exists-p file) + (autoload symbol file docstring interactivep type))) + ;; --- Splitting windows --- (defconst mdw-scrollbar-width (if window-system 6 1) @@ -87,6 +128,19 @@ symbols `sunday', `monday', etc. (or a mixture). If the date stored in ;;;----- Utility functions -------------------------------------------------- +(defun line-number-at-pos (&optional pos) + "Print the current buffer line number and narrowed line number of point." + (let ((opoint (or pos (point))) start) + (save-excursion + (save-restriction + (goto-char (point-min)) + (widen) + (forward-line 0) + (setq start (point)) + (goto-char opoint) + (forward-line 0) + (1+ (count-lines 1 (point))))))) + ;; --- mdw-uniquify-alist --- (defun mdw-uniquify-alist (&rest alists) @@ -185,9 +239,9 @@ input lists are not modified, although they'll probably become garbage." (interactive) (save-excursion (or arg (progn - (goto-char (point-max)) + (goto-char (point-max)) (insert "\nNP: ") - (insert-file np-file))))) + (insert-file np-file))))) (trap (require 'tramp) @@ -251,6 +305,46 @@ Not much right now. Just support for doing MailCrypt stuff." (perform-replace "\n-- \n" "\n-- " nil nil nil))) (add-hook 'mail-setup-hook 'mdwmail-mangle-signature) +;;;----- URL viewing -------------------------------------------------------- + +(defun mdw-w3m-browse-url (url &optional new-session-p) + "Invoke w3m on the URL in its current window, or at least a different one. +If NEW-SESSION-P, start a new session." + (interactive "sURL: \nP") + (save-excursion + (let ((window (selected-window))) + (unwind-protect + (progn + (select-window (or (and (not new-session-p) + (get-buffer-window "*w3m*")) + (progn + (if (one-window-p t) (split-window)) + (get-lru-window)))) + (w3m-browse-url url new-session-p)) + (select-window window))))) + +(defvar mdw-good-url-browsers + '((w3m . mdw-w3m-browse-url) + browse-url-w3 + browse-url-mozilla) + "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).") + +(defun mdw-good-url-browser () + "Return a good URL browser. Trundle the list of such things, finding the +first item for which CHECK is fboundp, and returning the correponding FUNC." + (let ((bs mdw-good-url-browsers) b check func answer) + (while (and bs (not answer)) + (setq b (car bs) + bs (cdr bs)) + (if (consp b) + (setq check (car b) func (cdr b)) + (setq check b func b)) + (if (fboundp check) + (setq answer func))) + answer)) + ;;;----- Paragraph filling -------------------------------------------------- ;; --- Useful variables --- @@ -408,16 +502,20 @@ doesn't cope with anything approximating a complicated case." (and mdw-auto-indent (cond ((eq major-mode 'lisp-mode) (local-set-key "\C-m" 'mdw-indent-newline-and-indent)) - ((eq major-mode 'slime-repl-mode) nil) + ((or (eq major-mode 'slime-repl-mode) + (eq major-mode 'asm-mode)) + nil) (t (local-set-key "\C-m" 'newline-and-indent)))) (local-set-key [C-return] 'newline) - (local-set-key [?\;] 'self-insert-command) + (or (eq major-mode 'asm-mode) + (local-set-key [?\;] 'self-insert-command)) (local-set-key [?\#] 'self-insert-command) (local-set-key [?\"] 'self-insert-command) (setq comment-column 40) (auto-fill-mode 1) (setq fill-column 77) + (setq show-trailing-whitespace t) (mdw-set-font)) ;; --- Set up all sorts of faces --- @@ -431,26 +529,28 @@ doesn't cope with anything approximating a complicated case." ;;;----- General fontification ---------------------------------------------- -(defun mdw-set-fonts (frame ff) - (if ff (progn (set-face-attribute (caar ff) frame - :family 'unspecified - :width 'unspecified - :height 'unspecified - :weight 'unspecified - :slant 'unspecified - :foreground 'unspecified - :background 'unspecified - :underline 'unspecified - :overline 'unspecified - :strike-through 'unspecified - :box 'unspecified - :inverse-video 'unspecified - :stipple 'unspecified -; :font 'unspecified - :inherit 'unspecified - ) - (apply 'set-face-attribute (caar ff) frame (cdar ff)) - (mdw-set-fonts frame (cdr ff))))) +(defun mdw-set-fonts (frame faces) + (while faces + (let ((face (caar faces))) + (or (facep face) (make-face face)) + (set-face-attribute face frame + :family 'unspecified + :width 'unspecified + :height 'unspecified + :weight 'unspecified + :slant 'unspecified + :foreground 'unspecified + :background 'unspecified + :underline 'unspecified + :overline 'unspecified + :strike-through 'unspecified + :box 'unspecified + :inverse-video 'unspecified + :stipple 'unspecified + ;:font 'unspecified + :inherit 'unspecified) + (apply 'set-face-attribute face frame (cdar faces)) + (setq faces (cdr faces))))) (defun mdw-do-set-font (&optional frame) (interactive) @@ -497,6 +597,7 @@ doesn't cope with anything approximating a complicated case." (diff-removed-face :foreground "white" :slant italic) (whizzy-slice-face :background "grey10") (whizzy-error-face :background "darkred") + (trailing-whitespace :background "red") ))) (defun mdw-set-font () @@ -553,8 +654,6 @@ doesn't cope with anything approximating a complicated case." (setq c-hanging-comment-ender-p nil) (setq c-backslash-column 72) (setq c-label-minimum-indentation 0) - (setq comment-start "/* ") - (setq comment-end " */") (setq mdw-fill-prefix `((,(concat "\\([ \t]*/?\\)" "\\([\*/][ \t]*\\)" @@ -564,15 +663,15 @@ doesn't cope with anything approximating a complicated case." ;; --- Now define things to be fontified --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((c-keywords (make-regexp '( - ;; "and" ;C++ - ;; "and_eq" ;C++ + "and" ;C++ + "and_eq" ;C++ "asm" ;K&R, GCC "auto" ;K&R, C89 - ;; "bitand" ;C++ - ;; "bitor" ;C++ + "bitand" ;C++ + "bitor" ;C++ "bool" ;C++, C9X macro "break" ;K&R, C89 "case" ;K&R, C89 @@ -580,7 +679,7 @@ doesn't cope with anything approximating a complicated case." "char" ;K&R, C89 "class" ;C++ "complex" ;C9X macro, C++ template type - ;; "compl" ;C++ + "compl" ;C++ "const" ;C89 "const_cast" ;C++ "continue" ;K&R, C89 @@ -594,12 +693,12 @@ doesn't cope with anything approximating a complicated case." ;; "entry" ;K&R -- never used "enum" ;C89 "explicit" ;C++ - ;; "export" ;C++ + "export" ;C++ "extern" ;K&R, C89 "false" ;C++, C9X macro "float" ;K&R, C89 "for" ;K&R, C89 - "fortran" ;K&R + ;; "fortran" ;K&R "friend" ;C++ "goto" ;K&R, C89 "if" ;K&R, C89 @@ -611,8 +710,8 @@ doesn't cope with anything approximating a complicated case." "namespace" ;C++ "new" ;C++ "operator" ;C++ - ;; "or" ;C++ - ;; "or_eq" ;C++ + "or" ;C++ + "or_eq" ;C++ "private" ;C++ "protected" ;C++ "public" ;C++ @@ -645,8 +744,8 @@ doesn't cope with anything approximating a complicated case." "volatile" ;C89 "wchar_t" ;C++, C89 library type "while" ;K&R, C89 - ;; "xor" ;C++ - ;; "xor_eq" ;C++ + "xor" ;C++ + "xor_eq" ;C++ "_Bool" ;C9X "_Complex" ;C9X "_Imaginary" ;C9X @@ -748,7 +847,7 @@ doesn't cope with anything approximating a complicated case." ;; --- Now define things to be fontified --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((c-keywords (make-regexp '("break" "case" "cd" "continue" "define" "default" "do" "else" "exit" "for" "global" "goto" "help" "if" @@ -816,7 +915,7 @@ doesn't cope with anything approximating a complicated case." ;; --- Now define things to be fontified --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((java-keywords (make-regexp '("abstract" "boolean" "break" "byte" "case" "catch" "char" "class" "const" "continue" "default" "do" @@ -855,6 +954,95 @@ doesn't cope with anything approximating a complicated case." (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" '(0 mdw-punct-face)))))) +;;;----- C# programming configuration --------------------------------------- + +;; --- Make indentation nice --- + +(defun mdw-csharp-style () + (c-add-style "[mdw] C# style" + '((c-basic-offset . 2) + (c-tab-always-indent . nil) + (c-offsets-alist (substatement-open . 0) + (label . 0) + (case-label . +) + (access-label . 0) + (inclass . +) + (statement-case-intro . +))) + t)) + +;; --- Declare C# fontification style --- + +(defun mdw-fontify-csharp () + + ;; --- Other stuff --- + + (mdw-csharp-style) + (modify-syntax-entry ?_ "w") + (setq c-hanging-comment-ender-p nil) + (setq c-backslash-column 72) + (setq comment-start "/* ") + (setq comment-end " */") + (setq mdw-fill-prefix + `((,(concat "\\([ \t]*/?\\)" + "\\([\*/][ \t]*\\)" + "\\([A-Za-z]+:[ \t]*\\)?" + mdw-hanging-indents) + (pad . 1) (match . 2) (pad . 3) (pad . 4)))) + + ;; --- Now define things to be fontified --- + + (make-local-variable 'font-lock-keywords) + (let ((csharp-keywords + (make-regexp '("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")))) + + (setq font-lock-keywords + (list + 't + + ;; --- Handle the keywords defined above --- + + (list (concat "\\<\\(" csharp-keywords "\\)\\>") + '(0 font-lock-keyword-face)) + + ;; --- Handle numbers too --- + ;; + ;; 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]+\\|\\)\\)" + "[lLfFdD]?") + '(0 mdw-number-face)) + + ;; --- And anything else is punctuation --- + + (list "\\(\\s.\\|\\s(\\|\\s)\\|\\s\\\\|\\s/\\)" + '(0 mdw-punct-face)))))) + +(defun csharp-mode () + (interactive) + (java-mode) + (setq major-mode 'csharp-mode) + (setq mode-name "C#") + (mdw-fontify-csharp) + (run-hooks 'csharp-mode-hook)) + ;;;----- Awk programming configuration -------------------------------------- ;; --- Make Awk indentation nice --- @@ -881,7 +1069,7 @@ doesn't cope with anything approximating a complicated case." ;; --- Now define things to be fontified --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((c-keywords (make-regexp '("BEGIN" "END" "ARGC" "ARGIND" "ARGV" "CONVFMT" "ENVIRON" "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" @@ -946,7 +1134,7 @@ doesn't cope with anything approximating a complicated case." ;; --- Now define fontification things --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((perl-keywords (make-regexp '("and" "cmp" "continue" "do" "else" "elsif" "eq" "for" "foreach" "ge" "gt" "goto" "if" @@ -1004,7 +1192,7 @@ strip numbers instead." ;; --- Now define fontification things --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((python-keywords (make-regexp '("and" "as" "assert" "break" "class" "continue" "def" "del" "elif" "else" "except" "exec" "finally" "for" @@ -1089,7 +1277,7 @@ strip numbers instead." ;; --- Fiddle with fontification --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (setq font-lock-keywords (list 't @@ -1124,12 +1312,20 @@ strip numbers instead." (run-hooks 'arm-assembler-mode-hook)) +;;;----- Assembler mode ----------------------------------------------------- + +(defun mdw-fontify-asm () + (modify-syntax-entry ?' "\"") + (modify-syntax-entry ?. "w") + (setf fill-prefix nil) + (mdw-standard-fill-prefix "\\([ \t]*;+[ \t]*\\)")) + ;;;----- TCL configuration -------------------------------------------------- (defun mdw-fontify-tcl () (mapcar #'(lambda (ch) (modify-syntax-entry ch ".")) '(?$)) (mdw-standard-fill-prefix "\\([ \t]*#+[ \t]*\\)") - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (setq font-lock-keywords (list 't @@ -1174,7 +1370,7 @@ strip numbers instead." (setq rexx-tab-always-indent nil) (setq rexx-cont-indent rexx-indent) - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((rexx-keywords (make-regexp '("address" "arg" "by" "call" "digits" "do" "drop" "else" "end" "engineering" "exit" "expose" "for" @@ -1234,7 +1430,7 @@ strip numbers instead." ;; --- Now define fontification things --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((sml-keywords (make-regexp '("abstype" "and" "andalso" "as" "case" @@ -1265,10 +1461,10 @@ strip numbers instead." (list (concat "\\<\\(\\~\\|\\)" "\\(0\\(\\([wW]\\|\\)[xX][0-9a-fA-F]+\\|" - "[wW][0-9]+\\)\\|" - "\\([0-9]+\\(\\.[0-9]+\\|\\)" - "\\([eE]\\(\\~\\|\\)" - "[0-9]+\\|\\)\\)\\)") + "[wW][0-9]+\\)\\|" + "\\([0-9]+\\(\\.[0-9]+\\|\\)" + "\\([eE]\\(\\~\\|\\)" + "[0-9]+\\|\\)\\)\\)") '(0 mdw-number-face)) ;; --- And anything else is punctuation --- @@ -1295,7 +1491,7 @@ strip numbers instead." ;; --- Fiddle with fontification --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (let ((haskell-keywords (make-regexp '("as" "case" "ccall" "class" "data" "default" "deriving" "do" "else" "foreign" "hiding" "if" @@ -1327,7 +1523,7 @@ strip numbers instead." ;; --- Real fontification things --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (setq font-lock-keywords (list 't @@ -1375,7 +1571,7 @@ strip numbers instead." ;; --- Real fontification things --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (setq font-lock-keywords (list 't @@ -1400,31 +1596,31 @@ strip numbers instead." ;; --- Handle @/.../ for italics --- ;; (list "\\(@/\\)\\([^/]*\\)\\(/\\)" - ;; '(1 font-lock-keyword-face) - ;; '(3 font-lock-keyword-face)) + ;; '(1 font-lock-keyword-face) + ;; '(3 font-lock-keyword-face)) ;; --- Handle @*...* for boldness --- ;; (list "\\(@\\*\\)\\([^*]*\\)\\(\\*\\)" - ;; '(1 font-lock-keyword-face) - ;; '(3 font-lock-keyword-face)) + ;; '(1 font-lock-keyword-face) + ;; '(3 font-lock-keyword-face)) ;; --- Handle @`...' for literal syntax things --- ;; (list "\\(@`\\)\\([^']*\\)\\('\\)" - ;; '(1 font-lock-keyword-face) - ;; '(3 font-lock-keyword-face)) + ;; '(1 font-lock-keyword-face) + ;; '(3 font-lock-keyword-face)) ;; --- Handle @<...> for nonterminals --- ;; (list "\\(@<\\)\\([^>]*\\)\\(>\\)" - ;; '(1 font-lock-keyword-face) - ;; '(3 font-lock-keyword-face)) + ;; '(1 font-lock-keyword-face) + ;; '(3 font-lock-keyword-face)) ;; --- Handle other @-commands --- ;; (list "@\\([^a-zA-Z]\\|[a-zA-Z]*\\)" - ;; '(0 font-lock-keyword-face)) + ;; '(0 font-lock-keyword-face)) ;; --- Make sure we get comments properly --- @@ -1547,15 +1743,14 @@ strip numbers instead." '(2 font-lock-string-face)) (list (concat "^\\([ \t]*#[ \t]*\\(\\(" preprocessor-keywords - "\\)\\>\\|[0-9]+\\|$\\)\\)") + "\\)\\>\\|[0-9]+\\|$\\)\\)") '(1 font-lock-keyword-face))) message-mode-keywords))) - (setq font-lock-defaults - '(message-mode-keywords nil nil nil nil)) (turn-on-font-lock-if-enabled) - (run-hooks 'messages-mode-hook)) + (run-hooks 'cpp-messages-mode-hook)) -(add-hook 'messages-file-hook 'mdw-misc-mode-config t) +(add-hook 'messages-mode-hook 'mdw-misc-mode-config t) +(add-hook 'cpp-messages-mode-hook 'mdw-misc-mode-config t) ; (add-hook 'messages-file-hook 'mdw-fontify-messages t) ;;;----- Messages-file mode ------------------------------------------------- @@ -1658,7 +1853,7 @@ strip numbers instead." (local-set-key "\C-i" 'smalltalk-reindent)) (defun mdw-fontify-smalltalk () - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (setq font-lock-keywords (list 't @@ -1699,7 +1894,7 @@ strip numbers instead." ;; --- Not much fontification needed --- - (make-local-variable 'font-lock-keywords) + (make-local-variable 'font-lock-keywords) (setq font-lock-keywords (list 't @@ -1729,7 +1924,7 @@ strip numbers instead." 'comint-watch-for-password-prompt)) (defun mdw-term-mode-setup () - (setq term-prompt-regexp "^[^]#$%>»\n]*[]#$%>»] *") + (setq term-prompt-regexp "^[^]#$%>»}\n]*[]#$%>»}] *") (make-local-variable 'mouse-yank-at-point) (make-local-variable 'transient-mark-mode) (setq mouse-yank-at-point t)