mmm-mode, crontab-mode, various
authorJoerg Jaspert <joerg@debian.org>
Wed, 22 May 2013 21:14:42 +0000 (23:14 +0200)
committerJoerg Jaspert <joerg@debian.org>
Wed, 22 May 2013 21:14:42 +0000 (23:14 +0200)
24 files changed:
.emacs.d/config/emacs.org
.emacs.d/elisp/local/crontab-mode.el [new file with mode: 0644]
.emacs.d/elisp/local/flymake-css.el [new file with mode: 0644]
.emacs.d/elisp/local/flymake-easy.el [new file with mode: 0644]
.emacs.d/elisp/local/loaddefs.el
.emacs.d/elisp/local/tidy.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-auto.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-class.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-cmds.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-compat.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-cweb.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-erb.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-mason.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-mode-autoloads.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-mode.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-myghty.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-noweb.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-region.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-rpm.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-sample.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-univ.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-utils.el [new file with mode: 0644]
.emacs.d/elisp/mmm/mmm-vars.el [new file with mode: 0644]
.emacs.d/initjj.org

index dc2865d..e2aeb09 100644 (file)
@@ -15,7 +15,7 @@ them first.
 
 safe-load does not break emacs initialization, should a file be
 unreadable while emacs boots up.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (defvar safe-load-error-list ""
           "*List of files that reported errors when loaded via safe-load")
   
@@ -39,7 +39,7 @@ unreadable while emacs boots up.
 #+END_SRC
 
 match-paren will either jump to the "other" paren or simply insert %
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defun match-paren (arg)
   "Go to the matching parenthesis if on parenthesis otherwise insert %."
   (interactive "p")
@@ -51,14 +51,14 @@ match-paren will either jump to the "other" paren or simply insert %
 I have some stuff put away in my local dir. I don't want to load it all
 at startup time, so it is using the autoload feature. For that to work
 load the loaddefs, so autoload knows where to grab stuff
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (load-file (concat jj-elisp-dir "/tiny/loaddefs.el"))
 (load-file (concat jj-elisp-local-dir "/loaddefs.el"))
 #+END_SRC
 
 
 Always ensure to have a scratch buffer around.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (save-excursion
     (set-buffer (get-buffer-create "*scratch*"))
     (lisp-interaction-mode)
@@ -66,8 +66,17 @@ Always ensure to have a scratch buffer around.
     (add-hook 'kill-buffer-query-functions 'kill-scratch-buffer))
 #+END_SRC
 
+Handier way to add modes to auto-mode-alist
+#+BEGIN_SRC emacs-lisp tangle:yes
+(defun add-auto-mode (mode &rest patterns)
+  "Add entries to `auto-mode-alist' to use `MODE' for all given file `PATTERNS'."
+  (dolist (pattern patterns)
+    (add-to-list 'auto-mode-alist (cons pattern mode))))
+#+END_SRC
+
+
 Helpers for the config
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'use-package)
 (require 'bind-key)
 #+END_SRC
@@ -80,10 +89,10 @@ that is already done in =init.el=.
 
 I also disliked the repeated /add-to-list/ lines, so I now just have
 one variable and go over that in a loop.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defvar jj-elisp-subdirs '(local gnus icicle org/contrib tiny mo-git-blame cedet
                            cedet/eieio ecb jdee/lisp sunrise multiple-cursors
-                           auto-complete yasnippet magit)
+                           auto-complete yasnippet magit mmm)
   "List of subdirectories in jj-elisp-dir to add to load-path")
 
 (let (dirval)
@@ -100,7 +109,7 @@ one variable and go over that in a loop.
 
 *** Info path
 Help emacs to find the info files
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq Info-directory-list '("~/emacs/info"
                             "/usr/local/share/info/"
                             "/usr/local/info/"
@@ -123,34 +132,34 @@ Help emacs to find the info files
 :ID: 0a1560d9-7e55-47ab-be52-b3a8b8eea4aa
 :END:
 I dislike the startup message
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq inhibit-splash-screen t)
 (setq inhibit-startup-message t)
 #+END_SRC
 
 Usually I want the lines to break at 72 characters.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (if (> emacs-major-version 22)
     (setq fill-column 72)
   (setq default-fill-column 72))
 #+END_SRC
 
 And it is nice to have a final newline in files.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq require-final-newline t)
 #+END_SRC
 
 After I typed 300 characters or took a break for more than a minute it
 would be nice of emacs to save whatever I am on in one of its auto-save
 backups. See [[info:emacs#Auto%20Save%20Control][info:emacs#Auto Save Control]] for more details.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq auto-save-interval 300)
 (setq auto-save-timeout   60)
 #+END_SRC
 
 Set my full name and my default mail address - for whatever wants to use
 it later. Also, I am using gnus.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq user-full-name "Joerg Jaspert")
 (setq user-mail-address "joerg@ganneff.de")
 (setq mail-user-agent (quote gnus-user-agent))
@@ -159,19 +168,19 @@ it later. Also, I am using gnus.
 My default mail server. Well, simply a localhost, I have a forwarder that
 puts mail off the right way, no need for emacs to have any further
 knowledge here.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq smtpmail-default-smtp-server "localhost")
 (setq smtpmail-smtp-server "localhost")
 #+END_SRC
 
 Enable automatic handling of compressed files.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (auto-compression-mode 1)
 #+END_SRC
 
 Emacs forbids a certain set of commands, as they can be very confusing
 for new users. Enable them.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (put 'narrow-to-region 'disabled nil)
 (put 'narrow-to-page 'disabled nil)
 (put 'narrow-to-defun 'disabled nil)
@@ -182,7 +191,7 @@ for new users. Enable them.
 *** Look / Theme
 I've tried various different fonts and while I like the Terminus font
 most for my shells, in Emacs Inconsolata clearly wins.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (if (> emacs-major-version 22)
     (set-frame-font "Inconsolata-14")
   (set-default-font "Inconsolata-14"))
@@ -190,7 +199,7 @@ most for my shells, in Emacs Inconsolata clearly wins.
 
 I always use dark backgrounds, so tell Emacs about it. No need to
 guess around.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq-default frame-background-mode 'dark)
 #+END_SRC
 
@@ -199,7 +208,7 @@ switched through multiple themes doing it in emacs too, but never
 entirely liked it. Until I found solarized, which is now not only my
 emacs theme, but also for most of my other software too, especially my
 shell. Consistent look is great.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (if (boundp 'custom-theme-load-path)
     (progn
       (defun jj-init-theme ()
@@ -218,20 +227,24 @@ shell. Consistent look is great.
 #+END_SRC
 
 Make the fringe (gutter) smaller, the argument is a width in pixels (the default is 8)
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (if (fboundp 'fringe-mode)
     (fringe-mode 4))
 #+END_SRC
 
+A bit more spacing between buffer lines
+#+BEGIN_SRC emacs-lisp tangle:yes
+(setq-default line-spacing 0.1)
+#+END_SRC
 *** Cursor changes
 [2013-04-21 So 20:54]
 I do not want my cursor to blink.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (blink-cursor-mode -1)
 #+END_SRC
 *** Menu, Tool and Scrollbar
 I don't want to see the menu-bar, tool-bar or scrollbar.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (when window-system
   (menu-bar-mode -1)
   (tool-bar-mode -1)
@@ -248,7 +261,7 @@ menu/tool/scrollbar settings. Sucks.
 For them to work even then, we have to do two things.
 1. We have to set the frame alist. We simple set both,
    =initial-frame-alist= and =default-frame-alist= to the same value here.
-   #+BEGIN_SRC emacs-lisp
+   #+BEGIN_SRC emacs-lisp tangle:yes
   (setq initial-frame-alist '(
                               (horizontal-scroll-bars . nil)
                               (vertical-scroll-bars . nil)
@@ -261,12 +274,12 @@ For them to work even then, we have to do two things.
 
 *** Hilight current line in buffer
 As it says, it does a hilight of the current line.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-hl-line-mode +1)
 #+END_SRC
 *** Allow recursive minibuffers
 This allows (additional) minibuffer commands while in the minibuffer.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq enable-recursive-minibuffers 't)
 #+END_SRC
 
@@ -277,7 +290,7 @@ Size indication lets me know how far I am in a buffer.
 And modeline-posn is great. It will hilight the column number in the
 modeline in red as soon as you are over the defined limit.
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (line-number-mode 1)
 (column-number-mode 1)
 (size-indication-mode 1)
@@ -297,7 +310,7 @@ see. So lets hide those. There are two ways, one of them uses diminish
 to get entirely rid of some modes, the other is a function taken from
 "Mastering Emacs" which replaces the modes text with an own (set of)
 character(s).
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (require 'diminish)
   (diminish 'auto-fill-function)
   (defvar mode-line-cleaner-alist
@@ -341,7 +354,7 @@ Back when I started with text-mode. But nowadays I want default mode to
 be org-mode - it is just so much better to use. And does sensible things
 with many README files out there, and various other "crap" you get to
 read in emacs.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (if (> emacs-major-version 22)
   (setq major-mode 'org-mode)
   (setq default-major-mode 'org-mode))
@@ -351,7 +364,7 @@ read in emacs.
 *** Shell
 [2013-04-23 Tue 16:43]
 Shell. zsh in my case.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq shell-file-name "zsh")
 (setq shell-command-switch "-c")
 (setq explicit-shell-file-name shell-file-name)
@@ -368,7 +381,7 @@ Shell. zsh in my case.
 
 *** Emacs shell
 Basic settings for emacs integrated shell
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq eshell-cmpl-cycle-completions nil
       eshell-save-history-on-exit t
       eshell-cmpl-dir-ignore "\\`\\(\\.\\.?\\|CVS\\|\\.svn\\|\\.git\\)/\\'")
@@ -401,7 +414,7 @@ you want. If you want to search for just the next (or previous)
 occurence of what is at your cursor position use the following.
 *C-x* will insert the current word while *M-up* and *M-down* will just
 jump to the next/previous occurence of it.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (define-key isearch-mode-map (kbd "C-x") 'sacha/isearch-yank-current-word)
 (global-set-key '[M-up] 'sacha/search-word-backward)
 (global-set-key '[M-down] 'sacha/search-word-forward)
@@ -410,7 +423,7 @@ jump to the next/previous occurence of it.
 *** Frame configuration
 I want to see the buffername and its size, not the host I am on in my
 frame title.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq frame-title-format "%b (%i)")
 #+END_SRC
 
@@ -418,7 +431,7 @@ frame title.
 I don't want some buffers to be killed, **scratch** for example.
 In the past I had a long function that just recreated them, but the
 =keep-buffers= package is easier.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'keep-buffers)
 (keep-buffers-mode 1)
 (push '("\\`*scratch" . erase) keep-buffers-protected-alist)
@@ -429,13 +442,13 @@ In the past I had a long function that just recreated them, but the
 *** yes-or-no-p
 Emas usually wants you to type /yes/ or /no/ fully. What a mess, I am
 lazy.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defalias 'yes-or-no-p 'y-or-n-p)
 #+END_SRC
 
 *** Language/i18n stuff
 In this day and age, UTF-8 is the way to go.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (set-language-environment 'utf-8)
 (set-default-coding-systems 'utf-8)
 (set-terminal-coding-system 'utf-8)
@@ -449,7 +462,7 @@ In this day and age, UTF-8 is the way to go.
 *** Hilight matching parentheses
 While I do have the nifty shortcut to jump to the other parentheses,
 hilighting them makes it obvious where they are.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'paren)
 (setq show-paren-style 'parenthesis)
 (show-paren-mode +1)
@@ -457,13 +470,13 @@ hilighting them makes it obvious where they are.
 *** Kill other buffers
 While many editors allow you to close "all the other files, not the one
 you are in", emacs doesn't have this... Except, now it will.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key (kbd "C-c k") 'prelude-kill-other-buffers)
 #+END_SRC
 *** Scrolling
 Default scrolling behaviour in emacs is a bit annoying, who wants to
 jump half-windows?
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq scroll-margin 0)
 (setq scroll-conservatively 100000)
 (setq scroll-up-aggressively 0.0)
@@ -475,7 +488,7 @@ jump half-windows?
 [2013-04-09 Di 23:31]
 The default how emacs handles cutting/pasting with the primary selection
 changed in emacs24. I am used to the old way, so get it back.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq x-select-enable-primary t)
 (setq x-select-enable-clipboard t        ;; copy-paste should work ...
   interprogram-paste-function            ;; ...with...
@@ -485,7 +498,7 @@ changed in emacs24. I am used to the old way, so get it back.
 
 *** Global keyboard changes not directly related to a mode
 Disable /suspend_frame/ function, I dislike it.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-unset-key [(control z)])
 (global-unset-key [(control x) (control z)])
 #+END_SRC
@@ -495,7 +508,7 @@ Default of *C-k* is to kill from the point to the end of line. If
 set, including newline. But to kill the entire line, one still needs a
 *C-a* in front of it. So I change it, by defining a function to do just this for
 me. Lazyness++.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defun kill-entire-line ()
   "Kill this entire line (including newline), regardless of where point is within the line."
   (interactive)
@@ -510,7 +523,7 @@ me. Lazyness++.
 
 And the same is true when I'm in org-mode, which has an own kill function...
 (the keybinding happens later, after org-mode is loaded fully)
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defun jj-org-kill-line (&optional arg)
   "Kill the entire line, regardless of where point is within the line, org-mode-version"
   (interactive "P")
@@ -523,12 +536,12 @@ And the same is true when I'm in org-mode, which has an own kill function...
 I really hate tabs, so I don't want any indentation to try using them.
 And in case a project really needs them, I can change it just for that
 file/project, but luckily none of those I work in is as broken.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq-default indent-tabs-mode nil)
 #+END_SRC
 
 Make the % key jump to the matching {}[]() if on another, like vi, see [[id:b6e6cf73-9802-4a7b-bd65-fdb6f9745319][the function]]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key "\M-5" 'match-paren)
 #+END_SRC
 
@@ -563,13 +576,13 @@ Rgrep is infinitely useful in multi-file projects.
 
 Easy way to move a line up - or down. Simpler than dealing with C-x C-t
 AKA transpose lines.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key [(meta shift up)]  'move-line-up)
 (global-set-key [(meta shift down)]  'move-line-down)
 #+END_SRC
 
 "Pull" lines up, join them
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key (kbd "M-j")
                 (lambda ()
                   (interactive)
@@ -577,24 +590,24 @@ AKA transpose lines.
 #+END_SRC
 
 When I press Enter I almost always want to go to the right indentation on the next line.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key (kbd "RET") 'newline-and-indent)
 #+END_SRC
 
 Easier undo, and i don't need suspend-frame
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key (kbd "C-z") 'undo)
 #+END_SRC
 
 Window switching, go backwards. (C-x o goes to the next window)
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key (kbd "C-x O") (lambda ()
                                 (interactive)
                                 (other-window -1)))
 #+END_SRC
 
 Edit file as root
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key (kbd "C-x C-r") 'prelude-sudo-edit)
 #+END_SRC
 
@@ -603,12 +616,12 @@ it does is remove all spaces around the cursor, except for one. But to
 be really useful, it also should include newlines. It doesn’t do this by
 default. Rather, you have to call it with a negative argument. Sure
 not, bad Emacs.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key (kbd "M-SPC") 'just-one-space-with-newline)
 #+END_SRC
 
 Count which commands I use how often.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defvar keyfreq-file
   (expand-file-name "keyfreq" jj-cache-dir)
   "Keyfreq cache file")
@@ -620,9 +633,25 @@ Count which commands I use how often.
 (keyfreq-autosave-mode 1)
 #+END_SRC
 
+Duplicate current line
+#+BEGIN_SRC emacs-lisp tangle:yes
+(defun duplicate-line ()
+  "Insert a copy of the current line after the current line."
+  (interactive)
+  (save-excursion
+    (let ((line-text (buffer-substring-no-properties
+                      (line-beginning-position)
+                      (line-end-position))))
+      (move-end-of-line 1)
+      (newline)
+      (insert line-text))))
+
+(global-set-key (kbd "C-c p") 'duplicate-line)
+#+END_SRC
+
 **** ace-jump-mode
 [2013-04-28 So 11:26]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'ace-jump-mode "ace-jump-mode" "Emacs quick move minor mode" t)
 (define-key global-map (kbd "H-SPC") 'ace-jump-mode)
 ;; enable a more powerful jump back function from ace jump mode
@@ -634,7 +663,7 @@ Count which commands I use how often.
 Usually you can press the *Ins*ert key, to get into overwrite mode. I
 don't like that, have broken much with it and so just forbid it by
 disabling that.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-unset-key [insert])
 (global-unset-key [kp-insert])
 #+END_SRC
@@ -644,7 +673,7 @@ Emacs should keep backup copies of files I edit, but I do not want them
 to clutter up the filesystem everywhere. So I put them into one defined
 place, backup-directory, which even contains my username (for systems
 where =temporary-file-directory= is not inside my home).
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq backup-directory-alist `(("." . ,jj-backup-directory)))
 (setq auto-save-file-name-transforms `((".*" ,jj-backup-directory t)))
 
@@ -670,17 +699,17 @@ where =temporary-file-directory= is not inside my home).
 #+END_SRC
 
 Weeks start on Monday, not sunday.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq calendar-week-start-day 1)
 #+END_SRC
 
 Searches and matches should ignore case.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq-default case-fold-search t)
 #+END_SRC
 
 Which buffers to get rid off at midnight.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq clean-buffer-list-kill-buffer-names (quote ("*Help*" "*Apropos*"
                                                   "*Man " "*Buffer List*"
                                                   "*Compile-Log*"
@@ -692,30 +721,30 @@ Which buffers to get rid off at midnight.
 #+END_SRC
 
 Don't display a cursor in non-selected windows.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq-default cursor-in-non-selected-windows nil)
 #+END_SRC
 
 What should be displayed in the mode-line for files with those types
 of line endings.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq eol-mnemonic-dos "(DOS)")
 (setq eol-mnemonic-mac "(Mac)")
 #+END_SRC
 
 Much larger threshold for garbage collection prevents it to run too often.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq gc-cons-threshold 48000000)
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq max-lisp-eval-depth 1000)
 (setq max-specpdl-size 3000)
 #+END_SRC
 
 Unfill paragraph
 From https://raw.github.com/qdot/conf_emacs/master/emacs_conf.org
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defun unfill-paragraph ()
   "Takes a multi-line paragraph and makes it into a single line of text."
   (interactive)
@@ -723,23 +752,25 @@ From https://raw.github.com/qdot/conf_emacs/master/emacs_conf.org
     (fill-paragraph nil)))
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq-default indicate-empty-lines t)
 #+END_SRC
 *** Browser
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq browse-url-browser-function (quote browse-url-generic))
 (setq browse-url-generic-program "/usr/bin/x-www-browser")
 #+END_SRC
 
 *** When saving a script - make it executable
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
 #+END_SRC
 
 *** Emacs Server
-#+BEGIN_SRC emacs-lisp
-(server-start)
+#+BEGIN_SRC emacs-lisp tangle:yes
+(require 'server)
+(unless (server-running-p)
+  (server-start))
 #+END_SRC
 
 ** Customized variables
@@ -747,7 +778,7 @@ From https://raw.github.com/qdot/conf_emacs/master/emacs_conf.org
 The following contains a set of variables i may reasonably want to
 change on other systems - which don't affect the init file loading
 process. So I *can* use the customization interface for it...
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (defgroup ganneff nil
     "Modify ganneffs settings"
     :group 'environment)
@@ -773,6 +804,14 @@ process. So I *can* use the customization interface for it...
 #+END_SRC
 
 
+** Compatibility
+[2013-05-21 Tue 23:22]
+Restore removed var alias, used by ruby-electric-brace and others
+#+BEGIN_SRC emacs-lisp tangle:yes
+(unless (boundp 'last-command-char)
+  (defvaralias 'last-command-char 'last-command-event))
+#+END_SRC
+
 * Customized variables
 :PROPERTIES:
 :ID: 0102208d-fdf6-4928-9e40-7e341bd3aa3a
@@ -782,7 +821,7 @@ things can only be set via it (or so they say). I usually prefer to put
 things I keep for a long while into statements somewhere else, not just
 custom-set here, but we need it anyways.
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq custom-file jj-custom-file)
 (safe-load custom-file)
 #+END_SRC
@@ -798,7 +837,7 @@ I only list modes here where I don't have any other special
 configuration.
 
 - Some extras for ruby, used with ruby on rails for example
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (add-to-list 'auto-mode-alist '("\\.rxml$" . ruby-mode))
 (add-to-list 'auto-mode-alist '("\\.rjs$" . ruby-mode))
 (add-to-list 'auto-mode-alist '("\\.rake$" . ruby-mode))
@@ -807,17 +846,17 @@ configuration.
 #+END_SRC
 
 - Markdown syntax
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (add-to-list 'auto-mode-alist '("\\.mdwn$" . markdown-mode))
 #+END_SRC
 
 - diff
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (add-to-list 'auto-mode-alist '("COMMIT_EDITMSG$" . diff-mode))
 #+END_SRC
 
 - perl
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (add-to-list 'auto-mode-alist '("\\.\\([pP][Llm]\\|al\\)\\'" . cperl-mode))
 (add-to-list 'auto-mode-alist '("\\.pod$" . pod-mode))
 (add-to-list 'auto-mode-alist '("\\.tt$" . tt-mode))
@@ -827,7 +866,7 @@ configuration.
 #+END_SRC
 
 - python
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
 (add-to-list 'auto-mode-alist '("\\.py$" . python-mode))
 (add-to-list 'interpreter-mode-alist '("python" . python-mode))
@@ -838,13 +877,13 @@ configuration.
 This mode allows to have keybindings that are only alive when the
 region is active. Helpful for things that only do any useful action
 then, like for example the [[*multiple%20cursors][multiple cursors]] mode I load later.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'region-bindings-mode)
 (region-bindings-mode-enable)
 #+END_SRC
 ** tramp
 Transparent Remote (file) Access, Multiple Protocol, remote file editing.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'tramp)
 (setq tramp-default-method "ssh")
 (setq tramp-persistency-file-name (expand-file-name "tramp" jj-cache-dir))
@@ -861,7 +900,7 @@ Transparent Remote (file) Access, Multiple Protocol, remote file editing.
 We configure only a bit of the tiny-tools to load when I should need
 them. I don't need much actually, but these things are nice to have.
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'turn-on-tinyperl-mode "tinyperl" "" t)
 (add-hook 'perl-mode-hook  'turn-on-tinyperl-mode)
 (add-hook 'cperl-mode-hook 'turn-on-tinyperl-mode)
@@ -877,7 +916,7 @@ them. I don't need much actually, but these things are nice to have.
 (autoload 'tinyeat-kill-buffer-lines-point-min "tinyeat" "" t)
 #+END_SRC
 *** Keyboard changes for tiny-tools
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (global-set-key  "\M-;" 'tinycomment-indent-for-comment)
 
 (global-set-key (kbd "ESC C-k")       'tinyeat-kill-line-backward)
@@ -892,7 +931,7 @@ them. I don't need much actually, but these things are nice to have.
 I like dired and work a lot with it, but it tends to leave lots of
 windows around.
 dired-single to the rescue.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'dired-single-buffer "dired-single" "" t)
 (autoload 'dired-single-buffer-mouse "dired-single" "" t)
 (autoload 'dired-single-magic-buffer "dired-single" "" t)
@@ -902,7 +941,7 @@ dired-single to the rescue.
 We want some extra key bindings loaded. In case we haven't loaded dired
 yet, there won't be a keymap to add to, so add our setup function to the
 load hook only. Otherwise just bind the keys.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (if (boundp 'dired-mode-map)
     ;; we're good to go; just add our bindings
     (my-dired-init)
@@ -911,7 +950,7 @@ load hook only. Otherwise just bind the keys.
 #+END_SRC
 
 A few settings
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq dired-auto-revert-buffer (quote dired-directory-changed-p))
 (setq dired-dwim-target t)
 (setq dired-listing-switches "-alh")
@@ -920,12 +959,12 @@ A few settings
 #+END_SRC
 
 wdired
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq wdired-allow-to-change-permissions t)
 #+END_SRC
 ** filladapt
 [2013-05-02 Thu 00:04]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'filladapt)
 (eval-after-load "filladapt" '(diminish 'filladapt-mode))
 (setq-default filladapt-mode t)
@@ -934,19 +973,19 @@ wdired
 [2013-05-03 Fri 16:09]
 Replace default find-file with find-file-at-point, which tries to
 guess the default file/URL from text around the point.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (ffap-bindings)
 #+END_SRC
 ** icicles
 [[http://article.gmane.org/gmane.emacs.orgmode/4574/match%3Dicicles]["In case you never heard of it, Icicles is to ‘TAB’ completion what
 ‘TAB’ completion is to typing things manually every time.”]]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'icicles)
 (icy-mode 1)
 #+END_SRC
 ** uniquify
 Always have unique buffernames. See [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Uniquify.html][Uniquify - GNU Emacs Manual]]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'uniquify)
 (setq uniquify-buffer-name-style 'post-forward)
 (setq uniquify-after-kill-buffer-p t)
@@ -957,7 +996,7 @@ Always have unique buffernames. See [[http://www.gnu.org/software/emacs/manual/h
 A defined abbrev is a word which expands, if you insert it, into some
 different text. Abbrevs are defined by the user to expand in specific
 ways.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq save-abbrevs 'silently)
 (setq abbrev-file-name (expand-file-name "abbrev_defs" jj-cache-dir))
 (if (file-exists-p abbrev-file-name)
@@ -969,14 +1008,14 @@ ways.
 Obviously emacs can do syntax hilighting. For more things than you ever
 heard about.
 And I want to have it everywhere.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'font-lock)
 (global-font-lock-mode 1)
 (setq font-lock-maximum-decoration t)
 #+END_SRC
 ** miniedit
 Edit minibuffer in a full (text-mode) buffer by pressing *M-C-e*.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'miniedit)
 (miniedit-install)
 #+END_SRC
@@ -986,7 +1025,7 @@ By default, Emacs can update the time stamp for the following two
 formats if one exists in the first 8 lines of the file.
 - Time-stamp: <>
 - Time-stamp: " "
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'time-stamp)
 (setq time-stamp-active t)
 (setq time-stamp-format "%02H:%02M:%02S (%z) - %02d.%02m.%:y from %u (%U) on %s")
@@ -998,7 +1037,7 @@ formats if one exists in the first 8 lines of the file.
 ** cperl
 I like /cperl-mode/ a bit more than the default /perl-mode/, so set it
 up here to be used.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'cperl-mode "cperl-mode" )
 (defalias 'perl-mode 'cperl-mode)
 (setq cperl-hairy t)
@@ -1016,7 +1055,7 @@ up here to be used.
 #+END_SRC
 
 And have cperl mode give ElDoc a useful string
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defun my-cperl-eldoc-documentation-function ()
   "Return meaningful doc string for `eldoc-mode'."
   (car
@@ -1030,7 +1069,7 @@ And have cperl mode give ElDoc a useful string
 #+END_SRC
 
 ** python
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (autoload 'python-mode "python-mode" "Python Mode." t)
   (add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
   (add-to-list 'interpreter-mode-alist '("python" . python-mode))
@@ -1064,7 +1103,7 @@ And have cperl mode give ElDoc a useful string
 
 If an =ipython= executable is on the path, then assume that IPython is
 the preferred method python evaluation.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (when (executable-find "ipython")
   (require 'ipython)
   (setq org-babel-python-mode 'python-mode))
@@ -1083,14 +1122,14 @@ the preferred method python evaluation.
 
 ** sh
 I prefer comments to be indented too
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq sh-indent-comment t)
 #+END_SRC
 
 ** auto-revert
 When files change outside emacs for whatever reason I want emacs to deal
 with it. Not to have to revert buffers myself
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'autorevert)
 (setq global-auto-revert-mode t)
 (global-auto-revert-mode)
@@ -1101,7 +1140,7 @@ Various modes should have line numbers in front of each line.
 
 But then there are some where it would just be deadly - like org-mode,
 gnus, so we have a list of modes where we don't want to see it.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (require 'linum)
   (setq linum-format "%3d ")
   (setq linum-mode-inhibit-modes-list '(org-mode
@@ -1121,14 +1160,64 @@ gnus, so we have a list of modes where we don't want to see it.
 #+END_SRC
 
 ** css
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'css-mode "css-mode")
-(setq auto-mode-alist (cons '("\\.css\\'" . css-mode) auto-mode-alist))
+(add-auto-mode 'css-mode "\\.css")
+;;; CSS flymake
+(require 'flymake-css)
+(defun maybe-flymake-css-load ()
+  "Activate flymake-css as necessary, but not in derived modes."
+  (when (eq major-mode 'css-mode)
+    (flymake-css-load)))
+(add-hook 'css-mode-hook 'maybe-flymake-css-load)
+;;; Auto-complete CSS keywords
+(eval-after-load 'auto-complete
+  '(progn
+     (dolist (hook '(css-mode-hook sass-mode-hook scss-mode-hook))
+       (add-hook hook 'ac-css-mode-setup))))
+#+END_SRC
+
+** mmm-mode
+[2013-05-21 Tue 23:39]
+MMM Mode is a minor mode for Emacs that allows Multiple Major Modes to
+coexist in one buffer.
+#+BEGIN_SRC emacs-lisp tangle:yes
+(require 'mmm-auto)
+(setq mmm-global-mode 'buffers-with-submode-classes)
+(setq mmm-submode-decoration-level 2)
+(eval-after-load 'mmm-vars
+  '(progn
+     (mmm-add-group
+      'html-css
+      '((css-cdata
+         :submode css-mode
+         :face mmm-code-submode-face
+         :front "<style[^>]*>[ \t\n]*\\(//\\)?<!\\[CDATA\\[[ \t]*\n?"
+         :back "[ \t]*\\(//\\)?]]>[ \t\n]*</style>"
+         :insert ((?j js-tag nil @ "<style type=\"text/css\">"
+                      @ "\n" _ "\n" @ "</script>" @)))
+        (css
+         :submode css-mode
+         :face mmm-code-submode-face
+         :front "<style[^>]*>[ \t]*\n?"
+         :back "[ \t]*</style>"
+         :insert ((?j js-tag nil @ "<style type=\"text/css\">"
+                      @ "\n" _ "\n" @ "</style>" @)))
+        (css-inline
+         :submode css-mode
+         :face mmm-code-submode-face
+         :front "style=\""
+         :back "\"")))
+     (dolist (mode (list 'html-mode 'nxml-mode))
+       (mmm-add-mode-ext-class mode "\\.r?html\\(\\.erb\\)?\\'" 'html-css))
+    (mmm-add-mode-ext-class 'html-mode "\\.php\\'" 'html-php)
+    ))
+
 #+END_SRC
 
 ** html-helper
 Instead of default /html-mode/ I use /html-helper-mode/.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'html-helper-mode "html-helper-mode" "Yay HTML" t)
 (setq auto-mode-alist (cons '("\\.html$" . html-helper-mode) auto-mode-alist))
 (setq auto-mode-alist (cons '("\\.asp$" . html-helper-mode) auto-mode-alist))
@@ -1137,7 +1226,7 @@ Instead of default /html-mode/ I use /html-helper-mode/.
 #+END_SRC
 
 ** auctex
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq auto-mode-alist (cons '("\\.tex\\'" . latex-mode) auto-mode-alist))
 (setq TeX-auto-save t)
 (setq TeX-parse-self t)
@@ -1145,7 +1234,7 @@ Instead of default /html-mode/ I use /html-helper-mode/.
 #+END_SRC
 
 ** Debian related
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'dpkg-dev-el-loaddefs nil 'noerror)
 (require 'debian-el-loaddefs nil 'noerror)
 
@@ -1159,13 +1248,13 @@ Instead of default /html-mode/ I use /html-helper-mode/.
 
 I use org-mode a lot and, having my config for this based on [[*Bernt%20Hansen][the config of Bernt Hansen]],
 it is quite extensive. Nevertheless, it starts out small, loading it.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (require 'org)
 #+END_SRC
 
 My browsers (Conkeror, Iceweasel) can store links in org-mode. For
 that we need org-protocol.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (require 'org-protocol)
 #+END_SRC
 
@@ -1173,7 +1262,7 @@ that we need org-protocol.
 
 My current =org-agenda-files= variable only includes a set of
 directories.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-agenda-files (quote ("~/org/"
                                "~/org/debian"
                                "~/org/debconf"
@@ -1195,7 +1284,7 @@ variable.  I just add and remove directories manually here.  Changing
 the list of directories in =org-agenda-files= happens very rarely
 since new files in existing directories are automatically picked up.
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ;; Keep tasks with dates on the global todo lists
 (setq org-agenda-todo-ignore-with-date nil)
 
@@ -1264,7 +1353,7 @@ since new files in existing directories are automatically picked up.
           'append)
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-agenda-persistent-filter t)
 (add-hook 'org-agenda-mode-hook
           '(lambda () (org-defkey org-agenda-mode-map "W" 'bh/widen))
@@ -1311,7 +1400,7 @@ Start off by defining a series of keybindings.
 Well, first we remove =C-c [= and =C-c ]=, as all agenda directories are
 setup manually, not by org-mode. Also turn off =C-c ;=, which
 comments headlines - a function never used.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (add-hook 'org-mode-hook
           (lambda ()
             (org-defkey org-mode-map "\C-c["    'undefined)
@@ -1321,7 +1410,7 @@ comments headlines - a function never used.
 #+END_SRC
 
 And now a largish set of keybindings...
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (global-set-key "\C-cl" 'org-store-link)
 (global-set-key "\C-ca" 'org-agenda)
 (global-set-key "\C-cb" 'org-iswitchb)
@@ -1368,7 +1457,7 @@ And now a largish set of keybindings...
 *** Tasks, States, Todo fun
 
 First we define the global todo keywords.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-todo-keywords
       (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d@/!)")
               (sequence "WAITING(w@/!)" "HOLD(h@/!)" "DELEGATED(g@/!)" "|" "CANCELLED(c@/!)" "PHONE"))))
@@ -1388,7 +1477,7 @@ First we define the global todo keywords.
 Fast todo selection allows changing from any task todo state to any
 other state directly by selecting the appropriate key from the fast
 todo selection key menu.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-use-fast-todo-selection t)
 #+END_SRC
 Changing a task state is done with =C-c C-t KEY=
@@ -1396,7 +1485,7 @@ Changing a task state is done with =C-c C-t KEY=
 where =KEY= is the appropriate fast todo state selection key as defined in =org-todo-keywords=.
 
 The setting
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-treat-S-cursor-todo-selection-as-state-change nil)
 #+END_SRC
 allows changing todo states with S-left and S-right skipping all of
@@ -1423,7 +1512,7 @@ The triggers break down to the following rules:
 - Moving a task to =DONE= removes =WAITING= and =CANCELLED= tags
 
 The tags are used to filter tasks in the agenda views conveniently.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-todo-state-tags-triggers
       (quote (("CANCELLED" ("CANCELLED" . t))
               ("WAITING" ("WAITING" . t))
@@ -1436,7 +1525,7 @@ The tags are used to filter tasks in the agenda views conveniently.
 
 *** Capturing new tasks
 Org capture replaces the old remember mode.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-directory "~/org")
 (setq org-default-notes-file "~/org/refile.org")
 
@@ -1491,14 +1580,14 @@ The quick clocking in and out of capture mode tasks (often it takes
 less than a minute to capture some new task details) can leave
 empty clock drawers in my tasks which aren't really useful.
 The following prevents this.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (add-hook 'org-clock-out-hook 'bh/remove-empty-drawer-on-clock-out 'append)
 #+END_SRC
 
 *** Refiling
 All my newly captured entries end up in =refile.org= and want to be
 moved over to the right place. The following is the setup for it.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ; Targets include this file and any file contributing to the agenda - up to 9 levels deep
 (setq org-refile-targets (quote ((nil :maxlevel . 9)
                                  (org-agenda-files :maxlevel . 9))))
@@ -1529,7 +1618,7 @@ moved over to the right place. The following is the setup for it.
 
 *** Custom agenda
 Agenda view is the central place for org-mode interaction...
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ;; Do not dim blocked tasks
 (setq org-agenda-dim-blocked-tasks nil)
 ;; Compact the block agenda view
@@ -1624,7 +1713,7 @@ Agenda view is the central place for org-mode interaction...
 #+END_SRC
 
 *** Time
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ;;
 ;; Resume clocking task when emacs is restarted
 (org-clock-persistence-insinuate)
@@ -1684,7 +1773,7 @@ clock moves up the project tree until you clock out the
 top-level task and the clock moves to the default task.
 
 **** Reporting
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ;; Agenda clock report parameters
 (setq org-agenda-clockreport-parameter-plist
       (quote (:link t :maxlevel 5 :fileskip0 t :compact t :narrow 80)))
@@ -1694,12 +1783,12 @@ top-level task and the clock moves to the default task.
 #+END_SRC
 **** Task estimates, column view
 Setup column view globally with the following headlines
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ; Set default column view headings: Task Effort Clock_Summary
 (setq org-columns-default-format "%80ITEM(Task) %10Effort(Effort){:} %10CLOCKSUM")
 #+END_SRC
 Setup the estimate for effort values.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ; global Effort estimate values
 ; global STYLE property values for completion
 (setq org-global-properties (quote (("Effort_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00")
@@ -1708,7 +1797,7 @@ Setup the estimate for effort values.
 
 *** Tags
 Tags are mostly used for filtering inside the agenda.
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ; Tags with fast selection keys
 (setq org-tag-alist (quote ((:startgroup)
                             ("@errand" . ?e)
@@ -1736,13 +1825,13 @@ Tags are mostly used for filtering inside the agenda.
 #+END_SRC
 
 *** Archiving
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-archive-mark-done nil)
 (setq org-archive-location "%s_archive::* Archived Tasks")
 #+END_SRC
 
 *** org-babel
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-ditaa-jar-path "~/java/ditaa0_6b.jar")
 (setq org-plantuml-jar-path "~/java/plantuml.jar")
 
@@ -1781,7 +1870,7 @@ Tags are mostly used for filtering inside the agenda.
 (add-to-list 'org-src-lang-modes (quote ("plantuml" . fundamental)))
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 ;; Don't have images visible on startup, breaks on console
 (setq org-startup-with-inline-images nil)
 #+END_SRC
@@ -1808,7 +1897,7 @@ Org-mode can export to a variety of publishing formats including (but not limite
 
 A new exporter created by Nicolas Goaziou was introduced in org 8.0.
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ;; Explicitly load required exporters
 (require 'ox-html)
 (require 'ox-latex)
@@ -1883,7 +1972,7 @@ A new exporter created by Nicolas Goaziou was introduced in org 8.0.
 
 **** Latex export
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-latex-to-pdf-process
       '("xelatex -interaction nonstopmode %f"
         "xelatex -interaction nonstopmode %f")) ;; for multiple passes
@@ -1969,12 +2058,12 @@ I find invisible edits (and undo's) hard to deal with so now I can't
 edit invisible text.  =C-c C-r= (org-reveal) will display where the
 point is if it is buried in invisible text to allow editing again.
 
-#+BEGIN_SRC emacs-lisp :tangle yes
+#+BEGIN_SRC emacs-lisp tangle:yes :tangle yes
 (setq org-catch-invisible-edits 'error)
 #+END_SRC
 
 *** Whatever
-#+BEGIN_SRC emacs-lisp :tangle yes
+#+BEGIN_SRC emacs-lisp tangle:yes :tangle yes
 ;; disable the default org-mode stuck projects agenda view
 (setq org-stuck-projects (quote ("" nil nil "")))
 
@@ -1997,11 +2086,11 @@ The following setting adds alphabetical lists like
   ,a. item one
   ,b. item two
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-alphabetical-lists t)
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp :tangle yes
+#+BEGIN_SRC emacs-lisp tangle:yes :tangle yes
 (setq org-remove-highlights-with-change nil)
 
 (setq org-list-demote-modify-bullet (quote (("+" . "-")
@@ -2020,7 +2109,7 @@ The following setting adds alphabetical lists like
 #+END_SRC
 
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 ;; Enable abbrev-mode
 (add-hook 'org-mode-hook (lambda () (abbrev-mode 1)))
 (setq org-startup-indented t)
@@ -2036,24 +2125,24 @@ lists with no blank lines better.
 
 The following setting prevents creating blank lines before headings
 but allows list items to adapt to existing blank lines around the items:
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-blank-before-new-entry (quote ((heading)
                                          (plain-list-item . auto))))
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-reverse-note-order nil)
 (setq org-default-notes-file "~/notes.org")
 #+END_SRC
 
 Enforce task blocking. Tasks can't go done when there is any subtask
 still open. Unless they have a property of =NOBLOCKING: t=
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-enforce-todo-checkbox-dependencies t)
 (setq org-enforce-todo-dependencies t)
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-fast-tag-selection-single-key (quote expert))
 (setq org-footnote-auto-adjust t)
 (setq org-hide-block-startup t)
@@ -2101,7 +2190,7 @@ are available at the beginning of a code block, the following key
 sequence =C-c C-v h= (bound to `=org-babel-describe-bindings=') will
 display a list of the code blocks commands and their related keys.
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-use-speed-commands t)
 (setq org-speed-commands-user (quote (("0" . ignore)
                                       ("1" . ignore)
@@ -2171,35 +2260,35 @@ using the major-mode of the code.  It also changes the behavior of
 that reading and editing code form inside of your Org-mode files is
 much more like reading and editing of code using its major mode.
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-src-fontify-natively t)
 (setq org-src-tab-acts-natively t)
 #+END_SRC
 
-#+BEGIN_SRC emacs-lisp :tangle yes
+#+BEGIN_SRC emacs-lisp tangle:yes :tangle yes
 (setq org-src-preserve-indentation nil)
 (setq org-edit-src-content-indentation 0)
 #+END_SRC
 
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-attach-directory "~/org/data/")
 #+END_SRC
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (setq org-agenda-sticky t)
 #+END_SRC
 
 **** Checklist handling
 [2013-05-11 Sat 22:15]
 
-#+BEGIN_SRC emacs-lisp tangle:yes
+#+BEGIN_SRC emacs-lisp tangle:yes tangle:yes
 (require 'org-checklist)
 #+END_SRC
 
 ** transient mark
 For some reason I prefer this mode more than the way without. I want to
 see the marked region.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (transient-mark-mode 1)
 #+END_SRC
 ** cua
@@ -2207,7 +2296,7 @@ I know that this lets it look "more like windows", but I don't much care
 about its paste/copy/cut keybindings, the really nice part is the great
 support for rectangular regions, which I started to use a lot since I
 know this mode. The normal keybindings for those are just to useless.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (cua-mode t)
 (setq cua-enable-cua-keys (quote shift))
 #+END_SRC
@@ -2217,7 +2306,7 @@ get the CUA selection and rectangle stuff, not the keybindings. Yes,
 even though the above =cua-enable-cua-keys= setting would only enable
 them if the selection is done when the region was marked with a shifted
 movement keys.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (cua-selection-mode t)
 #+END_SRC
 
@@ -2225,7 +2314,7 @@ movement keys.
 This is [[https://github.com/mbunkus/mo-git-blame][mo-git-blame -- An interactive, iterative 'git blame' mode for
 Emacs]].
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'mo-git-blame-file "mo-git-blame" nil t)
 (autoload 'mo-git-blame-current "mo-git-blame" nil t)
 #+END_SRC
@@ -2234,7 +2323,7 @@ Emacs]].
 [[https://github.com/pft/mingus][Mingus]] is a nice interface to mpd, the Music Player Daemon.
 
 I want to access it from anywhere using =F6=.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (autoload 'mingus "mingus-stays-home" nil t)
 (global-set-key (kbd "<f6>") 'mingus)
 (setq mingus-dired-add-keys t)
@@ -2246,17 +2335,50 @@ I want to access it from anywhere using =F6=.
 (setq mingus-mpd-root "/share/music/")
 #+END_SRC
 
-** saveplace
-Store at which point I have been in files.
-#+BEGIN_SRC emacs-lisp
-(setq-default save-place t)
-(require 'saveplace)
-(setq save-place-file (expand-file-name "saved-places" jj-cache-dir))
-#+END_SRC
-** savehist
+** sessions
+[2013-05-22 Wed 22:40]
+Save and restore the desktop
+#+BEGIN_SRC emacs-lisp tangle:yes
+(setq desktop-path (list jj-cache-dir))
+(desktop-save-mode 1)
+(defadvice desktop-read (around trace-desktop-errors activate)
+  (let ((debug-on-error t))
+    ad-do-it))
+
+
+;;----------------------------------------------------------------------------
+;; Restore histories and registers after saving
+;;----------------------------------------------------------------------------
+(require 'session)
+
+(setq session-save-file (expand-file-name "session" jj-cache-dir))
+(add-hook 'after-init-hook 'session-initialize)
+
+;; save a bunch of variables to the desktop file
+;; for lists specify the len of the maximal saved data also
+(setq desktop-globals-to-save
+      (append '((extended-command-history . 30)
+                (file-name-history        . 100)
+                (grep-history             . 30)
+                (compile-history          . 30)
+                (minibuffer-history       . 50)
+                (query-replace-history    . 60)
+                (read-expression-history  . 60)
+                (regexp-history           . 60)
+                (regexp-search-ring       . 20)
+                (search-ring              . 20)
+                (comint-input-ring        . 50)
+                (shell-command-history    . 50)
+                kill-ring
+                desktop-missing-file-warning
+                tags-file-name
+                register-alist)))
+
+#+END_SRC
+*** savehist
 [2013-04-21 So 20:25]
 Save a bit of history
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle no
 (require 'savehist)
 (setq savehist-additional-variables
  '(search ring regexp-search-ring kill-ring compile-history))
@@ -2266,15 +2388,22 @@ Save a bit of history
 (savehist-mode +1)
 #+END_SRC
 
+*** saveplace
+Store at which point I have been in files.
+#+BEGIN_SRC emacs-lisp tangle:yes
+(setq-default save-place t)
+(require 'saveplace)
+(setq save-place-file (expand-file-name "saved-places" jj-cache-dir))
+#+END_SRC
 ** easypg
 EasyPG is a GnuPG interface for Emacs.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'epa-file)
 (epa-file-enable)
 #+END_SRC
 
 I took the following from [[http://www.emacswiki.org/emacs/EasyPG][EmacsWiki: Easy PG]]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (defadvice epg--start (around advice-epg-disable-agent disable)
   "Don't allow epg--start to use gpg-agent in plain text
     terminals."
@@ -2288,7 +2417,7 @@ I took the following from [[http://www.emacswiki.org/emacs/EasyPG][EmacsWiki: Ea
 (ad-activate 'epg--start)
 #+END_SRC
 ** message
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (require 'message)
   (setq message-kill-buffer-on-exit t)
 #+END_SRC
@@ -2296,7 +2425,7 @@ I took the following from [[http://www.emacswiki.org/emacs/EasyPG][EmacsWiki: Ea
 Most of my gnus config is in an own file, [[file:gnus.org][gnus.org]], here I only have
 what I want every emacs to know.
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 ;;*** Keyboardmacros
 (global-unset-key "\M-n")
 (global-set-key "\M-n" 'gnus) ; Start gnus with M-n
@@ -2306,14 +2435,14 @@ what I want every emacs to know.
 url contains code to parse and handle URLs - who would have thought? I
 set it to send Accept-language header and tell it to not send email,
 operating system or location info.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq url-mime-language-string "de,en")
 (setq url-privacy-level (quote (email os lastloc)))
 #+END_SRC
 ** hippie-exp
 Crazy way of completion. It looks at the word before point and then
 tries to expand it in various ways.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (require 'hippie-exp)
   (setq hippie-expand-try-functions-list '(try-expand-dabbrev
                                            try-expand-dabbrev-all-buffers
@@ -2330,7 +2459,7 @@ tries to expand it in various ways.
 [2013-04-27 Sa 23:16]
 Yasnippet is a template system. Type an abbreviation, expand it into
 whatever the snippet holds.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (setq yas-snippet-dirs (expand-file-name "yasnippet/snippets" jj-elisp-dir))
 (require 'yasnippet)
 (yas-global-mode 1)
@@ -2343,7 +2472,7 @@ whatever the snippet holds.
 The Emacs Lisp Package Archive (may) contain(s) some things I
 want. Even though I usually only use it to get the package, then when I
 like it move it into my own space. My elpa subdir stays empty.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (when (> emacs-major-version 23)
   (require 'package)
   (setq package-user-dir (expand-file-name "elpa" jj-cache-dir))
@@ -2356,7 +2485,7 @@ like it move it into my own space. My elpa subdir stays empty.
 [2013-04-08 Mon 23:57]
 Use multiple cursors mode. See [[http://emacsrocks.com/e13.html][Emacs Rocks! multiple cursors]] and
 [[https://github.com/emacsmirror/multiple-cursors][emacsmirror/multiple-cursors · GitHub]]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
   (require 'multiple-cursors)
   (define-key region-bindings-mode-map "a" 'mc/mark-all-like-this)
 
@@ -2373,7 +2502,7 @@ which highlights parens, brackets, and braces according to their
 depth. Each successive level is highlighted a different color. This
 makes it easy to spot matching delimiters, orient yourself in the code,
 and tell which statements are at the same depth.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (when (require 'rainbow-delimiters nil 'noerror)
   (global-rainbow-delimiters-mode))
 #+END_SRC
@@ -2384,7 +2513,7 @@ tons of modes available to change it, even downgrade it to the very
 crappy ways one usually knows from other systems which lose
 information. undo-tree is different - it helps keeping you sane while
 keeping the full power of emacs undo/redo.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'undo-tree)
 (global-undo-tree-mode)
 (diminish 'undo-tree-mode)
@@ -2393,7 +2522,7 @@ keeping the full power of emacs undo/redo.
 Additionally I would like to keep the region active should I undo
 while I have one.
 
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 ;; Keep region when undoing in region
 (defadvice undo-tree-undo (around keep-region activate)
   (if (use-region-p)
@@ -2409,7 +2538,7 @@ while I have one.
 ** windmove
 [2013-04-21 So 20:27]
 Use shift + arrow keys to switch between visible buffers
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'windmove)
 (windmove-default-keybindings 'hyper)
 (setq windmove-wrap-around t)
@@ -2420,7 +2549,7 @@ VolatileHighlights highlights changes to the buffer caused by commands
 such as ‘undo’, ‘yank’/’yank-pop’, etc. The highlight disappears at the
 next command. The highlighting gives useful visual feedback for what
 your operation actually changed in the buffer.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'volatile-highlights)
 (volatile-highlights-mode t)
 (diminish 'volatile-highlights-mode)
@@ -2434,7 +2563,7 @@ ediff - don't start another frame
 #+END_SRC
 ** re-builder
 Saner regex syntax
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 're-builder)
 (setq reb-re-syntax 'string)
 #+END_SRC
@@ -2444,7 +2573,7 @@ Saner regex syntax
 ** magit
 [2013-04-21 So 20:48]
 magit is a mode for interacting with git.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'magitload)
 (require 'magit-svn)
 (global-set-key (kbd "C-x g") 'magit-status)
@@ -2455,9 +2584,10 @@ magit is a mode for interacting with git.
 [2013-04-21 So 21:00]
 I'm not doing much of it, except for my emacs and gnus configs, but
 then I like it nice too...
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (define-key read-expression-map (kbd "TAB") 'lisp-complete-symbol)
 (require 'paredit)
+
 (setq lisp-coding-hook 'lisp-coding-defaults)
   (setq interactive-lisp-coding-hook 'interactive-lisp-coding-defaults)
 
@@ -2482,7 +2612,7 @@ then I like it nice too...
 This highlights some /weaselwords/, a mode to /aid in finding common
 writing problems/...
 [2013-04-27 Sa 23:29]
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'writegood-mode)
 (global-set-key "\C-cg" 'writegood-mode)
 #+END_SRC
@@ -2492,12 +2622,56 @@ And aren't we all lazy? I definitely am, and I like my emacs doing as
 much possible work for me as it can.
 So here, auto-complete-mode, which lets emacs do this, based on what I
 already had typed.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'auto-complete)
 (setq ac-comphist-file (expand-file-name "ac-comphist.dat" jj-cache-dir))
+(global-auto-complete-mode t)
+
+(setq ac-expand-on-auto-complete nil)
 (setq ac-dwim t)
 (setq ac-auto-start t)
 
+;;----------------------------------------------------------------------------
+;; Use Emacs' built-in TAB completion hooks to trigger AC (Emacs >= 23.2)
+;;----------------------------------------------------------------------------
+(setq tab-always-indent 'complete)  ;; use 't when auto-complete is disabled
+(add-to-list 'completion-styles 'initials t)
+
+;; hook AC into completion-at-point
+(defun sanityinc/auto-complete-at-point ()
+  (when (and (not (minibufferp)) 
+             (fboundp 'auto-complete-mode)
+             auto-complete-mode)
+    (auto-complete)))
+
+(defun set-auto-complete-as-completion-at-point-function ()
+  (add-to-list 'completion-at-point-functions 'sanityinc/auto-complete-at-point))
+
+(add-hook 'auto-complete-mode-hook 'set-auto-complete-as-completion-at-point-function)
+
+(require 'ac-dabbrev)
+(set-default 'ac-sources
+             '(ac-source-imenu
+               ac-source-dictionary
+               ac-source-words-in-buffer
+               ac-source-words-in-same-mode-buffers
+               ac-source-words-in-all-buffer
+               ac-source-dabbrev))
+
+(dolist (mode '(magit-log-edit-mode log-edit-mode org-mode text-mode haml-mode
+                sass-mode yaml-mode csv-mode espresso-mode haskell-mode
+                html-mode nxml-mode sh-mode smarty-mode clojure-mode
+                lisp-mode textile-mode markdown-mode tuareg-mode
+                js3-mode css-mode less-css-mode sql-mode ielm-mode))
+  (add-to-list 'ac-modes mode))
+
+;; Exclude very large buffers from dabbrev
+(defun sanityinc/dabbrev-friend-buffer (other-buffer)
+  (< (buffer-size other-buffer) (* 1 1024 1024)))
+
+(setq dabbrev-friend-buffer-function 'sanityinc/dabbrev-friend-buffer)
+
+
 ;; custom keybindings to use tab, enter and up and down arrows
 (define-key ac-complete-mode-map "\t" 'ac-expand)
 (define-key ac-complete-mode-map "\r" 'ac-complete)
@@ -2505,11 +2679,8 @@ already had typed.
 (define-key ac-complete-mode-map "\M-p" 'ac-previous)
 (define-key ac-mode-map (kbd "M-TAB") 'auto-complete)
 
-(require 'ac-dabbrev)
-(setq ac-sources (list ac-source-dabbrev))
-
 (setq auto-completion-syntax-alist (quote (global accept . word))) ;; Use space and punctuation to accept the current the most likely completion.
-(setq auto-completion-min-chars (quote (global . 2))) ;; Avoid completion for short trivial words.
+(setq auto-completion-min-chars (quote (global . 3))) ;; Avoid completion for short trivial words.
 (setq completion-use-dynamic t)
 
 (add-hook 'latex-mode-hook 'auto-complete-mode)
@@ -2521,7 +2692,7 @@ already had typed.
 [2013-04-28 So 01:13]
 YAML is a nice format for data, which is both, human and machine
 readable/editable without getting a big headache.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (require 'yaml-mode)
 (add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))
 (add-hook 'yaml-mode-hook
@@ -2534,11 +2705,114 @@ readable/editable without getting a big headache.
 Flycheck is a on-the-fly syntax checking tool, supposedly better than Flymake.
 As the one time I tried Flymake i wasn't happy, thats easy to
 understand for me.
-#+BEGIN_SRC emacs-lisp
+#+BEGIN_SRC emacs-lisp tangle:yes
 (when (> emacs-major-version 23)
   (require 'flycheck)
   (add-hook 'after-init-hook #'global-flycheck-mode))
 #+END_SRC
+** crontab-mode
+[2013-05-21 Tue 23:18]
+#+BEGIN_SRC emacs-lisp tangle:yes
+(require 'crontab-mode)
+(add-auto-mode 'crontab-mode "\\.?cron\\(tab\\)?\\'")
+#+END_SRC
+
+** nxml
+[2013-05-22 Wed 22:02]
+
+nxml-mode is a major mode for editing XML.
+#+BEGIN_SRC emacs-lisp tangle:yes
+(add-auto-mode
+ 'nxml-mode
+ (concat "\\."
+         (regexp-opt
+          '("xml" "xsd" "sch" "rng" "xslt" "svg" "rss"
+            "gpx" "tcx"))
+         "\\'"))
+(setq magic-mode-alist (cons '("<\\?xml " . nxml-mode) magic-mode-alist))
+(fset 'xml-mode 'nxml-mode)
+(setq nxml-slash-auto-complete-flag t)
+
+
+;; See: http://sinewalker.wordpress.com/2008/06/26/pretty-printing-xml-with-emacs-nxml-mode/
+(defun pp-xml-region (begin end)
+  "Pretty format XML markup in region. The function inserts
+linebreaks to separate tags that have nothing but whitespace
+between them.  It then indents the markup by using nxml's
+indentation rules."
+  (interactive "r")
+  (save-excursion
+      (nxml-mode)
+      (goto-char begin)
+      (while (search-forward-regexp "\>[ \\t]*\<" nil t)
+        (backward-char) (insert "\n"))
+      (indent-region begin end)))
+
+;;----------------------------------------------------------------------------
+;; Integration with tidy for html + xml
+;;----------------------------------------------------------------------------
+;; tidy is autoloaded
+(eval-after-load 'tidy
+  '(progn
+     (add-hook 'nxml-mode-hook (lambda () (tidy-build-menu nxml-mode-map)))
+     (add-hook 'html-mode-hook (lambda () (tidy-build-menu html-mode-map)))
+     ))
+(add-auto-mode 'html-mode "\\.(jsp|tmpl)\\'")
+
+#+END_SRC
+** ruby
+[2013-05-22 Wed 22:33]
+Programming in ruby...
+
+#+BEGIN_SRC emacs-lisp tangle:yes
+(add-auto-mode 'ruby-mode
+               "Rakefile\\'" "\\.rake\\'" "\.rxml\\'"
+               "\\.rjs\\'" ".irbrc\\'" "\.builder\\'" "\\.ru\\'"
+               "\\.gemspec\\'" "Gemfile\\'" "Kirkfile\\'")
+
+(setq ruby-use-encoding-map nil)
+
+(eval-after-load 'ruby-mode
+  '(progn
+     (define-key ruby-mode-map (kbd "RET") 'reindent-then-newline-and-indent)
+     (define-key ruby-mode-map (kbd "TAB") 'indent-for-tab-command)))
+
+;; Stupidly the non-bundled ruby-mode isn't a derived mode of
+;; prog-mode: we run the latter's hooks anyway in that case.
+(add-hook 'ruby-mode-hook
+          (lambda ()
+            (unless (derived-mode-p 'prog-mode)
+              (run-hooks 'prog-mode-hook))))
+
+;;; ERB
+(defun sanityinc/ensure-mmm-erb-loaded ()
+  (require 'mmm-erb))
+
+(require 'derived)
+
+(defun sanityinc/set-up-mode-for-erb (mode)
+  (add-hook (derived-mode-hook-name mode) 'sanityinc/ensure-mmm-erb-loaded)
+  (mmm-add-mode-ext-class mode "\\.erb\\'" 'erb))
+
+(let ((html-erb-modes '(html-mode html-erb-mode nxml-mode)))
+  (dolist (mode html-erb-modes)
+    (sanityinc/set-up-mode-for-erb mode)
+    (mmm-add-mode-ext-class mode "\\.r?html\\(\\.erb\\)?\\'" 'html-js)
+    (mmm-add-mode-ext-class mode "\\.r?html\\(\\.erb\\)?\\'" 'html-css)))
+
+(mapc 'sanityinc/set-up-mode-for-erb
+      '(coffee-mode js-mode js2-mode js3-mode markdown-mode textile-mode))
+
+(mmm-add-mode-ext-class 'html-erb-mode "\\.jst\\.ejs\\'" 'ejs)
+
+(add-auto-mode 'html-erb-mode "\\.rhtml\\'" "\\.html\\.erb\\'")
+(add-to-list 'auto-mode-alist '("\\.jst\\.ejs\\'"  . html-erb-mode))
+(mmm-add-mode-ext-class 'yaml-mode "\\.yaml\\'" 'erb)
+
+(dolist (mode (list 'js-mode 'js2-mode 'js3-mode))
+  (mmm-add-mode-ext-class mode "\\.js\\.erb\\'" 'erb))
+
+#+END_SRC
 * Thats it
 And thats it for this file, control passes "back" to [[file:../initjj.org][initjj.org/el]]
 which then may load more files.
diff --git a/.emacs.d/elisp/local/crontab-mode.el b/.emacs.d/elisp/local/crontab-mode.el
new file mode 100644 (file)
index 0000000..6ba6b93
--- /dev/null
@@ -0,0 +1,227 @@
+;;; crontab-mode.el --- Mode for editing crontab files
+;; Version: 20090510.2255
+;;
+;; ~/share/emacs/pkg/crontab/crontab-mode.el ---
+;;
+;; $Id: crontab-mode.el,v 1.20 2005/10/04 03:58:52 harley Exp $
+;;
+
+;; Author:    Harley Gorrell <harley@mahalito.net>
+;; URL:       http://www.mahalito.net/~harley/elisp/crontab-mode.el
+;; License:   GPL v2
+;; Keywords: cron, crontab, emacs
+
+;;; Commentary:
+;; * I want to keep my crontabs under rcs to keep a history of
+;;   the file.  Editing them with 'crontab -e' is rather
+;;   cumbersome.  My method is to keep the crontab as a file,
+;;   under rcs, and check in the changes with 'C-c C-c' after
+;;   editing.
+;; 
+;; * The remote systems are expected to share a filesystem.
+;;   If they dont, modify crontab-shell or crontab-apply to
+;;   suit your needs.
+;;
+;; * You may want to add one of these to your startup:
+;;   (add-to-list 'auto-mode-alist '("\\.cron\\(tab\\)?\\'" . crontab-mode))
+;;   (add-to-list 'auto-mode-alist '("cron\\(tab\\)?\\."    . crontab-mode))
+
+;;; History:
+;;  2003-03-16: Updated URL and contact info
+;;  2004-02-26: Use ssh to apply crontabs to remote hosts.
+
+;;; Code:
+
+(defvar crontab-suffix ".crontab"
+  "*Suffix for crontab buffers.")
+
+(defvar crontab-apply-after-save nil
+  "*Non-nil to apply the crontab after a save.")
+(make-variable-buffer-local 'crontab-apply-after-save)
+
+(defvar crontab-host nil
+  "*Hostname to use when saving the crontab to a remote host.")
+(make-variable-buffer-local 'crontab-host)
+
+(defvar crontab-user nil
+  "*Username to use when saving the crontab to a remote host.")
+(make-variable-buffer-local 'crontab-user)
+
+;; Would be better to have "\\([0-9]\\([-,][0-9]+\\)+\\|...
+(defvar crontab-unit-regexp "\\(\\(?:[-,0-9]+\\|\\*\\)\\(?:/[0-9]+\\)?\\)"
+  "A regexp which matches a cron time unit.")
+
+(defvar crontab-sep-regexp "[ \t]+"
+  "A regexp to match whitespace seperating cron time units.")
+
+(defvar crontab-ruler "
+# min   hour    day     month   day-of-week command
+#(0-59) (0-23)  (1-31)  (1-12)  (0-6)
+#------------------------------------------------------------
+"
+  "*The ruler `crontab-insert-ruler' inserts.")
+
+;;
+(defvar crontab-mode-hook nil
+  "*Hook for customising `crontab-mode'.")
+
+(defvar crontab-load-hook nil
+  "*Hook run when the `crontab-mode' is loaded.")
+
+;;
+(defvar crontab-font-lock-keywords
+  (list
+   ;; Comments
+   '("^#.*$" . font-lock-comment-face)
+   ;; Blank lines are bad!
+   '("^[ \t]+$" . highlight)
+   ;; Variable defs
+   '("^\\([A-Z_]+\\)=\\(.*\\)$" .
+     ((1 font-lock-keyword-face)
+      (2 font-lock-string-face)) )
+   ;; Cron lines
+   ;; 50 * * * * /usr/gnu/bin/bash
+   (cons
+    (concat "^"
+           crontab-unit-regexp crontab-sep-regexp
+           crontab-unit-regexp crontab-sep-regexp
+           crontab-unit-regexp crontab-sep-regexp
+           crontab-unit-regexp crontab-sep-regexp
+           crontab-unit-regexp crontab-sep-regexp
+           "\\(.*\\)$")
+    '((1 font-lock-keyword-face)
+      (2 font-lock-keyword-face)
+      (3 font-lock-keyword-face)
+      (4 font-lock-keyword-face)
+      (5 font-lock-keyword-face)
+      (6 font-lock-string-face))) )
+  "Info for function `font-lock-mode'.")
+
+(defvar crontab-mode-map nil
+  "Keymap used in `crontab-mode'.")
+
+(if crontab-mode-map
+  ()
+  (setq crontab-mode-map (make-sparse-keymap))
+  (define-key crontab-mode-map "\C-c\C-c" 'crontab-save-and-apply)
+  (define-key crontab-mode-map "\C-cc" 'crontab-save-and-apply)
+  (define-key crontab-mode-map "\C-ca" 'crontab-save-and-apply-to)
+  (define-key crontab-mode-map "\C-ci" 'crontab-insert-local-var)
+  (define-key crontab-mode-map "\C-cr" 'crontab-insert-ruler))
+
+;; This will barf without the correct agent or key setup.
+(defvar crontab-rsh-cmd "ssh" ;; "rsh"
+  "Program to use for remote shells.")
+
+(defun crontab-rsh-cmd ()
+  "Generate the rsh command.  Redefine as needed."
+  (if crontab-user
+    (concat crontab-rsh-cmd " -l " (format "%s" crontab-user)) ;; str-ify
+    crontab-rsh-cmd) )
+
+(defun crontab-localhost-p (&optional host)
+  "True if this is the same HOST Emacs is on."
+  (or (null host)
+      (string= host "")
+      (string= host "localhost")
+      (string= host (system-name))) )
+
+(defun crontab-shell (host cmd out-buffer)
+  "On a possibly remote HOST, run CMD  Output to OUT-BUFFER."
+  (when (not (crontab-localhost-p host))
+    (setq cmd (concat (crontab-rsh-cmd) " " host " " cmd)))
+  (shell-command cmd out-buffer) )
+
+;;;###autoload
+(defun crontab-mode ()
+  "Major mode for editing crontabs.
+Defines commands for getting and applying crontabs for hosts.
+Sets up command `font-lock-mode'.
+
+\\{crontab-mode-map}"
+  (interactive)
+  ;;
+  (kill-all-local-variables)
+  (setq mode-name "crontab")
+  (setq major-mode 'crontab-mode)
+  (use-local-map crontab-mode-map)
+  ;;
+  (setq comment-start "#")
+  (setq comment-start-skip "#+ *")
+  ;;
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '(crontab-font-lock-keywords))
+  ;; Add to the end of the buffers save hooks.
+  (add-hook 'after-save-hook 'crontab-after-save t t)
+  ;;
+  (run-hooks 'crontab-mode-hook) )
+
+
+;;;###autoload
+(defun crontab-get (host)
+  "Get the crontab for the HOST into a buffer."
+  (interactive "sCrontab for host:")
+  (let ((cbn (generate-new-buffer-name (concat host crontab-suffix))))
+    (switch-to-buffer-other-window cbn)
+    (erase-buffer)
+    (crontab-mode)
+    (crontab-insert host)
+    (not-modified)
+    (setq crontab-host host)) )
+
+(defun crontab-insert (&optional host)
+  "Insert the crontab for the HOST into the current buffer."
+  (crontab-shell host "crontab -l" t) )
+
+(defun crontab-apply (&optional host)
+  "Apply the crontab to a HOST.  The filesystem must be common."
+  (if (buffer-file-name)
+    (crontab-shell host (concat "crontab " (buffer-file-name)) nil)
+    (error "No filename  for this buffer")))
+
+(defun crontab-save-and-apply ()
+  "Save and apply the buffer to the HOST."
+  (interactive)
+  (save-buffer)
+  (if (not crontab-apply-after-save) ;; Dont apply it twice.
+    (crontab-apply (crontab-host))) )
+
+(defun crontab-save-and-apply-to (host)
+  "Prompt for the HOST and apply the file."
+  (interactive "sApply to host:")
+  (setq crontab-host host) ;; remember the change
+  (crontab-save-and-apply) )
+
+(defun crontab-insert-ruler ()
+  "Insert a ruler with comments into the crontab."
+  (interactive)
+  (end-of-line)
+  (insert crontab-ruler) )
+
+(defun crontab-insert-local-var ()
+  "Insert the current values of buffer local variables."
+  (interactive)
+  (goto-char (point-max))
+  (insert "
+" comment-start " Local " "Variables:
+" comment-start " mode: " (format "%s" (or mode-name "crontab")) "
+" comment-start " crontab-host: " (crontab-host) "
+" comment-start " crontab-apply-after-save: "
+(format "%s" crontab-apply-after-save) "
+" comment-start " End:
+") )
+
+(defun crontab-host ()
+  "Return the hostname as a string, defaulting to the local host.
+The variable `crontab-host' could be a symbol or a string."
+  (format "%s" (or crontab-host system-name)) )
+
+;;
+(defun crontab-after-save ()
+  "If `crontab-apply-after-save' is set, apply the crontab after a save."
+  (if crontab-apply-after-save (crontab-apply (crontab-host))) )
+
+(provide 'crontab-mode)
+(run-hooks 'crontab-load-hook)
+
+;;; crontab-mode.el ends here
diff --git a/.emacs.d/elisp/local/flymake-css.el b/.emacs.d/elisp/local/flymake-css.el
new file mode 100644 (file)
index 0000000..7e2d6ef
--- /dev/null
@@ -0,0 +1,64 @@
+;;; flymake-css.el --- Flymake support for css using csslint
+;;
+;;; Author: Steve Purcell <steve@sanityinc.com>
+;;; Homepage: https://github.com/purcell/flymake-css
+;; Version: 20121104.1904
+;;; X-Original-Version: DEV
+;;; Package-Requires: ((flymake-easy "0.1"))
+;;
+;;; Commentary:
+;;
+;; Usage:
+;;   (require 'flymake-css)
+;;   (add-hook 'css-mode-hook 'flymake-css-load)
+;;
+;; Beware that csslint is quite slow, so there can be a significant lag
+;; between editing and the highlighting of resulting errors.
+;;
+;; Like the author's many other flymake-*.el extensions, this code is
+;; designed to configure flymake in a buffer-local fashion, which
+;; avoids the dual pitfalls of 1) inflating the global list of
+;; `flymake-err-line-patterns' and 2) being required to specify the
+;; matching filename extensions (e.g. "*.css") redundantly.
+;;
+;; Based mainly on the author's flymake-jslint.el, and using the
+;; error regex from Arne Jørgensen's similar flymake-csslint.el.
+;;
+;; Uses flymake-easy, from https://github.com/purcell/flymake-easy
+
+(require 'flymake-easy)
+
+;;; Code:
+
+(defgroup flymake-css nil
+  "Flymake checking of CSS using csslint"
+  :group 'programming
+  :prefix "flymake-css-")
+
+;;;###autoload
+(defcustom flymake-css-lint-command "csslint"
+  "Name (and optionally full path) of csslint executable."
+  :type 'string :group 'flymake-css)
+
+(defvar flymake-css-err-line-patterns
+  '(("^\\(.*\\): line \\([[:digit:]]+\\), col \\([[:digit:]]+\\), \\(.+\\)$" 1 2 3 4)))
+
+(defun flymake-css-command (filename)
+  "Construct a command that flymake can use to check css source."
+  (list flymake-css-lint-command "--format=compact" filename))
+
+
+;;;###autoload
+(defun flymake-css-load ()
+  "Configure flymake mode to check the current buffer's css syntax."
+  (interactive)
+  (when (eq major-mode 'css-mode)
+    ;; Don't activate in derived modes, e.g. less-css-mode
+    (flymake-easy-load 'flymake-css-command
+                       flymake-css-err-line-patterns
+                       'tempdir
+                       "css")))
+
+
+(provide 'flymake-css)
+;;; flymake-css.el ends here
diff --git a/.emacs.d/elisp/local/flymake-easy.el b/.emacs.d/elisp/local/flymake-easy.el
new file mode 100644 (file)
index 0000000..7d30173
--- /dev/null
@@ -0,0 +1,148 @@
+;;; flymake-easy.el --- Helpers for easily building flymake checkers
+
+;; Copyright (C) 2012 Steve Purcell
+
+;; Author: Steve Purcell <steve@sanityinc.com>
+;; URL: https://github.com/purcell/flymake-easy
+;; Version: 20130520.1855
+;; X-Original-Version: DEV
+;; Keywords: convenience, internal
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides the `flymake-easy-load' helper function for
+;; setting up flymake checkers. Just call that function with the
+;; appropriate arguments in a major mode hook function. See
+;; `flymake-ruby' for an example:
+;; https://github.com/purcell/flymake-ruby
+
+;;; Code:
+
+(require 'flymake)
+
+(defvar flymake-easy--active nil
+  "Indicates when flymake-easy-load has successfully run in this buffer.")
+(defvar flymake-easy--command-fn nil
+  "The user-specified function for building the flymake command.")
+(defvar flymake-easy--location nil
+  "Where to create the temp file when checking, one of 'tempdir or 'inplace.")
+(defvar flymake-easy--extension nil
+  "The canonical file name extension to use for the current file.")
+
+(mapc 'make-variable-buffer-local
+      '(flymake-easy--active
+        flymake-easy--command-fn
+        flymake-easy--location
+        flymake-easy--extension))
+
+(defun flymake-easy--tempfile-in-temp-dir (file-name prefix)
+  "Create a temporary file for storing the contents of FILE-NAME in the system tempdir.
+Argument PREFIX temp file prefix, supplied by flymake."
+  (make-temp-file (or prefix "flymake-easy")
+                  nil
+                  (concat "." flymake-easy--extension)))
+
+(defun flymake-easy--flymake-init ()
+  "A catch-all flymake init function for use in `flymake-allowed-file-name-masks'."
+  (let* ((tempfile
+          (flymake-init-create-temp-buffer-copy
+           (cond
+            ((eq 'tempdir flymake-easy--location)
+             'flymake-easy--tempfile-in-temp-dir)
+            ((eq 'inplace flymake-easy--location)
+             'flymake-create-temp-inplace)
+            (t
+             (error "unknown location for flymake-easy: %s" flymake-easy--location)))))
+         (command (funcall flymake-easy--command-fn tempfile)))
+    (list (car command) (cdr command))))
+
+(defun flymake-easy-exclude-buffer-p ()
+  "Whether to skip flymake in the current buffer."
+  (and (fboundp 'tramp-tramp-file-p)
+       (buffer-file-name)
+       (tramp-tramp-file-p (buffer-file-name))))
+
+(defun flymake-easy-load (command-fn &optional err-line-patterns location extension warning-re info-re)
+  "Enable flymake in the containing buffer using a specific narrow configuration.
+Argument COMMAND-FN function called to build the
+   command line to run (receives filename, returns list).
+Argument ERR-LINE-PATTERNS patterns for identifying errors (see `flymake-err-line-patterns').
+Argument EXTENSION a canonical extension for this type of source file, e.g. \"rb\".
+Argument LOCATION where to create the temporary copy: one of 'tempdir (default) or 'inplace.
+Argument WARNING-RE a pattern which identifies error messages as warnings.
+Argument INFO-RE a pattern which identifies messages as infos (supported only
+by the flymake fork at https://github.com/illusori/emacs-flymake)."
+  (let ((executable (car (funcall command-fn "dummy"))))
+    (if (executable-find executable) ;; TODO: defer this checking
+        (unless (flymake-easy-exclude-buffer-p)
+          (setq flymake-easy--command-fn command-fn
+                flymake-easy--location (or location 'tempdir)
+                flymake-easy--extension extension
+                flymake-easy--active t)
+          (set (make-local-variable 'flymake-allowed-file-name-masks)
+               '(("." flymake-easy--flymake-init)))
+          (when err-line-patterns
+            (set (make-local-variable 'flymake-err-line-patterns) err-line-patterns))
+          (dolist (var '(flymake-warning-re flymake-warn-line-regexp))
+            (set (make-local-variable var) (or warning-re "^[wW]arn")))
+          (when (boundp 'flymake-info-line-regexp)
+            (set (make-local-variable 'flymake-info-line-regexp)
+                 (or info-re "^[iI]nfo")))
+          (flymake-mode t))
+      (message "Not enabling flymake: '%s' program not found" executable))))
+
+;; Internal overrides for flymake
+
+(defun flymake-easy--find-all-matches (str)
+  "Return all matched for error line patterns in STR.
+
+This is a judicious override for `flymake-split-output', enabled
+by the advice below, which allows for matching multi-line
+patterns."
+  (let (matches
+        (last-match-end-pos 0))
+    (dolist (pattern flymake-err-line-patterns)
+      (let ((regex (car pattern))
+            (pos 0))
+        (while (string-match regex str pos)
+          (push (match-string 0 str) matches)
+          (setq pos (match-end 0)))
+        (setf last-match-end-pos (max pos last-match-end-pos))))
+    (let ((residual (substring str last-match-end-pos)))
+      (list matches
+            (unless (string= "" residual) residual)))))
+
+(defadvice flymake-split-output (around flymake-easy--split-output (output) activate protect)
+  "Override `flymake-split-output' to support mult-line error messages."
+  (setq ad-return-value (if flymake-easy--active
+                            (flymake-easy--find-all-matches output)
+                          ad-do-it)))
+
+
+(defadvice flymake-post-syntax-check (before flymake-easy--force-check-was-interrupted activate)
+  (when flymake-easy--active
+    (setq flymake-check-was-interrupted t)))
+
+
+(provide 'flymake-easy)
+
+;; Local Variables:
+;; coding: utf-8
+;; byte-compile-warnings: (not cl-functions)
+;; eval: (checkdoc-minor-mode 1)
+;; End:
+
+;;; flymake-easy.el ends here
index 3a6d31e..0432392 100644 (file)
@@ -192,6 +192,26 @@ Initialize the color theme package by loading color-theme-libraries.
 
 ;;;***
 \f
+;;;### (autoloads (crontab-get crontab-mode) "crontab-mode" "crontab-mode.el"
+;;;;;;  (20891 58911 0 0))
+;;; Generated autoloads from crontab-mode.el
+
+(autoload 'crontab-mode "crontab-mode" "\
+Major mode for editing crontabs.
+Defines commands for getting and applying crontabs for hosts.
+Sets up command `font-lock-mode'.
+
+\\{crontab-mode-map}
+
+\(fn)" t nil)
+
+(autoload 'crontab-get "crontab-mode" "\
+Get the crontab for the HOST into a buffer.
+
+\(fn HOST)" t nil)
+
+;;;***
+\f
 ;;;### (autoloads (diminished-modes diminish-undo diminish) "diminish"
 ;;;;;;  "diminish.el" (20865 30363 579223 949000))
 ;;; Generated autoloads from diminish.el
@@ -1939,40 +1959,31 @@ Open the Flycheck manual.
 
 ;;;***
 \f
-;;;### (autoloads (toggle-follow-mouse turn-off-follow-mouse turn-on-follow-mouse)
-;;;;;;  "follow-mouse" "follow-mouse.el" (20858 49922 453891 89000))
-;;; Generated autoloads from follow-mouse.el
+;;;### (autoloads (flymake-css-load flymake-css-lint-command) "flymake-css"
+;;;;;;  "flymake-css.el" (20891 59932 137784 394000))
+;;; Generated autoloads from flymake-css.el
 
-(autoload 'turn-on-follow-mouse "follow-mouse" "\
-Moving the mouse will automatically select the window under it.
+(defvar flymake-css-lint-command "csslint" "\
+Name (and optionally full path) of csslint executable.")
 
-\(fn)" t nil)
+(custom-autoload 'flymake-css-lint-command "flymake-css" t)
 
-(autoload 'turn-off-follow-mouse "follow-mouse" "\
-Moving the mouse will not automatically select the window under it.
+(autoload 'flymake-css-load "flymake-css" "\
+Configure flymake mode to check the current buffer's css syntax.
 
 \(fn)" t nil)
 
-(autoload 'toggle-follow-mouse "follow-mouse" "\
-Toggle whether moving the mouse automatically selects the window under it.
-If the optional prefix ARG is specified, follow-mouse is enabled if it is
-positive, and disabled otherwise.  If called interactively, or the optional
-VERBOSE argument is non-nil, display a confirmation message.
-
-\(fn &optional ARG VERBOSE)" t nil)
-
 ;;;***
 \f
 ;;;### (autoloads (just-one-space-with-newline prelude-kill-other-buffers
 ;;;;;;  force-backup-of-buffer clean-mode-line prelude-emacs-lisp-mode-defaults
 ;;;;;;  prelude-remove-elc-on-save interactive-lisp-coding-defaults
 ;;;;;;  lisp-coding-defaults prelude-sudo-edit jj-untabify-buffer
-;;;;;;  move-line-down move-line-up revert-all-buffers org-mycal-export
-;;;;;;  mycal-export-limit org-mycal-export-limit my-c-return epa-dired-mode-hook
-;;;;;;  sacha/decrease-font-size sacha/increase-font-size sacha/search-word-forward
-;;;;;;  sacha/search-word-backward sacha/isearch-yank-current-word
+;;;;;;  move-line-down move-line-up revert-all-buffers my-c-return
+;;;;;;  epa-dired-mode-hook sacha/decrease-font-size sacha/increase-font-size
+;;;;;;  sacha/search-word-forward sacha/search-word-backward sacha/isearch-yank-current-word
 ;;;;;;  ido-disable-line-trucation my-dired-init) "ganneff" "ganneff.el"
-;;;;;;  (20866 32703 266707 225000))
+;;;;;;  (20879 28061 273891 427000))
 ;;; Generated autoloads from ganneff.el
 
 (autoload 'my-dired-init "ganneff" "\
@@ -2018,21 +2029,6 @@ Find the next occurrance of the current word.
 (autoload 'my-c-return "ganneff" "\
 When in minibuffer use `icicle-candidate-action', otherwise use `cua-set-rectangle-mark'.
 
-\(fn)" t nil)
-
-(autoload 'org-mycal-export-limit "ganneff" "\
-Limit the export to items that have a date, time and a range. Also exclude certain categories.
-
-\(fn)" nil nil)
-
-(autoload 'mycal-export-limit "ganneff" "\
-Limit the export to items that don't match an unwanted category 
-
-\(fn)" nil nil)
-
-(autoload 'org-mycal-export "ganneff" "\
-
-
 \(fn)" t nil)
 
 (autoload 'revert-all-buffers "ganneff" "\
@@ -2281,7 +2277,9 @@ Open a summary buffer containing the current notmuch article.
 
 ;;;***
 \f
-;;;### (autoloads (bh/get-pom-from-agenda-restriction-or-point bh/set-agenda-restriction-lock
+;;;### (autoloads (org-mycal-export mycal-export-limit org-mycal-export-limit
+;;;;;;  bh/save-then-publish bh/display-inline-images bh/view-next-project
+;;;;;;  bh/get-pom-from-agenda-restriction-or-point bh/set-agenda-restriction-lock
 ;;;;;;  bh/clock-in-last-task bh/clock-out-maybe bh/clock-in-organization-task-as-default
 ;;;;;;  bh/clock-in-parent-task bh/clock-in-default-task bh/punch-out
 ;;;;;;  bh/punch-in bh/find-project-task bh/clock-in-to-next bh/narrow-to-project
@@ -2290,7 +2288,7 @@ Open a summary buffer containing the current notmuch article.
 ;;;;;;  bh/org-agenda-to-appt bh/skip-non-subprojects bh/skip-projects-and-habits
 ;;;;;;  bh/skip-project-tasks-maybe bh/skip-projects-and-habits-and-single-tasks
 ;;;;;;  bh/skip-project-trees-and-habits bh/skip-non-projects bh/skip-non-stuck-projects
-;;;;;;  bh/list-sublevels-for-projects bh/list-sublevels-for-projects-indented
+;;;;;;  bh/skip-stuck-projects bh/list-sublevels-for-projects bh/list-sublevels-for-projects-indented
 ;;;;;;  bh/is-subproject-p bh/is-task-p bh/is-project-subtree-p bh/is-project-p
 ;;;;;;  org-my-archive-done-tasks bh/phone-call bh/prepare-meeting-notes
 ;;;;;;  bh/remove-empty-drawer-on-clock-out bh/insert-heading-inactive-timestamp
@@ -2300,8 +2298,8 @@ Open a summary buffer containing the current notmuch article.
 ;;;;;;  bh/is-scheduled bh/is-deadline bh/is-pending-deadline bh/is-late-deadline
 ;;;;;;  bh/is-due-deadline bh/is-not-scheduled-or-deadline bh/agenda-sort
 ;;;;;;  bh/agenda-sort-test-num bh/agenda-sort-test bh/verify-refile-target
-;;;;;;  bh/show-org-agenda) "ganneff-org" "ganneff-org.el" (20866
-;;;;;;  32672 234553 345000))
+;;;;;;  bh/show-org-agenda) "ganneff-org" "ganneff-org.el" (20879
+;;;;;;  28085 514011 628000))
 ;;; Generated autoloads from ganneff-org.el
 
 (autoload 'bh/show-org-agenda "ganneff-org" "\
@@ -2471,6 +2469,11 @@ Set org-tags-match-list-sublevels so when restricted to a subtree we list all su
 
 \(fn)" nil nil)
 
+(autoload 'bh/skip-stuck-projects "ganneff-org" "\
+Skip trees that are not stuck projects
+
+\(fn)" nil nil)
+
 (autoload 'bh/skip-non-stuck-projects "ganneff-org" "\
 Skip trees that are not stuck projects
 
@@ -2611,6 +2614,36 @@ Set restriction lock to current task subtree or file if prefix is specified
 
 \(fn)" nil nil)
 
+(autoload 'bh/view-next-project "ganneff-org" "\
+
+
+\(fn)" t nil)
+
+(autoload 'bh/display-inline-images "ganneff-org" "\
+
+
+\(fn)" nil nil)
+
+(autoload 'bh/save-then-publish "ganneff-org" "\
+
+
+\(fn &optional FORCE)" t nil)
+
+(autoload 'org-mycal-export-limit "ganneff-org" "\
+Limit the export to items that have a date, time and a range. Also exclude certain categories.
+
+\(fn)" nil nil)
+
+(autoload 'mycal-export-limit "ganneff-org" "\
+Limit the export to items that don't match an unwanted category 
+
+\(fn)" nil nil)
+
+(autoload 'org-mycal-export "ganneff-org" "\
+
+
+\(fn)" t nil)
+
 ;;;***
 \f
 ;;;### (autoloads (gnus-alias-determine-identity gnus-alias-use-identity
@@ -2885,6 +2918,44 @@ The query function that disable deletion of buffers we protect.
 
 ;;;***
 \f
+;;;### (autoloads (keyfreq-autosave-mode keyfreq-mode) "keyfreq"
+;;;;;;  "keyfreq.el" (20870 14397 870087 510000))
+;;; Generated autoloads from keyfreq.el
+
+(defvar keyfreq-mode nil "\
+Non-nil if Keyfreq mode is enabled.
+See the command `keyfreq-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `keyfreq-mode'.")
+
+(custom-autoload 'keyfreq-mode "keyfreq" nil)
+
+(autoload 'keyfreq-mode "keyfreq" "\
+Keyfreq mode records number of times each command was
+called making it possible to access usage statistics through
+various keyfreq-* functions.
+
+\(fn &optional ARG)" t nil)
+
+(defvar keyfreq-autosave-mode nil "\
+Non-nil if Keyfreq-Autosave mode is enabled.
+See the command `keyfreq-autosave-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `keyfreq-autosave-mode'.")
+
+(custom-autoload 'keyfreq-autosave-mode "keyfreq" nil)
+
+(autoload 'keyfreq-autosave-mode "keyfreq" "\
+Keyfreq Autosave mode automatically saves
+`keyfreq-table' every `keyfreq-autosave-timeout' seconds
+and when emacs is killed.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+\f
 ;;;### (autoloads (mpd-libmpdee-submit-bug-report mpd-output-disable
 ;;;;;;  mpd-output-enable mpd-update mpd-set-password mpd-set-crossfade
 ;;;;;;  mpd-adjust-volume mpd-set-volume mpd-toggle-repeat mpd-toggle-random
@@ -3573,6 +3644,37 @@ Turn off Screen Lines minor mode for the current buffer.
 
 ;;;***
 \f
+;;;### (autoloads (tidy-buffer tidy-save-settings tidy-parse-config-file
+;;;;;;  tidy-build-menu) "tidy" "tidy.el" (20893 10149 0 0))
+;;; Generated autoloads from tidy.el
+
+(autoload 'tidy-build-menu "tidy" "\
+Set up the tidy menu in MAP. Used to set up a Tidy menu in your
+favourite mode.
+
+\(fn &optional MAP)" t nil)
+
+(autoload 'tidy-parse-config-file "tidy" "\
+If `tidy-config-file' is non-nil parse that file setting variables accordingly.
+
+\(fn)" t nil)
+
+(autoload 'tidy-save-settings "tidy" "\
+Query saving the current settings to your `tidy-config-file'.
+Perhaps put this on your `kill-buffer-hook'.
+
+\(fn &optional CONFIG-FILE)" t nil)
+
+(autoload 'tidy-buffer "tidy" "\
+Run the HTML Tidy program on the current buffer.
+If PREFIX is non-nil, or if called interactively with a prefix argument,
+then Tidy is applied to the currently selected region.  Any error messages
+generated by that program are sent to \"*tidy-errors*\" buffer.
+
+\(fn &optional PREFIX)" t nil)
+
+;;;***
+\f
 ;;;### (autoloads (global-undo-tree-mode undo-tree-mode) "undo-tree"
 ;;;;;;  "undo-tree.el" (20858 49922 501891 327000))
 ;;; Generated autoloads from undo-tree.el
@@ -3746,11 +3848,11 @@ Simple mode to edit YAML.
 ;;;***
 \f
 ;;;### (autoloads nil nil ("beamer.el" "bind-key.el" "buildd-gnus.el"
-;;;;;;  "crypt++.el" "dash.el" "filladapt.el" "ganneff2.el" "ldap-mode.el"
+;;;;;;  "crypt++.el" "dash.el" "filladapt.el" "flymake-easy.el" "ldap-mode.el"
 ;;;;;;  "mingus-stays-home.el" "mingus.el" "moinmoin-mode.el" "nnir.el"
 ;;;;;;  "nntodo.el" "randomsig.el" "region-bindings-mode.el" "s.el"
-;;;;;;  "typing.el" "use-package.el" "volatile-highlights.el") (20866
-;;;;;;  32858 445377 86000))
+;;;;;;  "typing.el" "use-package.el" "volatile-highlights.el") (20893
+;;;;;;  13603 30386 364000))
 
 ;;;***
 \f
diff --git a/.emacs.d/elisp/local/tidy.el b/.emacs.d/elisp/local/tidy.el
new file mode 100644 (file)
index 0000000..33f3f31
--- /dev/null
@@ -0,0 +1,1973 @@
+;;; tidy.el --- Interface to the HTML Tidy program
+
+;; Copyright (C) 2001, 2002, 2003 by Free Software Foundation, Inc.
+
+;; Emacs Lisp Archive Entry
+;; Filename: tidy.el
+;; Author: Kahlil (Kal) HODGSON <dorge@tpg.com.au>
+;; X-URL: http://www.emacswiki.org/elisp/tidy.el
+;; Time-stamp: <2002-09-30 13:16:23 kahlil>
+;; Version: 20111222.1756
+;; X-Original-Version: 2.12
+;; Keywords: languages
+
+;; This file is NOT part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;;; Commentary:
+
+;; Provides a simple interface to the HTML Tidy program -- a free
+;; utility that can fix common errors in your mark-up and clean up
+;; sloppy editing automatically. See
+;;
+;;       <http://tidy.sourceforge.net/>
+;;
+;; for more details.  This package provides the following functions:
+;;
+;;       `tidy-buffer',
+;;       `tidy-parse-config-file',
+;;       `tidy-save-settings', and
+;;       `tidy-describe-options',
+;;
+;; These can be invoked interactively (using M-x) or via the menu-bar.
+;; The function `tidy-buffer' sends the current buffer to HTML Tidy,
+;; replacing the existing contents with a "tidied" version.  If
+;; `tidy-buffer' is given a prefix argument, tidy operates on the
+;; current region, ignoring mark-up outside <BODY>...</BODY> tags
+;; (useful for writhing cgi scripts in Pearl).  Warnings and errors
+;; are presented in a compilation buffer to facilitate tracking down
+;; necessary changes (e.g. C-x ` is bound to `next-error').
+;;
+;; This package also provides menu-bar support for setting Tidy's many
+;; options, and includes support for Tidy configuration files.  The
+;; function `tidy-parse-config-file' will synchronise options
+;; displayed in the menu-bar with the settings in `tidy-config-file'.
+;; This is normally called by the load-hook for your HTML editing mode
+;; (see installation instructions below).  The function
+;; `tidy-save-settings' will save the current option settings to your
+;; `tidy-config-file'.  Finally `tidy-describe-options' allows you to
+;; browse the documentation strings associated with each option.
+
+;;;
+
+;;;; Installation:
+
+;; This package assumes you have and up-to-date HTML Tidy program
+;; installed on your system.  See the URL above for instructions on
+;; how to do this.  To set up this support package, first place the
+;; "tidy.el" file somewhere in your `load-path' and open it in Emacs.
+;; Byte-compile and load this package using the command
+;;
+;; M-x emacs-lisp-byte-compile-and-load <RET>
+;;
+;; Next customise the variables `tidy-config-file', `tidy-temp-dir'
+;; `tidy-shell-command', `tidy-menu-lock' and `tidy-menu-x-position'
+;;
+;; M-x customize-group <RET> tidy <RET>
+;;
+;; Now add the following autoloads to your ".emacs.el" file:
+;;
+;; (autoload 'tidy-buffer "tidy" "Run Tidy HTML parser on current buffer" t)
+;; (autoload 'tidy-parse-config-file "tidy" "Parse the `tidy-config-file'" t)
+;; (autoload 'tidy-save-settings "tidy" "Save settings to `tidy-config-file'" t)
+;; (autoload 'tidy-build-menu  "tidy" "Install an options menu for HTML Tidy." t)
+;;
+;; If you use html-mode to edit HTML files then add something like
+;; this as well
+
+;; (defun my-html-mode-hook () "Customize my html-mode."
+;;   (tidy-build-menu html-mode-map)
+;;   (local-set-key [(control c) (control c)] 'tidy-buffer)
+;;   (setq sgml-validate-command "tidy"))
+;;
+;; (add-hook 'html-mode-hook 'my-html-mode-hook)
+
+;; This will set up a "tidy" menu in the menu bar and bind the key
+;; sequence "C-c C-c" to `tidy-buffer' in html-mode (normally bound to
+;; `validate-buffer').
+;;
+;; For other modes (like html-helper-mode) simple change the variables
+;; `html-mode-hook' and `html-mode-map' to whatever is appropriate e.g.
+
+;; (defun my-html-mode-hook () "Customize my html-helper-mode."
+;;   (tidy-build-menu html-helper-mode-map)
+;;   (local-set-key [(control c) (control c)] 'tidy-buffer)
+;;   (setq sgml-validate-command "tidy"))
+;;
+;; (add-hook 'html-helper-mode-hook 'my-html-mode-hook)
+
+;; Finally, restart Emacs and open an HTML file to test-drive the tidy
+;; package. For people new to HTML tidy check that the option "markup"
+;; under the "Input/Output" sub menu is set. You can read the
+;; documentation on this option via the menu item "Describe Options".
+;;
+;; Enjoy!
+
+;;;; New Features:
+;;
+;; 0. Now compatible with CVS version of Tidy as at 22 May 2003
+;; 1. Improved menu support to facillitate incorporting new options
+;; 2. Menu lock option makes menu stick when toggling options.
+;; 3. Now runs on XEmacs!!
+;; 4. Uses error file rather than std-error to retrieve errors (this
+;;    fixes some odd pop up behaviour)
+;; 5. minor bug fix (empty config files)
+;; 6. handle buffer modified query in error buffer better
+;; 7. make it impossible to mark the error buffer as modified
+;; 8. Added the variable `tidy-temp-directory'.
+;; 9. Bugfix in tidy-buffer: call find-file-noselect with NOWARN
+
+;;;; ToDo:
+;;
+;; 1. Automatically set "char-encoding" according to the buffer encoding
+;; 2. Should check value of HTML_TIDY environment variable.
+
+
+;;;; Bugs:
+
+;; Requires a version of HTML Tidy that understands the "-f"
+;; "-config" "--show-body-only" command line options e.g. source-forge
+;; pre-release.
+;;
+;; There may be a bug with setting doctypes.  I don't use this feature
+;; yet and, well, don't really know how its supposed to work:-)
+;;
+;; Care with character encodings!!
+
+;;;; Credits
+
+;; This code was inspired by an Emacs "tip" suggested by Pete Gelbman.
+;;
+;; Thanks to Hans-Michael Stahl for comments regarding XEmacs
+;; compatibility.
+;;
+;; Thanks to Thomas Baumann for bugfix's in `tidy-parse-config-file'
+;; and `tidy-buffer'.
+;;
+;; Thanks to Chris Lott for comments regarding installation and menu
+;; display
+;;
+;; Thanks to Jeroen Baekelandt for noting a problem with ange-ftp and
+;; inspiring `tidy-temp-directory'.
+
+;;;; Code:
+
+;;;;; Forward references (stuff which must come first)
+
+(require 'easymenu) ;; This makes menus so much easier!
+(require 'compile)  ;; To make the error buffer more sexy
+
+;; The following two are functions so that the same compiled code will
+;; work in both situations (time cost is negligible)
+
+(defsubst tidy-xemacs-p ()
+  "Return t iff we are running XEmacs this session."
+  (not (null (string-match "^XEmacs.*" (emacs-version)))))
+
+(defsubst tidy-windows-p ()
+  "Return t iff we are running on a Windows system."
+  (memq system-type '(emx win32 w32 mswindows ms-dos windows-nt)))
+
+;; function definitions
+
+;; XEmacs
+(defalias 'tidy-x-event-function          'event-function)
+(defalias 'tidy-x-event-object            'event-object)
+(defalias 'tidy-x-find-menu-item          'find-menu-item)
+(defalias 'tidy-x-get-popup-menu-response 'get-popup-menu-response)
+(defalias 'tidy-x-make-event              'make-event)
+(defalias 'tidy-x-misc-user-event-p       'misc-user-event-p)
+
+;;;;; User Variables
+
+(defgroup tidy nil
+"*Provides a simple interface to the HTML Tidy program -- a free
+utility that can fix common errors in your mark-up and clean up
+sloppy editing automatically. See
+
+      <http://tidy.sourceforge.net/>
+
+for more details.  This package provides the following functions:
+
+      `tidy-buffer',
+      `tidy-parse-config-file',
+      `tidy-save-settings', and
+      `tidy-describe-options',
+
+These can be invoked interactively (using M-x) or via the menu-bar.
+The function `tidy-buffer' sends the current buffer to HTML Tidy,
+replacing the existing contents with a \"tidied\" version.  If
+`tidy-buffer' is given a prefix argument, tidy operates on the
+current region, ignoring mark-up outside <BODY>...</BODY> tags
+\(useful for writhing cgi scripts in Pearl).  Warnings and errors
+are presented in a compilation buffer to facilitate tracking down
+necessary changes (e.g. C-x ` is bound to `next-error').
+
+This package also provides menu-bar support for setting Tidy's many
+options, and includes support for Tidy configuration files.  The
+function `tidy-parse-config-file' will synchronise options
+displayed in the menu-bar with the settings in `tidy-config-file'.
+This is normally called by the load-hook for your HTML editing mode
+\(see installation instructions below).  The function
+`tidy-save-settings' will save the current option settings to your
+`tidy-config-file'.  Finally `tidy-describe-options' allows you to
+browse the documentation strings associated with each option.
+")
+
+
+(defcustom tidy-config-file "~/.tidyrc"
+  "*Path to your default tidy configuration file.
+
+This is used by `tidy-parse-config-file' to synchronise Tidy's behaviour
+inside Emacs with its behaviour outside, and by `tidy-save-settings' to
+set your configuration file from within Emacs.  If you never want this to
+happen, set `tidy-config-file' to nil."
+  :group 'tidy
+  :type 'string)
+
+(defcustom tidy-shell-command "/usr/bin/tidy"
+  "*Full path to command to call HTML tidy from a shell."
+  :group 'tidy
+  :type 'string)
+
+(defcustom tidy-temp-directory "."
+  "Directory where tidy places its temp files.  The default is the
+current directory which works fine unless you are operating on remote
+files via `ange-ftp' and its ilk, in which case it will try to place
+the temp files on the remote server (and will probably fail).  If this
+is the case try setting this variable to something like \"/tmp/\" or
+\"/var/tmp/\"."
+  :group 'tidy
+  :type 'string)
+
+(defcustom tidy-menu-lock t
+  " *Non-nil means menu is locked (i.e. doesn't pop down) when
+selecting toggle and radio options.
+
+See also `tidy-menu-x-position'."
+  :type 'boolean
+  :group 'tidy)
+
+(defcustom tidy-menu-x-position 211
+  "*Specify menu position height in pixels.
+
+This variable is used to set the horizontal position of the locked
+menu, so don't forget to adjust it if menu position is not ok.
+
+See also `tidy-menu-lock'."
+  :type 'integer
+  :group 'tidy)
+
+;;;;; Local Variables
+
+(defvar tidy-debug  nil
+  "If t then we rebuild everything on reload. Useful for debugging.")
+
+;;(eval-when-compile (setq tidy-debug t))
+
+(defun tidy-toggle-debug () "Toggle value of tidy-debug."
+  (interactive)
+  (message "tidy-debug is %s" (setq tidy-debug (not tidy-debug))))
+
+(defvar tidy-options-alist nil
+  "An alist containing all valid tidy options.
+Each element is a list of the form
+    (NAME, SUB-MENU, VALUE-TYPE, DEFAULT-VALUE, DOC-STRING).
+This is used to automatically construct variables and a menu bar.
+To add new or modify exiting options simply modify this list.")
+
+(when (or (null tidy-options-alist) tidy-debug)
+  (setq tidy-options-alist
+       '(
+         ("add-xml-decl" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should add the XML declaration when
+outputting XML or XHTML. Note that if the input already includes an <?xml
+... ?> declaration then this option will be ignored.")
+
+         ("add-xml-pi" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option is the same as the add-xml-decl option.")
+
+         ("add-xml-space" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should add xml:space=\"preserve\" to elements
+such as <PRE>, <STYLE> and <SCRIPT> when generating XML. This is needed if
+the whitespace in such elements is to be parsed appropriately without
+having access to the DTD.")
+
+         ("alt-text" "Fix Markup" "String" ""
+          "
+Type: String
+Default: -none-
+
+This option specifies the default \"alt=\" text Tidy uses for <IMG>
+attributes. This feature is dangerous as it suppresses further
+accessibility warnings. You are responsible for making your documents
+accessible to people who can not see the images!")
+
+         ("ascii-chars" "Fix Markup" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+Can be used to modify behavior of -c (--clean yes) option.
+Defaults to \"yes\" when using -c. Set to \"no\" to prevent
+converting &emdash;, &rdquo;, and other named character entities
+to their ascii equivalents.")
+
+         ("assume-xml-procins" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should change the parsing of processing
+instructions to require ?> as the terminator rather than >. This option is
+automatically set if the input is in XML.")
+
+         ("bare" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should strip Microsoft specific HTML from
+Word 2000 documents, and output spaces rather than non-breaking spaces
+where they exist in the input.")
+
+         ("break-before-br" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output a line break before each <BR>
+element.")
+
+         ("char-encoding" "Encoding" "Encoding" "ascii"
+          "
+Type: Encoding
+Default: ascii
+Example: ascii, latin1, raw, utf8, iso2022, mac, win1252
+
+This option specifies the character encoding Tidy uses for both the input
+and output. Possible values are: ascii, latin1, raw, utf8, iso2022, mac,
+win1252. For ascii, Tidy will accept Latin-1 (ISO-8859-1) character
+values, but will use entities for all characters whose value > 127. For
+raw, Tidy will output values above 127 without translating them into
+entities. For latin1, characters above 255 will be written as
+entities. For utf8, Tidy assumes that both input and output is encoded as
+UTF-8. You can use iso2022 for files encoded using the ISO-2022 family of
+encodings e.g. ISO-2022-JP. For mac and win1252, Tidy will accept vendor
+specific character values, but will use entities for all characters whose
+value > 127.")
+
+         ("clean" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should strip out surplus presentational tags
+and attributes replacing them by style rules and structural markup as
+appropriate. It works well on the HTML saved by Microsoft Office products.")
+
+         ("doctype" "Fix Markup" "DocType" "auto"
+          "
+Type: DocType
+Default: auto
+Example: auto, omit, strict, loose, transitional, user specified fpi \(string\)
+
+This option specifies the DOCTYPE declaration generated by Tidy. If set to
+\"omit\" the output won't contain a DOCTYPE declaration. If set to \"auto\"
+\(the default\) Tidy will use an educated guess based upon the contents of
+the document. If set to \"strict\", Tidy will set the DOCTYPE to the strict
+DTD. If set to \"loose\", the DOCTYPE is set to the loose \(transitional\)
+DTD. Alternatively, you can supply a string for the formal public
+identifier \(FPI\). For example:
+
+      doctype: \"-//ACME//DTD HTML 3.14159//EN\"
+
+If you specify the FPI for an XHTML document, Tidy will set
+the system identifier to the empty string. Tidy leaves the DOCTYPE for
+generic XML documents unchanged.")
+
+         ("drop-empty-paras" "Fix Markup" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should discard empty paragraphs. If set to
+no, empty paragraphs are replaced by a pair of <BR> elements as HTML4
+precludes empty paragraphs.")
+
+         ("drop-font-tags" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should discard <FONT> and <CENTER> tags
+rather than creating the corresponding style rules, but only if the clean
+option is also set to yes.")
+
+         ("drop-proprietary-attributes" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should strip out proprietary attributes,
+such as MS data binding attributes.")
+
+         ("enclose-block-text" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should insert a <P> element to enclose any
+text it finds in any element that allows mixed content for HTML
+transitional but not HTML strict.")
+
+         ("enclose-text" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should enclose any text it finds in the body
+element within a <P> element. This is useful when you want to take
+existing HTML and use it with a style sheet.")
+
+         ("error-file" "Omit" "String" "-none-"
+          "
+Type: String
+Default: -none-
+
+This option specifies the error file Tidy uses for errors and
+warnings. Normally errors and warnings are output to \"stderr\".
+
+This is option is ignored in Emacs.")
+
+         ("escape-cdata" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should convert <![CDATA[]]> sections to
+normal text.")
+
+         ("fix-backslash" "Fix Markup" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should replace backslash characters \"\\\" in
+URLs by forward slashes \"/\".")
+
+         ("fix-bad-comments" "Fix Markup" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should replace unexpected hyphens with \"=\"
+characters when it comes across adjacent hyphens. The default is yes. This
+option is provided for users of Cold Fusion which uses the comment syntax:
+<!--- --->")
+
+         ("fix-uri" "Fix Markup" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should check attribute values that carry
+URIsfor illegal characters and if such are found, escape them as HTML 4
+recommends.")
+
+         ("force-output" "Input/Output" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should produce output even if errors are
+encountered. Use this option with care - if Tidy reports an error,
+this means Tidy was not able to, or is not sure how to, fix the error,
+so the resulting output may not reflect your intention.")
+
+         ("gnu-emacs" "Omit" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should change the format for reporting
+errors and warnings to a format that is more easily parsed by GNU
+Emacs.
+
+This option is automatically set in Emacs."  )
+
+         ("hide-comments" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should print out comments.")
+
+         ("hide-endtags" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should omit optional end-tags when
+generating the pretty printed markup. This option is ignored if you are
+outputting to XML.")
+
+         ("indent" "Indentation" "AutoBool" "no"
+          "
+Type: AutoBool
+Default: no
+Example: auto, y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should indent block-level tags.  If set to
+\"auto\", this option causes Tidy to decide whether or not to indent the
+content of tags such as TITLE, H1-H6, LI, TD, TD, or P depending on whether
+or not the content includes a block-level element. You are advised to avoid
+setting indent to yes as this can expose layout bugs in some browsers.")
+
+         ("indent-attributes" "Indentation" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should begin each attribute on a new line.")
+
+         ("indent-cdata" "Indent" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should indent <![CDATA[]]> sections.")
+
+         ("indent-spaces" "Indentation" "Integer" "2"
+          "
+Type: Integer
+Default: 2
+Example: 0, 1, 2, ...
+
+This option specifies the number of spaces Tidy uses to indent content,
+when indentation is enabled.")
+
+         ("input-encoding" "Encoding" "Encoding" "latin1"
+          "
+Type: Encoding
+Default: ascii
+Example: ascii, latin1, raw, utf8, iso2022, mac, win1252
+
+This option specifies the character encoding Tidy uses for the input. See
+char-encoding for more info.")
+
+         ("input-xml" "Input/Output" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should use the XML parser rather than the
+error correcting HTML parser.")
+
+         ("join-classes" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should combine class names to generate a
+single new class name, if multiple class assignments are detected on an
+element.")
+
+         ("join-styles" "Fix Markup" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should combine styles to generate a single
+new style, if multiple style values are detected on an element.")
+
+         ("keep-time" "Preference" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should alter the last modified time for
+files it writes back to. The default is no, which allows you to tidy files
+without affecting which ones will be uploaded to a Web server when using a
+tool such as 'SiteCopy'. Note that this feature may not work on some
+platforms.")
+
+         ("literal-attributes" "Preference" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should ensure that whitespace characters
+within attribute values are passed through unchanged.")
+
+         ("logical-emphasis" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should replace any occurrence of <I> by <EM>
+and any occurrence of <B> by <STRONG>. In both cases, the attributes are
+preserved unchanged. This option can be set independently of the clean and
+drop-font-tags options.")
+
+         ("lower-literals" "Preference" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should convert the value of an attribute
+that takes a list of predefined values to lower case. This is required for
+XHTML documents.")
+
+         ("markup" "Input/Output" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should generate a pretty printed version of
+the markup. Note that Tidy won't generate a pretty printed version if it
+finds significant errors (see force-output).")
+
+         ("ncr" "Preference" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should allow numeric character references.")
+
+         ("new-blocklevel-tags" "Tags" "Tag names" ""
+          "
+Type: Tag names
+Default: -none-
+Example: tagX, tagY, ...
+
+This option specifies new block-level tags. This option takes a space or
+comma separated list of tag names. Unless you declare new tags, Tidy will
+refuse to generate a tidied file if the input includes previously unknown
+tags. Note you can't change the content model for elements such as
+<TABLE>, <UL>, <OL> and <DL>.")
+
+         ("new-empty-tags" "Tags" "Tag names" ""
+          "
+Type: Tag names
+Default: -none-
+Example: tagX, tagY, ...
+
+This option specifies new empty inline tags. This option takes a space or
+comma separated list of tag names. Unless you declare new tags, Tidy will
+refuse to generate a tidied file if the input includes previously unknown
+tags. Remember to also declare empty tags as either inline or blocklevel.")
+
+         ("new-inline-tags" "Tags" "Tag names" ""
+          "
+Type: Tag names
+Default: -none-
+Example: tagX, tagY, ...
+
+This option specifies new non-empty inline tags. This option takes a space
+or comma separated list of tag names. Unless you declare new tags, Tidy
+will refuse to generate a tidied file if the input includes previously
+unknown tags.")
+
+         ("new-pre-tags" "Tags" "Tag names" ""
+          "
+Type: Tag names
+Default: -none-
+Example: tagX, tagY, ...
+
+This option specifies new tags that are to be processed in exactly the
+same way as HTML's <PRE> element. This option takes a space or comma
+separated list of tag names. Unless you declare new tags, Tidy will refuse
+to generate a tidied file if the input includes previously unknown
+tags. Note you can not as yet add new CDATA elements (similar to
+<SCRIPT>).")
+
+         ("numeric-entities" "Preference" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output entities other than the
+built-in HTML entities \(&amp;, &lt;, &gt; and &quot;\) in the numeric
+rather than the named entity form.")
+
+         ("output-bom" "Encoding" "AutoBool" "auto"
+          "
+Type: AutoBool
+Default: auto
+Example: auto, y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should write a Unicode Byte Order Mark
+character (BOM; also known as Zero Width No-Break Space; has value of
+U+FEFF) to the beginning of the output; only for UTF-8 and UTF-16 output
+encodings. If set to \"auto\", this option causes Tidy to write a BOM to the
+output only if a BOM was present at the beginning of the input. A BOM is
+always written for XML/XHTML output using UTF-16 output encodings.")
+
+         ("output-encoding" "Encoding" "Encoding" "ascii"
+          "
+Type: Encoding
+Default: ascii
+Example: ascii, latin1, raw, utf8, iso2022, mac, win1252
+
+This option specifies the character encoding Tidy uses for the output. See
+char-encoding for more info. May only be different from input-encoding for
+Latin encodings (ascii, latin1, mac, win1252).")
+
+         ("output-xhtml" "Input/Output" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should generate pretty printed output,
+writing it as extensible HTML. This option causes Tidy to set the DOCTYPE
+and default namespace as appropriate to XHTML. If a DOCTYPE or namespace
+is given they will checked for consistency with the content of the
+document. In the case of an inconsistency, the corrected values will
+appear in the output. For XHTML, entities can be written as named or
+numeric entities according to the setting of the \"numeric-entities\"
+option.  The original case of tags and attributes will be preserved,
+regardless of other options.")
+
+         ("output-xml" "Input/Output" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should pretty print output, writing it as
+well-formed XML. Any entities not defined in XML 1.0 will be written as
+numeric entities to allow them to be parsed by a XML parser. The original
+case of tags and attributes will be preserved, regardless of other
+options.")
+
+         ("quiet" "Input/Output" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output the summary of the numbers of
+errors and warnings, or the welcome or informational messages.")
+
+         ("quote-ampersand" "Preference" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output unadorned & characters as
+&amp;.")
+
+         ("quote-marks" "Preference"  "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output \" characters as &quot; as is
+preferred by some editing environments. The apostrophe character \' is
+written out as &#39; since many web browsers don't yet support &apos;.")
+
+         ("quote-nbsp" "Preference" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output non-breaking space characters
+as entities, rather than as the Unicode character value 160 (decimal).")
+
+         ("raw" "Omit" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0 char-encoding
+
+Currently not used, but this option would be the same as the
+char-encoding: raw option.")
+
+         ("repeated-attributes" "Fix Markup" ("keep-first" "keep-last") "keep-last"
+          "
+Type: -
+Default: keep-last
+Example: keep-first, keep-last
+
+This option specifies if Tidy should keep the first or last attribute, if
+an attribute is repeated, e.g. has two align attributes.")
+
+
+         ("replace-color" "Fix Markup" "Boolean"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should replace numeric values in color
+attributes by HTML/XHTML color names where defined, e.g. replace
+\"#ffffff\" with \"white\"."  )
+
+         ("slide-style" "Omit" "String"
+          "
+Type: Name
+Default: -none-
+split Currently not used.")
+
+         ("show-body-only" "Omit" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should print only the contents of the body
+tag as an HTML fragment. Useful for incorporating existing whole pages as
+a portion of another page.
+
+Emacs overrides this option.")
+
+         ("show-errors" "Input/Output" "Integer" "6"
+          "
+Type: Integer
+Default: 6
+Example: 0, 1, 2, ...
+
+This option specifies the number Tidy uses to determine if further errors
+should be shown. If set to 0, then no errors are shown.")
+
+         ("show-warnings" "Input/Output" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should suppress warnings. This can be useful
+when a few errors are hidden in a flurry of warnings.")
+
+         ("slide-style" "Omit" "String" ""
+          "
+Type: Name
+Default: -none-
+
+Currently not used.")
+
+         ("split" "Omit" "Boolean" "no"
+           "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should create a sequence of slides from
+the input, splitting the markup prior to each successive <H2>. The
+slides are written to \"slide001.html\", \"slide002.html\" etc.
+
+There is currently no Emacs support for this option.")
+
+         ("tab-size" "Indentation" "Integer" "4"
+          "
+Type: Integer
+Default: 4
+Example: 0, 1, 2, ...
+
+This option specifies the number of columns that Tidy uses between
+successive tab stops. It is used to map tabs to spaces when reading the
+input. Tidy never outputs tabs.")
+
+         ("tidy-mark" "Preference" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should add a meta element to the document
+head to indicate that the document has been tidied. Tidy won't add a meta
+element if one is already present.")
+
+         ("uppercase-attributes" "Preference" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output attribute names in upper
+case. The default is no, which results in lower case attribute names,
+except for XML input, where the original case is preserved.")
+
+         ("uppercase-tags" "Preference" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should output tag names in upper case. The
+default is no, which results in lower case tag names, except for XML
+input, where the original case is preserved.")
+
+         ("word-2000" "Fix Markup" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should go to great pains to strip out all
+the surplus stuff Microsoft Word 2000 inserts when you save Word documents
+as \"Web pages\".  Doesn't handle embedded images or VML.")
+
+         ("wrap" "Line Wrapping" "Integer" "68"
+          "
+Type: Integer
+Default: 68
+Example: 0, 1, 2, ...
+
+This option specifies the right margin Tidy uses for line wrapping. Tidy
+tries to wrap lines so that they do not exceed this length. Set wrap to
+zero if you want to disable line wrapping.")
+
+         ("wrap-asp" "Line Wrapping" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should line wrap text contained within ASP
+pseudo elements, which look like: <% ... %>.")
+
+         ("wrap-attributes" "Line Wrapping" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should line wrap attribute values, for
+easier editing. This option can be set independently of
+wrap-script-literals.")
+
+         ("wrap-jste" "Line Wrapping" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should line wrap text contained within JSTE
+pseudo elements, which look like: <# ... #>.")
+
+         ("wrap-php" "Line Wrapping" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should line wrap text contained within PHP
+pseudo elements, which look like: <?php ... ?>.")
+
+         ("wrap-script-literals" "Line Wrapping" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should line wrap string literals that appear
+in script attributes. Tidy wraps long script string literals by inserting
+a backslash character before the line break.")
+
+         ("wrap-sections" "Line Wrapping" "Boolean" "yes"
+          "
+Type: Boolean
+Default: yes
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should line wrap text contained within
+<![... ]> section tags.")
+
+         ("write-back" "Omit" "Boolean" "no"
+          "
+Type: Boolean
+Default: no
+Example: y/n, yes/no, t/f, true/false, 1/0
+
+This option specifies if Tidy should write back the tidied markup to
+the same file it read from. You are advised to keep copies of
+important files before tidying them, as on rare occasions the result
+may not be what you expect.
+
+This option is ignored by Emacs.")
+         ))
+  )
+
+;;;;; Create a variable for each option in `tidy-options-alist'"
+
+;; these variables are made buffer local so that different buffers can
+;; use a different set of options
+
+(let ((options-alist tidy-options-alist)
+      option name symbol docstring)
+
+  (while (setq option (car options-alist))
+    (setq name      (nth 0 option)
+         docstring (nth 4 option)
+         symbol    (intern (concat "tidy-" name)))
+    ;; create the variable on the fly
+    (put symbol 'variable-documentation docstring)
+    (make-variable-buffer-local symbol)
+    (set symbol nil) ;;default)
+    (setq options-alist (cdr options-alist))
+    )
+  )
+
+;;;;; Menu Lock (adapted from printing.el)
+
+;; quite compiler
+(eval-when-compile
+  (progn
+        (or (boundp 'current-menubar)
+            (defvar current-menubar nil))
+        (or (fboundp 'tidy-menu-position)
+            (defun  tidy-menu-position () ""))
+        (or (fboundp 'tidy-menu-lock)
+            (defun tidy-menu-lock (entry state path) ""))
+        (or (fboundp 'tidy-menu-lookup)
+            (defun tidy-menu-lookup (path) ""))
+        ))
+
+;; always define these
+(defvar tidy-menu-position nil)
+(defvar tidy-menu-state nil)
+
+(cond
+ ((tidy-xemacs-p)
+  ;; XEmacs
+  (defun tidy-menu-position ()
+    (tidy-x-make-event
+     'button-release
+     (list 'button 1
+          'x tidy-menu-x-position
+          'y -5
+          )))
+
+  ;; XEmacs
+  (defun tidy-menu-lock (entry state path)
+    (when (and (not (interactive-p)) tidy-menu-lock)
+      (or (and tidy-menu-position (eq state tidy-menu-state))
+         (setq tidy-menu-position (tidy-menu-position)
+               tidy-menu-state    state))
+      (let* ((menu   (tidy-menu-lookup path))
+            (result (tidy-x-get-popup-menu-response menu tidy-menu-position)))
+       (and (tidy-x-misc-user-event-p result)
+            (funcall (tidy-x-event-function result)
+                     (tidy-x-event-object result))))
+      (setq tidy-menu-position nil)))
+
+  ;; XEmacs
+  (defun tidy-menu-lookup (path)
+    (car (tidy-x-find-menu-item current-menubar (cons "Tidy" path)))))
+
+ (t
+    ;; GNU Emacs
+  (defun tidy-menu-position ()
+    (let ()
+      (list (list tidy-menu-x-position '-5)
+           (selected-frame))))         ; frame
+
+  ;; GNU Emacs
+  (defun tidy-menu-lock (entry state path)
+    (when (and (not (interactive-p)) tidy-menu-lock)
+      (or (and tidy-menu-position (eq state tidy-menu-state))
+         (setq tidy-menu-position (tidy-menu-position )
+               tidy-menu-state    state))
+      (let* ((menu   (tidy-menu-lookup path))
+            (result (x-popup-menu tidy-menu-position menu)))
+       (and result
+            (let ((command (lookup-key menu (vconcat result))))
+              (if (fboundp command)
+                  (funcall command)
+                (eval command)))))
+      (setq tidy-menu-position nil)))
+
+  ;; GNU Emacs
+  (defun tidy-menu-lookup (dummy)
+    (lookup-key (current-local-map) [menu-bar Tidy])))
+ )
+
+;;;;; Define classes of menu items
+
+(defun tidy-set (var-sym value mess entry state &optional path)
+  "Set the value of the symbol VAR-SYM to VALUE giving a message
+derived from VALUE and MESS.  Pass on menu data to `tidy-menu-lock'."
+  (set var-sym value)
+  (message "%s is %s" mess value)
+  (tidy-menu-lock entry state path))
+
+(defun tidy-boolean-entry (symbol name type default menu)
+  "Returns a menu entry that allows us to toggle the value of SYMBOL.
+SYMBOL refers to the option called NAME which has default value
+DEFAULT.  TYPE should always have the value \"Boolean\".  MENU refers
+to the sub-menu that this item belongs to and POSITION its position in
+that list."
+  (cond ((equal default "no")
+        (list (vector name
+                      (list 'tidy-set (list 'quote symbol)
+                            (list 'if symbol 'nil "yes")
+                            name
+                            (list 'quote menu)
+                            '(quote toggle)
+                            )
+                      :style 'toggle
+                      :selected (list 'if symbol 't 'nil))))
+
+       ((equal default "yes")
+        (list (vector name (list 'tidy-set (list 'quote symbol)
+                                 (list 'if symbol 'nil "no")
+                                 name
+                                 (list 'quote menu)
+                                 '(quote toggle)
+                                 )
+                      :style 'toggle
+                      :selected (list 'if symbol 'nil 't))))))
+
+(defun tidy-list-entry (symbol name type default menu)
+"Returns a menu entry that allows us to set via a radio button the
+value of SYMBOL.  SYMBOL refers to the option called NAME which has
+default value DEFAULT.  TYPE should be a list of the possible
+values. MENU refers to the sub-menu that this item belongs to and
+POSITION its position in that list."
+  (let (value element)
+      (while (setq value (car type))
+       (if (equal value default)
+           (setq element
+                 (append element
+                         (list
+                          (vector
+                           (concat name " is \"" value "\"")
+                           (list 'tidy-set (list 'quote symbol)
+                                 (list 'if symbol 'nil value)
+                                 name
+                                 (list 'quote menu)
+                                 '(quote toggle)
+                                 )
+                           :style 'radio
+                           :selected (list 'if symbol 'nil 't)
+                           ))))
+         (setq element
+               (append element
+                       (list
+                        (vector
+                         (concat name " is \"" value "\"")
+
+                         (list 'tidy-set (list 'quote symbol)
+                               (list 'if symbol 'nil value)
+                               name
+                               (list 'quote menu)
+                               '(quote toggle)
+                               )
+
+                         :style 'radio
+                         :selected (list
+                                    'if (list 'string-equal symbol value)
+                                    't 'nil)
+                        )))))
+       (setq type (cdr type)))
+       element))
+
+(defun tidy-set-string (symbol name default)
+  "Set the value of SYMBOL identified by name to VALUE,
+unless VALUE equals DEFAULT, in which case we set it to nil."
+  (interactive)
+  (let* ((last-value (symbol-value symbol))
+        (new-value
+         (if (tidy-xemacs-p)
+             (read-string (format "Set %s to: " name)
+                          (or last-value default) nil) ;; no default arg
+           (read-string (format "Set %s to: " name)
+                        (or last-value default) nil default))))
+    (set symbol (if (equal new-value default) nil new-value))))
+
+(defun tidy-set-integer (symbol name default)
+  "Set the value of SYMBOL identified by name to VALUE,
+unless VALUE = DEFAULT, in which case we set it to nil."
+  (interactive)
+  (let* ((last-value (symbol-value symbol))
+        ;; careful to interpret the string as a number
+        (new-value
+         (string-to-number
+          (if (tidy-xemacs-p)
+              (read-string (format "Set %s to: " name)
+               (or last-value default) nil)
+            (read-string (format "Set %s to: " name)
+               (or last-value default) nil default)
+            ))))
+        (set symbol (if (= new-value (string-to-number default)) nil
+                      (number-to-string new-value)))))
+
+
+(defun tidy-string-entry (symbol name type default menu)
+  "Returns a menu entry that allows us to set the value of SYMBOL.
+SYMBOL refers to the option called NAME which has default value
+DEFAULT.  TYPE should always be one of \"String\" \"Tags\", or
+\"DocType\".  MENU and POSITION are not used in this case."
+
+  (list (vector (concat "set " name)
+               (list 'tidy-set-string
+                     (list 'quote symbol)
+                     name default))))
+
+(defun tidy-integer-entry (symbol name type default menu)
+"Returns a menu entry that allows us to set the value of SYMBOL.
+SYMBOL refers to the option called NAME which has default value
+DEFAULT.  TYPE should always have the value \"Integer\". MENU and
+POSITION are not used in this case. "
+  (list (vector (concat "set " name)
+               (list 'tidy-set-integer
+                     (list 'quote symbol)
+                     name default))))
+
+(defvar tidy-top-menu nil
+  "The first part of teh menu.")
+(when (or (null tidy-top-menu) tidy-debug)
+  (setq tidy-top-menu
+       '("Tidy"
+         ["Tidy buffer" tidy-buffer
+          :active (and tidy-shell-command ;; check that tidy can be executed
+                       (file-executable-p (car (split-string tidy-shell-command))))]
+
+         ["Tidy region" (tidy-buffer 1)
+          :active (and tidy-shell-command ;; check that tidy can be executed
+                       (file-executable-p (car (split-string tidy-shell-command))))
+          :keys "C-u \\[tidy-buffer]"]
+
+         "----------------------------------------------"
+
+         ["Parse config file" tidy-parse-config-file
+          :active (and tidy-config-file (file-exists-p tidy-config-file))]
+
+         ["Save settings" tidy-save-settings
+          :active (and tidy-config-file (file-exists-p tidy-config-file))]
+
+         "----------------------------------------------"
+
+         ["Menu Lock" (tidy-set 'tidy-menu-lock
+                                (if tidy-menu-lock nil t)
+                                "Menu Lock"
+                                'top
+                                'toggle)
+          :style toggle
+          :selected (if tidy-menu-lock t nil)
+          ]
+         )))
+
+(defvar tidy-doctype-menu nil "The second to last sub-menu.")
+(when (or (null tidy-doctype-menu) tidy-debug)
+  (setq  tidy-doctype-menu
+        '("Set doctype" ;; ==>
+
+          ["auto"   (tidy-set 'tidy-doctype
+                              nil
+                              "doctype"
+                              'doctype
+                              'toggle)
+           :style radio
+           :selected (if (null tidy-doctype)  t nil)]
+
+          ["omit"   (tidy-set 'tidy-doctype
+                              "omit"
+                              "doctype"
+                              'doctype
+                              'toggle)
+           :style radio
+           :selected (if (equal tidy-doctype "omit") t nil)]
+
+          ["strict" (tidy-set 'tidy-doctype
+                              "strict"
+                              "doctype"
+                              'doctype
+                              'toggle)
+           :style radio
+           :selected (if (equal tidy-doctype "strict") t nil)]
+
+          ["loose"  (tidy-set 'tidy-doctype
+                              "loose"
+                              "doctype"
+                              'doctype
+                              'toggle)
+           :style radio
+           :selected (if (equal tidy-doctype "loose") t nil)]
+
+          ["transitional"  (tidy-set 'tidy-doctype
+                                     "transitional"
+                                     "doctype"
+                                     'doctype
+                                     'toggle)
+           :style radio
+           :selected (if (equal tidy-doctype "transitional") t nil)]
+
+          ["fpi" (null nil) ;; stub function
+           :style radio
+           :selected (if (or (null tidy-doctype)
+                             (equal tidy-doctype "omit")
+                             (equal tidy-doctype "strict")
+                             (equal tidy-doctype "loose"))
+                         nil t) ]
+
+          ["reset fpi" (tidy-set-string 'tidy-doctype "doctype" "" "")]
+          )))
+
+(defvar tidy-char-encoding-menu nil "The last sub-menu.")
+(when (or (null tidy-char-encoding-menu) tidy-debug)
+  (setq tidy-char-encoding-menu
+       '("Set char-encoding" ;; ==>
+         ["ascii"   (tidy-set 'tidy-char-encoding
+                              nil
+                              "char-encoding"
+                              'encoding
+                              'toggle)
+          :style radio
+          :selected (if (null tidy-char-encoding) t nil) ;; default
+          ]
+
+         ["raw"     (tidy-set 'tidy-char-encoding
+                              "raw"
+                              "char-encoding"
+                              'encoding
+                              'toggle)
+          :style radio
+          :selected (if (equal tidy-char-encoding "raw") t nil)]
+
+         ["latin1"  (tidy-set 'tidy-char-encoding
+                              "latin1"
+                              "char-encoding"
+                              'encoding
+                              'toggle)
+          :style radio
+          :selected (if (equal tidy-char-encoding "latin1") t nil)]
+
+         ["utf8"    (tidy-set 'tidy-char-encoding
+                              "utf8"
+                              "char-encoding"
+                              'encoding
+                              'toggle)
+          :style radio
+          :selected (if (equal tidy-char-encoding "utf8") t nil)]
+
+         ["iso2022" (tidy-set 'tidy-char-encoding
+                              "iso2022"
+                              "char-encoding"
+                              'encoding
+                              'toggle)
+          :style radio
+          :selected (if (equal tidy-char-encoding "iso2022") t nil)]
+
+         ["mac" (tidy-set 'tidy-char-encoding
+                          "mac"
+                          "char-encoding"
+                          'encoding
+                          'toggle)
+          :style radio
+          :selected (if (equal tidy-char-encoding "mac") t nil)]
+
+         ["win1252" (tidy-set 'tidy-char-encoding
+                              "win1252"
+                              "char-encoding"
+                              'encoding
+                              'toggle)
+          :style radio
+          :selected (if (equal tidy-char-encoding "win1252") t nil)]
+
+         )))
+
+;;;;; Create a menu item for each option that has a valid sub-menu
+;; field
+
+(defvar tidy-menu nil "Menu used by tidy.")
+(when (or (null tidy-menu) tidy-debug)
+  (let ((options-alist       tidy-options-alist)
+
+       ;; sub menus are divided into two parts with list type options
+       ;; coming first, followed by the rest
+
+       markup-menu-bool     markup-menu-set
+       line-wrap-menu-bool  line-wrap-menu-set
+       preference-menu-bool preference-menu-set
+       indent-menu-bool     indent-menu-set
+       io-menu-bool         io-menu-set
+       tags-menu-bool       tags-menu-set
+
+       name sub-menu type default symbol entry entry-function option)
+
+    (while (setq option (car options-alist))
+      (setq name      (nth 0 option)
+           sub-menu  (nth 1 option)
+           type      (nth 2 option)
+           default   (nth 3 option)
+           symbol    (intern (concat "tidy-" name))
+           entry     nil)
+
+      (cond ((equal type "Boolean")
+            (setq entry-function 'tidy-boolean-entry))
+
+           ((equal type "AutoBool")
+            (setq entry-function 'tidy-list-entry)
+            (setq type '("auto" "yes" "no")))
+
+           ((equal type "DocType")
+            (setq entry '())) ;; handled below
+
+           ((equal type "Tag names")
+            (setq entry-function 'tidy-string-entry))
+
+           ((equal type "String")
+            (setq entry-function 'tidy-string-entry))
+
+           ((equal type "Integer")
+            (setq entry-function 'tidy-integer-entry))
+
+           ((equal type "Encoding")
+            (setq entry '()));; handled below
+
+           ((listp type)
+            (setq entry-function 'tidy-list-entry))
+           (t
+            (error (concat "Tidy: unhandled value type " type " for " name))))
+
+      (cond ((equal sub-menu "Fix Markup")
+            (setq entry (funcall
+                         entry-function
+                         symbol
+                         name
+                         type
+                         default
+                         'markup))
+
+            (if (or (equal type "Boolean") (equal type "AutoBool") (listp type))
+                (setq markup-menu-bool (append markup-menu-bool entry))
+              (setq markup-menu-set (append markup-menu-set entry))))
+
+           ((equal sub-menu "Indentation")
+            (setq entry (funcall
+                         entry-function
+                         symbol
+                         name
+                         type
+                         default
+                         'indent))
+
+            (if (or (equal type "Boolean") (equal type "AutoBool") (listp type))
+                (setq indent-menu-bool (append indent-menu-bool entry))
+              (setq indent-menu-set (append indent-menu-set entry))))
+
+           ((equal sub-menu "Line Wrapping")
+            (setq entry (funcall
+                         entry-function
+                         symbol
+                         name
+                         type
+                         default
+                         'line-wrap))
+
+            (if (or (equal type "Boolean") (equal type "AutoBool") (listp type))
+                (setq line-wrap-menu-bool (append line-wrap-menu-bool entry))
+              (setq line-wrap-menu-set (append line-wrap-menu-set entry))))
+
+           ((equal sub-menu "Input/Output")
+            (setq entry (funcall
+                         entry-function
+                         symbol
+                         name
+                         type
+                         default
+                         'io))
+
+            (if (or (equal type "Boolean") (equal type "AutoBool") (listp type))
+                (setq io-menu-bool (append io-menu-bool entry))
+              (setq io-menu-set (append io-menu-set entry))))
+
+           ((equal sub-menu "Preference")
+            (setq entry (funcall
+                         entry-function
+                         symbol
+                         name
+                         type
+                         default
+                         'preference))
+
+            (if (or (equal type "Boolean") (equal type "AutoBool") (listp type))
+                (setq preference-menu-bool (append preference-menu-bool entry))
+              (setq preference-menu-set (append preference-menu-set entry))))
+
+           ((equal sub-menu "Tags")
+            (setq entry (funcall
+                         entry-function
+                         symbol
+                         name
+                         type
+                         default
+                         'tags))
+
+            (if (or (equal type "Boolean") (equal type "AutoBool"))
+            (setq tags-menu-bool (append tags-menu-bool entry))
+            (setq tags-menu-set (append tags-menu-set entry))))
+           (t)) ;; we simple omit all other menus
+
+      (setq options-alist (cdr options-alist)))
+
+  (setq tidy-menu (append
+                  tidy-top-menu
+                  (list (append (list "Fix Markup")
+                              markup-menu-bool
+                              markup-menu-set))
+                  (list (append  (list "Line Wrapping")
+                              line-wrap-menu-bool
+                              line-wrap-menu-set))
+                  (list (append (list "Preference")
+                              preference-menu-bool
+                              preference-menu-set))
+                  (list (append (list "Indentation")
+                              indent-menu-bool
+                              indent-menu-set))
+                  (list (append(list "Input/Output")
+                              io-menu-bool
+                              io-menu-set))
+                  (list (append (list "Tags")
+                              tags-menu-bool
+                              tags-menu-set))
+                  (list tidy-doctype-menu)
+                  (list tidy-char-encoding-menu)
+                  '(["Describe options" tidy-describe-options t])))
+  )
+)
+
+;;;###autoload
+(defun tidy-build-menu (&optional map)
+  "Set up the tidy menu in MAP. Used to set up a Tidy menu in your
+favourite mode."
+  (interactive) ;; for debugging
+  (or map (setq map (current-local-map)))
+  (tidy-parse-config-file)
+  (easy-menu-remove tidy-menu)
+  (easy-menu-define tidy-menu-symbol map "Menu for tidy.el" tidy-menu)
+  (easy-menu-add tidy-menu map))
+
+;;;;; Option description support
+
+;; quiet FSF Emacs and XEmacs compilers
+(eval-when-compile
+  (progn (or (fboundp 'event-point) (defun event-point (dummy) ""))
+        (or (fboundp 'posn-point)  (defun posn-point  (dummy) ""))
+        (or (fboundp 'event-start) (defun event-start (dummy) ""))))
+
+(defun tidy-describe-this-option (click)
+  "Describe variable associated with the text at point."
+  (interactive "e")
+
+  (let* ((variable (get-text-property
+                   (if (tidy-xemacs-p)
+                       (event-point click)
+                     (posn-point (event-start click))) 'tidy-variable))
+        value
+        buffer) ;; reuse the help buffer
+    (when variable
+      (save-selected-window
+       (setq value (symbol-value variable)
+             buffer (get-buffer-create "*Help*"))
+       (set-buffer buffer)
+       (setq buffer-read-only nil)
+       (delete-region (point-min) (point-max)) ;; empty the buffer
+       (insert (substring (symbol-name variable) 5) ;; clip the `tidy-' prefix
+               " is set to ")
+       (if value (insert value) (insert "set to the default value"))
+
+       (insert "\n\n" (documentation-property variable 'variable-documentation))
+       (setq buffer-read-only t)
+       (local-set-key [(q)] 'tidy-quit-describe-options)
+       (pop-to-buffer buffer)))))
+
+(defun tidy-quit-describe-options ()
+"Rid thyself of any display associated with Tidy's options."
+  (interactive)
+  (bury-buffer (get-buffer "*tidy-options*"))
+  (delete-windows-on (get-buffer "*tidy-options*"))
+  (bury-buffer (get-buffer "*Help*"))
+  (delete-windows-on (get-buffer "*Help*")))
+
+;; nicked this from cal-desk-calendar.el:-)
+(defun tidy-current-line ()
+  "Get the current line number (in the buffer) of point."
+  (interactive)
+  (save-restriction
+    (widen)
+    (save-excursion
+      (beginning-of-line)
+      (1+ (count-lines 1 (point))))))
+
+(defun tidy-describe-options ()
+  "Interactively access documentation strings for `tidy-' variables."
+  (interactive)
+  (let ((buffer (get-buffer "*tidy-options*")))
+    (if buffer (pop-to-buffer buffer)
+      ;; else build it from scratch
+      (setq buffer (get-buffer-create "*tidy-options*"))
+      (let* ((start 0)
+           (end 0)
+           name
+           (count 0)
+           (option-alist tidy-options-alist)
+           (column2a (+ (length "drop-proprietary-attributes") 3))
+           (column2b (/ (window-width) 3))
+           (column2 (if (> column2a column2b) column2a column2b))
+           (column3 (* 2 column2))
+           (start-line 0)
+           (third-length 0)
+           (two-third-length 0))
+
+       (set-buffer buffer)
+
+       (setq buffer-read-only nil)
+       (delete-region (point-min) (point-max)) ;; empty the buffer
+
+       ;; set up local bindings
+       (if (tidy-xemacs-p)
+           (local-set-key [(button2)] 'tidy-describe-this-option)
+         (local-set-key [(mouse-2)] 'tidy-describe-this-option))
+
+       (local-set-key [(q)] 'tidy-quit-describe-options)
+
+       (insert "Click [mouse-2] over option to see its description.  "
+               "Type \"q\" to quit." "\n\n")
+
+       (setq start-line (tidy-current-line))
+       (setq third-length (1+ (/ (length option-alist) 3) ))
+       (setq two-third-length (1- (* 2 third-length)))
+
+       (while (setq name (car (car-safe option-alist)))
+         (setq option-alist (cdr option-alist))
+         (setq count (+ count 1))
+
+         (cond
+          ((< count third-length)     ;; 0 <= count < third-length
+           (setq start (point))
+               (insert name)
+               (setq end (point))
+               (insert "\n"))
+          ((< count two-third-length) ;; third-length <= count < two-third-length
+           (if (= count third-length)
+               (goto-line start-line)
+             (forward-line 1))
+           (end-of-line)
+           (setq start (point))
+           (indent-to-column column2)
+           (setq end (point))
+           (put-text-property start end 'mouse-face 'default)
+           (setq start (point))
+           (insert name)
+           (setq end (point)))
+          (t                          ;; two-third-length <= count < length
+           (if (= count two-third-length)
+               (goto-line start-line)
+             (forward-line 1))
+           (end-of-line)
+           (setq start (point))
+           (indent-to-column column3)
+           (setq end (point))
+           (put-text-property start end 'mouse-face 'default)
+           (setq start (point))
+           (insert name)
+           (setq end (point))))
+
+         ;; make the strings funky
+         (put-text-property start end 'mouse-face 'highlight)
+         (put-text-property start end 'tidy-variable (intern (concat "tidy-" name)))
+         )
+       (setq buffer-read-only t)
+       (beginning-of-buffer)
+       (pop-to-buffer buffer)
+       ))))
+
+;;;;; Configuration file support
+
+;;;###autoload
+(defun tidy-parse-config-file ()
+  "If `tidy-config-file' is non-nil parse that file setting variables accordingly."
+  (interactive)
+  (when tidy-config-file
+    (if (not (file-exists-p tidy-config-file))
+       (message "Could not find config file \"%s\".  Winging it." tidy-config-file)
+      (message "Parsing config file...")
+      (let ((html-buffer (current-buffer))
+           (config-buffer (find-file-noselect tidy-config-file t)))
+       (save-excursion
+         (set-buffer config-buffer)
+         (goto-char (point-min)) ;; unnecessary but pedantic
+
+         ;; delete all comments
+         (while (re-search-forward "//.*\n" nil t)
+           (replace-match "" nil nil))
+
+         (goto-char (point-min))
+         (while (re-search-forward "\\([a-z,-]+\\):\\s-*\\(.*\\)\\s-*" nil t)
+           ;; set the variable
+           ;; Thanks to Thomas Baumann for this bugfix
+           (let ((variable (concat "tidy-" (match-string 1)))
+                 (value (match-string 2)))
+             (save-excursion
+               (set-buffer html-buffer)
+               (set (intern variable) value))))
+
+         (set-buffer-modified-p nil) ;; don't save changes
+         (kill-buffer config-buffer)))
+      (message "Parsing config file...done")
+      )))
+
+;;;###autoload
+(defun tidy-save-settings (&optional config-file)
+  "Query saving the current settings to your `tidy-config-file'.
+Perhaps put this on your `kill-buffer-hook'."
+  (interactive)
+  (or config-file (setq config-file tidy-config-file))
+  (when config-file
+
+    ;; should check for locks!
+    (if (or (not (interactive-p))
+            (y-or-n-p "Save settings to your tidy configuration file? "))
+
+        (let ((buffer (find-file-noselect config-file t))
+              (option-alist tidy-options-alist)
+              (outer-buffer (current-buffer))
+              option name symbol value)
+          (save-excursion
+            (set-buffer buffer)
+            (delete-region (point-min) (point-max)) ;; clear the buffer
+
+            ;; need this line so that config file is always non empty
+            (insert "// HTML Tidy configuration file \n")
+            (while (setq option (car option-alist))
+              (setq option-alist (cdr option-alist))
+              (setq name      (nth 0 option)
+                    symbol    (intern (concat "tidy-" name)))
+              (save-excursion ;; this is a local variable
+                (set-buffer outer-buffer)
+                (setq value (symbol-value symbol)))
+              (when value ;; nil iff default
+                (insert (car option) ": " value "\n")))
+
+            (save-buffer)
+            (kill-buffer buffer)
+            )))))
+
+
+;;;;; Main user function
+
+(eval-when-compile (defvar tidy-markup nil ""))
+
+(defun tidy-set-buffer-unmodified (dummy1 dummy2 dumm3)
+  "Used to prevent error buffer form being marked as modified."
+  (set-buffer-modified-p nil))
+
+;;;###autoload
+(defun tidy-buffer (&optional prefix)
+  "Run the HTML Tidy program on the current buffer.
+If PREFIX is non-nil, or if called interactively with a prefix argument,
+then Tidy is applied to the currently selected region.  Any error messages
+generated by that program are sent to \"*tidy-errors*\" buffer."
+
+  (interactive "P")
+
+  (let* ((start (if (null prefix) (point-min) (mark)))
+        (end   (if (null prefix) (point-max) (point)))
+        (filename (file-name-nondirectory (buffer-file-name (current-buffer))))
+        ;; Gasp! We have to use temp files here because the command
+        ;; line would likely get too long!
+
+        (error-file (concat
+                     ;; name may or may not end in "/"
+                     (directory-file-name tidy-temp-directory)
+                     "/temp-tidy-errors"))
+
+        (error-buffer (get-buffer error-file))
+
+        (temp-buffer " *tidy-temp*") ;; invisible
+
+        (config-file (concat
+                      ;; name may or may not end in "/"
+                      (directory-file-name tidy-temp-directory)
+                      "/temp-tidy-config"))
+
+        (command (concat tidy-shell-command
+                         ;; load configuration file first so that
+                         ;; options are overridden by command line
+                         " -config " config-file
+                         " --error-file " error-file
+                         " --write-back no"
+                         (if prefix " --show-body-only yes"
+                           " --show-body-only no")
+                         " --gnu-emacs yes"
+                         " --gnu-emacs-file \"" filename "\""
+                         ))
+        (errors 0)
+        (warnings 0)
+        (tidy-message "")
+        (seg-error nil))
+
+    (if (> start end) (setq end (mark) start (point))) ;; rare case swap
+
+    (when error-buffer ;; flush the error buffer
+      (save-excursion
+       (set-buffer error-buffer)
+       (set-buffer-modified-p nil)
+       (kill-buffer error-buffer)))
+
+    (when (get-buffer temp-buffer) ;; flush the temp buffer
+      (save-excursion
+       (set-buffer temp-buffer)
+       (delete-region (point-min) (point-max))))
+
+    (tidy-save-settings config-file)
+
+    ;; OK do the tidy
+    (shell-command-on-region start end command temp-buffer nil)
+
+    ;; Since XEmacs can't grab the std error stream we use an error file
+    (setq error-buffer (find-file-noselect error-file t))
+
+    ;; avoid leaving theses guys lying around
+    (if (file-exists-p error-file)  (delete-file error-file))
+    (if (file-exists-p config-file) (delete-file config-file))
+
+    ;; scan the buffer for error strings
+    (save-excursion
+      (set-buffer error-buffer)
+      (goto-char (point-min))
+      (when (re-search-forward (concat
+                               "\\([0-9]+\\) warnings?, "
+                               "\\([0-9]+\\) errors? were found!")
+                              nil t)
+       (setq warnings (string-to-number (match-string 1)))
+       (setq errors (string-to-number (match-string 2)))
+       (setq tidy-message (match-string 0)))
+
+      (goto-char (point-min))
+      (while (re-search-forward "stdin:" nil t)
+       (replace-match (concat filename ":")))
+      (setq buffer-read-only t)
+      (compilation-mode)
+      ;; don't save changes
+      (set-buffer-modified-p nil)
+      ;; Unfortunately as soon as you do `next-error' this will change
+      ;; the buffer again (setting text properties), so we make it
+      ;; impossible to mark this buffer as modified by setting the
+      ;; following buffer local variable:
+      (make-variable-buffer-local 'after-change-functions)
+      (add-hook 'after-change-functions 'tidy-set-buffer-unmodified t t)
+      ;;      (remove-hook 'after-change-functions 'tidy-set-buffer-unmodified t)
+      (goto-char (point-min))
+      )
+
+    ;; Catch segmentation violations
+    ;; Sometimes get this when editing files from Macs
+    ;; See the function at the bottom of the file
+
+    (if (buffer-live-p temp-buffer)
+       (save-excursion
+         (set-buffer temp-buffer)
+         (goto-char (point-min))
+         (let ((case-fold-search t))
+           (if (looking-at "Segmentation") ;; might work with XEmacs
+               (setq seg-error t)))))
+
+    (unless (or (> errors 0) seg-error)
+      (let* ((window (get-buffer-window (current-buffer)))
+            (top (window-start window)))
+
+       (unless tidy-markup ;; default is "yes" hence inverted logic
+         (delete-region start end)    ;; delete the buffer/region
+         (insert-buffer temp-buffer)) ;; replace with tidied text
+
+       ;; Try not to move the window too much when we tidy the whole buffer
+       (set-window-start window top)))
+
+    ;; only pop-up window if there's an error
+
+    (if (and (= warnings 0)
+            (= errors 0))
+       (delete-windows-on error-buffer t) ;; else delete the pop-up window
+
+;;; Thanks to Thomas Baumann for the following fix
+;;;       (pop-to-buffer error-buffer t)
+;;;       (beginning-of-buffer))
+      ;; display the error-buffer, but do not select it
+      ;; one can use C-x ` or mouse-2 to jump to the errors
+      (display-buffer error-buffer t))
+;;;
+
+    (delete-windows-on temp-buffer t) ;; sometimes pops up
+
+    (if seg-error
+       (message (concat "Tidy: Segmentation violation!!!"
+                        "  Check your character encoding."))
+      (message "%s" tidy-message)
+      )
+    ))
+
+;;;}}} +
+
+;;;}}}
+
+(provide 'tidy)
+
+;;; tidy.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-auto.el b/.emacs.d/elisp/mmm/mmm-auto.el
new file mode 100644 (file)
index 0000000..dad030f
--- /dev/null
@@ -0,0 +1,177 @@
+;;; mmm-auto.el --- loading and enabling MMM Mode automatically
+
+;; Copyright (C) 2000 by Michael Abraham Shulman
+
+;; Author: Michael Abraham Shulman <mas@kurukshetra.cjb.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains functions and hooks to load and enable MMM Mode
+;; automatically. It sets up autoloads for the main MMM Mode functions
+;; and interactive commands, and also sets up MMM Global Mode.
+
+;;{{{ Comments on MMM Global Mode
+
+;; This is a kludge borrowed from `global-font-lock-mode'.  The idea
+;; is the same: we have a function (here `mmm-mode-on-maybe') that we
+;; want to be run whenever a major mode starts.  Unfortunately, there
+;; is no hook (like, say `major-mode-hook') that all major modes run
+;; when they are finished.  `post-command-hook', however, is run after
+;; *every* command, so we do our work in there.  (Actually, using
+;; `post-command-hook' is even better than being run by major mode
+;; functions, since it is run after all local variables and text are
+;; loaded, which may not be true in certain cases for the other.)
+
+;; In order to do this magic, we rely on the fact that there *is* a
+;; hook that all major modes run when *beginning* their work. They
+;; call `kill-all-local-variables' (unless they are broken), which in
+;; turn runs `change-major-mode-hook'.  So we add a function to *that*
+;; hook which saves the current buffer and temporarily adds a function
+;; to `post-command-hook' which processes that buffer.
+
+;; Actually, in the interests of generality, what that function does
+;; is run the hook `mmm-major-mode-hook'. Our desired function
+;; `mmm-mode-on-maybe' is then added to that hook. This way, if the
+;; user wants to run something else on every major mode, they can just
+;; add it to `mmm-major-mode-hook' and take advantage of this hack.
+
+;;}}}
+
+;;; Code:
+
+(require 'cl)
+(require 'mmm-vars)
+
+;;{{{ Autoload Submode Classes
+
+(defvar mmm-autoloaded-classes
+  '((mason "mmm-mason" nil)
+    (myghty "mmm-myghty" nil)
+    (html-css "mmm-sample" nil)
+    (html-js "mmm-sample" nil)
+    (here-doc "mmm-sample" nil)
+    (embperl "mmm-sample" nil)
+    (eperl "mmm-sample" nil)
+    (jsp "mmm-sample" nil)
+    (file-variables "mmm-sample" nil)
+    (rpm-sh "mmm-rpm" t)
+    (rpm "mmm-rpm" nil)
+    (cweb "mmm-cweb" nil)
+    (sgml-dtd "mmm-sample" nil)
+    (noweb "mmm-noweb" nil)
+    (html-php "mmm-sample" nil)
+    )
+  "Alist of submode classes autoloaded from files.
+Elements look like \(CLASS FILE PRIVATE) where CLASS is a submode
+class symbol, FILE is a string suitable for passing to `load', and
+PRIVATE is non-nil if the class is invisible to the user.  Classes can
+be added to this list with `mmm-autoload-class'.")
+
+(defun mmm-autoload-class (class file &optional private)
+  "Autoload submode class CLASS from file FILE.
+PRIVATE, if non-nil, means the class is user-invisible.  In general,
+private classes need not be autoloaded, since they will usually be
+invoked by a public class in the same file."
+  ;; Don't autoload already defined classes
+  (unless (assq class mmm-classes-alist)
+    (add-to-list 'mmm-autoloaded-classes
+                 (list class file private))))
+
+;;}}}
+;;{{{ Autoload Functions
+
+;; To shut up the byte compiler.
+(eval-and-compile
+  (autoload 'mmm-mode-on "mmm-mode" "Turn on MMM Mode. See `mmm-mode'.")
+  (autoload 'mmm-mode-off "mmm-mode" "Turn off MMM Mode. See `mmm-mode'.")
+  (autoload 'mmm-update-font-lock-buffer "mmm-region")
+  (autoload 'mmm-ensure-fboundp "mmm-utils")
+  (autoload 'mmm-mode "mmm-mode"
+    "Minor mode to allow multiple major modes in one buffer.
+Without ARG, toggle MMM Mode. With ARG, turn MMM Mode on iff ARG is
+positive and off otherwise." t))
+
+;; These may actually be used.
+(autoload 'mmm-ify-by-class "mmm-cmds" "" t)
+(autoload 'mmm-ify-by-regexp "mmm-cmds" "" t)
+(autoload 'mmm-ify-region "mmm-cmds" "" t)
+(autoload 'mmm-parse-buffer "mmm-cmds" "" t)
+(autoload 'mmm-parse-region "mmm-cmds" "" t)
+(autoload 'mmm-parse-block "mmm-cmds" "" t)
+(autoload 'mmm-clear-current-region "mmm-cmds" "" t)
+(autoload 'mmm-reparse-current-region "mmm-cmds" "" t)
+(autoload 'mmm-end-current-region "mmm-cmds" "" t)
+(autoload 'mmm-insertion-help "mmm-cmds" "" t)
+(autoload 'mmm-insert-region "mmm-cmds" "" t)
+
+;;}}}
+;;{{{ MMM Global Mode
+
+(defvar mmm-changed-buffers-list ()
+  "Buffers that need to be checked for running the major mode hook.")
+
+(defun mmm-major-mode-change ()
+  "Add this buffer to `mmm-changed-buffers-list' for checking.
+When the current command is over, MMM Mode will be turned on in this
+buffer depending on the value of `mmm-global-mode'.  Actually,
+everything in `mmm-major-mode-hook' will be run."
+  (and (boundp 'mmm-mode)
+       mmm-mode
+       (mmm-mode-off))
+  (add-to-list 'mmm-changed-buffers-list (current-buffer))
+  (add-hook 'post-command-hook 'mmm-check-changed-buffers))
+
+(add-hook 'change-major-mode-hook 'mmm-major-mode-change)
+
+(defun mmm-check-changed-buffers ()
+  "Run major mode hook for the buffers in `mmm-changed-buffers-list'."
+  (remove-hook 'post-command-hook 'mmm-check-changed-buffers)
+  (dolist (buffer mmm-changed-buffers-list)
+    (when (buffer-live-p buffer)
+      (with-current-buffer buffer
+        (mmm-run-major-mode-hook))))
+  (setq mmm-changed-buffers-list '()))
+
+(defun mmm-mode-on-maybe ()
+  "Conditionally turn on MMM Mode.
+Turn on MMM Mode if `mmm-global-mode' is non-nil and there are classes
+to apply, or always if `mmm-global-mode' is t."
+  (cond ((eq mmm-global-mode t) (mmm-mode-on))
+        ((not mmm-global-mode))
+        ((mmm-get-all-classes nil) (mmm-mode-on)))
+  (when mmm-mode
+    (mmm-update-font-lock-buffer)))
+
+(add-hook 'mmm-major-mode-hook 'mmm-mode-on-maybe)
+
+(defalias 'mmm-add-find-file-hooks 'mmm-add-find-file-hook)
+(defun mmm-add-find-file-hook ()
+  "Equivalent to \(setq mmm-global-mode 'maybe).
+This function is deprecated and may be removed in future."
+  (message "Warning: `mmm-add-find-file-hook' is deprecated.")
+  (setq mmm-global-mode 'maybe))
+
+;;}}}
+
+(provide 'mmm-auto)
+
+;;; mmm-auto.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-class.el b/.emacs.d/elisp/mmm/mmm-class.el
new file mode 100644 (file)
index 0000000..3f40e1f
--- /dev/null
@@ -0,0 +1,326 @@
+;;; mmm-class.el --- MMM submode class variables and functions
+
+;; Copyright (C) 2000, 2004 by Michael Abraham Shulman
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains variable and function definitions for
+;; manipulating and applying MMM submode classes. See `mmm-vars.el'
+;; for variables that list classes.
+
+;;; Code:
+
+(require 'cl)
+(require 'mmm-vars)
+(require 'mmm-region)
+
+;;; CLASS SPECIFICATIONS
+;;{{{ Get Class Specifications
+
+(defun mmm-get-class-spec (class)
+  "Get the class specification for CLASS.
+CLASS can be either a symbol to look up in `mmm-classes-alist' or a
+class specifier itself."
+  (cond ((symbolp class)        ; A symbol must be looked up
+         (or (cdr (assq class mmm-classes-alist))
+             (and (cadr (assq class mmm-autoloaded-classes))
+                  (load (cadr (assq class mmm-autoloaded-classes)))
+                  (cdr (assq class mmm-classes-alist)))
+             (signal 'mmm-invalid-submode-class (list class))))
+        ((listp class)          ; A list must be a class spec
+         class)
+        (t (signal 'mmm-invalid-submode-class (list class)))))
+
+;;}}}
+;;{{{ Get and Set Class Parameters
+
+(defun mmm-get-class-parameter (class param)
+  "Get the value of the parameter PARAM for CLASS, or nil if none."
+  (cadr (member param (mmm-get-class-spec class))))
+
+(defun mmm-set-class-parameter (class param value)
+  "Set the value of the parameter PARAM for CLASS to VALUE.
+Creates a new parameter if one is not present."
+  (let* ((spec (mmm-get-class-spec class))
+         (current (member param spec)))
+    (if current
+        (setcar (cdr current) value)
+      (nconc spec (list param value)))))
+
+;;}}}
+;;{{{ Apply Classes
+
+(defun* mmm-apply-class
+    (class &optional (start (point-min)) (stop (point-max)) face)
+  "Apply the submode class CLASS from START to STOP in FACE.
+If FACE is nil, the face for CLASS is used, or the default face if
+none is specified by CLASS."
+  ;; The "special" class t means do nothing. It is used to turn on
+  ;; MMM Mode without applying any classes.
+  (unless (eq class t)
+    (apply #'mmm-ify :start start :stop stop
+           (append (mmm-get-class-spec class)
+                  (list :face face)))
+    (mmm-run-class-hook class)
+    ;; Hack in case class hook sets mmm-buffer-mode-display-name etc.
+    (mmm-set-mode-line)))
+
+(defun* mmm-apply-classes
+    (classes &key (start (point-min)) (stop (point-max)) face)
+  "Apply all submode classes in CLASSES, in order.
+All classes are applied regardless of any errors that may occur in
+other classes. If any errors occur, `mmm-apply-classes' exits with an
+error once all classes have been applied."
+  (let (invalid-classes)
+    (dolist (class classes)
+      (condition-case err
+          (mmm-apply-class class start stop face)
+        (mmm-invalid-submode-class
+         ;; Save the name of the invalid class, so we can report them
+         ;; all together at the end.
+         (add-to-list 'invalid-classes (second err)))))
+    (when invalid-classes
+      (signal 'mmm-invalid-submode-class invalid-classes))))
+
+;;}}}
+;;{{{ Apply All Classes
+
+(defun* mmm-apply-all (&key (start (point-min)) (stop (point-max)))
+  "MMM-ify from START to STOP by all submode classes.
+The classes come from mode/ext, `mmm-classes', `mmm-global-classes',
+and interactive history."
+  (mmm-clear-overlays start stop 'strict)
+  (mmm-apply-classes (mmm-get-all-classes t) :start start :stop stop)
+  (mmm-update-submode-region)
+  (syntax-ppss-flush-cache start)
+  (mmm-refontify-maybe start stop))
+
+;;}}}
+
+;;; BUFFER SCANNING
+;;{{{ Scan for Regions
+
+(defun* mmm-ify
+    (&rest all &key classes handler
+          submode match-submode
+           (start (point-min)) (stop (point-max))
+           front back save-matches (case-fold-search t)
+           (beg-sticky (not (number-or-marker-p front)))
+           (end-sticky (not (number-or-marker-p back)))
+           include-front include-back
+           (front-offset 0) (back-offset 0)
+          (front-delim nil) (back-delim nil)
+          (delimiter-mode mmm-delimiter-mode)
+          front-face back-face
+           front-verify back-verify
+           front-form back-form
+          creation-hook
+           face match-face
+          save-name match-name
+          (front-match 0) (back-match 0)
+          end-not-begin
+           ;insert private
+           &allow-other-keys
+           )
+  "Create submode regions from START to STOP according to arguments.
+If CLASSES is supplied, it must be a list of valid CLASSes. Otherwise,
+the rest of the arguments are for an actual class being applied. See
+`mmm-classes-alist' for information on what they all mean."
+  ;; Make sure we get the default values in the `all' list.
+  (setq all (append
+             all
+             (list :start start :stop stop
+                  :beg-sticky beg-sticky :end-sticky end-sticky
+                  :front-offset front-offset :back-offset back-offset
+                  :front-delim front-delim :back-delim back-delim
+                  :front-match 0 :back-match 0
+                  )))
+  (cond
+   ;; If we have a class list, apply them all.
+   (classes
+    (mmm-apply-classes classes :start start :stop stop :face face))
+   ;; Otherwise, apply this class.
+   ;; If we have a handler, call it.
+   (handler
+    (apply handler all))
+   ;; Otherwise, we search from START to STOP for submode regions,
+   ;; continuining over errors, until we don't find any more. If FRONT
+   ;; and BACK are number-or-markers, this should only execute once.
+   (t
+    (mmm-save-all
+     (goto-char start)
+     (loop for (beg end front-pos back-pos matched-front matched-back
+                    matched-submode matched-face matched-name
+                    invalid-resume ok-resume) =
+                    (apply #'mmm-match-region :start (point) all)
+           while beg
+           if end             ; match-submode, if present, succeeded.
+           do
+           (condition-case nil
+               (progn
+                 (mmm-make-region
+                 (or matched-submode submode) beg end
+                 :face (or matched-face face)
+                 :front front-pos :back back-pos
+                 :evaporation 'front
+                 :match-front matched-front :match-back matched-back
+                 :beg-sticky beg-sticky :end-sticky end-sticky
+                 :name matched-name
+                 :delimiter-mode delimiter-mode
+                 :front-face front-face :back-face back-face
+                 :creation-hook creation-hook
+                 )
+                (goto-char ok-resume))
+             ;; If our region is invalid, go back to the end of the
+             ;; front match and continue on.
+             (mmm-error (goto-char invalid-resume)))
+           ;; If match-submode was unable to find a match, go back to
+           ;; the end of the front match and continue on.
+           else do (goto-char invalid-resume)
+           )))))
+
+;;}}}
+;;{{{ Match Regions
+
+(defun* mmm-match-region
+    (&key start stop front back front-verify back-verify
+          front-delim back-delim
+          include-front include-back front-offset back-offset
+          front-form back-form save-matches match-submode match-face
+         front-match back-match end-not-begin
+         save-name match-name
+          &allow-other-keys)
+  "Find the first valid region between point and STOP.
+Return \(BEG END FRONT-POS BACK-POS FRONT-FORM BACK-FORM SUBMODE FACE
+NAME INVALID-RESUME OK-RESUME) specifying the region.  See
+`mmm-match-and-verify' for the valid values of FRONT and BACK
+\(markers, regexps, or functions).  A nil value for END means that
+MATCH-SUBMODE failed to find a valid submode.  INVALID-RESUME is the
+point at which the search should continue if the region is invalid,
+and OK-RESUME if the region is valid."
+  (when (mmm-match-and-verify front start stop front-verify)
+    (let ((beg (mmm-match->point include-front front-offset front-match))
+         (front-pos (if front-delim
+                        (mmm-match->point t front-delim front-match)
+                      nil))
+          (invalid-resume (match-end front-match))
+          (front-form (mmm-get-form front-form)))
+      (let ((submode (if match-submode
+                         (condition-case nil
+                             (mmm-save-all
+                              (funcall match-submode front-form))
+                           (mmm-no-matching-submode
+                            (return-from
+                                mmm-match-region
+                              (values beg nil nil nil nil nil nil nil nil
+                                      invalid-resume nil))))
+                       nil))
+           (name (cond ((functionp match-name)
+                        (mmm-save-all (funcall match-name front-form)))
+                       ((stringp match-name)
+                        (if save-name
+                            (mmm-format-matches match-name)
+                          match-name))))
+            (face (cond ((functionp match-face)
+                         (mmm-save-all
+                          (funcall match-face front-form)))
+                        (match-face
+                         (cdr (assoc front-form match-face))))))
+        (when (mmm-match-and-verify
+               (if save-matches
+                   (mmm-format-matches back)
+                 back)
+               beg stop back-verify)
+          (let* ((end (mmm-match->point (not include-back)
+                                       back-offset back-match))
+                (back-pos (if back-delim
+                              (mmm-match->point nil back-delim back-match)
+                            nil))
+                (back-form (mmm-get-form back-form))
+                (ok-resume (if end-not-begin 
+                               (match-end back-match)
+                             end)))
+            (values beg end front-pos back-pos front-form back-form
+                   submode face name
+                    invalid-resume ok-resume)))))))
+
+(defun mmm-match->point (beginp offset match)
+  "Find a point of starting or stopping from the match data.  If
+BEGINP, start at \(match-beginning MATCH), else \(match-end MATCH),
+and move OFFSET.  Handles all values of OFFSET--see `mmm-classes-alist'."
+  (save-excursion
+    (goto-char (if beginp
+                  (match-beginning match)
+                (match-end match)))
+    (dolist (spec (if (listp offset) offset (list offset)))
+      (if (numberp spec)
+          (forward-char (or spec 0))
+        (funcall spec)))
+    (point)))
+
+(defun mmm-match-and-verify (pos start stop &optional verify)
+  "Find first match for POS between point and STOP satisfying VERIFY.
+Return non-nil if a match was found, and set match data. POS can be a
+number-or-marker, a regexp, or a function.
+
+If POS is a number-or-marker, it is used as-is. If it is a string, it
+is searched for as a regexp until VERIFY returns non-nil. If it is a
+function, it is called with argument STOP and must return non-nil iff
+a match is found, and set the match data. Note that VERIFY is ignored
+unless POS is a regexp."
+  (cond
+   ;; A marker can be used as-is, but only if it's in bounds.
+   ((and (number-or-marker-p pos) (>= pos start) (<= pos stop))
+    (goto-char pos)
+    (looking-at ""))            ; Set the match data
+   ;; Strings are searched for as regexps.
+   ((stringp pos)
+    (loop always (re-search-forward pos stop 'limit)
+          until (or (not verify) (mmm-save-all (funcall verify)))))
+   ;; Otherwise it must be a function.
+   ((functionp pos)
+    (funcall pos stop))))
+
+;;}}}
+;;{{{ Get Delimiter Forms
+
+(defun mmm-get-form (form)
+  "Return the delimiter form specified by FORM.
+If FORM is nil, call `mmm-default-get-form'. If FORM is a string,
+return it. If FORM is a function, call it. If FORM is a list, return
+its `car' \(usually in this case, FORM is a one-element list
+containing a function to be used as the delimiter form."
+  (cond ((stringp form) form)
+        ((not form) (mmm-default-get-form))
+        ((functionp form) (mmm-save-all (funcall form)))
+        ((listp form) (car form))))
+
+(defun mmm-default-get-form ()
+  (regexp-quote (match-string 0)))
+
+;;}}}
+
+(provide 'mmm-class)
+
+;;; mmm-class.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-cmds.el b/.emacs.d/elisp/mmm/mmm-cmds.el
new file mode 100644 (file)
index 0000000..b5ea748
--- /dev/null
@@ -0,0 +1,444 @@
+;;; mmm-cmds.el --- MMM Mode interactive commands and keymap
+
+;; Copyright (C) 2000 by Michael Abraham Shulman
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains the interactive commands for MMM Mode.
+
+;;; Code:
+
+(require 'cl)
+(require 'font-lock)
+(require 'mmm-compat)
+(require 'mmm-vars)
+(require 'mmm-class)
+
+;; APPLYING CLASSES
+;;{{{ Applying Predefined Classes
+
+(defun mmm-ify-by-class (class)
+  "Add submode regions according to an existing submode class."
+  (interactive
+   (list (intern
+          (completing-read
+           "Submode Class: "
+           (remove-duplicates
+            (mapcar #'(lambda (spec) (list (symbol-name (car spec))))
+                    (append
+                     (remove-if #'(lambda (spec) (plist-get (cdr spec) :private))
+                                mmm-classes-alist)
+                     (remove-if #'caddr mmm-autoloaded-classes)))
+            :test #'equal)
+           nil t))))
+  (unless (eq class (intern ""))
+    (mmm-apply-class class)
+    (mmm-add-to-history class)
+    (mmm-update-font-lock-buffer)))
+
+;;}}}
+;;{{{ Applying by the Region
+
+(defun mmm-ify-region (submode front back)
+  "Add a submode region for SUBMODE coinciding with current region."
+  (interactive "aSubmode: \nr")
+  (mmm-ify :submode submode :front front :back back)
+  (setq front (mmm-make-marker front t nil)
+        back (mmm-make-marker back nil nil))
+  (mmm-add-to-history `(:submode ,submode :front ,front :back ,back))
+  (mmm-enable-font-lock submode))
+
+;;}}}
+;;{{{ Applying Simple Regexps
+
+(defun mmm-ify-by-regexp
+  (submode front front-offset back back-offset save-matches)
+  "Add SUBMODE regions to the buffer delimited by FRONT and BACK.
+With prefix argument, prompts for all additional keywords arguments.
+See `mmm-classes-alist'."
+  (interactive "aSubmode: 
+sFront Regexp: 
+nOffset from Front Regexp: 
+sBack Regexp: 
+nOffset from Back Regexp: 
+nNumber of matched substrings to save: ")
+  (let ((args (mmm-save-keywords submode front back front-offset
+                                 back-offset save-matches)))
+    (apply #'mmm-ify args)
+    (mmm-add-to-history args))
+  (mmm-enable-font-lock submode))
+
+;;}}}
+
+;; EDITING WITH REGIONS
+;;{{{ Re-parsing Areas
+
+(defun mmm-parse-buffer ()
+  "Re-apply all applicable submode classes to current buffer.
+Clears all current submode regions, reapplies all past interactive
+mmm-ification, and applies `mmm-classes' and mode-extension classes."
+  (interactive)
+  (message "MMM-ifying buffer...")
+  (mmm-apply-all)
+  (message "MMM-ifying buffer...done"))
+
+(defun mmm-parse-region (start stop)
+  "Re-apply all applicable submode classes between START and STOP.
+Clears all current submode regions, reapplies all past interactive
+mmm-ification, and applies `mmm-classes' and mode-extension classes."
+  (interactive "r")
+  (message "MMM-ifying region...")
+  (mmm-apply-all :start start :stop stop)
+  (message "MMM-ifying region...done"))
+
+(defun mmm-parse-block (&optional lines)
+  "Re-parse LINES lines before and after point \(default 1).
+Clears all current submode regions, reapplies all past interactive
+mmm-ification, and applies `mmm-classes' and mode-extension classes.
+
+This command is intended for use when you have just typed what should
+be the delimiters of a submode region and you want to create the
+region. However, you may want to look into the various types of
+delimiter auto-insertion that MMM Mode provides. See, for example,
+`mmm-insert-region'."
+  (interactive "p")
+  (message "MMM-ifying block...")
+  (destructuring-bind (start stop) (mmm-get-block lines)
+    (when (< start stop)
+      (mmm-apply-all :start start :stop stop)))
+  (message "MMM-ifying block...done"))
+
+(defun mmm-get-block (lines)
+  (let ((inhibit-point-motion-hooks t))
+    (list (save-excursion
+            (forward-line (- lines))
+            (beginning-of-line)
+            (point))
+          (save-excursion
+            (forward-line lines)
+            (end-of-line)
+            (point)))))
+
+;;}}}
+;;{{{ Reparse Current Region
+
+(defun mmm-reparse-current-region ()
+  "Clear and reparse the area of the current submode region.
+Use this command if a submode region's boundaries have become wrong."
+  (interactive)
+  (let ((ovl (mmm-overlay-at (point) 'all)))
+    (when ovl
+      (let ((beg (save-excursion
+                   (goto-char (mmm-front-start ovl))
+                   (forward-line -1)
+                   (point)))
+            (end (save-excursion
+                   (goto-char (mmm-back-end ovl))
+                   (forward-line 1)
+                   (point))))
+        (mmm-parse-region beg end)))))
+
+;;}}}
+;;{{{ Clear Submode Regions
+
+;; See also `mmm-clear-history' which is interactive.
+
+(defun mmm-clear-current-region ()
+  "Deletes the submode region point is currently in, if any."
+  (interactive)
+  (delete-overlay (mmm-overlay-at (point) 'all)))
+
+(defun mmm-clear-regions (start stop)
+  "Deletes all submode regions from START to STOP."
+  (interactive "r")
+  (mmm-clear-overlays start stop))
+
+(defun mmm-clear-all-regions ()
+  "Deletes all submode regions in the current buffer."
+  (interactive)
+  (mmm-clear-overlays))
+
+;;}}}
+;;{{{ End Current Region
+
+(defun* mmm-end-current-region (&optional arg)
+  "End current submode region.
+If ARG is nil, end it at the most appropriate place, usually its
+current back boundary. If ARG is non-nil, end it at point. If the
+current region is correctly bounded, the first does nothing, but the
+second deletes that delimiter as well.
+
+If the region's BACK property is a string, it is inserted as above and
+the overlay moved if necessary. If it is a function, it is called with
+two arguments--the overlay, and \(if ARG 'middle t)--and must do the
+entire job of this function."
+  (interactive "P")
+  (let ((ovl (mmm-overlay-at)))
+    (when ovl
+      (combine-after-change-calls
+        (save-match-data
+          (save-excursion
+            (when (mmm-match-back ovl)
+              (if arg
+                  (replace-match "")
+                (return-from mmm-end-current-region)))))
+        (let ((back (overlay-get ovl 'back)))
+          (cond ((stringp back)
+                 (save-excursion
+                   (unless arg (goto-char (overlay-end ovl)))
+                   (save-excursion (insert back))
+                   (move-overlay ovl (overlay-start ovl) (point))))
+                ((functionp back)
+                 (funcall back ovl (if arg 'middle t))))))
+      (mmm-refontify-maybe (save-excursion (forward-line -1) (point))
+                           (save-excursion (forward-line 1) (point))))))
+
+;;}}}
+;;{{{ Narrow to Region
+
+(defun mmm-narrow-to-submode-region (&optional pos)
+  "Narrow to the submode region at point."
+  (interactive)
+  ;; Probably don't use mmm-current-overlay here, because this is
+  ;; sometimes called from inside messy functions.
+  (let ((ovl (mmm-overlay-at pos)))
+    (when ovl
+      (narrow-to-region (overlay-start ovl) (overlay-end ovl)))))
+
+;; The inverse command is `widen', usually on `C-x n w'
+
+;;}}}
+
+;; INSERTING REGIONS
+;;{{{ Insert regions by keystroke
+
+;; This is the "default" binding in the MMM Mode keymap. Keys defined
+;; by classes should be control keys, to avoid conflicts with MMM
+;; commands.
+(defun mmm-insert-region (arg)
+  "Insert a submode region based on last character in invoking keys.
+Keystrokes after `mmm-mode-prefix-key' which are not bound to an MMM
+Mode command \(see `mmm-command-modifiers') are passed on to this
+function. If they have the modifiers `mmm-insert-modifiers', then they
+are looked up, sans those modifiers, in all current submode classes to
+find an insert skeleton. For example, in Mason, `p' \(with appropriate
+prefix and modifiers) will insert a <%perl>...</%perl> region."
+  (interactive "P")
+  (let* ((seq (this-command-keys))
+         (event (aref seq (1- (length seq))))
+         (mods (event-modifiers event))
+         (key (mmm-event-key event)))
+    (if (subsetp mmm-insert-modifiers mods)
+        (mmm-insert-by-key
+         (append (set-difference mods mmm-insert-modifiers)
+                 key)
+         arg))))
+
+(defun mmm-insert-by-key (key &optional arg)
+  "Insert a submode region based on event KEY.
+Inspects all the classes of the current buffer to find a matching
+:insert key sequence. See `mmm-classes-alist'. ARG, if present, is
+passed on to `skeleton-proxy-new' to control wrapping.
+
+KEY must be a list \(MODIFIERS... . BASIC-KEY) where MODIFIERS are
+symbols such as shift, control, etc. and BASIC-KEY is a character code
+or a symbol such as tab, return, etc. Note that if there are no
+MODIFIERS, the dotted list becomes simply BASIC-KEY."
+  (multiple-value-bind (class skel str) (mmm-get-insertion-spec key)
+    (when skel
+      (let ((after-change-functions nil)
+            (old-undo buffer-undo-list) undo)
+        ;; XEmacs' skeleton doesn't manage positions by itself, so we
+        ;; have to do it.
+        (if mmm-xemacs (setq skeleton-positions nil))
+        (skeleton-proxy-new skel str arg)
+        (destructuring-bind (back end beg front) skeleton-positions
+          ;; TODO: Find a way to trap invalid-parent signals from
+          ;; make-region and undo the skeleton insertion.
+          (let ((match-submode (plist-get class :match-submode))
+               (match-face (plist-get class :match-face))
+               (match-name (plist-get class :match-name))
+               (front-form (regexp-quote (buffer-substring front beg)))
+               (back-form (regexp-quote (buffer-substring end back)))
+               submode face name)
+           (setq submode
+                 (mmm-modename->function
+                  (if match-submode
+                      (mmm-save-all (funcall match-submode front-form))
+                    (plist-get class :submode))))
+           (setq face
+                  (cond ((functionp match-face)
+                         (mmm-save-all
+                          (funcall match-face front-form)))
+                        (match-face
+                         (cdr (assoc front-form match-face)))
+                        (t
+                         (plist-get class :face))))
+           (setq name
+                 (cond ((plist-get class :skel-name)
+                        ;; Optimize the name to the user-supplied str
+                        ;; if we are so instructed.
+                        str)
+                       ;; Call it if it is a function
+                       ((functionp match-name)
+                        (mmm-save-all (funcall match-name front-form)))
+                       ;; Now we know it's a string, does it need to
+                       ;; be formatted?
+                       ((plist-get class :save-name)
+                        ;; Yes.  Haven't done a match before, so
+                        ;; match the front regexp against the given
+                        ;; form to format the string
+                        (string-match (plist-get class :front)
+                                      front-form)
+                        (mmm-format-matches match-name front-form))
+                       (t
+                        ;; No, just use it as-is
+                        match-name)))
+            (mmm-make-region
+             submode beg end 
+            :face face
+            :name name
+            :front front :back back
+            :match-front front-form :match-back back-form
+            :evaporation 'front
+;;;             :beg-sticky (plist-get class :beg-sticky)
+;;;             :end-sticky (plist-get class :end-sticky)
+             :beg-sticky t :end-sticky t
+             :creation-hook (plist-get class :creation-hook))
+            (mmm-enable-font-lock submode)))
+        ;; Now get rid of intermediate undo boundaries, so that the entire
+        ;; insertion can be undone as one action.  This should really be
+        ;; skeleton's job, but it doesn't do it.
+        (setq undo buffer-undo-list)
+        (while (not (eq (cdr undo) old-undo))
+          (when (eq (cadr undo) nil)
+            (setcdr undo (cddr undo)))
+          (setq undo (cdr undo)))))))
+
+(defun mmm-get-insertion-spec (key &optional classlist)
+  "Get the insertion info for KEY from all classes in CLASSLIST.
+Return \(CLASS SKEL STR) where CLASS is the class spec a match was
+found in, SKEL is the skeleton to insert, and STR is the argument.
+CLASSLIST defaults to the return value of `mmm-get-all-classes',
+including global classes."
+  (loop for classname in (or classlist (mmm-get-all-classes t))
+        for class = (mmm-get-class-spec classname)
+        for inserts = (plist-get class :insert)
+        for skel = (cddr (assoc key inserts))
+        with str
+        ;; If SKEL is a dotted pair, it means call another key's
+        ;; insertion spec with an argument.
+        unless (consp (cdr skel))
+        do (setq str (cdr skel)
+                 skel (cddr (assoc (car skel) inserts)))
+        if skel return (list class skel str)
+        ;; If we have a group class, recurse.
+        if (plist-get class :classes)
+           if (mmm-get-insertion-spec key it)
+              return it))
+
+;;}}}
+;;{{{ Help on Insertion
+
+(defun mmm-insertion-help ()
+  "Display help on currently available MMM insertion commands."
+  (interactive)
+  (with-output-to-temp-buffer "*Help*"
+    (princ "Available MMM Mode Insertion Commands:\n")
+    (princ "Key             Inserts\n")
+    (princ "---             -------\n\n")
+    (mapcar #'mmm-display-insertion-key
+            (mmm-get-all-insertion-keys))))
+
+(defun mmm-display-insertion-key (spec)
+  "Print an insertion binding to standard output.
+SPEC should be \(KEY NAME ...) where KEY is an insertion key and NAME
+is a symbol naming the insertion."
+  (let* ((str (make-string 16 ?\ ))
+         ;; This gets us a dotted list, because of the way insertion
+         ;; keys are specified.
+         (key (append mmm-insert-modifiers (car spec)))
+         (lastkey (nthcdr (max (1- (safe-length key)) 0) key)))
+    ;; Now we make it a true list
+    (if (consp key)
+        (setcdr lastkey (list (cdr lastkey)))
+      (setq key (list key)))
+    ;; Get the spacing right
+    (store-substring str 0
+      (key-description
+       (apply #'vector (append mmm-mode-prefix-key (list key)))))
+    (princ str)
+    ;; Now print the binding symbol
+    (princ (cadr spec))
+    (princ "\n")))
+
+(defun mmm-get-all-insertion-keys (&optional classlist)
+  "Return an alist of all currently available insertion keys.
+Elements look like \(KEY NAME ...) where KEY is an insertion key and
+NAME is a symbol naming the insertion."
+  (remove-duplicates
+   (loop for classname in (or classlist (mmm-get-all-classes t))
+         for class = (mmm-get-class-spec classname)
+         append (plist-get class :insert) into keys
+         ;; If we have a group class, recurse.
+         if (plist-get class :classes)
+         do (setq keys (append keys (mmm-get-all-insertion-keys it)))
+         finally return keys)
+   :test #'equal
+   :key #'(lambda (x) (cons (car x) (cadr x)))
+   :from-end t))
+
+;;}}}
+
+;;{{{ Auto Insertion (copied from interactive session);-COM-
+;-COM-
+;-COM-;; Don't use `mmm-ify-region' of course. And rather than having
+;-COM-;; classes define their own functions, we should have them pass a
+;-COM-;; skeleton as an attribute. Then our insert function can turn off
+;-COM-;; after-change hooks and add the submode region afterward.
+;-COM-
+;-COM-(define-skeleton mmm-see-inline
+;-COM-  "" nil
+;-COM-  -1 @ " " _ " " @ "%>"
+;-COM-  '(apply #'mmm-ify-region 'cperl-mode (reverse skeleton-positions)))
+;-COM-
+;-COM-(define-skeleton mmm-see-other
+;-COM-  "" nil
+;-COM-  @ ";\n" _ "\n" @ "<%/" str ">"
+;-COM-  '(apply #'mmm-ify-region 'cperl-mode (reverse skeleton-positions)))
+;-COM-
+;-COM-(make-local-hook 'after-change-functions)
+;-COM-(add-hook 'after-change-functions 'mmm-detect t)
+;-COM-
+;-COM-(defun mmm-detect (beg end length)
+;-COM-  (when (mmm-looking-back-at "<% ")
+;-COM-    (mmm-see-inline))
+;-COM-  (when (mmm-looking-back-at "<%\\(\\w+\\)>")
+;-COM-    (mmm-see-other (match-string 1))))
+;-COM-
+;;}}}
+
+(provide 'mmm-cmds)
+
+;;; mmm-cmds.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-compat.el b/.emacs.d/elisp/mmm/mmm-compat.el
new file mode 100644 (file)
index 0000000..46b4a77
--- /dev/null
@@ -0,0 +1,122 @@
+;;; mmm-compat.el --- MMM Hacks for compatibility with other Emacsen
+
+;; Copyright (C) 2000 by Michael Abraham Shulman
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file provides a number of hacks that are necessary for MMM
+;; Mode to function in different Emacsen.  MMM Mode is designed for
+;; FSF Emacs, but these hacks usually enable it to work
+;; almost perfectly in XEmacs 21.
+
+;;; Code:
+
+(require 'cl)
+
+;;{{{ Emacsen Detection
+
+(defvar mmm-xemacs (featurep 'xemacs)
+  "Whether we are running XEmacs.")
+
+;;}}}
+;;{{{ Regexp-Opt (XEmacs)
+
+;; As of XEmacs' xemacs-base package version 1.82,
+;; the regexp-opt API is compatible with GNU Emacs.
+(defalias 'mmm-regexp-opt 'regexp-opt)
+
+;;}}}
+;;{{{ Overlays (XEmacs)
+
+;; The main thing we use from FSF Emacs that XEmacs doesn't support
+;; are overlays. XEmacs uses extents instead, but comes with a package
+;; to emulate overlays.
+(when mmm-xemacs
+  ;; This does almost everything we need.
+  (require 'overlay))
+
+;; We also use a couple "special" overlay properties which have
+;; different names for XEmacs extents.
+(defvar mmm-evaporate-property
+  (if (featurep 'xemacs) 'detachable 'evaporate)
+  "The name of the overlay property controlling evaporation.")
+
+;; We don't use this any more, since its behavior is different in FSF
+;; and XEmacs: in the one it replaces the buffer's local map, but in
+;; the other it gets stacked on top of it. Instead we just set the
+;; buffer's local map temporarily.
+;;;(defvar mmm-keymap-property
+;;;  (if (featurep 'xemacs) 'keymap 'local-map)
+;;;  "The name of the overlay property controlling keymaps.")
+
+;;}}}
+;;{{{ Keymaps and Events (XEmacs)
+
+;; In XEmacs, keymaps are a primitive type, while in FSF Emacs, they
+;; are a list whose car is the symbol `keymap'. Among other things,
+;; this means that they handle default bindings differently.
+(defmacro mmm-set-keymap-default (keymap binding)
+  (if (featurep 'xemacs)
+      `(set-keymap-default-binding ,keymap ,binding)
+    `(define-key ,keymap [t] ,binding)))
+
+;; In XEmacs, events are a primitive type, while in FSF Emacs, they
+;; are represented by characters or vectors. We treat them as vectors.
+;; We can use `event-modifiers' in both Emacsen to extract the
+;; modifiers, but the function to extract the basic key is different.
+(defmacro mmm-event-key (event)
+  (if (featurep 'xemacs)
+      `(event-key ,event)
+    `(event-basic-type ,event)))
+
+;;}}}
+;;{{{ Skeleton (XEmacs)
+
+;; XEmacs' `skeleton' package doesn't provide `@' to record positions.
+(defvar skeleton-positions ())
+(defun mmm-fixup-skeleton ()
+  "Add `@' to `skeleton-further-elements' if XEmacs and not there.
+This makes `@' in skeletons act approximately like it does in FSF."
+  (and (featurep 'xemacs)
+       (defvar skeleton-further-elements ())
+       (not (assoc '@ skeleton-further-elements))
+       (add-to-list 'skeleton-further-elements
+                    '(@ ''(push (point) skeleton-positions)))))
+
+;;}}}
+;;{{{ Make Temp Buffers (XEmacs)
+
+(defmacro mmm-make-temp-buffer (buffer name)
+  "Return a buffer with name based on NAME including the text of BUFFER.
+This text should not be modified."
+  (if (fboundp 'make-indirect-buffer)
+      `(make-indirect-buffer ,buffer (generate-new-buffer-name ,name))
+    `(save-excursion
+       (set-buffer (generate-new-buffer ,name))
+       (insert-buffer ,buffer)
+       (current-buffer))))
+
+(provide 'mmm-compat)
+
+;;; mmm-compat.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-cweb.el b/.emacs.d/elisp/mmm/mmm-cweb.el
new file mode 100644 (file)
index 0000000..c40a899
--- /dev/null
@@ -0,0 +1,100 @@
+;;; mmm-cweb.el --- MMM submode class for CWeb programs
+
+;; Copyright (C) 2001 by Alan Shutko
+
+;; Author: Alan Shutko <ats@acm.org>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains the definition of an MMM Mode submode class for
+;; editing CWeb programs.
+
+;;; Code:
+
+(require 'mmm-compat)
+(require 'mmm-vars)
+(require 'mmm-auto)
+
+(defvar mmm-cweb-section-tags
+  '("@ " "@*"))
+
+(defvar mmm-cweb-section-regexp
+  (concat "^" (mmm-regexp-opt mmm-cweb-section-tags t)))
+
+(defvar mmm-cweb-c-part-tags
+  '("@c" "@>=" "@>+=" "@p"))
+
+(defvar mmm-cweb-c-part-regexp
+  (concat (mmm-regexp-opt mmm-cweb-c-part-tags t)))
+
+(defun mmm-cweb-in-limbo (pos)
+  "Check to see if POS is in limbo, ie before any cweb sections."
+  (save-match-data
+    (save-excursion
+      (goto-char pos)
+      (not (re-search-backward mmm-cweb-section-regexp nil t)))))
+
+(defun mmm-cweb-verify-brief-c ()
+  "Verify function for cweb-brief-c class.
+Checks whether the match is in limbo."
+  (not (mmm-cweb-in-limbo (match-beginning 0))))
+
+(mmm-add-group
+ 'cweb
+ `(
+   (cweb-c-part
+    :submode c-mode
+    :front ,mmm-cweb-c-part-regexp
+    :back ,mmm-cweb-section-regexp)
+   (cweb-label
+    :submode tex-mode
+    :front "@<"
+    :back "@>"
+    :face mmm-comment-submode-face
+    :insert ((?l cweb-label nil @ "@<" @ "@>")))
+   (cweb-brief-c
+    :submode c-mode
+    :front "[^\\|]\\(|\\)[^|]"
+    :front-match 1
+    :front-verify mmm-cweb-verify-brief-c
+;    :front-offset -1
+    :back "[^\\|]\\(|\\)"
+    :back-match 1
+;    :back-offset 1
+    :end-not-begin t
+    :insert ((?| cweb-c-in-tex nil "|" @ "|")))
+    (cweb-comment
+     :submode tex-mode
+     :front "/[*]"
+     :back "[*]/"
+     :face mmm-comment-submode-face)
+))
+
+;; (add-to-list 'mmm-mode-ext-classes-alist
+;;                   '(plain-tex-mode "\\.w\\'" cweb))
+;; (add-to-list 'mmm-mode-ext-classes-alist
+;;                   '(latex-mode "\\.w\\'" cweb))
+;; (add-to-list 'auto-mode-alist '("\\.w\\'" . tex-mode))
+
+(provide 'mmm-cweb)
+
+;;; mmm-cweb.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-erb.el b/.emacs.d/elisp/mmm/mmm-erb.el
new file mode 100644 (file)
index 0000000..e1a4e3d
--- /dev/null
@@ -0,0 +1,244 @@
+;;; mmm-erb.el --- ERB templates editing support
+
+;; Copyright (C) 2012, 2013 by Dmitry Gutov
+
+;; Author: Dmitry Gutov <dgutov@yandex.ru>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains definitions of ERB and EJS submode classes, and well as
+;; support functions for proper indentation.
+
+;; Usage:
+
+;; (require 'mmm-auto)
+
+;; (setq mmm-global-mode 'auto)
+
+;; (mmm-add-mode-ext-class 'html-erb-mode "\\.html\\.erb\\'" 'erb)
+;; (mmm-add-mode-ext-class 'html-erb-mode "\\.jst\\.ejs\\'" 'ejs)
+;; (mmm-add-mode-ext-class 'html-erb-mode nil 'html-js)
+;; (mmm-add-mode-ext-class 'html-erb-mode nil 'html-css)
+
+;; (add-to-list 'auto-mode-alist '("\\.html\\.erb\\'" . html-erb-mode))
+;; (add-to-list 'auto-mode-alist '("\\.jst\\.ejs\\'"  . html-erb-mode))
+
+;; Optional settings:
+
+;; (setq mmm-submode-decoration-level 2
+;;       mmm-parse-when-idle t)
+
+;; nXML as primary mode (supports only JS and CSS subregions):
+
+;; (mmm-add-mode-ext-class 'nxml-web-mode nil 'html-js)
+;; (mmm-add-mode-ext-class 'nxml-web-mode nil 'html-css)
+
+;; (add-to-list 'auto-mode-alist '("\\.xhtml\\'" . nxml-web-mode))
+
+;;; Code:
+
+(require 'sgml-mode)
+(eval-when-compile (require 'cl))
+(require 'mmm-vars)
+(require 'mmm-region)
+
+(mmm-add-classes
+ '((erb :submode ruby-mode :front "<%[#=]?" :back "-?%>"
+        :match-face (("<%#" . mmm-comment-submode-face)
+                     ("<%=" . mmm-output-submode-face)
+                     ("<%" . mmm-code-submode-face))
+        :insert ((?% erb-code nil @ "<%" @ " " _ " " @ "%>" @)
+                 (?# erb-comment nil @ "<%#" @ " " _ " " @ "%>" @)
+                 (?= erb-expression nil @ "<%=" @ " " _ " " @ "%>" @))
+        :creation-hook mmm-erb-mark-as-special)
+   (ejs :submode js-mode :front "<%[#=]?" :back "-?%>"
+        :match-face (("<%#" . mmm-comment-submode-face)
+                     ("<%=" . mmm-output-submode-face)
+                     ("<%" . mmm-code-submode-face))
+        :insert ((?% ejs-code nil @ "<%" @ " " _ " " @ "%>" @)
+                 (?# ejs-comment nil @ "<%#" @ " " _ " " @ "%>" @)
+                 (?= ejs-expression nil @ "<%=" @ " " _ " " @ "%>" @))
+        :creation-hook mmm-erb-mark-as-special)))
+
+(defun mmm-erb-mark-as-special ()
+  "Hook function to run in ERB and EJS tag regions."
+  (overlay-put mmm-current-overlay 'mmm-special-tag t))
+
+;;;###autoload
+(define-derived-mode html-erb-mode html-mode "ERB-HTML"
+  (setq sgml-unclosed-tags nil) ; Simplifies indentation logic.
+  (set (make-local-variable 'mmm-indent-line-function) 'mmm-erb-indent-line)
+  (add-hook 'mmm-after-syntax-propertize-functions
+            'html-erb-after-syntax-propertize nil t))
+
+(defun html-erb-after-syntax-propertize (overlay mode beg end)
+  (when overlay
+    (with-silent-modifications
+      (funcall
+       (syntax-propertize-rules ("<\\|>" (0 ".")))
+       beg end))))
+
+(defun mmm-erb-indent-line ()
+  "Indent the current line intelligently."
+  (interactive)
+  (let ((offset (- (current-column) (current-indentation))))
+    (back-to-indentation)
+    (mmm-update-submode-region)
+    (if (and mmm-current-overlay mmm-current-submode
+             (< (overlay-start mmm-current-overlay) (point-at-bol)))
+        ;; Region starts before the current line (and contains indentation).
+        ;; If it starts on the current line, then either first part of the line
+        ;; is in primary mode, or we're on the first line of a script or style
+        ;; tag contents. In the latter case, better to also indent it according
+        ;; to the primary mode (as text): `js-indent-line' ignores narrowing,
+        ;; gets confused by the angle bracket on the previous line and thus
+        ;; breaks our "top level" heuristic.
+        (mmm-erb-indent-line-submode)
+      (mmm-erb-indent-line-primary))
+    (when (> offset 0) (forward-char offset))))
+
+(defun mmm-erb-indent-line-submode ()
+  "Indent line within a submode."
+  (let (added-whitespace)
+    (if (<= (overlay-end mmm-current-overlay)
+            (save-excursion (back-to-indentation) (point)))
+        ;; We're at a closing tag.
+        (mmm-erb-indent-to-region-start)
+      (save-restriction
+        (save-excursion
+          (goto-char (overlay-start mmm-current-overlay))
+          (when (not (looking-at "^\\|\\s-*$"))
+            ;; Submode region has text on the same line as the opening tag,
+            ;; pad it with whitespace to make the following lines line up.
+            (setq added-whitespace (current-column))
+            (insert-char ?\s added-whitespace)))
+        (narrow-to-region (overlay-start mmm-current-overlay)
+                          (overlay-end mmm-current-overlay))
+        (funcall (mmm-erb-orig-indent-function mmm-current-submode))
+        (when added-whitespace
+          ;; Remove the padding.
+          (save-excursion
+            (goto-char (overlay-start mmm-current-overlay))
+            (delete-char added-whitespace))))
+      ;; If submode indent function moved us to bol,
+      ;; we're on the top level, indent according to the primary mode.
+      (when (zerop (current-indentation))
+        (mmm-erb-indent-to-region-start
+         (mmm-erb-indent-offset mmm-primary-mode))))))
+
+(defun mmm-erb-indent-to-region-start (&optional additional-offset)
+  "Indent line to match start of region, possibly adding ADDITIONAL-OFFSET."
+  (let ((indent (current-indentation)))
+    (indent-line-to
+     (save-excursion
+       (goto-char (1- (overlay-start mmm-current-overlay)))
+       (+ (current-indentation)
+          (or additional-offset 0))))))
+
+(defun mmm-erb-indent-line-primary ()
+  "Indent line in primary mode."
+  (let* ((here (point))
+         ;; Go before previous line's tag.
+         (start (progn (forward-line -1)
+                       (back-to-indentation)
+                       (let ((lcon (sgml-lexical-context)))
+                         (when (eq (car lcon) 'tag)
+                           ;; Tag spreads several lines.
+                           (goto-char (cdr lcon))
+                           (back-to-indentation)))
+                       (point)))
+         (regions (mmm-regions-in start here))
+         (n 0))
+    ;; Collect indent modifier depending on type of tags.
+    (loop for region in regions
+          for type = (mmm-erb-scan-region region)
+          when type do
+          (if (eq type 'close)
+              (when (plusp n) (decf n))
+            (incf n (if (eq type 'close) 0 1))))
+    (let ((eol (progn (goto-char here) (end-of-line 1) (point))))
+      ;; Look for "else" and "end" instructions to adjust modifier.
+      ;; If a block start instruction comes first, abort.
+      (loop for region in (mmm-regions-in here eol)
+            for type = (mmm-erb-scan-region region)
+            until (eq type 'open)
+            when (memq type '(middle close)) do (decf n)))
+    (goto-char here)
+    (funcall (mmm-erb-orig-indent-function mmm-primary-mode))
+    (let* ((indent (current-indentation))
+           (indent-step (mmm-erb-indent-offset mmm-primary-mode)))
+      (indent-line-to (+ indent (if n (* indent-step n) 0))))))
+
+(defun mmm-erb-scan-region (region)
+  (when region ; Can be nil if a line is empty, for example.
+    (destructuring-bind (submode beg end ovl) region
+      (let ((scan-fn (plist-get '(ruby-mode mmm-erb-scan-erb
+                                  js-mode   mmm-erb-scan-ejs)
+                                submode)))
+        (and scan-fn
+             (overlay-get ovl 'mmm-special-tag)
+             (save-excursion
+               (goto-char beg)
+               (skip-syntax-forward "-")
+               (funcall scan-fn end)))))))
+
+(defconst mmm-erb-ruby-close-re "\\<end\\>\\|}"
+  "Regexp to match the end of a Ruby block.")
+
+(defun mmm-erb-scan-erb (limit)
+  (cond ((looking-at "\\(?:if\\|unless\\|for\\|while\\)\\b") 'open)
+        ((looking-at "\\(?:else\\|elsif\\)\\b") 'middle)
+        ((looking-at mmm-erb-ruby-close-re) 'close)
+        ((and (re-search-forward (concat "\\(?: +do +\\| *{ *\\)"
+                                         "\\(?:|[A-Za-z0-9_, ]*|\\)? *")
+                                 limit t)
+              (let ((pt (point)))
+                (not (when (< pt limit)
+                       (goto-char limit)
+                       (skip-syntax-backward "-")
+                       (looking-back mmm-erb-ruby-close-re pt)))))
+         'open)))
+
+(defun mmm-erb-scan-ejs (limit)
+  (cond ((looking-at "\\(?:if\\|for\\|while\\)\\b") 'open)
+        ((looking-at "} *else\\b") 'middle)
+        ((looking-at "}") 'close)
+        ((re-search-forward " *{ *" limit t) 'open)))
+
+(defun mmm-erb-orig-indent-function (mode)
+  (get mode 'mmm-indent-line-function))
+
+(defvar mmm-erb-offset-var-alist
+  '((html-erb-mode . sgml-basic-offset)
+    (nxml-web-mode . nxml-child-indent)))
+
+(defun mmm-erb-indent-offset (mode)
+  (let ((name (cdr (assoc mode mmm-erb-offset-var-alist))))
+    (when name (symbol-value name))))
+
+;;;###autoload
+(define-derived-mode nxml-web-mode nxml-mode "nXML-Web"
+  (set (make-local-variable 'mmm-indent-line-function) 'mmm-erb-indent-line))
+
+(provide 'mmm-erb)
+
+;;; mmm-erb.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-mason.el b/.emacs.d/elisp/mmm/mmm-mason.el
new file mode 100644 (file)
index 0000000..8650ea7
--- /dev/null
@@ -0,0 +1,175 @@
+;;; mmm-mason.el --- MMM submode class for Mason components
+
+;; Copyright (C) 2000 by Michael Abraham Shulman
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains the definition of an MMM Mode submode class for
+;; editing Mason components.  See the file README.Mason for more
+;; details.
+
+;;; Code:
+
+(require 'mmm-compat)
+(require 'mmm-vars)
+(require 'mmm-auto)
+
+;;{{{ Perl Tags
+
+(defvar mmm-mason-perl-tags
+  '("perl" "init" "cleanup" "once" "filter" "shared"
+    "perl_init" "perl_cleanup" "perl_once" "perl_filter"))
+
+(defvar mmm-mason-pseudo-perl-tags
+  '("args" "perl_args" "attr" "flags"))
+
+(defvar mmm-mason-non-perl-tags
+  '("doc" "perl_doc" "text" "perl_text" "def" "perl_def" "method"))
+
+(defvar mmm-mason-perl-tags-regexp
+  (concat "<%" (mmm-regexp-opt mmm-mason-perl-tags t) ">")
+  "Matches tags beginning Mason sections containing Perl code.
+Saves the name of the tag matched.")
+
+(defvar mmm-mason-pseudo-perl-tags-regexp
+  (concat "<%" (mmm-regexp-opt mmm-mason-pseudo-perl-tags t) ">")
+  "Match tags beginning Mason sections that look like Perl but aren't.
+Saves the name of the tag matched.")
+
+(defvar mmm-mason-tag-names-regexp
+  (regexp-opt (append mmm-mason-perl-tags mmm-mason-non-perl-tags) t)
+  "Matches any Mason tag name after the \"<%\". Used to verify that a
+\"<%\" sequence starts an inline section.")
+
+(defun mmm-mason-verify-inline ()
+  (not (looking-at mmm-mason-tag-names-regexp)))
+
+;;}}}
+;;{{{ Add Classes
+
+(mmm-add-group
+ 'mason
+ `((mason-text
+    :submode nil
+    :front "<%text>"
+    :back "</%text>"
+    :insert ((?t mason-<%text> nil @ "<%text>" @ "\n"
+                 _ "\n" @ "</%text>" @)))
+   (mason-doc
+    :submode text-mode
+    :face mmm-comment-submode-face
+    :front "<%doc>"
+    :back "</%doc>"
+    :face nil
+    :insert ((?d mason-<%doc> nil @ "<%doc>" @ "\n"
+                 _ "\n" @ "</%doc>" @)))
+   (mason-perl
+    :submode perl
+    :match-face (("<%perl>" . mmm-code-submode-face)
+                 ("<%init>" . mmm-init-submode-face)
+                 ("<%cleanup>" . mmm-cleanup-submode-face)
+                 ("<%once>" . mmm-init-submode-face)
+                 ("<%filter>" . mmm-special-submode-face)
+                 ("<%shared>" . mmm-init-submode-face))
+    :front ,mmm-mason-perl-tags-regexp
+    :back "</%~1>"
+    :save-matches 1
+    :match-name "~1"
+    :save-name 1
+    :insert ((?, mason-<%TAG> "Perl section: " @ "<%" str ">" @
+                 ";\n" _ "\n" @ "</%" str ">" @)
+             (?< mason-<%TAG> ?, . nil)
+             (?p mason-<%perl> ?, . "perl")
+             (?i mason-<%init> ?, . "init")
+             (?c mason-<%cleanup> ?, . "cleanup")
+             (?o mason-<%once> ?, . "once")
+             (?l mason-<%filter> ?, . "filter")
+             (?s mason-<%shared> ?, . "shared")))
+   (mason-pseudo-perl
+    :submode perl
+    :face mmm-declaration-submode-face
+    :front ,mmm-mason-pseudo-perl-tags-regexp
+    :back "</%~1>"
+    :save-matches 1
+    :insert ((?. mason-pseudo-<%TAG> "Pseudo-perl section: " @ "<%" str ">" @
+                 "\n" _ "\n" @ "</%" str ">" @)
+             (?> mason-pseudo-<%TAG> ?, . nil)
+             (?a mason-<%args> ?. . "args")
+             (?f mason-<%flags> ?. . "flags")
+             (?r mason-<%attr> ?. . "attr")))
+   (mason-inline
+    :submode perl
+    :face mmm-output-submode-face
+    :front "<%"
+    :front-verify mmm-mason-verify-inline
+    :back "%>"
+    :insert ((?% mason-<%-%> nil @ "<%" @ " " _ " " @ "%>" @)
+             (?5 mason-<%-%> ?% . nil)))
+   (mason-call
+    :submode perl
+    :face mmm-special-submode-face
+    :front "<&"
+    :back "&>"
+    :insert ((?& mason-<&-&> nil @ "<&" @ " " _ " " @ "&>" @)
+             (?7 mason-<&-&> ?% . nil)))
+   (mason-one-line-comment
+    :submode text-mode
+    :face mmm-comment-submode-face
+    :front "^%#"
+    :back "\n"
+    :insert ((?# mason-%-comment nil (mmm-mason-start-line)
+                @ "%" @ "# " _ @ '(mmm-mason-end-line) "\n" @)
+             (?3 mason-%-comment ?# . nil)))
+   (mason-one-line
+    :submode perl
+    :face mmm-code-submode-face
+    :front "^%"
+    :back "\n"
+    :insert ((return mason-%-line nil (mmm-mason-start-line)
+                     @ "%" @ " " _ @ '(mmm-mason-end-line) "\n" @)))))
+
+;;}}}
+;;{{{ One-line Sections
+
+(defun mmm-mason-start-line ()
+  (if (bolp)
+      ""
+    "\n"))
+
+(defun mmm-mason-end-line ()
+  (if (eolp)
+      (delete-char 1)))
+
+;;}}}
+;;{{{ Set Mode Line
+
+(defun mmm-mason-set-mode-line ()
+  (setq mmm-buffer-mode-display-name "Mason"))
+(add-hook 'mmm-mason-class-hook 'mmm-mason-set-mode-line)
+
+;;}}}
+
+(provide 'mmm-mason)
+
+;;; mmm-mason.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-mode-autoloads.el b/.emacs.d/elisp/mmm/mmm-mode-autoloads.el
new file mode 100644 (file)
index 0000000..4ae1b3c
--- /dev/null
@@ -0,0 +1,35 @@
+;;; mmm-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
+\f
+;;;### (autoloads (nxml-web-mode html-erb-mode) "mmm-erb" "mmm-erb.el"
+;;;;;;  (20891 59622 632249 639000))
+;;; Generated autoloads from mmm-erb.el
+
+(autoload 'html-erb-mode "mmm-erb" "\
+
+
+\(fn)" t nil)
+
+(autoload 'nxml-web-mode "mmm-erb" "\
+
+
+\(fn)" t nil)
+
+;;;***
+\f
+;;;### (autoloads nil nil ("mmm-auto.el" "mmm-class.el" "mmm-cmds.el"
+;;;;;;  "mmm-compat.el" "mmm-cweb.el" "mmm-mason.el" "mmm-mode-pkg.el"
+;;;;;;  "mmm-mode.el" "mmm-myghty.el" "mmm-noweb.el" "mmm-region.el"
+;;;;;;  "mmm-rpm.el" "mmm-sample.el" "mmm-univ.el" "mmm-utils.el"
+;;;;;;  "mmm-vars.el") (20891 59622 643765 210000))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; mmm-mode-autoloads.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-mode.el b/.emacs.d/elisp/mmm/mmm-mode.el
new file mode 100644 (file)
index 0000000..b9ce714
--- /dev/null
@@ -0,0 +1,305 @@
+;;; mmm-mode.el --- Allow Multiple Major Modes in a buffer
+
+;; Copyright (C) 1999, 2004 by Michael Abraham Shulman
+;; Copyright (C) 2013 by Dmitry Gutov
+
+;; Emacs Lisp Archive Entry
+;; Package: mmm-mode
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
+;; URL: https://github.com/purcell/mmm-mode
+;; Keywords: convenience, faces, languages, tools
+;; Version: 0.5.1
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, or (at your
+;; option) any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;;; MMM Mode is a minor mode that allows multiple major modes to
+;;; coexist in a single buffer. Refer to the documentation of the
+;;; function `mmm-mode' for more detailed information. This file
+;;; contains mode on/off functions and the mode keymap, but mostly
+;;; just loads all the subsidiary files.
+
+;;{{{ Parameter Naming
+
+;;; Since version 0.3.7, I've tried to use a uniform scheme for naming
+;;; parameters. Here's a brief summary.
+
+;;; BEG and END refer to the beginning and end of a region.
+;;; FRONT and BACK refer to the respective delimiters of a region.
+;;; FRONT- and BACK-OFFSET are the offsets from delimiter matches.
+;;; FRONT-BEG through BACK-END are the endings of the delimiters.
+;;; START and STOP bound actions, like searching, fontification, etc.
+
+;;}}}
+;;{{{ CL and Parameters
+
+;;; Keyword parameters can be nice because it makes it easier to see
+;;; what's getting passed as what. But I try not to use them in user
+;;; functions, because CL doesn't make good documentation strings.
+;;; Similarly, any hook or callback function can't take keywords,
+;;; since Emacs as a whole doesn't use them. And for small parameter
+;;; lists, they are overkill. So I use them only for a large number of
+;;; optional parameters, such as `mmm-make-region'.
+
+;;; An exception is the various submode class application functions,
+;;; which all take all their arguments as keywords, for consistency
+;;; and so the classes alist looks nice.
+
+;;; When using keyword arguments, defaults should *always* be supplied
+;;; in all arglists. (This pertains mostly to :start and :stop
+;;; arguments, usually defaulting to (point-min) and (point-max)
+;;; respectively.) `mmm-save-keywords' should only be used for lists
+;;; with more than four arguments, such as in `mmm-ify-by-regexp'.
+
+;;; In general, while I have no qualms about using things from CL like
+;;; `mapl', `loop' and `destructuring-bind', I try not to use `defun*'
+;;; more than I have to. For one, it sometimes makes bad documentation
+;;; strings. Furthermore, to a `defun'ned function, a nil argument is
+;;; the same as no argument, so it will use its (manual) default, but
+;;; to a `defun*'ned function, a nil argument *is* the argument, so
+;;; any default specified in the arglist will be ignored. Confusion of
+;;; this type should be avoided when at all possible.
+
+;;}}}
+
+;;; Code:
+
+(require 'cl)
+;; If we don't load font-lock now, but it is loaded later, the
+;; necessary mmm-font-lock-* properties may not be there.
+(require 'font-lock)
+(require 'mmm-compat)
+(require 'mmm-utils)
+(require 'mmm-vars)
+(require 'mmm-auto)
+(require 'mmm-region)
+(require 'mmm-class)
+;; This file is set up to autoload by `mmm-auto.el'.
+;; (require 'mmm-cmds)
+(require 'mmm-univ)
+
+;;{{{ Toggle Function
+
+(defun mmm-mode (&optional arg)
+  "Minor mode to allow multiple major modes in one buffer.
+Without ARG, toggle MMM Mode. With ARG, turn MMM Mode on iff ARG is
+positive and off otherwise.
+
+Commands Available:
+\\<mmm-mode-map>
+\\{mmm-mode-map}
+
+BASIC CONCEPTS
+
+The idea of MMM Mode is to allow multiple major modes to coexist in
+the same buffer.  There is one \"primary\" major mode that controls
+most of the buffer, and a number of \"submodes\" that each hold sway
+over certain regions.  The submode regions are usually highlighted by
+a background color for ease of recognition.  While the point is in a
+submode region, the following changes \(are supposed to) occur:
+
+1. The local keymap and the syntax table are that of the submode.
+2. The mode line changes to show what submode region is active.
+3. The major mode menu and mouse popup menu are that of the submode.
+4. Some local variables of the submode shadow the default mode's.
+5. Font-lock fontifies correctly for the submode.
+6. Indentation function dispatches to the appropriate submode.
+
+For further information, including installation and configuration
+instructions, see the Info file mmm.info which is included with the
+distribution of MMM Mode.  Many of MMM's configuration variables are
+available through M-x customize-group RET mmm."
+  (interactive "P")
+  (if (if arg (> (prefix-numeric-value arg) 0) (not mmm-mode))
+      (mmm-mode-on)
+    (mmm-mode-off)))
+
+(add-to-list 'minor-mode-alist (list 'mmm-mode mmm-mode-string))
+
+;;}}}
+;;{{{ Mode On
+
+(defun mmm-mode-on ()
+  "Turn on MMM Mode. See `mmm-mode'."
+  (interactive)
+  ;; This function is called from mode hooks, so we need to make sure
+  ;; we're not in a temporary buffer.  We don't need to worry about
+  ;; recursively ending up in ourself, however, since by that time the
+  ;; variable `mmm-mode' will already be set.
+  (mmm-valid-buffer
+   (unless mmm-mode
+     (setq mmm-primary-mode major-mode)
+     (when (fboundp 'c-make-styles-buffer-local)
+       (c-make-styles-buffer-local t))
+     (mmm-update-mode-info major-mode)
+     (setq mmm-region-saved-locals-for-dominant
+           ;; FIXME: Neither is defined in recent Emacs.
+           (list* (list 'font-lock-cache-state nil)
+                  (list 'font-lock-cache-position (make-marker))
+                  (copy-tree (cdr (assq major-mode mmm-region-saved-locals-defaults)))))
+     ;; Without the next line, the (make-marker) above gets replaced
+     ;; with the starting value of nil, and all comes to naught.
+     (mmm-set-local-variables major-mode nil)
+     (mmm-add-hooks)
+     (mmm-fixup-skeleton)
+     (make-local-variable 'font-lock-fontify-region-function)
+     (setq font-lock-fontify-region-function 'mmm-fontify-region)
+     (set (make-local-variable (if (boundp 'syntax-begin-function) ; Emacs >= 23
+                                   'syntax-begin-function
+                                 'font-lock-beginning-of-syntax-function))
+          'mmm-beginning-of-syntax)
+     (set (make-local-variable 'syntax-propertize-function)
+          'mmm-syntax-propertize-function)
+     (set (make-local-variable 'indent-line-function) mmm-indent-line-function)
+     (setq mmm-mode t)
+     (condition-case err
+         (mmm-apply-all)
+       (mmm-error
+        ;; Complain, but don't die, since we want files to go ahead
+        ;; and be opened anyway, and the mode to go ahead and be
+        ;; turned on. Should we delete all previously made submode
+        ;; regions when we find an invalid one?
+        (message "%s" (error-message-string err))))
+     (run-hooks 'mmm-mode-hook)
+     (mmm-run-major-hook))))
+
+;;}}}
+;;{{{ Mode Off
+
+(defun mmm-mode-off ()
+  "Turn off MMM Mode. See `mmm-mode'."
+  (interactive)
+  (when mmm-mode
+    (mmm-remove-hooks)
+    (mmm-clear-overlays)
+    (mmm-clear-history)
+    (mmm-clear-mode-ext-classes)
+    (mmm-clear-local-variables)
+    (mmm-update-submode-region)
+    (setq font-lock-fontify-region-function
+          (get mmm-primary-mode 'mmm-fontify-region-function))
+    (set (if (boundp 'syntax-begin-function) ; Emacs >= 23
+             'syntax-begin-function
+           'font-lock-beginning-of-syntax-function)
+         (get mmm-primary-mode 'mmm-beginning-of-syntax-function))
+    (mmm-update-font-lock-buffer)
+    (mmm-refontify-maybe)
+    (setq mmm-mode nil)
+    ;; Restore the mode line
+    (setq mmm-primary-mode-display-name nil
+         mmm-buffer-mode-display-name nil)
+    (mmm-set-mode-line)))
+
+;;}}}
+;;{{{ Mode Keymap
+
+(defvar mmm-mode-map (make-sparse-keymap)
+  "Keymap for MMM Minor Mode.")
+
+(defvar mmm-mode-prefix-map (make-sparse-keymap)
+  "Keymap for MMM Minor Mode after `mmm-mode-prefix-key'.")
+
+(defvar mmm-mode-menu-map (make-sparse-keymap "MMM")
+  "Keymap for MMM Minor Mode menu.")
+
+(defun mmm-define-key (key binding &optional keymap)
+  (define-key (or keymap mmm-mode-prefix-map)
+    (vector (append mmm-command-modifiers (list key)))
+    binding))
+
+(when mmm-use-old-command-keys
+  (mmm-use-old-command-keys))
+
+(mmm-define-key ?c 'mmm-ify-by-class)
+(mmm-define-key ?x 'mmm-ify-by-regexp)
+(mmm-define-key ?r 'mmm-ify-region)
+
+(mmm-define-key ?b 'mmm-parse-buffer)
+(mmm-define-key ?g 'mmm-parse-region)
+(mmm-define-key ?% 'mmm-parse-block)
+(mmm-define-key ?5 'mmm-parse-block)
+
+(mmm-define-key ?k 'mmm-clear-current-region)
+(mmm-define-key ?\  'mmm-reparse-current-region)
+(mmm-define-key ?e 'mmm-end-current-region)
+
+(mmm-define-key ?z 'mmm-narrow-to-submode-region)
+
+;; This one is exact, since C-h is (usually) already used for help.
+(define-key mmm-mode-prefix-map [?h] 'mmm-insertion-help)
+
+;; Default bindings to do insertion (dynamic)
+(mmm-set-keymap-default mmm-mode-prefix-map 'mmm-insert-region)
+
+;; Set up the prefix help command, since otherwise the default binding
+;; overrides it.
+(define-key mmm-mode-prefix-map (vector help-char) prefix-help-command)
+
+;; And put it all onto the prefix key
+(define-key mmm-mode-map mmm-mode-prefix-key mmm-mode-prefix-map)
+
+;; Order matters for the menu bar.
+(define-key mmm-mode-menu-map [off]
+  '("MMM Mode Off" . mmm-mode-off))
+(define-key mmm-mode-menu-map [sep0] '(menu-item "----"))
+
+(define-key mmm-mode-menu-map [clhist]
+  '("Clear History" . mmm-clear-history))
+(define-key mmm-mode-menu-map [end]
+  '("End Current" . mmm-end-current-region))
+(define-key mmm-mode-menu-map [clear]
+  '("Clear Current" . mmm-clear-current-region))
+(define-key mmm-mode-menu-map [reparse]
+  '("Reparse Current" . mmm-reparse-current-region))
+
+(define-key mmm-mode-menu-map [sep10] '(menu-item "----"))
+
+(define-key mmm-mode-menu-map [ins-help]
+  '("List Insertion Keys" . mmm-insertion-help))
+
+(define-key mmm-mode-menu-map [sep20] '(menu-item "----"))
+
+(define-key mmm-mode-menu-map [region]
+  '(menu-item "MMM-ify Region" mmm-ify-region :enable mark-active))
+(define-key mmm-mode-menu-map [regexp]
+  '("MMM-ify by Regexp" . mmm-ify-by-regexp))
+(define-key mmm-mode-menu-map [class]
+  '("Apply Submode Class" . mmm-ify-by-class))
+
+(define-key mmm-mode-menu-map [sep30] '(menu-item "----"))
+
+(define-key mmm-mode-menu-map [parse-region]
+  '(menu-item "Parse Region" mmm-parse-region :enable mark-active))
+(define-key mmm-mode-menu-map [parse-buffer]
+  '("Parse Buffer" . mmm-parse-buffer))
+(define-key mmm-mode-menu-map [parse-block]
+  '("Parse Block" . mmm-parse-block))
+
+(define-key mmm-mode-map [menu-bar mmm] (cons "MMM" mmm-mode-menu-map))
+
+(add-to-list 'minor-mode-map-alist (cons 'mmm-mode mmm-mode-map))
+
+;;}}}
+
+(provide 'mmm-mode)
+
+;;; mmm-mode.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-myghty.el b/.emacs.d/elisp/mmm/mmm-myghty.el
new file mode 100644 (file)
index 0000000..96802d9
--- /dev/null
@@ -0,0 +1,188 @@
+;;; mmm-myghty.el --- MMM submode class for Myghty components
+;;;     
+
+;; Copyright (C) 2000 by Michael Abraham Shulman
+;; Copyright (C) 2004 by Ben Bangert
+
+;; Original Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;; Based on mmm-mason.el, trivial changes by Ben Bangert
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;;; I went to the hard (sarcasm) effort of applying two global 
+;;; search/replaces, and adding a few keywords for additional
+;;; blocks that Myghty introduced. Many thanks to Michael for writing
+;;; the mmm-mason without which I would never have found the time
+;;; to patch up for Myghty.
+
+;;; Code:
+
+(require 'mmm-compat)
+(require 'mmm-vars)
+(require 'mmm-auto)
+
+;;{{{ Python Tags
+
+(defvar mmm-myghty-python-tags
+  '("python" "init" "cleanup" "once" "filter" "shared" "global"
+    "threadlocal" "requestlocal"
+    "python_init" "python_cleanup" "python_once" "python_filter"))
+
+(defvar mmm-myghty-pseudo-python-tags
+  '("args" "python_args" "attr" "flags"))
+
+(defvar mmm-myghty-non-python-tags
+  '("doc" "python_doc" "text" "python_text" "def" "python_def" "method"))
+
+(defvar mmm-myghty-python-tags-regexp
+  (concat "<%" (mmm-regexp-opt mmm-myghty-python-tags t) ">")
+  "Matches tags beginning Myghty sections containing Python code.
+Saves the name of the tag matched.")
+
+(defvar mmm-myghty-pseudo-python-tags-regexp
+  (concat "<%" (mmm-regexp-opt mmm-myghty-pseudo-python-tags t) ">")
+  "Match tags beginning Myghty sections that look like Python but aren't.
+Saves the name of the tag matched.")
+
+(defvar mmm-myghty-tag-names-regexp
+  (regexp-opt (append mmm-myghty-python-tags mmm-myghty-non-python-tags) t)
+  "Matches any Myghty tag name after the \"<%\". Used to verify that a
+\"<%\" sequence starts an inline section.")
+
+(defun mmm-myghty-verify-inline ()
+  (not (looking-at mmm-myghty-tag-names-regexp)))
+
+;;}}}
+;;{{{ Add Classes
+
+(mmm-add-group
+ 'myghty
+ `((myghty-text
+    :submode nil
+    :front "<%text>"
+    :back "</%text>"
+    :insert ((?t myghty-<%text> nil @ "<%text>" @ "\n"
+                 _ "\n" @ "</%text>" @)))
+   (myghty-doc
+    :submode text-mode
+    :face mmm-comment-submode-face
+    :front "<%doc>"
+    :back "</%doc>"
+    :face nil
+    :insert ((?d myghty-<%doc> nil @ "<%doc>" @ "\n"
+                 _ "\n" @ "</%doc>" @)))
+   (myghty-python
+    :submode python
+    :match-face (("<%python>" . mmm-code-submode-face)
+                 ("<%init>" . mmm-init-submode-face)
+                 ("<%cleanup>" . mmm-cleanup-submode-face)
+                 ("<%once>" . mmm-init-submode-face)
+                 ("<%global>" . mmm-init-submode-face)
+                 ("<%filter>" . mmm-special-submode-face)
+                 ("<%shared>" . mmm-init-submode-face)
+                 ("<%threadlocal>" . mmm-init-submode-face)
+                 ("<%requestlocal>" . mmm-init-submode-face))
+    :front ,mmm-myghty-python-tags-regexp
+    :back "</%~1>"
+    :save-matches 1
+    :match-name "~1"
+    :save-name 1
+    :insert ((?, myghty-<%TAG> "Python section: " @ "<%" str ">" @
+                 ";\n" _ "\n" @ "</%" str ">" @)
+             (?< myghty-<%TAG> ?, . nil)
+             (?p myghty-<%python> ?, . "python")
+             (?i myghty-<%init> ?, . "init")
+             (?c myghty-<%cleanup> ?, . "cleanup")
+             (?o myghty-<%once> ?, . "once")
+             (?g myghty-<%global> ?, . "global")
+             (?t myghty-<%threadlocal> ?, . "threadlocal")
+             (?e myghty-<%requestlocal> ?, . "requestlocal")
+             (?l myghty-<%filter> ?, . "filter")
+             (?s myghty-<%shared> ?, . "shared")))
+   (myghty-pseudo-python
+    :submode python
+    :face mmm-declaration-submode-face
+    :front ,mmm-myghty-pseudo-python-tags-regexp
+    :back "</%~1>"
+    :save-matches 1
+    :insert ((?. myghty-pseudo-<%TAG> "Pseudo-python section: " @ "<%" str ">" @
+                 "\n" _ "\n" @ "</%" str ">" @)
+             (?> myghty-pseudo-<%TAG> ?, . nil)
+             (?a myghty-<%args> ?. . "args")
+             (?f myghty-<%flags> ?. . "flags")
+             (?r myghty-<%attr> ?. . "attr")))
+   (myghty-inline
+    :submode python
+    :face mmm-output-submode-face
+    :front "<%"
+    :front-verify mmm-myghty-verify-inline
+    :back "%>"
+    :insert ((?% myghty-<%-%> nil @ "<%" @ " " _ " " @ "%>" @)
+             (?5 myghty-<%-%> ?% . nil)))
+   (myghty-call
+    :submode python
+    :face mmm-special-submode-face
+    :front "<&"
+    :back "&>"
+    :insert ((?& myghty-<&-&> nil @ "<&" @ " " _ " " @ "&>" @)
+             (?7 myghty-<&-&> ?% . nil)))
+   (myghty-one-line-comment
+    :submode text-mode
+    :face mmm-comment-submode-face
+    :front "^%#"
+    :back "\n"
+    :insert ((?# myghty-%-comment nil (mmm-myghty-start-line)
+                @ "%" @ "# " _ @ '(mmm-myghty-end-line) "\n" @)
+             (?3 myghty-%-comment ?# . nil)))
+   (myghty-one-line
+    :submode python
+    :face mmm-code-submode-face
+    :front "^%"
+    :back "\n"
+    :insert ((return myghty-%-line nil (mmm-myghty-start-line)
+                     @ "%" @ " " _ @ '(mmm-myghty-end-line) "\n" @)))))
+
+;;}}}
+;;{{{ One-line Sections
+
+(defun mmm-myghty-start-line ()
+  (if (bolp)
+      ""
+    "\n"))
+
+(defun mmm-myghty-end-line ()
+  (if (eolp)
+      (delete-char 1)))
+
+;;}}}
+;;{{{ Set Mode Line
+
+(defun mmm-myghty-set-mode-line ()
+  (setq mmm-buffer-mode-display-name "Myghty"))
+(add-hook 'mmm-myghty-class-hook 'mmm-myghty-set-mode-line)
+
+;;}}}
+
+(provide 'mmm-myghty)
+
+;;; mmm-myghty.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-noweb.el b/.emacs.d/elisp/mmm/mmm-noweb.el
new file mode 100644 (file)
index 0000000..4f6bec4
--- /dev/null
@@ -0,0 +1,415 @@
+;;; mmm-noweb.el --- MMM submode class for Noweb programs
+;;
+;; Copyright 2003, 2004 Joe Kelsey <joe@zircon.seattle.wa.us>
+;;
+;; The filling, completion and chunk motion commands either taken
+;; directly from or inspired by code in:
+;; noweb-mode.el - edit noweb files with GNU Emacs
+;; Copyright 1995 by Thorsten.Ohl @ Physik.TH-Darmstadt.de
+;;     with a little help from Norman Ramsey <norman@bellcore.com>
+;; 
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains the definition of an MMM Mode submode class for
+;; editing Noweb programs.
+;;
+;; FIXME: The more advanced features don't work: `mmm-name-at' and
+;; `mmm-syntax-region' are undefined. Need to dig around in the bug reports
+;; and/or discussions, wherever the code using them was submitted.
+
+;;; Code:
+
+(require 'cl)
+(require 'mmm-region)
+(require 'mmm-vars)
+(require 'mmm-mode)
+
+;;{{{ Variables
+
+(defvar mmm-noweb-code-mode 'fundamental-mode
+  "*Major mode for editing code chunks.
+This is set to FUNDAMENTAL-MODE by default, but you might want to change
+this in the Local Variables section of your file to something more
+appropriate, like C-MODE, FORTRAN-MODE, or even INDENTED-TEXT-MODE.")
+
+(defvar mmm-noweb-quote-mode nil
+  "*Major mode for quoted code chunks within documentation chunks.
+If nil, defaults to `mmm-noweb-code-mode', which see.")
+
+(defvar mmm-noweb-quote-string "quote"
+  "*String used to form quoted code submode region names.
+See `mmm-noweb-quote'.")
+
+(defvar mmm-noweb-quote-number 0
+  "*Starting value appended to `mmm-noweb-quote-string'.
+See `mmm-noweb-quote'.")
+
+(defvar mmm-noweb-narrowing nil
+  "*Narrow the region to the current pair of chunks.")
+
+;;}}}
+;;{{{ Support for mmm submode stuff
+
+(defun mmm-noweb-chunk (form)
+  "Return the noweb code mode chosen by the user.
+If the next 100 characters of the buffer contain a string of the form
+\"-*- MODE -*-\", then return MODE as the chosen mode, otherwise
+return the value of `mmm-noweb-code-mode'."
+  ;; Look for -*- mode -*- in the first two lines.
+  ;; 120 chars = 40 chars for #! + 80 chars for following line...
+  (if (re-search-forward "-\\*-\\s +\\(\\S-+\\)\\s +-\\*-" (+ (point) 120) t)
+      (let* ((string (match-string-no-properties 1))
+            (modestr (intern (if (string-match "mode\\'" string)
+                                 string
+                               (concat string "-mode")))))
+       (or (mmm-ensure-modename modestr)
+           mmm-noweb-code-mode))
+    mmm-noweb-code-mode))
+
+(defun mmm-noweb-quote (form)
+  "Create a unique name for a quoted code region within a documentation chunk."
+  (or mmm-noweb-quote-mode
+      mmm-noweb-code-mode))
+
+(defun mmm-noweb-quote-name (form)
+  "Create a unique name for a quoted code region within a documentation chunk."
+  (setq mmm-noweb-quote-number (1+ mmm-noweb-quote-number))
+  (concat mmm-noweb-quote-string "-"
+         (number-to-string mmm-noweb-quote-number)))
+
+(defun mmm-noweb-chunk-name (form)
+  "Get the chunk name from FRONT-FORM."
+  (string-match "<<\\(.*\\)>>=" form)
+  (match-string-no-properties 1 form))
+
+;;}}}
+;;{{{ mmm noweb submode group
+
+;; We assume that the global document mode is latex or whatever, the
+;; user wants.  This class controls the code chunk submodes.  We use
+;; match-submode to either return the value in mmm-noweb-code-mode or to
+;; look at the first line of the chunk for a submode setting.  We reset
+;; case-fold-search because chunk names are case sensitive.  The front
+;; string identifies the chunk name between the <<>>.  Since this is
+;; done, name-match can use the same functions as save-matches for back.
+;; Our insert skeleton places a new code chunk and the skel-name lets us
+;; optimize the skelton naming to use the inserted string.
+
+(mmm-add-group
+ 'noweb
+ '((noweb-chunk
+    :match-submode mmm-noweb-chunk
+    :case-fold-search nil
+    :front "^<<\\(.*\\)>>="
+    :match-name "~1"
+    :save-name 1
+    :front-offset (end-of-line 1)
+    :back "^@\\( \\|$\\|\\( %def .*$\\)\\)"
+    :insert ((?c noweb-code "Code Chunk Name: "
+               "\n" @ "<<" str ">>=" @ "\n" _ "\n" @ "@ " @ "\n"))
+    :skel-name t
+    )
+   (noweb-quote
+    :match-submode mmm-noweb-quote
+    :face mmm-special-submode-face
+    :front "\\[\\["
+;    :name-match mmm-noweb-quote-name
+    :back "\\]\\]"
+    :insert ((?q noweb-quote nil @ "[[" @ _ @ "]]" @))
+    )
+   ))
+
+;;}}}
+;;{{{ Noweb regions
+
+(defun mmm-noweb-regions (start stop regexp &optional delim)
+  "Return a liat of regions of the form \(NAME BEG END) that exclude
+names which match REGEXP."
+  (let* ((remove-next nil)
+        (regions
+         (maplist #'(lambda (pos-list)
+                      (if (cdr pos-list)
+                          (if remove-next
+                              (setq remove-next nil)
+                            (let ((name (or (mmm-name-at (car pos-list) 'beg)
+                                            (symbol-name mmm-primary-mode))))
+                              (if (and regexp (string-match regexp name) )
+                                  (progn
+                                    (setq remove-next t)
+                                    nil)
+                                (list name
+                                      (car pos-list) (cadr pos-list)))))))
+                  (mmm-submode-changes-in start stop t delim))))
+    ;; The above loop leaves lots of nils in the list...
+    ;; Removing them saves us from having to do the (last x 2)
+    ;; trick that mmm-regions-in does.
+    (setq regions (delq nil regions))))
+
+;;}}}
+;;{{{ Filling, etc
+
+(defun mmm-noweb-narrow-to-doc-chunk ()
+  "Narrow to the current doc chunk.
+The current chunk includes all quoted code chunks (i.e., \[\[...\]\]).
+This function is only valid when called with point in a doc chunk or
+quoted code chunk."
+  (interactive)
+  (let ((name (mmm-name-at (point))))
+    (if (or (null name) (string-match "^quote" name))
+       (let ((prev (cond
+                    ((= (point) (point-min)) (point))
+                    (t (cadar (last (mmm-noweb-regions (point-min) (point)
+                                                       "^quote"))))))
+             (next (cond
+                    ((= (point) (point-max)) (point))
+                    (t (save-excursion
+                         (goto-char (cadr
+                                     (cadr (mmm-noweb-regions (point)
+                                                              (point-max)
+                                                              "^quote"))))
+                         (forward-line -1)
+                         (point))))))
+         (narrow-to-region prev next)))))
+
+(defun mmm-noweb-fill-chunk (&optional justify)
+  "Fill the current chunk according to mode.
+Run `fill-region' on documentation chunks and `indent-region' on code
+chunks."
+  (interactive "P")
+  (save-restriction
+    (let ((name (mmm-name-at (point))))
+      (if (and name (not (string-match "^quote" name)))
+         (if (or indent-region-function indent-line-function)
+             (progn
+               (mmm-space-other-regions)
+               (indent-region (overlay-start mmm-current-overlay)
+                              (overlay-end mmm-current-overlay) nil))
+           (error "No indentation functions defined in %s!" major-mode))
+       (progn
+         (mmm-word-other-regions)
+         (fill-paragraph justify)))
+      (mmm-undo-syntax-other-regions))))
+
+(defun mmm-noweb-fill-paragraph-chunk (&optional justify)
+  "Fill a paragraph in the current chunk."
+  (interactive "P")
+  (save-restriction
+    (let ((name (mmm-name-at (point))))
+      (if (and name (not (string-match "^quote" name)))
+         (progn
+           (mmm-space-other-regions)
+           (fill-paragraph justify))
+       (progn
+         (mmm-word-other-regions)
+         (fill-paragraph justify)))
+      (mmm-undo-syntax-other-regions))))
+
+(defun mmm-noweb-fill-named-chunk (&optional justify)
+  "Fill the region containing the named chunk."
+  (interactive "P")
+  (save-restriction
+    (let* ((name (or (mmm-name-at) (symbol-name mmm-primary-mode)))
+          (list (cdr (assoc name (mmm-names-alist (point-min) (point-max))))))
+      (if (or (string= name (symbol-name mmm-primary-mode))
+             (string-match "^quote" name))
+         (progn
+           (mmm-word-other-regions)
+           (do-auto-fill))
+       (progn
+         (mmm-space-other-regions)
+         (indent-region (caar list) (cadar (last list)) nil)))
+      (mmm-undo-syntax-other-regions))))
+
+(defun mmm-noweb-auto-fill-doc-chunk ()
+  "Replacement for `do-auto-fill'."
+  (save-restriction
+    (mmm-noweb-narrow-to-doc-chunk)
+    (mmm-word-other-regions)
+    (do-auto-fill)
+    (mmm-undo-syntax-other-regions)))
+
+(defun mmm-noweb-auto-fill-doc-mode ()
+  "Install the improved auto fill function, iff necessary."
+  (if auto-fill-function
+      (setq auto-fill-function 'mmm-noweb-auto-fill-doc-chunk)))
+
+(defun mmm-noweb-auto-fill-code-mode ()
+  "Install the default auto fill function, iff necessary."
+  (if auto-fill-function
+      (setq auto-fill-function 'do-auto-fill)))
+
+;;}}}
+;;{{{ Functions on named chunks
+
+(defun mmm-noweb-complete-chunk ()
+  "Try to complete the chunk name."
+  (interactive)
+  (let ((end (point))
+       (beg (save-excursion
+              (if (re-search-backward "<<"
+                                      (save-excursion
+                                        (beginning-of-line)
+                                        (point))
+                                      t)
+                  (match-end 0)
+                nil))))
+       (if beg
+           (let* ((pattern (buffer-substring beg end))
+                  (alist (mmm-names-alist (point-min) (point-max)))
+                  (completion (try-completion pattern alist)))
+             (cond ((eq completion t))
+                   ((null completion)
+                    (message "Can't find completion for \"%s\"" pattern)
+                    (ding))
+                   ((not (string= pattern completion))
+                    (delete-region beg end)
+                    (insert completion)
+                    (if (not (looking-at ">>"))
+                        (insert ">>")))
+                   (t
+                    (message "Making completion list...")
+                    (with-output-to-temp-buffer "*Completions*"
+                      (display-completion-list
+                       (all-completions pattern alist)))
+                    (message "Making completion list...%s" "done"))))
+         (message "Not at chunk name..."))))
+
+(defvar mmm-noweb-chunk-history nil
+  "History for `mmm-noweb-goto-chunk'.")
+
+(defun mmm-noweb-goto-chunk ()
+  "Goto the named chunk."
+  (interactive)
+  (widen)
+  (let* ((completion-ignore-case t)
+        (alist (mmm-names-alist (point-min) (point-max)))
+        (chunk (completing-read
+                "Chunk: " alist nil t
+                (mmm-name-at (point))
+                mmm-noweb-chunk-history)))
+    (goto-char (caadr (assoc chunk alist)))))
+
+(defun mmm-noweb-goto-next (&optional cnt)
+  "Goto the continuation of the current chunk."
+  (interactive "p")
+  (widen)
+  (let ((name (mmm-name-at (point))))
+    (if name
+       (let ((list (cdr (assoc name (mmm-names-alist
+                                     (overlay-end mmm-current-overlay)
+                                     (point-max))))))
+         (if list
+             (goto-char (caar (nthcdr (1- cnt) list))))))))
+
+(defun mmm-noweb-goto-previous (&optional cnt)
+  "Goto the continuation of the current chunk."
+  (interactive "p")
+  (widen)
+  (let ((name (mmm-name-at (point))))
+    (if name
+       (let ((list (reverse
+                    (cdr (assoc name
+                                (mmm-names-alist (point-min)
+                                                 (overlay-start
+                                                  mmm-current-overlay)))))))
+         (if list
+             (goto-char (cadar (nthcdr cnt list))))))))
+
+;;}}}
+;;{{{ Key mappings
+
+(defvar mmm-noweb-map (make-sparse-keymap))
+(defvar mmm-noweb-prefix-map (make-sparse-keymap))
+(define-key mmm-noweb-map mmm-mode-prefix-key mmm-noweb-prefix-map)
+
+(mmm-define-key ?d 'mmm-noweb-narrow-to-doc-chunk mmm-noweb-prefix-map)
+(mmm-define-key ?n 'mmm-noweb-goto-next mmm-noweb-prefix-map)
+(mmm-define-key ?p 'mmm-noweb-goto-previous mmm-noweb-prefix-map)
+(mmm-define-key ?q 'mmm-noweb-fill-chunk mmm-noweb-prefix-map)
+;; Cannot use C-g as goto command, so use C-s.
+(mmm-define-key ?s 'mmm-noweb-goto-chunk mmm-noweb-prefix-map)
+
+(define-key mmm-noweb-prefix-map "\t" 'mmm-noweb-complete-chunk)
+
+;; Don't want to add to either the mmm mode map (used in other mmm
+;; buffers) or the local map (used in other major mode buffers), so we
+;; make a full-buffer spanning overlay and add the map there.
+(defun mmm-noweb-bind-keys ()
+  (save-restriction
+    (widen)
+    (let ((ovl (make-overlay (point-min) (point-max) nil nil t)))
+      ;; 'keymap', not 'local-map'
+      (overlay-put ovl 'keymap mmm-noweb-map))))
+
+(add-hook 'mmm-noweb-class-hook 'mmm-noweb-bind-keys)
+
+;; TODO: make this overlay go away if mmm is turned off
+
+;;}}}
+
+;; These functions below living here temporarily until a real place is
+;; found.
+
+(defun mmm-syntax-region-list (syntax regions)
+  "Apply SYNTAX to a list of REGIONS of the form (BEG END).
+If SYNTAX is not nil, set the syntax-table property of each region.
+If SYNTAX is nil, remove the region syntax-table property.
+See `mmm-syntax-region'."
+  (mapcar #'(lambda (reg)
+             (mmm-syntax-region (car reg) (cadr reg) syntax))
+         regions))
+
+(defun mmm-syntax-other-regions (syntax &optional name)
+  "Apply SYNTAX cell to other regions.
+Regions are separated by name, using either `mmm-name-at' or the
+optional NAME to determine the current region name."
+  (if (null name)
+      (setq name (or (mmm-name-at)
+                    (symbol-name mmm-primary-mode))))
+  (mapcar #'(lambda (reg)
+             (if (not (string= (car reg) name))
+                 (mmm-syntax-region-list syntax (cdr reg))))
+         (mmm-names-alist (point-min) (point-max))))
+
+(defun mmm-word-other-regions ()
+  "Give all other regions word syntax."
+  (interactive)
+  (mmm-syntax-other-regions '(2 . 0))
+  (setq parse-sexp-lookup-properties t))
+
+(defun mmm-space-other-regions ()
+  "Give all other regions space syntax."
+  (interactive)
+  (mmm-syntax-other-regions '(0 . 0))
+  (setq parse-sexp-lookup-properties t))
+
+(defun mmm-undo-syntax-other-regions ()
+  "Remove syntax-table property from other regions."
+  (interactive)
+  (mmm-syntax-other-regions nil)
+  (setq parse-sexp-lookup-properties nil))
+
+
+(provide 'mmm-noweb)
+
+;;; mmm-noweb.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-region.el b/.emacs.d/elisp/mmm/mmm-region.el
new file mode 100644 (file)
index 0000000..7600ff0
--- /dev/null
@@ -0,0 +1,882 @@
+;;; mmm-region.el --- Manipulating and behavior of MMM submode regions
+
+;; Copyright (C) 2000 by Michael Abraham Shulman
+;; Copyright (C) 2012, 2013 by Dmitry Gutov
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file provides the functions and variables to create, delete,
+;; and inspect submode regions, as well as functions that make them
+;; behave like the submode with respect to syntax tables, local maps,
+;; font lock, etc.
+
+;; See mmm-class.el for functions which scan the buffer and decide
+;; where to create regions.
+
+;;; Code:
+
+(require 'cl)
+(require 'font-lock)
+(require 'mmm-compat)
+(require 'mmm-utils)
+(require 'mmm-auto)
+(require 'mmm-vars)
+
+;; INSPECTION
+;;{{{ Current Overlays
+
+;; Emacs counts an overlay starting at POS as "at" POS, but not an
+;; overlay ending at POS. XEmacs is more sensible and uses beg- and
+;; end-stickiness to determine whether an endpoint is within an
+;; extent. Here we want to act like XEmacs does.
+
+(defsubst mmm-overlay-at (&optional pos type)
+  "Return the highest-priority MMM Mode overlay at POS.
+See `mmm-included-p' for the values of TYPE."
+  (car (mmm-overlays-at pos type)))
+
+(defun mmm-overlays-at (&optional pos type)
+  "Return a list of the MMM overlays at POS, in decreasing priority.
+See `mmm-included-p' for the values of TYPE."
+  (or pos (setq pos (point)))
+  (mmm-sort-overlays
+   (remove-if-not
+    #'(lambda (ovl)
+       (and (overlay-get ovl 'mmm)
+            (mmm-included-p ovl pos type)))
+    ;; XEmacs complains about positions outside the buffer
+    (overlays-in (max (1- pos) (point-min))
+                (min (1+ pos) (point-max))))))
+
+(defun mmm-included-p (ovl pos &optional type)
+  "Return true if the overlay OVL contains POS.
+
+If OVL strictly contains POS, always return true.  If OVL starts or
+ends at POS, return true or false based on the value of TYPE, which
+should be one of nil, `beg', `end', `none', or `all'.
+* If TYPE is nil, return true for an overlay starting at POS only if
+  it is beg-sticky, and for one ending at POS only if it is end-sticky.
+* If TYPE is `beg', return true for any overlay starting at POS but
+  false for any ending at POS.
+* If TYPE is `end', return true for any overlay ending at POS but
+  false for any starting at POS.
+* If TYPE is `all', return true for any overlay starting or ending at POS.
+* If TYPE is `none' \(or any other value), return false for any
+  overlay starting or ending at POS."
+  (let ((beg (overlay-start ovl))
+       (end (overlay-end ovl)))
+    (cond ((and (= beg pos) (= end pos))
+          ;; Do the Right Thing for zero-width overlays
+          (case type
+            ((nil) (and (overlay-get ovl 'beg-sticky)
+                        (overlay-get ovl 'end-sticky)))
+            ((none) nil)
+            (t t)))
+         ((= beg pos)
+          (case type
+            ((nil) (overlay-get ovl 'beg-sticky))
+            ((beg all) t)
+            (t nil)))
+         ((= end pos)
+          (case type
+            ((nil) (overlay-get ovl 'end-sticky))
+            ((end all) t)
+            (t nil)))
+         ((and (> end pos) (< beg pos))
+          t))))
+
+;;; `mmm-overlays-in' has been retired as altogether too confusing a
+;;; name, when what is really meant is one of the following three:
+
+(defun mmm-overlays-containing (start stop)
+  "Return all MMM overlays containing the region START to STOP.
+The overlays are returned in order of decreasing priority.  No
+attention is paid to stickiness."
+  (mmm-sort-overlays
+   (remove-if-not
+    #'(lambda (ovl)
+       (and (overlay-get ovl 'mmm)
+            (<= (overlay-start ovl) start)
+            (>= (overlay-end ovl) stop)))
+    (overlays-in (max start (point-min))
+                (min stop (point-max))))))
+
+(defun mmm-overlays-contained-in (start stop)
+  "Return all MMM overlays entirely contained in START to STOP.
+The overlays are returned in order of decreasing priority.  No
+attention is paid to stickiness."
+  (mmm-sort-overlays
+   (remove-if-not
+    #'(lambda (ovl)
+       (and (overlay-get ovl 'mmm)
+            (>= (overlay-start ovl) start)
+            (<= (overlay-end ovl) stop)))
+    (overlays-in (max start (point-min))
+                (min stop (point-max))))))
+
+(defun mmm-overlays-overlapping (start stop)
+  "Return all MMM overlays overlapping the region START to STOP.
+The overlays are returned in order of decreasing priority.  No
+attention is paid to stickiness."
+  (mmm-sort-overlays
+   (remove-if-not
+    #'(lambda (ovl)
+       (overlay-get ovl 'mmm))
+    (overlays-in (max start (point-min))
+                (min stop (point-max))))))
+
+(defun mmm-sort-overlays (overlays)
+  "Sort OVERLAYS in order of decreasing priority."
+  (sort (copy-list overlays)
+        #'(lambda (x y) (> (or (overlay-get x 'priority) 0)
+                           (or (overlay-get y 'priority) 0)))))
+
+;;}}}
+;;{{{ Current Submode
+
+(defvar mmm-current-overlay nil
+  "What submode region overlay we think we are currently in.
+May be out of date; call `mmm-update-current-submode' to correct it.")
+(make-variable-buffer-local 'mmm-current-overlay)
+
+(defvar mmm-previous-overlay nil
+  "What submode region overlay we were in just before this one.
+Set by `mmm-update-current-submode'.")
+(make-variable-buffer-local 'mmm-previous-overlay)
+
+(defvar mmm-current-submode nil
+  "What submode we think we are currently in.
+May be out of date; call `mmm-update-current-submode' to correct it.")
+(make-variable-buffer-local 'mmm-current-submode)
+
+(defvar mmm-previous-submode nil
+  "What submode we were in just before this one.
+Set by `mmm-update-current-submode'.")
+(make-variable-buffer-local 'mmm-previous-submode)
+
+(defun mmm-update-current-submode (&optional pos)
+  "Update current and previous position variables to POS, or point.
+Return non-nil if the current region changed.
+
+Also deletes overlays that ought to evaporate because their delimiters
+have disappeared."
+  (mapc #'delete-overlay
+       (remove-if #'(lambda (ovl)
+                      (or (not (eq (overlay-get ovl 'mmm-evap) 'front))
+                          (overlay-buffer (overlay-get ovl 'front))))
+                  (mmm-overlays-at pos)))
+  (let ((ovl (mmm-overlay-at pos)))
+    (if (eq ovl mmm-current-overlay)
+        nil
+      (mmm-set-current-pair (if ovl (overlay-get ovl 'mmm-mode)) ovl)
+      t)))
+
+(defun mmm-set-current-pair (mode ovl)
+  "Set the current submode to MODE, the current overlay to OVL
+and update the saved previous values."
+  (setq mmm-previous-overlay mmm-current-overlay
+        mmm-previous-submode mmm-current-submode)
+  (setq mmm-current-submode mode
+        mmm-current-overlay ovl))
+
+(defun mmm-submode-at (&optional pos type)
+  "Return the submode at POS \(or point), or NIL if none.
+See `mmm-included-p' for values of TYPE."
+  (let ((ovl (mmm-overlay-at pos type)))
+    (if ovl (overlay-get ovl 'mmm-mode))))
+
+;;}}}
+;;{{{ Delimiter Matching and Boundaries
+
+(defun mmm-match-front (ovl)
+  "Return non-nil if the front delimiter of OVL matches as it should.
+Sets the match data to the front delimiter, if it is a regexp.
+Otherwise, calls it as a function with point at the beginning of the
+front delimiter overlay \(i.e. where the front delimiter ought to
+start) and one argument being the region overlay. The function should
+return non-nil if the front delimiter matches correctly, and set the
+match data appropriately."
+  (let* ((front-ovl (overlay-get ovl 'front))
+        (front (if front-ovl (overlay-get front-ovl 'match))))
+    (when front
+      (save-excursion
+       (goto-char (overlay-start front-ovl))
+       (if (stringp front)
+           ;; It's a regexp
+           (looking-at front)
+         ;; It's a function
+         (funcall front ovl))))))
+
+(defun mmm-match-back (ovl)
+  "Return non-nil if the back delimiter of OVL matches as it should.
+Sets the match data to the back delimiter, if it is a regexp.
+Otherwise, calls it as a function with point at the beginning of the
+back delimiter overlay \(i.e. where the back delimiter ought to start)
+and one argument being the region overlay. The function should return
+non-nil if the back delimiter matches correctly, and set the match
+data appropriately."
+  (let* ((back-ovl (overlay-get ovl 'back))
+        (back (if back-ovl (overlay-get back-ovl 'match))))
+    (when back
+      (save-excursion
+       (goto-char (overlay-start back-ovl))
+       (if (stringp back)
+           ;; It's a regexp
+           (looking-at back)
+         ;; It's a function
+         (funcall back ovl))))))
+
+(defun mmm-front-start (ovl)
+  "Return the position at which the front delimiter of OVL starts."
+  (let ((front (overlay-get ovl 'front)))
+    ;; Overlays which have evaporated become "overlays in no buffer"
+    (if (and front (overlay-buffer front))
+       (overlay-start front)
+      (overlay-start ovl))))
+
+(defun mmm-back-end (ovl)
+  "Return the position at which the back delimiter of OVL ends."
+  (let ((back (overlay-get ovl 'back)))
+    ;; Overlays which have evaporated become "overlays in no buffer"
+    (if (and back (overlay-buffer back))
+       (overlay-end back)
+      (overlay-end ovl))))
+
+;;}}}
+
+;; CREATION & DELETION
+;;{{{ Make Submode Regions
+
+(defun mmm-valid-submode-region (submode beg end)
+  "Check if the region between BEG and END is valid for SUBMODE.
+This region must be entirely contained within zero or more existing
+submode regions, none of which start or end inside it, and it must be
+a valid child of the highest-priority of those regions, if any.
+Signals errors, returns `t' if no error."
+  ;; First check if the placement is valid.  Every existing region
+  ;; that overlaps this one must contain it in its entirety.
+  (let ((violators (set-difference
+                   (mmm-overlays-overlapping beg end)
+                   (mmm-overlays-containing beg end))))
+    (if violators
+       (signal 'mmm-subregion-invalid-placement
+               violators)))
+  ;; Now check if it is inside a valid parent
+  (let ((parent-mode (mmm-submode-at beg 'beg)))
+    (and parent-mode
+        ;; TODO: Actually check parents here.  For present purposes,
+        ;; we just make sure we aren't putting a submode inside one
+        ;; of the same type.  Actually, what we should really be
+        ;; doing is checking classes/names of regions, not just the
+        ;; submodes.
+        (eq submode parent-mode)
+        (signal 'mmm-subregion-invalid-parent
+                (list parent-mode))))
+  t)
+
+(defun* mmm-make-region
+    (submode beg end &key face
+            front back (evaporation 'front)
+            delimiter-mode front-face back-face
+            display-name
+            (match-front "") (match-back "")
+             (beg-sticky t) (end-sticky t)
+            name creation-hook
+             )
+  "Make a submode region from BEG to END of SUBMODE.
+
+BEG and END are buffer positions or markers with BEG <= END \(although
+see EVAPORATION below).  SUBMODE is a major mode function or a valid
+argument to `mmm-modename->function'.  FACE is a valid display face.
+
+FRONT and BACK specify the positions of the front and back delimiters
+for this region, if any.  If FRONT is a buffer position or marker, the
+front delimiter runs from it to BEG.  FRONT can also be a two-element
+list \(FRONT-BEG FRONT-END) specifying the exact position of the front
+delimiter.  One must have FRONT-BEG < FRONT-END <= BEG.
+
+Similarly, BACK may be a buffer position or marker, in which case the
+back delimiter runs from END to BACK.  BACK can also be a two-element
+list \(BACK-BEG BACK-END) specifying the exact position, in which case
+we must have END <= BACK-BEG < BACK-END.
+
+EVAPORATION specifies under what conditions this submode region should
+disappear.
+* If `nil', the region never disappears.  This can cause serious
+  problems when using cut-and-paste and is not recommended.
+* If the value is t, the region disappears whenever it has zero
+  length.  This is recommended for manually created regions used for
+  temporary editing convenience.
+* If the value is `front', the region will disappear whenever the text
+  in its front delimiter disappears, that is, whenever the overlay
+  which marks its front delimiter has zero width.
+The default value is `front'.  However, if the parameter FRONT is nil,
+then this makes no sense, so the default becomes `t'.  Note that if
+EVAPORATION is `t', then an error is signalled if BEG = END.
+
+MATCH-FRONT \(resp. MATCH-BACK) is a regexp or function to match the
+correct delimiters, see `mmm-match-front' \(resp. `mmm-match-back').
+It is ignored if FRONT \(resp. BACK) is nil.  At present these are not
+used much.
+
+DELIMITER-MODE specifies the major mode to use for delimiter regions.
+A `nil' value means they remain in the primary mode.
+
+FACE, FRONT-FACE, and BACK-FACE, are faces to use for the region, the
+front delimiter, and the back delimiter, respectively, under high
+decoration \(see `mmm-submode-decoration-level').
+
+BEG-STICKY and END-STICKY determine whether the front and back of the
+region, respectively, are sticky with respect to new insertion.  The
+default is yes.
+
+NAME is a string giving the \"name\" of this submode region.  Submode
+regions with the same name are considered part of the same code
+fragment and formatted accordingly.
+
+DISPLAY-NAME is a string to display in the mode line when point is in
+this submode region.  If nil or not given, the name associated with
+SUBMODE is used.  In delimiter regions, \"--\" is shown.
+
+CREATION-HOOK should be a function to run after the region is created,
+with point at the start of the new region."
+  ;; Check placement of region and delimiters
+  (unless (if (eq evaporation t)
+              (< beg end)
+            (<= beg end))
+    (signal 'mmm-subregion-invalid-placement (list beg end)))
+  (when front
+    (unless (listp front)
+      (setq front (list front beg)))
+    (unless (and (< (car front) (cadr front))
+                (<= (cadr front) beg))
+      (signal 'mmm-subregion-invalid-placement front)))
+  (when back
+    (unless (listp back)
+      (setq back (list end back)))
+    (unless (and (< (car back) (cadr back))
+                (<= end (car back)))
+      (signal 'mmm-subregion-invalid-placement back)))
+  (setq submode (mmm-modename->function submode))
+  ;; Check embedding in existing regions
+  (mmm-valid-submode-region submode beg end)
+  (mmm-mode-on)
+  (when submode
+    (mmm-update-mode-info submode))
+  (and (not front) (eq evaporation 'front) (setq evaporation t))
+  (let ((region-ovl
+        (mmm-make-overlay submode beg end name face beg-sticky end-sticky
+                          (or (eq evaporation t) nil) display-name)))
+    ;; Save evaporation type for checking later
+    (overlay-put region-ovl 'mmm-evap evaporation)
+    ;; Calculate priority to supersede anything already there.
+    (overlay-put region-ovl 'priority (length (mmm-overlays-at beg)))
+    ;; Make overlays for the delimiters, with appropriate pointers.
+    (when front
+      (let ((front-ovl
+            (mmm-make-overlay delimiter-mode (car front) (cadr front)
+                              nil front-face nil nil t "--" t)))
+       (overlay-put region-ovl 'front front-ovl)
+       (overlay-put front-ovl 'region region-ovl)
+       (overlay-put front-ovl 'match match-front)))
+    (when back
+      (let ((back-ovl
+            (mmm-make-overlay delimiter-mode (car back) (cadr back)
+                              nil back-face nil nil t "--" t)))
+       (overlay-put region-ovl 'back back-ovl)
+       (overlay-put back-ovl 'region region-ovl)
+       (overlay-put back-ovl 'match match-back)))
+    ;; Update everything and run all the hooks
+    (mmm-save-all
+     ;; Can be nil when a zero-width region is immediately evaporated
+     (when (overlay-start region-ovl)
+       (goto-char (overlay-start region-ovl)))
+     (mmm-set-current-pair submode region-ovl)
+     (mmm-set-local-variables submode region-ovl)
+     (mmm-run-submode-hook submode)
+     (when creation-hook
+       (funcall creation-hook)))
+    (mmm-update-submode-region)
+    region-ovl))
+
+(defun mmm-make-overlay (submode beg end name face beg-sticky end-sticky evap
+                                &optional display-name delim)
+  "Internal function to make submode overlays.
+Does not handle delimiters.  Use `mmm-make-region'."
+  (let ((ovl (make-overlay beg end nil (not beg-sticky) end-sticky)))
+    (mapc
+     #'(lambda (pair) (overlay-put ovl (car pair) (cadr pair)))
+     `((mmm t)                         ; Mark all submode overlays
+       (mmm-mode ,submode)
+       ,@(if delim '((delim t)) nil)
+       (mmm-local-variables
+       ;; Have to be careful to make new list structure here
+       ,(list* (list 'font-lock-cache-state nil)
+               (list 'font-lock-cache-position (make-marker))
+               (copy-tree
+                (cdr (assq submode mmm-region-saved-locals-defaults)))))
+       (name ,name)
+       (display-name ,display-name)
+       ;; Need to save these, because there's no way of accessing an
+       ;; overlay's official "front-advance" parameter once it's created.
+       (beg-sticky ,beg-sticky)
+       (end-sticky ,end-sticky)
+       ;; These have special meaning to Emacs
+       (,mmm-evaporate-property ,evap)
+       (face ,(mmm-get-face face submode delim))
+       ))
+    ovl))
+
+(defun mmm-get-face (face submode &optional delim)
+  (cond ((= mmm-submode-decoration-level 0) nil)
+       ((and (= mmm-submode-decoration-level 2) face) face)
+       (delim 'mmm-delimiter-face)
+       (submode 'mmm-default-submode-face)))
+
+;;}}}
+;;{{{ Clear Overlays
+
+;; See also `mmm-clear-current-region'.
+
+(defun mmm-clear-overlays (&optional start stop strict)
+  "Clears all MMM overlays overlapping START and STOP.
+If STRICT, only clear those entirely included in that region."
+  (mapc #'delete-overlay
+        (if strict
+            (mmm-overlays-contained-in (or start (point-min))
+                                       (or stop (point-max)))
+          (mmm-overlays-overlapping (or start (point-min))
+                                    (or stop (point-max)))))
+  (mmm-update-submode-region))
+
+;;}}}
+
+;; BASIC UPDATING
+;;{{{ Submode Info
+
+(defun mmm-update-mode-info (mode &optional force)
+  "Save the global-saved and buffer-saved variables for MODE.
+Global saving is done on properties of the symbol MODE and buffer
+saving in `mmm-buffer-saved-locals'.  This function must be called for
+both the dominant mode and all submodes, in each file.  Region-saved
+variables are initialized from `mmm-region-saved-locals-defaults',
+which is set here as well.  See `mmm-save-local-variables'.  If FORCE
+is non-nil, don't quit if the info is already there."
+  (let ((buffer-entry (assq mode mmm-buffer-saved-locals))
+        (region-entry (assq mode mmm-region-saved-locals-defaults))
+        global-vars buffer-vars region-vars
+        ;; http://debbugs.gnu.org/13836
+        buffer-file-truename)
+    (unless (and (not force)
+                 (get mode 'mmm-local-variables)
+                 buffer-entry
+                 region-entry)
+      (let ((temp-buffer (mmm-make-temp-buffer (current-buffer)
+                                               mmm-temp-buffer-name))
+            (filename (buffer-file-name))
+            (mmm-in-temp-buffer t))
+        (unwind-protect
+            (with-current-buffer temp-buffer
+              ;; Handle stupid modes that need the file name set.
+              (when (memq mode mmm-set-file-name-for-modes)
+                (setq buffer-file-name filename))
+              (funcall mode)
+              (when (featurep 'font-lock)
+                (put mode 'mmm-font-lock-mode font-lock-mode)
+                ;; These can't be in the local variables list, because we
+                ;; replace their actual values, but we want to use their
+                ;; original values elsewhere.
+                (put mode 'mmm-fontify-region-function
+                     font-lock-fontify-region-function)
+                (put mode 'mmm-beginning-of-syntax-function
+                     (or syntax-begin-function
+                         font-lock-beginning-of-syntax-function))
+                (put mode 'mmm-syntax-propertize-function
+                     (and (boundp 'syntax-propertize-function)
+                          syntax-propertize-function))
+                (put mode 'mmm-indent-line-function indent-line-function))
+              ;; Get variables
+              (setq global-vars (mmm-get-locals 'global)
+                    buffer-vars (mmm-get-locals 'buffer)
+                    region-vars (mmm-get-locals 'region))
+              (put mode 'mmm-mode-name mode-name))
+          (kill-buffer temp-buffer)))
+      (put mode 'mmm-local-variables global-vars)
+      (if buffer-entry
+          (setcdr buffer-entry buffer-vars)
+        (push (cons mode buffer-vars) mmm-buffer-saved-locals))
+      (if region-entry
+          (setcdr region-entry region-vars)
+        (push (cons mode region-vars)
+              mmm-region-saved-locals-defaults)))))
+
+;;}}}
+;;{{{ Updating Hooks
+
+(defun mmm-update-submode-region ()
+  "Update all MMM properties correctly for the current position.
+This function and those it calls do the actual work of setting the
+different keymaps, syntax tables, local variables, etc. for submodes."
+  (when (mmm-update-current-submode)
+    (mmm-save-changed-local-variables mmm-previous-submode
+                                      mmm-previous-overlay)
+    (let ((mode (or mmm-current-submode mmm-primary-mode)))
+      (mmm-update-mode-info mode)
+      (mmm-set-local-variables mode mmm-current-overlay)
+      (mmm-enable-font-lock mode))
+    (mmm-set-mode-line)
+    (dolist (func (if mmm-current-overlay
+                     (overlay-get mmm-current-overlay 'entry-hook)
+                   mmm-primary-mode-entry-hook))
+      (ignore-errors (funcall func)))))
+
+(defun mmm-add-hooks ()
+  (if (featurep 'xemacs)
+      (make-local-hook 'post-command-hook))
+  (add-hook 'post-command-hook 'mmm-update-submode-region nil t)
+  (when mmm-parse-when-idle
+    (add-hook 'pre-command-hook 'mmm-mode-reset-timer nil t)
+    (add-hook 'after-change-functions 'mmm-mode-edit nil t)))
+
+(defun mmm-remove-hooks ()
+  (remove-hook 'post-command-hook 'mmm-update-submode-region t)
+  (remove-hook 'pre-command-hook 'mmm-mode-reset-timer t)
+  (remove-hook 'after-change-functions 'mmm-mode-edit t))
+
+;;}}}
+;;{{{ Local Variables
+
+(defun mmm-get-local-variables-list (type mode)
+  "Filter `mmm-save-local-variables' to match TYPE and MODE.
+Return a list \(VAR ...).  In some cases, VAR will be a cons cell
+\(GETTER . SETTER) -- see `mmm-save-local-variables'."
+  (mapcan #'(lambda (element)
+              (and (if (and (consp element)
+                            (cdr element)
+                            (cadr element))
+                       (eq (cadr element) type)
+                     (eq type 'global))
+                   (if (and (consp element)
+                            (cddr element)
+                            (not (eq (caddr element) t)))
+                       (if (functionp (caddr element))
+                           (funcall (caddr element))
+                         (member mode (caddr element)))
+                     t)
+                   (list (if (consp element) (car element) element))))
+          mmm-save-local-variables))
+
+(defun mmm-get-locals (type)
+  "Get the local variables and values for TYPE from this buffer.
+Return \((VAR VALUE) ...).  In some cases, VAR will be of the form
+\(GETTER . SETTER) -- see `mmm-save-local-variables'."
+  (mapcan #'(lambda (var)
+              (if (consp var)
+                  `((,var ,(funcall (car var))))
+                (and (boundp var)
+                     ;; This seems logical, but screws things up.
+                     ;;(local-variable-p var)
+                     `((,var ,(symbol-value var))))))
+          (mmm-get-local-variables-list type major-mode)))
+
+;; FIXME: Has no callers. Used for debugging?
+(defun mmm-get-saved-local (mode ovl var)
+  "Get the value of the local variable VAR saved for MODE and OVL, if any."
+  (cadr (assq var (mmm-get-saved-local-variables ovl mode))))
+
+;; FIXME: It's too easy to accidentally pass nil as MODE here.
+;; We probably should call this from `mmm-set-current-pair', and not
+;; rely on its callers to default to the primary mode when appropriate.
+;; Also, incorporate the opmimization from `mmm-fontify-region-list'.
+(defun mmm-set-local-variables (mode ovl)
+  "Set all the local variables saved for MODE and OVL.
+Looks up global, buffer and region saves.  When MODE is nil, just
+the region ones."
+  (mapcar #'(lambda (var)
+              ;; (car VAR) may be (GETTER . SETTER)
+              (if (consp (car var))
+                  (funcall (cdar var) (cadr var))
+                (make-local-variable (car var))
+                (set (car var) (cadr var))))
+          (mmm-get-saved-local-variables mode ovl)))
+
+;; Used for debugging.
+(defun mmm-diff-local-variables (mode ovl)
+  (let (res)
+    (mapc (lambda (var)
+            (let ((current-value (if (consp (car var))
+                                     (funcall (caar var))
+                                   (symbol-value (car var)))))
+              (unless (equal current-value (cadr var))
+                (push
+                 (message "var: %s, current: %s, saved: %s" (car var)
+                          current-value (cadr var))
+                 res))))
+          (mmm-get-saved-local-variables mode ovl))
+    res))
+
+(defun mmm-get-saved-local-variables (mode ovl)
+  (append (get mode 'mmm-local-variables)
+          (cdr (assq mode mmm-buffer-saved-locals))
+          (if ovl
+              (overlay-get ovl 'mmm-local-variables)
+            mmm-region-saved-locals-for-dominant)))
+
+(defun mmm-save-changed-local-variables (mode ovl)
+  "Save by-buffer and by-region variables for MODE and OVL.
+Called when we move to a new submode region, with MODE and OVL the
+region and mode for the previous position."
+  (let ((buffer-vars (cdr (assq (or mode mmm-primary-mode)
+                                mmm-buffer-saved-locals)))
+        (region-vars (if ovl
+                         (overlay-get ovl 'mmm-local-variables)
+                       mmm-region-saved-locals-for-dominant))
+        (set-local-value
+         #'(lambda (var)
+             (setcar (cdr var)
+                     ;; (car VAR) may be (GETTER . SETTER)
+                     (if (consp (car var))
+                         (funcall (caar var))
+                       (symbol-value (car var)))))))
+    (mapc set-local-value buffer-vars)
+    (mapc set-local-value region-vars)))
+
+(defun mmm-clear-local-variables ()
+  "Clear all buffer- and region-saved variables for current buffer."
+  (setq mmm-buffer-saved-locals ()
+        mmm-region-saved-locals-defaults ()
+        mmm-region-saved-locals-for-dominant ()))
+
+;;}}}
+
+;; FONT LOCK
+;;{{{ Enable Font Lock
+
+(defun mmm-enable-font-lock (mode)
+  "Turn on font lock if it is not already on and MODE enables it."
+  (mmm-update-mode-info mode)
+  (and (not font-lock-mode)
+       (get mode 'mmm-font-lock-mode)
+       (font-lock-mode 1)))
+
+(defun mmm-update-font-lock-buffer ()
+  "Turn on font lock if any mode in the buffer enables it."
+  (if (some #'(lambda (mode)
+                (get mode 'mmm-font-lock-mode))
+            (cons mmm-primary-mode
+                  (mapcar #'(lambda (ovl)
+                              (overlay-get ovl 'mmm-mode))
+                          (mmm-overlays-overlapping
+                           (point-min) (point-max)))))
+      (font-lock-mode 1)
+    (font-lock-mode 0)))
+
+(defun mmm-refontify-maybe (&optional start stop)
+  "Re-fontify from START to STOP, or entire buffer, if enabled."
+  (and font-lock-mode
+       (if (or start stop)
+           (font-lock-fontify-region (or start (point-min))
+                                     (or stop (point-max)))
+         (font-lock-fontify-buffer))))
+
+;;}}}
+;;{{{ Get Submode Regions
+
+;;; In theory, these are general functions that have nothing to do
+;;; with font-lock, but they aren't used anywhere else, so we might as
+;;; well have them close.
+
+(defun mmm-submode-changes-in (start stop)
+  "Return a list of all submode-change positions from START to STOP.
+The list is sorted in order of increasing buffer position."
+  (let ((changes (sort (remove-duplicates
+                        (mapcan #'(lambda (ovl)
+                                    `(,(overlay-start ovl)
+                                      ,(overlay-end ovl)))
+                                (mmm-overlays-overlapping start stop)))
+                       #'<)))
+    (when (or (not changes) (< start (car changes)))
+      (push start changes))
+    (let ((last (last changes)))
+      (when (> stop (car last))
+        (setcdr last (list stop))))
+    changes))
+
+(defun mmm-regions-in (start stop)
+  "Return a list of regions of the form (MODE BEG END OVL) whose disjoint
+union covers the region from START to STOP, including delimiters."
+  (let ((regions 
+         (maplist #'(lambda (pos-list)
+                      (when (cdr pos-list)
+                        (let ((ovl (mmm-overlay-at (car pos-list) 'beg)))
+                          (list (if ovl
+                                    (overlay-get ovl 'mmm-mode)
+                                  mmm-primary-mode)
+                                (car pos-list) (cadr pos-list)
+                                ovl))))
+                  (mmm-submode-changes-in start stop))))
+    (setcdr (last regions 2) nil)
+    regions))
+
+(defun mmm-regions-alist (start stop)
+  "Return a list of lists of the form \(MODE . REGIONS) where REGIONS
+is a list of elements of the form \(BEG END OVL). The disjoint union all
+of the REGIONS covers START to STOP."
+  (let ((regions (mmm-regions-in start stop))
+        alist)
+    (mapc (lambda (region)
+            (let* ((mode (car region))
+                   (elem (cdr region))
+                   (kv (assoc mode alist)))
+              (if kv
+                  (push elem (cdr kv))
+                (push (cons mode (list elem)) alist))))
+          regions)
+    (mapcar (lambda (kv)
+              (cons (car kv) (nreverse (cdr kv))))
+            alist)))
+
+;;}}}
+;;{{{ Fontify Regions
+
+(defun mmm-fontify-region (start stop &optional loudly)
+  "Fontify from START to STOP keeping track of submodes correctly."
+  (let ((saved-mode mmm-current-submode)
+        (saved-ovl  mmm-current-overlay))
+    (unwind-protect
+        (progn
+          (when loudly
+            (message "Fontifying %s with submode regions..." (buffer-name)))
+          ;; Necessary to catch changes in font-lock cache state and position.
+          (mmm-save-changed-local-variables
+           mmm-current-submode mmm-current-overlay)
+          ;; For some reason `font-lock-fontify-block' binds this to nil, thus
+          ;; preventing `mmm-beginning-of-syntax' from doing The Right Thing.
+          ;; I don't know why it does this, but let's undo it here.
+          (let ((font-lock-beginning-of-syntax-function 'mmm-beginning-of-syntax))
+            (mapc #'(lambda (elt)
+                      (when (get (car elt) 'mmm-font-lock-mode)
+                        (mmm-fontify-region-list (car elt) (cdr elt))))
+                  (mmm-regions-alist start stop))))
+      ;; `post-command-hook' contains `mmm-update-submode-region',
+      ;; but jit-lock runs later, so we need to restore local vars now.
+      (mmm-set-current-pair saved-mode saved-ovl)
+      (mmm-set-local-variables (or saved-mode mmm-primary-mode) saved-ovl)))
+  (when loudly (message nil)))
+
+(defun mmm-fontify-region-list (mode regions)
+  "Fontify REGIONS, each like \(BEG END), in mode MODE."
+  (save-excursion
+    (let ((func (get mode 'mmm-fontify-region-function))
+          font-lock-extend-region-functions)
+      (mapc #'(lambda (reg)
+                  (goto-char (car reg))
+                  ;; Here we do the same sort of thing that
+                  ;; `mmm-update-submode-region' does, but we force it
+                  ;; to use a specific mode, and don't save anything,
+                  ;; fontify, or change the mode line.
+                  (mmm-set-current-pair mode (caddr reg))
+                  (mmm-set-local-variables (unless (eq mmm-previous-submode mode)
+                                             mode)
+                                           mmm-current-overlay)
+                  (funcall func (car reg) (cadr reg) nil)
+                  ;; Catch changes in font-lock cache.
+                  (mmm-save-changed-local-variables
+                   mmm-current-submode mmm-current-overlay))
+              regions))))
+
+;;}}}
+;;{{{ Syntax
+
+(defun mmm-beginning-of-syntax ()
+  (goto-char
+   (let ((ovl (mmm-overlay-at (point) 'beg))
+         (func (get (or mmm-current-submode mmm-primary-mode)
+                    'mmm-beginning-of-syntax-function)))
+     (max (if ovl (overlay-start ovl) (point-min))
+          (if func (progn (funcall func) (point)) (point-min))
+          (point-min)))))
+
+(defvar mmm-after-syntax-propertize-functions nil
+  "List of functions to call after applying `syntax-table' text
+properties to a submode region. It is passed four arguments: the
+region overlay, the submode and the bounds of the region.")
+
+(defun mmm-syntax-propertize-function (start stop)
+  "Composite function that applies `syntax-table' text properties.
+It iterates over all submode regions between START and STOP and
+calls each respective submode's `syntax-propertize-function'."
+  (let ((saved-mode mmm-current-submode)
+        (saved-ovl  mmm-current-overlay))
+    (mmm-save-changed-local-variables
+     mmm-current-submode mmm-current-overlay)
+    (unwind-protect
+        (mapc #'(lambda (elt)
+                  (let* ((mode (car elt))
+                         (func (get mode 'mmm-syntax-propertize-function))
+                         (beg (cadr elt)) (end (caddr elt))
+                         (ovl (cadddr elt))
+                         syntax-ppss-cache
+                         syntax-ppss-last)
+                    (goto-char beg)
+                    (mmm-set-current-pair mode ovl)
+                    (mmm-set-local-variables mode mmm-current-overlay)
+                    (save-restriction
+                      (when mmm-current-overlay
+                        (narrow-to-region (overlay-start mmm-current-overlay)
+                                          (overlay-end mmm-current-overlay)))
+                      (cond
+                       (func
+                        (funcall func beg end))
+                       (font-lock-syntactic-keywords
+                        (let ((syntax-propertize-function nil))
+                          (font-lock-fontify-syntactic-keywords-region beg end))))
+                      (run-hook-with-args 'mmm-after-syntax-propertize-functions
+                                          mmm-current-overlay mode beg end))))
+              (mmm-regions-in start stop))
+      (mmm-set-current-pair saved-mode saved-ovl)
+      (mmm-set-local-variables (or saved-mode mmm-primary-mode) saved-ovl))))
+
+;;}}}
+;;{{{ Indentation
+
+(defvar mmm-indent-line-function 'mmm-indent-line
+  "The function to call to indent inside a primary mode region.
+This will be the value of `indent-line-function' for the whole
+buffer. It's supposed to delegate to the appropriate submode's
+indentation function. See `mmm-indent-line' as the starting point.")
+
+(defun mmm-indent-line ()
+  (interactive)
+  (funcall
+    (save-excursion
+      (back-to-indentation)
+      (mmm-update-submode-region)
+      (get (or mmm-current-submode mmm-primary-mode)
+           'mmm-indent-line-function))))
+
+;;}}}
+(provide 'mmm-region)
+
+;;; mmm-region.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-rpm.el b/.emacs.d/elisp/mmm/mmm-rpm.el
new file mode 100644 (file)
index 0000000..71fe923
--- /dev/null
@@ -0,0 +1,80 @@
+;;; mmm-rpm.el --- MMM submode class for RPM spec files
+
+;; Copyright (C) 2000 by Marcus Harnisch <Marcus.Harnisch@gmx.net>
+
+;; Author:  Marcus Harnisch <Marcus.Harnisch@gmx.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains the definition of an MMM Mode submode class for
+;; editing shell script sections within RPM (Redhat Package Manager)
+;; spec files. I recommend to use it in combination with
+;; rpm-spec-mode.el by Stig Bjørlykke <stigb@tihlde.hist.no> and Steve
+;; Sanbeg <sanbeg@dset.com> (http://www.xemacs.org/~stigb/rpm-spec-mode.el)
+
+;;; Installation:
+
+;; 1. Copy this file where Emacs can find it.
+;;
+;; 2. Add the following lines to one of your startup files (e.g. ~/.emacs):
+;;
+;;   (add-to-list 'mmm-mode-ext-classes-alist
+;;                '(rpm-spec-mode "\\.spec\\'" rpm-sh))
+
+;;; Code:
+
+(require 'mmm-auto)
+
+(defconst mmm-rpm-sh-start-tags
+  '("prep" "build" "install" "clean" "preun" "postun" "pre"
+    "post" "triggerin" "triggerun" "triggerpostun")
+  "List containing RPM tags that start a shell-script section in a spec file")
+
+(defvar mmm-rpm-sh-end-tags
+  (append '("files" "description" "package") mmm-rpm-sh-start-tags)
+  "List containing RPM tags that end a shell-script section in a spec file")
+
+(defvar mmm-rpm-sh-start-regexp
+  (concat "^%" (mmm-regexp-opt mmm-rpm-sh-start-tags t) "\\b.*$")
+  "Regexp matching RPM tags that start a shell-script section in a spec file")
+
+(defvar mmm-rpm-sh-end-regexp
+  (concat "\\'\\|^%" (mmm-regexp-opt mmm-rpm-sh-end-tags t) "\\b.*$")
+  "Regexp matching RPM tags that end a shell-script section in a spec file")
+
+(mmm-add-group
+ 'rpm
+ `((rpm-sh
+    :submode sh-mode
+    :face mmm-code-submode-face
+    ;; match tags that starts sh-script region
+    :front ,mmm-rpm-sh-start-regexp
+    ;; match end of buffer or next tag that ends sh-script region
+    :back ,mmm-rpm-sh-end-regexp
+    :front-offset 1
+    :back-offset 0
+    :save-matches 0
+    )))
+
+(provide 'mmm-rpm)
+
+;;; mmm-rpm.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-sample.el b/.emacs.d/elisp/mmm/mmm-sample.el
new file mode 100644 (file)
index 0000000..6320a31
--- /dev/null
@@ -0,0 +1,384 @@
+;;; mmm-sample.el --- Sample MMM submode classes
+
+;; Copyright (C) 2003, 2004 by Michael Abraham Shulman
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file contains several sample submode classes for use with MMM
+;; Mode. For a more detailed, advanced example, see `mmm-mason.el'.
+
+;; In order to use any of classes defined here, just require `mmm-auto' and
+;; add the respective (major mode -> class <- file extension) associations
+;; with `mmm-add-mode-ext-class'.
+
+;;; Code:
+
+(require 'cl)
+(require 'mmm-auto)
+(require 'mmm-vars)
+
+;;{{{ <Perl> in httpd.conf
+
+;; This is the simplest example. Many applications will need no more
+;; than a simple regexp.
+;;
+;; Usage: (mmm-add-mode-ext-class 'apache-generic-mode nil 'httpd-conf-perl)
+
+(mmm-add-classes
+ '((httpd-conf-perl
+    :submode perl
+    :delimiter-mode nil
+    :front "<Perl>"
+    :back "</Perl>")))
+
+;;}}}
+;;{{{ JavaScript in HTML
+
+;; We use two classes here, both for code in a <script> tag, one wrapped in
+;; CDATA, another not. And another class to group them together.
+;;
+;; Usage: (mmm-add-mode-ext-class 'html-mode nil 'html-js)
+
+(mmm-add-group
+ 'html-js
+ '((js-script-cdata
+    :submode js-mode
+    :face mmm-code-submode-face
+    :front "<script[^>]*>[ \t\n]*\\(//\\)?<!\\[CDATA\\[[ \t]*\n?"
+    :back "[ \t]*\\(//\\)?]]>[ \t\n]*</script>")
+   (js-script
+    :submode js-mode
+    :face mmm-code-submode-face
+    :front "<script[^>]*>[ \t]*\n?"
+    :back "[ \t]*</script>"
+    :insert ((?j js-tag nil @ "<script type=\"text/javascript\">\n"
+                 @ "" _ "" @ "\n</script>" @)))))
+
+;;}}}
+;;{{{ CSS in HTML
+
+(mmm-add-group
+ 'html-css
+ '((css-cdata
+    :submode css-mode
+    :face mmm-code-submode-face
+    :front "<style[^>]*>[ \t\n]*\\(//\\)?<!\\[CDATA\\[[ \t]*\n?"
+    :back "[ \t]*\\(//\\)?]]>[ \t\n]*</style>")
+   (css
+    :submode css-mode
+    :face mmm-code-submode-face
+    :front "<style[^>]*>[ \t]*\n?"
+    :back "[ \t]*</style>"
+    :insert ((?c css-tag nil @ "<style type=\"text/css\">\n"
+                 @ "" _ "" @ "\n</style>" @)))))
+
+;;}}}
+;;{{{ Here-documents
+
+;; Here we match the here-document syntax used by Perl and shell
+;; scripts.  We try to be automagic about recognizing what mode the
+;; here-document should be in.  To make sure that it is recognized
+;; correctly, the name of the mode, perhaps minus `-mode', in upper
+;; case, and/or with hyphens converted to underscores, should be
+;; separated from the rest of the here-document name by hyphens or
+;; underscores.
+
+(defvar mmm-here-doc-mode-alist '()
+  "Alist associating here-document name regexps to submodes.
+Normally, this variable is unnecessary, as the `here-doc' submode
+class tries to automagically recognize the right submode.  If you use
+here-document names that it doesn't recognize, however, then you can
+add elements to this alist.  Each element is \(REGEXP . MODE) where
+REGEXP is a regular expression matched against the here-document name
+and MODE is a major mode function symbol.")
+
+(defun mmm-here-doc-get-mode (string)
+  (string-match "[a-zA-Z_-]+" string)
+  (setq string (match-string 0 string))
+  (or (mmm-ensure-modename
+       ;; First try the user override variable.
+       (some #'(lambda (pair)
+                (if (string-match (car pair) string) (cdr pair) nil))
+             mmm-here-doc-mode-alist))
+      (let ((words (split-string (downcase string) "[_-]+")))
+        (or (mmm-ensure-modename
+             ;; Try the whole name, stopping at "mode" if present.
+             (intern
+              (mapconcat #'identity
+                         (nconc (ldiff words (member "mode" words))
+                                (list "mode"))
+                         "-")))
+            ;; Try each word by itself (preference list)
+            (some #'(lambda (word)
+                      (mmm-ensure-modename (intern word)))
+                  words)
+            ;; Try each word with -mode tacked on
+            (some #'(lambda (word)
+                      (mmm-ensure-modename
+                       (intern (concat word "-mode"))))
+                  words)
+            ;; Try each pair of words with -mode tacked on
+            (loop for (one two) on words
+                  if (mmm-ensure-modename
+                      (intern (concat one two "-mode")))
+                  return it)
+            ;; I'm unaware of any modes whose names, minus `-mode',
+            ;; are more than two words long, and if the entire mode
+            ;; name (perhaps minus `-mode') doesn't occur in the
+            ;; here-document name, we can give up.
+            (signal 'mmm-no-matching-submode nil)))))
+
+(mmm-add-classes
+ '((here-doc
+    :front "<<[\"\'\`]?\\([a-zA-Z0-9_-]+\\)"
+    :front-offset (end-of-line 1)
+    :back "^~1$"
+    :save-matches 1
+    :delimiter-mode nil
+    :match-submode mmm-here-doc-get-mode
+    :insert ((?d here-doc "Here-document Name: " @ "<<" str _ "\n"
+                 @ "\n" @ str "\n" @))
+    )))
+
+;;}}}
+;;{{{ Embperl
+
+(mmm-add-group
+ 'embperl
+ '((embperl-perl
+    :submode perl
+    :front "\\[\\([-\\+!\\*\\$]\\)"
+    :back "~1\\]"
+    :save-matches 1
+    :match-name "embperl"
+    :match-face (("[+" . mmm-output-submode-face)
+                 ("[-" . mmm-code-submode-face)
+                 ("[!" . mmm-init-submode-face)
+                 ("[*" . mmm-code-submode-face)
+                 ("[$" . mmm-special-submode-face))
+    :insert ((?p embperl "Region Type (Character): " @ "[" str
+                 @ " " _ " " @ str "]" @)
+             (?+ embperl+ ?p . "+")
+             (?- embperl- ?p . "-")
+             (?! embperl! ?p . "!")
+             (?* embperl* ?p . "*")
+             (?$ embperl$ ?p . "$")
+             )
+    )
+   (embperl-comment
+    :submode text-mode
+    :face mmm-comment-submode-face
+    :front "\\[#"
+    :back "#\\]"
+    :insert ((?# embperl-comment nil @ "[#" @ " " _ " " @ "#]" @))
+    )))
+
+;;}}}
+;;{{{ ePerl
+
+(mmm-add-group
+ 'eperl
+ '((eperl-expr
+    :submode perl
+    :face mmm-output-submode-face
+    :front "<:="
+    :back ":>"
+    :insert ((?= eperl-expr nil @ "<:=" @ " " _ " " @ ":>" @)))
+   (eperl-code
+    :submode perl
+    :face mmm-code-submode-face
+    :front "<:"
+    :back "_?:>"
+    :match-name "eperl"
+    :insert ((?p eperl-code nil @ "<:" @ " " _ " " @ ":>" @)
+             (?: eperl-code ?p . nil)
+             (?_ eperl-code_ nil @ "<:" @ " " _ " " @ "_:>" @)))
+   (eperl-comment
+    :submode text
+    :face mmm-comment-submode-face
+    :front ":>//"
+    :back "\n")
+   ))
+
+;;}}}
+;;{{{ File Variables
+
+;; This submode class puts file local variable values, specified with
+;; a `Local Variables:' line as in (emacs)File Variables, into Emacs
+;; Lisp Mode.  It is a good candidate to put in `mmm-global-classes'.
+
+(defun mmm-file-variables-verify ()
+  ;; It would be nice to cache this somehow, which could be done in a
+  ;; buffer-local variable with markers for positions, but the trick
+  ;; is knowing when to expire the cache.
+  (let ((bounds
+         (save-excursion
+           (save-match-data
+             (goto-char (point-max))
+             (backward-page)
+             (and (re-search-forward "^\\(.*\\)Local Variables:" nil t)
+                  (list (match-string 1)
+                        (progn (end-of-line) (point))
+                        (and (search-forward
+                              (format "%sEnd:" (match-string 1))
+                              nil t)
+                             (progn (beginning-of-line)
+                                    (point)))))))))
+    (and bounds (caddr bounds)
+         (save-match-data
+           (string-match (format "^%s" (regexp-quote (car bounds)))
+                         (match-string 0)))
+         (> (match-beginning 0) (cadr bounds))
+         (< (match-end 0) (caddr bounds)))))
+
+(defun mmm-file-variables-find-back (bound)
+  (forward-sexp)
+  (if (> (point) bound)
+      nil
+    (looking-at "")))
+
+(mmm-add-classes
+ '((file-variables
+    :front ".+:"
+    :front-verify mmm-file-variables-verify
+    :back mmm-file-variables-find-back
+    :submode emacs-lisp-mode
+    :delimiter-mode nil
+    )))
+
+;;}}}
+;;{{{ JSP Pages
+
+(mmm-add-group 'jsp
+ `((jsp-comment
+    :submode text-mode
+    :face mmm-comment-submode-face
+    :front "<%--"
+    :back "--%>"
+    :insert ((?- jsp-comment nil @ "<%--" @ " " _ " " @ "--%>" @))
+    )
+   (jsp-code
+    :submode java
+    :match-face (("<%!" . mmm-declaration-submode-face)
+                 ("<%=" . mmm-output-submode-face)
+                 ("<%"  . mmm-code-submode-face))
+    :front "<%[!=]?"
+    :back "%>"
+    :match-name "jsp"
+    :insert ((?% jsp-code nil @ "<%" @ " " _ " " @ "%>" @)
+             (?! jsp-declaration nil @ "<%!" @ " " _ " " @ "%>" @)
+             (?= jsp-expression nil @ "<%=" @ " " _ " " @ "%>" @))
+    )
+   (jsp-directive
+    :submode text-mode
+    :face mmm-special-submode-face
+    :front "<%@"
+    :back "%>"
+    :insert ((?@ jsp-directive nil @ "<%@" @ " " _ " " @ "%>" @))
+    )))
+
+;;}}}
+;;{{{ SGML DTD
+
+;; Thanks to Yann Dirson <ydirson@fr.alcove.com> for writing and
+;; contributing this submode class.
+
+(mmm-add-classes
+ '((sgml-dtd
+    :submode dtd-mode
+    :face mmm-declaration-submode-face
+    :delimiter-mode nil
+    :front "<! *doctype[^>[]*\\["
+    :back "]>")))
+
+;;}}}
+;;{{{ PHP in HTML
+
+(mmm-add-group 'html-php
+ '((html-php-output
+    :submode php-mode
+    :face mmm-output-submode-face
+    :front "<\\?php *echo "
+    :back "\\?>"
+    :include-front t
+    :front-offset 5
+    :insert ((?e php-echo nil @ "<?php" @ " echo " _ " " @ "?>" @))
+    )
+   (html-php-code
+    :submode php-mode
+    :face mmm-code-submode-face
+    :front "<\\?\\(php\\)?"
+    :back "\\?>"
+    :insert ((?p php-section nil @ "<?php" @ " " _ " " @ "?>" @)
+             (?b php-block nil @ "<?php" @ "\n" _ "\n" @ "?>" @))
+    )))
+
+;;}}}
+
+;; NOT YET UPDATED
+;;{{{ HTML in PL/SQL;-COM-
+;-COM-
+;-COM-;; This one is the most complex example. In PL/SQL, HTML is generally
+;-COM-;; output as a (single quote delimited) string inside a call to htp.p or
+;-COM-;; its brethren. The problem is that there may be strings outside of
+;-COM-;; htp.p calls that should not be HTML, so we need to only look inside
+;-COM-;; these calls. The situation is complicated by PL/SQL's rule that two
+;-COM-;; sequential single quotes in a string mean to put a single quote
+;-COM-;; inside the string.
+;-COM-
+;-COM-;; These functions have not been thoroughly tested, and always search
+;-COM-;; the entire buffer, ignoring START and END.
+;-COM-
+;-COM-(defun mmm-html-in-plsql (start end)
+;-COM-  (save-match-data
+;-COM-    (let ((case-fold-search t))
+;-COM-      (and (re-search-forward "htp.p\\(\\|rn\\|rint\\)1?(" nil t)
+;-COM-           (mmm-html-in-plsql-in-htp
+;-COM-            ;; Find the end of the procedure call
+;-COM-            (save-excursion (forward-char -1) (forward-sexp) (point))
+;-COM-            start end)))))
+;-COM-
+;-COM-(defun mmm-html-in-plsql-in-htp (htp-end start end)
+;-COM-  (let (beg end)
+;-COM-    (or (and (re-search-forward "'" htp-end 'limit)
+;-COM-      (setf beg (match-end 0))
+;-COM-      ;; Find an odd number of 's to end the string.
+;-COM-      (do ((lgth 0 (length (match-string 0))))
+;-COM-          ((oddp lgth) t)
+;-COM-        (re-search-forward "'+" nil t))
+;-COM-      (setf end (1- (match-end 0)))
+;-COM-      (cons (cons beg end)
+;-COM-            (mmm-html-in-plsql-in-htp htp-end start end)))
+;-COM- ;; No more strings in the procedure call; look for another.
+;-COM- (and (eql (point) htp-end)
+;-COM-      (mmm-html-in-plsql start end)))))
+;-COM-
+;-COM-(add-to-list 'mmm-classes-alist
+;-COM-  '(htp-p (:function html-mode mmm-html-in-plsql)))
+;-COM-
+;;}}}
+
+(provide 'mmm-sample)
+
+;;; mmm-sample.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-univ.el b/.emacs.d/elisp/mmm/mmm-univ.el
new file mode 100644 (file)
index 0000000..ddd5276
--- /dev/null
@@ -0,0 +1,64 @@
+;;; mmm-univ.el --- The "Universal" Submode Class
+
+;; Copyright (C) 2000 by Free Software Foundation, Inc.
+
+;; Author: Michael Abraham Shulman <mas@kurukshetra.cjb.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file defines the "universal" submode class, the default value
+;; of `mmm-global-classes', which specifies a standard way to indicate
+;; that part of a buffer should be in a different mode--for example,
+;; in an email message.
+
+;;; Code:
+
+(require 'mmm-auto)
+(require 'mmm-vars)
+
+(defun mmm-univ-get-mode (string)
+  (string-match "[a-zA-Z-]+" string)
+  (setq string (match-string 0 string))
+  (let ((modestr (intern (if (string-match "mode\\'" string)
+                             string
+                           (concat string "-mode")))))
+    (or (mmm-ensure-modename modestr)
+        (signal 'mmm-no-matching-submode nil))))
+
+(mmm-add-classes
+ `((universal
+    :front "{%\\([a-zA-Z-]+\\)%}"
+    :back "{%/~1%}"
+    :insert ((?/ universal "Submode: " @ "{%" str "%}" @ "\n" _ "\n"
+                 @ "{%/" str "%}" @))
+    :match-submode mmm-univ-get-mode
+    :save-matches 1
+    )))
+
+(provide 'mmm-univ)
+
+\f
+;;; Local Variables:
+;;; mmm-global-classes: nil
+;;; End:
+
+;;; mmm-univ.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-utils.el b/.emacs.d/elisp/mmm/mmm-utils.el
new file mode 100644 (file)
index 0000000..2f391b7
--- /dev/null
@@ -0,0 +1,159 @@
+;;; mmm-utils.el --- Coding Utilities for MMM Mode
+
+;; Copyright (C) 2000 by Michael Abraham Shulman
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file provides a number of macros and other coding utilities
+;; for MMM Mode.
+
+;;; Code:
+
+(require 'cl)
+
+;;{{{ Valid Buffer
+
+;; We used to wrap almost everything in this, but I realized that
+;; only `mmm-mode-on' really needs it. Kept it as a macro, though,
+;; for modularity and in case we need it somewhere else.
+(defmacro mmm-valid-buffer (&rest body)
+  "Execute BODY if in a valid buffer for MMM Mode to be enabled.  This
+means not hidden, not a minibuffer, not in batch mode, and not in of
+`mmm-never-modes'."
+  `(unless (or (eq (aref (buffer-name) 0) ?\ )
+               (window-minibuffer-p (selected-window))
+               (memq major-mode mmm-never-modes)
+               noninteractive
+               mmm-in-temp-buffer)
+     ,@body))
+
+;;;(def-edebug-spec mmm-valid-buffer t)
+
+;;}}}
+;;{{{ Save Everything
+
+;; Never trust callback functions to preserve anything.
+(defmacro mmm-save-all (&rest body)
+  "Execute BODY forms, then restoring point, mark, current buffer,
+restrictions, and match data."
+  `(save-excursion
+     (save-restriction
+       (save-match-data
+         ,@body))))
+
+;;;(def-edebug-spec mmm-save-all t)
+
+;;}}}
+;;{{{ String Formatting
+
+(defun mmm-format-string (string arg-pairs)
+  "Format STRING by replacing arguments as specified by ARG-PAIRS.
+Each element of ARG-PAIRS is \(REGEXP . STR) where each STR is to be
+substituted for the corresponding REGEXP wherever it matches."
+  (let ((case-fold-search nil))
+    (save-match-data
+      (dolist (pair arg-pairs)
+        (while (string-match (car pair) string)
+          (setq string (replace-match
+                        (if (fboundp 'format-mode-line)
+                            (format-mode-line (cdr pair))
+                          (cdr pair))
+                        t t string))))))
+  string)
+
+(defun mmm-format-matches (string &optional on-string)
+  "Format STRING by matches from the current match data.
+Strings like ~N are replaced by the Nth subexpression from the last
+global match.  Does nothing if STRING is not a string.
+
+ON-STRING, if supplied, means to use the match data from a
+`string-match' on that string, rather than the global match data."
+  (when (stringp string)
+    (let ((old-data (match-data))
+          subexp)
+      (save-match-data
+        (while (string-match "~\\([0-9]\\)" string)
+          (setq subexp (string-to-number (match-string-no-properties 1 string))
+                string (replace-match
+                       (save-match-data
+                         (set-match-data old-data)
+                         (match-string-no-properties subexp on-string))
+                       t t string))))))
+  string)
+
+;;}}}
+;;{{{ Save Keywords
+
+(defmacro mmm-save-keyword (param)
+  "If the value of PARAM as a variable is non-nil, return the list
+\(:PARAM (symbol-value PARAM)), otherwise NIL. Best used only when it
+is important that nil values disappear."
+  `(if (and (boundp ',param) ,param)
+       (list (intern (concat ":" (symbol-name ',param))) ,param)
+     nil))
+
+(defmacro mmm-save-keywords (&rest params)
+  "Return a list saving the non-nil elements of PARAMS. E.g.
+\(let \(\(a 1) \(c 2)) \(mmm-save-keywords a b c))  ==>  \(:a 1 :c 2)
+Use of this macro can make code more readable when there are a lot of
+PARAMS, but less readable when there are only a few. Also best used
+only when it is important that nil values disappear."
+  `(append ,@(mapcar #'(lambda (param)
+                         (macroexpand `(mmm-save-keyword ,param)))
+                     params)))
+
+;;}}}
+;;{{{ Looking Back At
+
+(defun mmm-looking-back-at (regexp &optional bound)
+  "Return t if text before point matches REGEXP.
+Modifies the match data. If supplied, BOUND means not to look farther
+back that that many characters before point. Otherwise, it defaults to
+\(length REGEXP), which is good enough when REGEXP is a simple
+string."
+  (eq (point)
+      (save-excursion
+        (and (re-search-backward regexp
+               (- (point) (or bound (length regexp)))
+               t)
+             (match-end 0)))))
+
+;;}}}
+;;{{{ Markers
+
+;; Mostly for remembering interactively made regions
+(defun mmm-make-marker (pos beg-p sticky-p)
+  "Make, and return, a marker at POS that is or isn't sticky.
+BEG-P represents whether the marker delimits the beginning of a
+region \(or the end of it). STICKY-P is whether it should be sticky,
+i.e. whether text inserted at the marker should be inside the region."
+  (let ((mkr (set-marker (make-marker) pos)))
+    (set-marker-insertion-type mkr (if beg-p (not sticky-p) sticky-p))
+    mkr))
+
+;;}}}
+
+(provide 'mmm-utils)
+
+;;; mmm-utils.el ends here
diff --git a/.emacs.d/elisp/mmm/mmm-vars.el b/.emacs.d/elisp/mmm/mmm-vars.el
new file mode 100644 (file)
index 0000000..21d17d7
--- /dev/null
@@ -0,0 +1,1112 @@
+;;; mmm-vars.el --- Variables for MMM Mode
+
+;; Copyright (C) 2000, 2004 by Michael Abraham Shulman
+;; Copyright (C) 2012, 2013 by Dmitry Gutov
+
+;; Author: Michael Abraham Shulman <viritrilbia@users.sourceforge.net>
+
+;;{{{ GPL
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;}}}
+
+;;; Commentary:
+
+;; This file provides the definitions for the variables used by MMM
+;; Mode, as well as several functions to manipulate them. It also
+;; defines the errors that MMM Mode can signal.
+
+;;; Code:
+
+(require 'mmm-compat)
+(require 'cl)
+
+;; MISCELLANEOUS
+;;{{{ Shut up the Byte Compiler
+
+;; Otherwise it complains about undefined variables.
+(eval-when-compile
+  (defvar mmm-current-submode)
+  (defvar mmm-save-local-variables)
+  (defvar mmm-mode-string)
+  (defvar mmm-submode-mode-line-format)
+  (defvar mmm-mode-ext-classes-alist)
+  (defvar mmm-mode-prefix-key)
+  (defvar mmm-global-mode)
+  (defvar mmm-primary-mode)
+  (defvar mmm-classes-alist))
+
+;;}}}
+;;{{{ Error Conditions
+
+;; Most of these should be caught internally and never seen by the
+;; user, except when the user is creating submode regions manually.
+
+;; Signalled when we try to put a submode region inside one where it
+;; isn't meant to go.
+(put 'mmm-subregion-invalid-parent
+     'error-conditions
+     '(mmm-subregion-invalid-parent mmm-error error))
+(put 'mmm-subregion-invalid-parent
+     'error-message
+     "Invalid submode region parent")
+
+;; Signalled when we try to put a submode region overlapping others in
+;; an invalid way.
+(put 'mmm-subregion-invalid-placement
+     'error-conditions
+     '(mmm-subregion-invalid-placement mmm-error error))
+(put 'mmm-subregion-invalid-placement
+     'error-message
+     "Submode region placement invalid")
+
+;; Signalled when we try to apply a submode class that doesn't exist.
+(put 'mmm-invalid-submode-class
+     'error-conditions
+     '(mmm-invalid-submode-class mmm-error error))
+(put 'mmm-invalid-submode-class
+     'error-message
+     "Invalid or undefined submode class")
+
+;; Signalled by :match-submode functions when they are unable to
+;; resolve a submode.  This error should *always* be caught internally
+;; and never seen by the user.
+(put 'mmm-no-matching-submode
+     'error-conditions
+     '(mmm-no-matching-submode mmm-error error))
+(put 'mmm-no-matching-submode
+     'error-message
+     "Internal error: no matching submode.")
+
+;;}}}
+
+;; USER VARIABLES
+;;{{{ Customization Group
+
+(defgroup mmm nil
+  "Multiple Major Modes in one buffer."
+  :group 'tools)
+
+;;}}}
+;;{{{ Save Local Variables
+
+(defvar mmm-c-derived-modes
+  '(c-mode c++-mode objc-mode pike-mode java-mode jde-mode javascript-mode
+    php-mode))
+
+(defvar mmm-save-local-variables 
+  `(;; Don't use `function' (#') here!!  We're already inside `quote'!
+    major-mode
+    comment-start
+    comment-end
+    (comment-line-start-skip buffer (fortran-mode))
+    comment-start-skip
+    (comment-column buffer)
+    comment-indent-function
+    comment-line-break-function
+    sentence-end
+    ,@(when mmm-xemacs
+        '(mode-popup-menu
+          (((lambda () current-menubar) . set-buffer-menubar))
+          ))
+    (font-lock-keywords buffer)
+    font-lock-set-defaults
+    font-lock-major-mode
+    font-lock-keywords-only
+    font-lock-keywords-case-fold-search
+    font-lock-syntax-table
+    font-lock-mark-block-function       ; Override this?
+    font-lock-syntactic-keywords
+    parse-sexp-ignore-comments  ; Fixes indentation in PHP-mode?
+    ;; Can be different in different buffers
+    (c-basic-offset
+     buffer (c-mode c++-mode objc-mode pike-mode java-mode jde-mode))
+    ;; These are necessary for C syntax parsing
+    (c-class-key nil ,mmm-c-derived-modes)
+    (c-extra-toplevel-key nil ,mmm-c-derived-modes)
+    (c-inexpr-class-key nil ,mmm-c-derived-modes)
+    (c-conditional-key nil ,mmm-c-derived-modes)
+    semantic-bovinate-toplevel-override
+    semantic-toplevel-bovine-table
+    ;; Indentation style control variables.
+    ;; These have to be localized in Emacs: see `mmm-mode-on'.
+    ,@(mapcar
+       #'(lambda (var) (list var nil mmm-c-derived-modes))
+       '(c++-template-syntax-table
+        c-<-op-cont-regexp 
+        c->-op-cont-regexp 
+        c-after-suffixed-type-decl-key
+        c-after-suffixed-type-maybe-decl-key
+        c-any-class-key
+        c-asm-stmt-kwds
+        c-assignment-op-regexp
+        c-backslash-column
+        c-basic-offset
+        c-bitfield-kwds
+        c-block-comment-prefix
+        c-block-decls-with-vars
+         c-block-prefix-charset
+        c-block-stmt-1-key
+        c-block-stmt-1-kwds
+        c-block-stmt-2-key
+        c-block-stmt-2-kwds
+        c-brace-list-key 
+        c-cast-parens 
+        c-class-key
+        c-class-kwds
+        c-cleanup-list
+        c-colon-type-list-re 
+        c-comment-only-line-offset
+        c-comment-prefix-regexp
+        c-comment-start-regexp
+        c-cpp-defined-fns
+        c-current-comment-prefix
+        c-decl-block-key
+         c-decl-hangon-key
+         c-decl-prefix-or-start-re
+        c-decl-prefix-re
+        c-decl-spec-kwds
+         c-decl-start-kwds
+         c-decl-start-re
+        c-doc-comment-start-regexp
+        c-expr-kwds
+        c-file-offsets
+        c-file-style
+        c-hanging-braces-alist
+        c-hanging-colons-alist
+        c-hanging-comment-ender-p
+        c-hanging-comment-starter-p
+        c-hanging-semi\&comma-criteria
+        c-identifier-key 
+        c-identifier-last-sym-match
+        c-identifier-start 
+        c-identifier-syntax-modifications
+        c-identifier-syntax-table
+        c-in-comment-lc-prefix
+        c-indent-comment-alist
+        c-indent-comments-syntactically-p
+        c-indentation-style
+        c-inexpr-block-kwds
+        c-inexpr-class-kwds
+        c-keywords
+        c-keywords-obarray
+        c-keywords-regexp
+        c-known-type-key
+        c-label-key
+        c-label-kwds
+        c-label-kwds-regexp
+        c-label-minimum-indentation
+        c-lambda-kwds
+        c-literal-start-regexp 
+        c-macro-with-semi-re
+         c-nonlabel-token-key
+        c-nonsymbol-chars 
+        c-nonsymbol-token-regexp
+        c-not-decl-init-keywords
+        c-offsets-alist
+        c-opt-<>-arglist-start 
+        c-opt-<>-arglist-start-in-paren
+        c-opt-<>-sexp-key 
+        c-opt-access-key
+        c-opt-asm-stmt-key
+        c-opt-bitfield-key
+        c-opt-block-decls-with-vars-key
+        c-opt-block-stmt-key
+        c-opt-cpp-prefix 
+        c-opt-cpp-start 
+        c-opt-decl-spec-key
+        c-opt-friend-key
+        c-opt-identifier-concat-key
+        c-opt-inexpr-block-key
+        c-opt-inexpr-brace-list-key
+        c-opt-inexpr-class-key
+        c-opt-lambda-key
+        c-opt-method-key
+        c-opt-postfix-decl-spec-key
+        c-opt-type-component-key
+        c-opt-type-concat-key 
+        c-opt-type-modifier-key 
+        c-opt-type-suffix-key 
+        c-other-decl-block-key
+        c-other-decl-block-kwds
+        c-other-decl-kwds
+        c-overloadable-operators-regexp
+        c-paragraph-separate 
+        c-paragraph-start 
+        c-paren-stmt-key 
+        c-primary-expr-regexp 
+        c-primitive-type-key 
+        c-primitive-type-kwds
+        c-protection-kwds
+        c-recognize-<>-arglists 
+        c-recognize-knr-p
+        c-recognize-paren-inits 
+        c-recognize-typeless-decls
+        c-regular-keywords-regexp
+        c-simple-stmt-key 
+        c-simple-stmt-kwds
+        c-special-brace-lists
+        c-specifier-key 
+        c-specifier-kwds
+        c-stmt-delim-chars 
+        c-stmt-delim-chars-with-comma
+        c-symbol-key
+        c-symbol-start 
+        c-syntactic-eol
+        c-syntactic-ws-end 
+        c-syntactic-ws-start 
+        c-type-decl-prefix-key 
+        c-type-decl-suffix-key 
+        c-type-prefix-key 
+         c-prefix-spec-kwds-re
+         c-typedef-key
+        c-typedef-decl-key
+        comment-end 
+        comment-start 
+        comment-start-skip))
+    ,@(mapcar
+       (lambda (var) (list var nil '(js-mode)))
+       '(js--quick-match-re
+         js--quick-match-re-func))
+    ;; Skeleton insertion
+    skeleton-transformation
+    ;; Abbrev mode
+    abbrev-mode
+    local-abbrev-table
+    ;; And finally the syntax table and local map.
+    ((syntax-table . set-syntax-table) buffer)
+    ((current-local-map . use-local-map) buffer)
+    paragraph-separate
+    paragraph-start
+    (whitespace-active-style buffer)
+    (whitespace-display-table buffer)
+    (whitespace-display-table-was-local buffer)
+    (whitespace-font-lock buffer)
+    (whitespace-font-lock-mode buffer)
+    (whitespace-font-lock-keywords buffer)
+    (whitespace-mode buffer)
+    )
+  "Which local variables to save for major mode regions.
+Each element has the form \(VARIABLE [TYPE [MODES]]), causing VARIABLE
+to be saved for all major modes in the list MODES.  If MODES is t or
+absent, the variable is saved for all major modes.  MODES can also be
+a function of no arguments which returns non-nil whenever the variable
+should be saved.
+
+TYPE should be either the symbol `global', meaning to save the
+variable globally, the symbol `buffer', meaning to save it per buffer,
+or the symbol `region', meaning to save it for each submode region.
+If TYPE has any other value, such as nil, or is absent, the variable
+is saved globally.  If all optional parameters are omitted, the
+element may be simply VARIABLE instead of \(VARIABLE).
+
+It is possible for VARIABLE to be not a symbol but a cons cell of the
+form \(GETTER . SETTER), thus specifying special functions to set and
+get the value of the \"variable\".  This is used for objects like
+local maps, syntax tables, etc. which need to be installed in a
+special way.  GETTER should be a function of no arguments, and SETTER
+a function of one.  In this case, even if TYPE and MODES are omitted,
+the list cannot be flattened--it must be \((GETTER . SETTER)).
+\"Variables\" of this type cannot be seen with `mmm-get-saved-local'.
+
+A single variable may appear more than once in this list, with
+different modes and/or types.  If the same mode appears more than once
+for the same variable with different types, the behavior is undefined.
+Changing the value of this variable after MMM Mode has been activated
+in some buffer may produce unpredictable results.
+
+Globally saved variables are saved in the mmm-local-variables property
+of the mode symbol.  Buffer saved variables are saved in the alist
+`mmm-buffer-saved-locals'.  Region saved variables are saved in the
+mmm-local-variables property of the overlay.")
+
+(defvar mmm-buffer-saved-locals ()
+  "Stores saved local variables for this buffer, by mode.
+Each element looks like \(MODE \(VAR VALUE) ...).")
+(make-variable-buffer-local 'mmm-buffer-saved-locals)
+
+(defvar mmm-region-saved-locals-defaults ()
+  "Stores saved defaults for region-saved locals, by mode.
+Each element looks like \(MODE \(VAR VALUE) ...).  Used to initialize
+new submode regions.")
+(make-variable-buffer-local 'mmm-region-saved-locals-defaults)
+
+(defvar mmm-region-saved-locals-for-dominant ()
+  "Stores saved region locals for the dominant major mode.
+The dominant major mode is considered to be one region for purposes of
+saving region variables.  Region-saved variables for submode regions
+are saved as overlay properties.")
+(make-variable-buffer-local 'mmm-region-saved-locals-for-dominant)
+
+;;}}}
+;;{{{ Submode Faces
+
+(defgroup mmm-faces nil
+  "Faces and coloring for submode regions.
+In general, only background colors should be set, to avoid interfering
+with font-lock."
+  :group 'mmm)
+
+(defcustom mmm-submode-decoration-level 1
+  "*Amount of coloring to use in submode regions.
+Should be either 0, 1, or 2, representing None, Low, and High amounts
+of coloring respectively.
+* None (0) means to use no coloring at all.
+* Low (1) means to use `mmm-default-submode-face' for all submode
+  regions \(except for \"non-submode\" regions, i.e. those that are of
+  the primary mode) and `mmm-delimiter-face' for region delimiters.
+* High (2) means to use different faces for different types of submode
+  regions and delimiters, such as initialization code, expressions that
+  are output, declarations, and so on, as specified by the submode
+  class.  The default faces are still used for regions that do not
+  specify a face."
+  :group 'mmm-faces
+  :type '(choice (const :tag "None" 0)
+                 (const :tag "Low" 1)
+                 (const :tag "High" 2)))
+
+(defface mmm-init-submode-face '((((background light)) (:background "Pink"))
+                                (((background dark)) (:background "MediumOrchid"))
+                                (t (:background "Pink")))
+  "Face used for submodes containing initialization code."
+  :group 'mmm-faces)
+
+(defface mmm-cleanup-submode-face '((((background light)) (:background "Wheat"))
+                                   (((background dark)) (:background "peru"))
+                                   (t (:background "Wheat")))
+  "Face used for submodes containing cleanup code."
+  :group 'mmm-faces)
+
+(defface mmm-declaration-submode-face '((((background light)) (:background "Aquamarine"))
+                                       (((background dark)) (:background "DarkTurquoise"))
+                                       (t (:background "Aquamarine")))
+  "Face used for submodes containing declarations."
+  :group 'mmm-faces)
+
+(defface mmm-comment-submode-face '((((background light)) (:background "SkyBlue"))
+                                   (((background dark)) (:background "SteelBlue"))
+                                   (t (:background "SkyBlue")))
+  "Face used for submodes containing comments and documentation."
+  :group 'mmm-faces)
+
+(defface mmm-output-submode-face '((((background light)) (:background "Plum"))
+                                   (((background dark)) (:background "MediumVioletRed"))
+                                   (t (:background "Plum")))
+  "Face used for submodes containing expression that are output."
+  :group 'mmm-faces)
+
+(defface mmm-special-submode-face '((((background light)) (:background "MediumSpringGreen"))
+                                   (((background dark)) (:background "ForestGreen"))
+                                   (t (:background "MediumSpringGreen")))
+  "Face used for special submodes not fitting any other category."
+  :group 'mmm-faces)
+
+(defface mmm-code-submode-face '((((background light)) (:background "LightGray"))
+                                (((background dark)) (:background "DimGray"))
+                                (t (:background "LightGray")))
+  "Face used for submodes containing ordinary code."
+  :group 'mmm-faces)
+
+(defface mmm-default-submode-face '((((background light)) (:background "gray85"))
+                                   (((background dark)) (:background "gray20"))
+                                   (t (:background "gray85")))
+  "Face used for all submodes at decoration level 1.
+Also used at decoration level 2 for submodes not specifying a type."
+  :group 'mmm-faces)
+
+(defface mmm-delimiter-face nil
+  "Face used to mark submode delimiters."
+  :group 'mmm-faces)
+
+;;}}}
+;;{{{ Mode Line Format
+
+(defcustom mmm-mode-string " MMM"
+  "*String to display in mode line as MMM minor mode indicator."
+  :group 'mmm
+  :type 'string)
+
+(defcustom mmm-submode-mode-line-format "~M[~m]"
+  "*Format of the mode-line display when point is in a submode region.
+
+~M is replaced by the name of the primary major mode \(which may be
+replaced by a combined-mode function, see the info documentation).
+
+~m is replaced by the submode region overlay's `display-name'
+property, if it has one.  Otherwise it is replaced by the mode name of
+the submode region.
+
+If `mmm-primary-mode-display-name' is non-nil, then this variable is
+used even when point is not in a submode region \(i.e. it is in a
+primary mode region), with ~m being replaced by the value of that
+variable."
+  :group 'mmm
+  :type 'string)