emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 8ed11ab 262/433: Added delimiter regions and region name m


From: Dmitry Gutov
Subject: [elpa] master 8ed11ab 262/433: Added delimiter regions and region name matching.
Date: Thu, 15 Mar 2018 19:44:17 -0400 (EDT)

branch: master
commit 8ed11ab9449c57833e63f32b0e87449f6944f6a8
Author: viritrilbia <viritrilbia>
Commit: viritrilbia <viritrilbia>

    Added delimiter regions and region name matching.
---
 ChangeLog     |  36 +++++
 NEWS          |  22 ++-
 mmm-class.el  | 113 +++++++++-----
 mmm-cmds.el   | 115 +++++++++-----
 mmm-compat.el |   8 +-
 mmm-mason.el  |  13 +-
 mmm-mode.el   |   9 +-
 mmm-noweb.el  |   8 +-
 mmm-region.el | 485 +++++++++++++++++++++++++++++++++++++---------------------
 mmm-sample.el |  20 ++-
 mmm-utils.el  |  22 +--
 mmm-vars.el   | 130 +++++++++++-----
 mmm.texinfo   | 166 ++++++++++++++++----
 13 files changed, 803 insertions(+), 344 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cd1fca3..8195b78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2003-03-09  Michael A. Shulman  <address@hidden>
+
+       * mmm-vars.el (mmm-set-mode-line): Added support for "buffer mode"
+       display name.
+
+       * mmm-cmds.el (mmm-insert-by-key): Match and calculate names, and
+       store front and back positions for delimiter overlays.
+
+       * mmm-mason.el: Added match-name parameter.
+
+       * mmm-sample.el: Added delimiter-mode and match-name parameters.
+
+       * mmm-region.el: Restructured current-overlay functions.
+       (mmm-make-region, mmm-make-overlay, mmm-get-face): Create
+       delimiter overlays with modes and faces, add display-name and name
+       parameters, and handle evaporation intelligently.
+       (mmm-front-start, mmm-back-end, etc.): Use delimiter overlays.
+       (mmm-update-current-submode): Delete overlays whose front
+       delimiter has evaporated.
+
+       * mmm-class.el (mmm-ify, mmm-match-region): Added matching for
+       region names.
+
+       * mmm-vars.el (mmm-delimiter-mode, mmm-delimiter-face): Added.
+
+2003-03-08  Michael A. Shulman  <address@hidden>
+
+       * mmm-region.el (mmm-clear-overlays): Fixed bug so turning mmm
+       mode off now restores primary mode correctly.
+
 2003-03-03  Michael A. Shulman  <address@hidden>
 
        * mmm-noweb.el (mmm-noweb-bind-keys): Implemented a "local to
@@ -47,6 +77,12 @@
 
        * mmm-noweb.el: Add support for noweb.
 
+       * mmm-class.el (mmm-ify, mmm-make-region): Add support for setting
+       the NAME property on regions.
+
+       * mmm-cmds.el (mmm-insert-by-key): Add support for setting the
+       NAME property on inserts.
+
 2002-11-11  Alan Shutko  <address@hidden>
 
        * .cvsignore: Add semantic.cache.
diff --git a/NEWS b/NEWS
index fc48736..f6ce1ea 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,27 @@ MMM Mode NEWS -- history of user-visible changes.  
-*-outline-*-
 Copyright (C) 2000 Michael Abraham Shulman
 See the file COPYING for copying conditions.
 
-Please send MMM Mode bug reports to address@hidden
+Please submit bug reports at http://sourceforge.net/projects/mmm-mode/
+
+* Changes in MMM Mode 0.4.8
+
+** Improved Syntax Handling
+
+(Not actually added yet, but it will be by the time 0.4.8 is released)
+
+** Delimiter Regions
+
+The delimiters which mark off submode regions now have their own
+overlays.  They can be highlighted if you so desire using appropriate
+class arguments and/or the variable mmm-delimiter-face.  They are also
+in an appropriate major mode, or non-mode as the case may be.
+
+** New Submode Classes
+
+Many thanks to Joe Kelsey for writing a very intelligent class for
+editing Noweb files, and to Alan Shutko for one for CWeb files.  We
+also have a mode for SGML DTD definitions from Yann Dirson.
+
 
 * Changes in MMM Mode 0.4.7
 
diff --git a/mmm-class.el b/mmm-class.el
index 7e6638c..82397b9 100644
--- a/mmm-class.el
+++ b/mmm-class.el
@@ -2,8 +2,8 @@
 
 ;; Copyright (C) 2000 by Michael Abraham Shulman
 
-;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-class.el,v 1.17 2001/07/05 06:15:11 viritrilbia Exp $
+;; Author: Michael Abraham Shulman <address@hidden>
+;; Version: $Id: mmm-class.el,v 1.18 2003/03/09 17:04:03 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -36,6 +36,7 @@
 (require 'mmm-vars)
 (require 'mmm-region)
 
+;;; CLASS SPECIFICATIONS
 ;;{{{ Get Class Specifications
 
 (defun mmm-get-class-spec (class)
@@ -81,7 +82,10 @@ none is specified by CLASS."
   (unless (eq class t)
     (apply #'mmm-ify :start start :stop stop
            (append (mmm-get-class-spec class)
-                  (list :face face)))))
+                  (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)
@@ -109,25 +113,32 @@ 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-current-submode)
+  (mmm-update-submode-region)
   (mmm-refontify-maybe start stop))
 
 ;;}}}
+
+;;; BUFFER SCANNING
 ;;{{{ Scan for Regions
 
 (defun* mmm-ify
-    (&rest all &key classes handler submode face
+    (&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 0) (back-delim 0)
+          (delimiter-mode mmm-delimiter-mode)
+          front-face back-face
            front-verify back-verify
-           front-form back-form creation-hook
-           match-submode match-face
-          (front-match 0)
-          (back-match 0)
+           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
@@ -139,11 +150,12 @@ the rest of the arguments are for an actual class being 
applied. See
   ;; 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-match 0
-                  :back-match 0)))
+             (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
@@ -158,23 +170,31 @@ the rest of the arguments are for an actual class being 
applied. See
    (t
     (mmm-save-all
      (goto-char start)
-     (loop for (beg end matched-front matched-back
-                    matched-submode matched-face
+     (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 (and end          ; match-submode, if present, succeeded.
-                   (< beg end)) ; empty overlays evaporate immediately
+           if end             ; match-submode, if present, succeeded.
            do
            (condition-case nil
                (progn
-                 (apply #'mmm-make-region (or matched-submode submode)
-                        beg end :front matched-front :back matched-back
-                        :face (or matched-face face) all)
+                 (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-invalid-parent (goto-char invalid-resume)))
+             (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)
@@ -188,17 +208,21 @@ the rest of the arguments are for an actual class being 
applied. See
           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-FORM BACK-FORM SUBMODE FACE 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."
+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 back-match))
+    (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
@@ -208,9 +232,15 @@ region is invalid, and OK-RESUME if the region is valid."
                            (mmm-no-matching-submode
                             (return-from
                                 mmm-match-region
-                              (values beg nil nil nil nil nil
+                              (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)))
@@ -221,22 +251,27 @@ region is invalid, and OK-RESUME if the region is valid."
                    (mmm-format-matches back)
                  back)
                beg stop back-verify)
-          (let* ((end (mmm-match->point (not include-back) back-offset 
-                                       front-match back-match))
+          (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-form back-form submode face
+            (values beg end front-pos back-pos front-form back-form
+                   submode face name
                     invalid-resume ok-resume)))))))
 
-(defun mmm-match->point (beginp offset front-match back-match)
+(defun mmm-match->point (beginp offset match)
   "Find a point of starting or stopping from the match data.  If
-BEGINP, start at \(match-beginning FRONT-MATCH), else \(match-end
-BACK-MATCH), and move OFFSET.  Handles all values for OFFSET--see
-`mmm-classes-alist'."
+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 front-match) (match-end 
back-match)))
+    (goto-char (if beginp
+                  (match-beginning front-match)
+                (match-end back-match)))
     (dolist (spec (if (listp offset) offset (list offset)))
       (if (numberp spec)
           (forward-char (or spec 0))
diff --git a/mmm-cmds.el b/mmm-cmds.el
index 06939a5..cbe677c 100644
--- a/mmm-cmds.el
+++ b/mmm-cmds.el
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2000 by Michael Abraham Shulman
 
 ;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-cmds.el,v 1.16 2003/03/03 23:08:22 viritrilbia Exp $
+;; Version: $Id: mmm-cmds.el,v 1.17 2003/03/09 17:04:03 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -35,6 +35,7 @@
 (require 'mmm-vars)
 (require 'mmm-class)
 
+;; APPLYING CLASSES
 ;;{{{ Applying Predefined Classes
 
 (defun mmm-ify-by-class (class)
@@ -89,6 +90,8 @@ nNumber of matched substrings to save: ")
   (mmm-enable-font-lock submode))
 
 ;;}}}
+
+;; EDITING WITH REGIONS
 ;;{{{ Re-parsing Areas
 
 (defun mmm-parse-buffer ()
@@ -138,6 +141,25 @@ delimiter auto-insertion that MMM Mode provides. See, for 
example,
             (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.
@@ -158,25 +180,6 @@ delimiter auto-insertion that MMM Mode provides. See, for 
example,
   (mmm-clear-overlays))
 
 ;;}}}
-;;{{{ 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)))))
-
-;;}}}
 ;;{{{ End Current Region
 
 (defun* mmm-end-current-region (&optional arg)
@@ -212,6 +215,22 @@ entire job of this function."
                            (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
@@ -256,26 +275,52 @@ MODIFIERS, the dotted list becomes simply BASIC-KEY."
         (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))
-                 (front-str (buffer-substring front beg))
-                 (back-str (buffer-substring end back))
-                 (submode
-                  (if match-submode
-                      (mmm-save-all (funcall match-submode front-str))
-                    (plist-get class :submode)))
-                 (match-face (plist-get class :match-face))
-                 (face
+          (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-str)))
+                          (funcall match-face front-form)))
                         (match-face
-                         (cdr (assoc front-str match-face)))
+                         (cdr (assoc front-form match-face)))
                         (t
-                         (plist-get class :face)))))
-            (setq submode (mmm-modename->function submode))
+                         (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 :front front-str :back back-str
-             :face face
+             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
diff --git a/mmm-compat.el b/mmm-compat.el
index 29eb455..0794d8b 100644
--- a/mmm-compat.el
+++ b/mmm-compat.el
@@ -2,8 +2,8 @@
 
 ;; Copyright (C) 2000 by Michael Abraham Shulman
 
-;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-compat.el,v 1.8 2000/09/16 00:12:33 mas Exp $
+;; Author: Michael Abraham Shulman <address@hidden>
+;; Version: $Id: mmm-compat.el,v 1.9 2003/03/09 17:04:03 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -28,8 +28,8 @@
 
 ;; This file provides a number of hacks that are necessary for MMM
 ;; Mode to function in different Emacsen.  MMM Mode is designed for
-;; Emacs 20, but these hacks usually enable it to work almost
-;; perfectly in Emacs 19 and XEmacs 20 or 21.
+;; FSF Emacs 20 and 21, but these hacks usually enable it to work
+;; almost perfectly in Emacs 19 and XEmacs 20 or 21.
 
 ;;; Code:
 
diff --git a/mmm-mason.el b/mmm-mason.el
index 1e4ac81..5d76c90 100644
--- a/mmm-mason.el
+++ b/mmm-mason.el
@@ -2,8 +2,8 @@
 
 ;; Copyright (C) 2000 by Michael Abraham Shulman
 
-;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-mason.el,v 1.12 2001/02/13 11:27:44 alanshutko Exp $
+;; Author: Michael Abraham Shulman <address@hidden>
+;; Version: $Id: mmm-mason.el,v 1.13 2003/03/09 17:04:03 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -96,6 +96,8 @@ Saves the name of the tag matched.")
     :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)
@@ -161,6 +163,13 @@ Saves the name of the tag matched.")
       (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)
 
diff --git a/mmm-mode.el b/mmm-mode.el
index 7ae1289..f6b533f 100644
--- a/mmm-mode.el
+++ b/mmm-mode.el
@@ -8,7 +8,7 @@
 ;; Keywords: convenience, faces, languages, tools
 ;; Version: 0.4.7
 
-;; Revision: $Id: mmm-mode.el,v 1.15 2003/03/03 23:09:43 viritrilbia Exp $
+;; Revision: $Id: mmm-mode.el,v 1.16 2003/03/09 17:04:03 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -172,7 +172,6 @@ available through M-x customize under Programming | Tools | 
Mmm."
         ;; turned on. Should we delete all previously made submode
         ;; regions when we find an invalid one?
         (message "%s" (error-message-string err))))
-     (mmm-update-current-submode)
      (run-hooks 'mmm-mode-hook)
      (mmm-run-major-hook))))
 
@@ -195,7 +194,11 @@ available through M-x customize under Programming | Tools 
| Mmm."
           (get mmm-primary-mode 'mmm-beginning-of-syntax-function))
     (mmm-update-font-lock-buffer)
     (mmm-refontify-maybe)
-    (setq mmm-mode nil)))
+    (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
diff --git a/mmm-noweb.el b/mmm-noweb.el
index e9be4ca..f860dc1 100644
--- a/mmm-noweb.el
+++ b/mmm-noweb.el
@@ -72,13 +72,13 @@ If the next 100 characters of the buffer contain a string 
of the form
 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 +\\(\\w+\\)\\s +-\\*-" (+ (point) 120) t)
+  (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)
-           (signal 'mmm-no-matching-submode nil)))
+           mmm-noweb-code-mode))
     mmm-noweb-code-mode))
 
 (defun mmm-noweb-quote (form)
@@ -116,7 +116,7 @@ return the value of `mmm-noweb-code-mode'."
     :match-submode mmm-noweb-chunk
     :case-fold-search nil
     :front "^<<\\(.*\\)>>="
-    :name-match "~1"
+    :match-name "~1"
     :save-name 1
     :front-offset (end-of-line 1)
     :back "address@hidden( \\|$\\|\\( %def .*$\\)\\)"
@@ -128,7 +128,7 @@ return the value of `mmm-noweb-code-mode'."
     :match-submode mmm-noweb-quote
     :face mmm-special-submode-face
     :front "\\[\\["
-    :name-match mmm-noweb-quote-name
+;    :name-match mmm-noweb-quote-name
     :back "\\]\\]"
     :insert ((?q noweb-quote nil @ "[[" @ _ @ "]]" @))
     )
diff --git a/mmm-region.el b/mmm-region.el
index 8defd11..7c1b87d 100644
--- a/mmm-region.el
+++ b/mmm-region.el
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2000 by Michael Abraham Shulman
 
 ;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-region.el,v 1.35 2003/03/02 20:29:27 viritrilbia Exp $
+;; Version: $Id: mmm-region.el,v 1.36 2003/03/09 17:04:03 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -51,54 +51,98 @@
 ;; end-stickiness to determine whether an endpoint is within an
 ;; extent. Here we want to act like XEmacs does.
 
-(defun mmm-overlay-at (&optional pos type)
+(defsubst mmm-overlay-at (&optional pos type)
   "Return the highest-priority MMM Mode overlay at POS.
-TYPE is passed on to `mmm-overlays-at', which see."
-  (car (mmm-overlays-at (or pos (point)) type)))
+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.
-TYPE should be nil, `beg', `end', `none', or `all'. If `none', return
-only overlays strictly including POS. If nil, return overlays starting
-at POS only if they are beg-sticky, and those ending at POS only if
-they are end-sticky. If `beg', return all overlays starting at POS but
-none ending at POS, if `end', return all overlays ending at POS
-but none starting at POS, and if `all', return both."
+See `mmm-included-p' for the values of TYPE."
   (or pos (setq pos (point)))
-  (remove-if-not #'(lambda (ovl)
-                     (mmm-included-p ovl pos type))
-                 (mmm-overlays-in (1- pos) (1+ pos))))
-
-(defun mmm-included-p (ovl pos type)
-  (cond ((eql (overlay-start ovl) pos)
-         (case type
-           ((none end) nil)
-           ((nil) (overlay-get ovl 'beg-sticky))
-           ((beg all) t)))
-        ((eql (overlay-end ovl) pos)
-         (case type
-           ((none beg) nil)
-           ((nil) (overlay-get ovl 'end-sticky))
-           ((end all) t)))
-        (t t)))
-
-(defun mmm-overlays-in (start stop &optional strict delim)
-  "Return the MMM overlays in START to STOP, in decreasing priority.
-If STRICT is non-nil, include only those overlays which are entirely
-contained in the region.  In this case, if DELIM is non-nil, the
-region delimiters, if any, must also be included."
   (mmm-sort-overlays
-   (remove-if-not #'(lambda (ovl)
-                      (and (overlay-get ovl 'mmm)
-                           (or (not strict)
-                               (>= stop (if delim
-                                            (mmm-back-end ovl)
-                                          (overlay-end ovl)))
-                               (<= start (if delim
-                                             (mmm-front-start ovl)
-                                           (overlay-start ovl))))))
-                  (overlays-in (max start (point-min))
-                               (min stop (point-max))))))
+   (remove-if-not
+    #'(lambda (ovl)
+       (and (overlay-get ovl 'mmm)
+            (mmm-included-p ovl pos type)))
+    (overlays-in (1- pos) (1+ pos)))))
+
+(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."
@@ -130,9 +174,17 @@ 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.
-Return non-nil if the current region changed."
-  (let ((ovl (mmm-overlay-at (or pos (point)))))
+  "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
       (setq mmm-previous-overlay mmm-current-overlay
@@ -155,8 +207,8 @@ region of that mode is present at POS, or nil if none."
 
 (defun mmm-submode-at (&optional pos type)
   "Return the submode at POS \(or point), or NIL if none.
-TYPE is passed on to `mmm-overlays-at', which see."
-  (let ((ovl (mmm-overlay-at (or pos (point)) type)))
+See `mmm-included-p' for values of TYPE."
+  (let ((ovl (mmm-overlay-at pos type)))
     (if ovl (overlay-get ovl 'mmm-mode))))
 
 ;;}}}
@@ -164,64 +216,59 @@ TYPE is passed on to `mmm-overlays-at', which see."
 
 (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
-overlay and one argument being the overlay. The function should return
-non-nil if the front delimiter matches correctly, and set the match
-data appropriately."
-  (let ((front (overlay-get ovl 'front)))
-    (save-excursion
-      (goto-char (overlay-start ovl))
-      (if (stringp front)
-          ;; It's a regexp
-          (mmm-looking-back-at front)
-        ;; It's a function
-        (funcall front ovl)))))
+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 end of the overlay
-and one argument being the overlay. The function should return non-nil
-if the back delimiter matches correctly, and set the match data
-appropriately."
-  (let ((back (overlay-get ovl 'back)))
-    (save-excursion
-      (goto-char (overlay-end ovl))
-      (if (stringp back)
-          ;; It's a regexp
-          (looking-at back)
-        (funcall back ovl)))))
+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.
-If OVL is not front-bounded correctly, return its start position."
-  (save-match-data
-    (if (mmm-match-front ovl)
-        (match-beginning 0)
+  "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.
-If OVL is not back-bounded correctly, return its end position."
-  (save-match-data
-    (if (mmm-match-back ovl)
-        (match-end 0)
+  "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))))
 
 ;;}}}
-;;{{{ 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 (or pos (point)))))
-    (when ovl
-      (narrow-to-region (overlay-start ovl) (overlay-end ovl)))))
-
-;;}}}
 
 ;; CREATION & DELETION
 ;;{{{ Make Submode Regions
@@ -234,16 +281,14 @@ 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 (remove-if-not
-                   #'(lambda (ovl)
-                       (or (> (overlay-start ovl) beg)
-                           (< (overlay-end ovl)   end)))
-                   (mmm-overlays-in beg end))))
+  (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)))
+  (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
@@ -256,69 +301,164 @@ Signals errors, returns `t' if no error."
   t)
 
 (defun* mmm-make-region
-    (submode beg end &rest rest &key (front "") (back "")
-             (beg-sticky t) (end-sticky t) face creation-hook
-             ;start stop submode insert private front-offset back-offset 
front-match back-match
-             &allow-other-keys
+    (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 in FACE.
-FRONT and BACK are regexps or functions to match the correct
-delimiters--see `mmm-match-front' and `mmm-match-back'.  BEG-STICKY
-and END-STICKY determine whether the front and back of the region,
-respectively, are sticky with respect to new insertion.  CREATION-HOOK
-should be a function to run after the region is created, with point at
-the start of the new region.  All other keyword arguments are stored
-as properties of the overlay, un-keyword-ified."
+  "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)
-  (setq rest (append rest (list :front front :back back :beg-sticky
-                                beg-sticky :end-sticky end-sticky)))
   (mmm-mode-on)
-  (setq submode (mmm-modename->function submode))
   (when submode
     (mmm-update-mode-info submode))
-  ;; Conditionally sticky overlays are by default sticky. Then the
-  ;; insert-in-front and -behind functions fix them.
-  (let ((ovl (make-overlay beg end nil (not beg-sticky) end-sticky)))
-    ;; Put our properties on the overlay
-    (dolist (prop '(front back beg-sticky end-sticky))
-      (overlay-put ovl prop (symbol-value prop)))
-    (overlay-put ovl 'priority (length (mmm-overlays-at beg)))
-    ;; Put anything else the caller wants on the overlay
-    (loop for (var val) on rest by #'cddr
-          do (overlay-put ovl (intern (substring (symbol-name var) 1)) val))
-    (mapcar #'(lambda (pair) (overlay-put ovl (car pair) (cadr pair)))
-            `((mmm t)           ; Mark our overlays
-              (mmm-mode ,submode)
-              (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)))))
-              ;; These have special meaning to Emacs
-              (,mmm-evaporate-property t)
-              (face ,(mmm-get-face face submode))
-              ))
-    (save-excursion
-      (goto-char (overlay-start ovl))
-      (mmm-set-current-submode submode)
-      (mmm-set-local-variables submode)
-      (mmm-run-submode-hook submode)
-      (when creation-hook
-        (funcall creation-hook))
-      (mmm-save-changed-local-variables ovl 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
+     (goto-char (overlay-start region-ovl))
+     (mmm-set-current-submode submode)
+     (mmm-set-local-variables submode)
+     (mmm-run-submode-hook submode)
+     (when creation-hook
+       (funcall creation-hook))
+     (mmm-save-changed-local-variables region-ovl submode))
     (setq mmm-previous-submode submode
-          mmm-previous-overlay ovl)
+          mmm-previous-overlay region-ovl)
     (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)
-  (case mmm-submode-decoration-level
-    ((0) nil)
-    ((1) (when submode
-           'mmm-default-submode-face))
-    ((2) (or face
-             (when submode
-               'mmm-default-submode-face)))))
+(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
@@ -326,13 +466,15 @@ as properties of the overlay, un-keyword-ified."
 ;; See also `mmm-clear-current-region'.
 
 (defun mmm-clear-overlays (&optional start stop strict)
-  "Clears all MMM overlays between START and STOP.
-If STRICT, only clear those strictly included, rather than partially."
+  "Clears all MMM overlays overlapping START and STOP.
+If STRICT, only clear those entirely included in that region."
   (mapcar #'delete-overlay
-        (mmm-overlays-in (or start (point-min))
-                         (or stop (point-max))
-                         strict))
-  (mmm-update-current-submode))
+         (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))
 
 ;;}}}
 
@@ -550,11 +692,11 @@ region and mode for the previous position."
   (when mmm-font-lock-available-p
     (if (some #'(lambda (mode)
                   (get mode 'mmm-font-lock-mode))
-              (remove-duplicates
-               (cons mmm-primary-mode
-                     (mapcar #'(lambda (ovl)
-                                 (overlay-get ovl 'mmm-mode))
-                             (mmm-overlays-in (point-min) (point-max))))))
+             (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))))
 
@@ -573,18 +715,15 @@ region and mode for the previous position."
 ;;; 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 &optional strict delim)
+(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.  The
-optional parameters STRICT and DELIM are passed to `mmm-overlays-in',
-which see."
+The list is sorted in order of increasing buffer position."
   (sort (remove-duplicates
          (list* start stop
                 (mapcan #'(lambda (ovl)
                             `(,(overlay-start ovl)
                               ,(overlay-end ovl)))
-                        (mmm-overlays-in start stop strict delim))))
-
+                        (mmm-overlays-overlapping start stop))))
         #'<))
 
 (defun mmm-regions-in (start stop)
@@ -596,7 +735,7 @@ union covers the region from START to STOP, including 
delimiters."
                           (list (or (mmm-submode-at (car pos-list) 'beg)
                                     mmm-primary-mode)
                                 (car pos-list) (cadr pos-list))))
-                  (mmm-submode-changes-in start stop t t))))
+                  (mmm-submode-changes-in start stop))))
     (setcdr (last regions 2) nil)
     regions))
 
diff --git a/mmm-sample.el b/mmm-sample.el
index 271113a..4defcca 100644
--- a/mmm-sample.el
+++ b/mmm-sample.el
@@ -1,9 +1,9 @@
 ;;; mmm-sample.el --- Sample MMM submode classes
 
-;; Copyright (C) 2000 by Michael Abraham Shulman
+;; Copyright (C) 2003 by Michael Abraham Shulman
 
-;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-sample.el,v 1.24 2003/03/02 20:24:37 viritrilbia Exp $
+;; Author: Michael Abraham Shulman <address@hidden>
+;; Version: $Id: mmm-sample.el,v 1.25 2003/03/09 17:04:04 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -42,6 +42,7 @@
  '((embedded-css
     :submode css
     :face mmm-declaration-submode-face
+    :delimiter-mode nil
     :front "<style[^>]*>"
     :back "</style>")))
 
@@ -56,7 +57,8 @@
  '((js-tag
     :submode javascript
     :face mmm-code-submode-face
-    :front 
"<script\[^>\]*\\(language=\"javascript\"\\|\\(type=\"text/javascript\"\\)\[^>\]*>"
+    :delimiter-mode nil
+    :front 
"<script\[^>\]*\\(language=\"javascript\"\\|type=\"text/javascript\"\\)\[^>\]*>"
     :back"</script>"
     :insert ((?j js-tag nil @ "<script language=\"JavaScript\">"
                  @ "\n" _ "\n" @ "</script>" @))
@@ -64,6 +66,7 @@
    (js-inline
     :submode javascript
     :face mmm-code-submode-face
+    :delimiter-mode nil
     :front "on\\w+=\""
     :back "\"")))
 
@@ -72,7 +75,7 @@
 
 ;; 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
+;; 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
@@ -129,6 +132,7 @@ and MODE is a major mode function symbol.")
     :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" @))
@@ -144,6 +148,7 @@ and MODE is a major mode function symbol.")
     :front "\\[\\([-\\+!\\*\\$]\\)"
     :back "~1\\]"
     :save-matches 1
+    :match-name "embperl"
     :match-face (("[+" . mmm-output-submode-face)
                  ("[-" . mmm-code-submode-face)
                  ("[!" . mmm-init-submode-face)
@@ -176,6 +181,7 @@ and MODE is a major mode function symbol.")
     :face mmm-code-submode-face
     :front "<:"
     :back "_?:>"
+    :match-name "eperl"
     :insert ((?p eperl-code nil @ "<:" @ " " _ " " @ ":>" @)
              (?: eperl-code ?p . nil)
              (?_ eperl-code_ nil @ "<:" @ " " _ " " @ "_:>" @)))
@@ -229,6 +235,7 @@ and MODE is a major mode function symbol.")
     :front-verify mmm-file-variables-verify
     :back mmm-file-variables-find-back
     :submode emacs-lisp-mode
+    :delimiter-mode nil
     )))
 
 ;;}}}
@@ -249,6 +256,7 @@ and MODE is a major mode function symbol.")
                  ("<%"  . mmm-code-submode-face))
     :front "<%[!=]?"
     :back "%>"
+    :match-name "jsp"
     :insert ((?% jsp-code nil @ "<%" @ " " _ " " @ "%>" @)
              (?! jsp-declaration nil @ "<%!" @ " " _ " " @ "%>" @)
              (?= jsp-expression nil @ "<%=" @ " " _ " " @ "%>" @))
@@ -271,6 +279,7 @@ and MODE is a major mode function symbol.")
  '((sgml-dtd
     :submode dtd-mode
     :face mmm-declaration-submode-face
+    :delimiter-mode nil
     :front "<! *doctype[^>[]*\\["
     :back "]>")))
 
@@ -280,6 +289,7 @@ and MODE is a major mode function symbol.")
 (mmm-add-classes
  '((httpd-conf-perl
     :submode perl
+    :delimiter-mode nil
     :front "<Perl>"
     :back "</Perl>")))
 
diff --git a/mmm-utils.el b/mmm-utils.el
index 772ec70..7f2eb4b 100644
--- a/mmm-utils.el
+++ b/mmm-utils.el
@@ -2,8 +2,8 @@
 
 ;; Copyright (C) 2000 by Michael Abraham Shulman
 
-;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-utils.el,v 1.13 2003/03/02 20:26:33 viritrilbia Exp $
+;; Author: Michael Abraham Shulman <address@hidden>
+;; Version: $Id: mmm-utils.el,v 1.14 2003/03/09 17:04:04 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -81,22 +81,24 @@ substituted for the corresponding REGEXP wherever it 
matches."
           (setq string (replace-match (cdr pair) t t string))))))
   string)
 
-(defun mmm-format-matches (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."
+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-int (match-string-no-properties 1 string))
-                string
-                (replace-match
-                 (save-match-data
-                   (set-match-data old-data)
-                   (match-string-no-properties subexp))
-                 t t string))))))
+                string (replace-match
+                       (save-match-data
+                         (set-match-data old-data)
+                         (match-string-no-properties subexp on-string))
+                       t t string))))))
   string)
 
 ;;}}}
diff --git a/mmm-vars.el b/mmm-vars.el
index d784846..d0237bb 100644
--- a/mmm-vars.el
+++ b/mmm-vars.el
@@ -2,8 +2,8 @@
 
 ;; Copyright (C) 2000 by Michael Abraham Shulman
 
-;; Author: Michael Abraham Shulman <address@hidden>
-;; Version: $Id: mmm-vars.el,v 1.52 2003/03/03 20:27:02 viritrilbia Exp $
+;; Author: Michael Abraham Shulman <address@hidden>
+;; Version: $Id: mmm-vars.el,v 1.53 2003/03/09 17:04:04 viritrilbia Exp $
 
 ;;{{{ GPL
 
@@ -282,12 +282,16 @@ with font-lock."
 (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.  None means to use no coloring at all.  Low means to use
-a single face \(`mmm-default-submode-face') for all submode regions,
-\(except for \"non-submode\" regions).  High means to use different
-faces for different types of submode regions, such as initialization
-code, expressions that are output, declarations, and so on.  The
-default face is still used for regions that do not specify a face."
+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)
@@ -326,6 +330,10 @@ default face is still used for regions that do not specify 
a face."
 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
 
@@ -352,25 +360,35 @@ variable."
   :type 'string)
 
 (defvar mmm-primary-mode-display-name nil
-  "If non-nil, displayed in the mode line next to the major mode name
-\(or whatever that has been replaced by) when outside all submode
-regions, i.e. in a primary mode region.")
+  "If non-nil, displayed as the primary mode name in the mode line.
+See also `mmm-buffer-mode-display-name'.")
 (make-variable-buffer-local 'mmm-primary-mode-display-name)
 
+(defvar mmm-buffer-mode-display-name nil
+  "If non-nil, displayed in the mode line instead of the primary mode
+name, which is then shown next to it as if it were a submode when in a
+primary mode region, i.e. outside all submode regions.")
+(make-variable-buffer-local 'mmm-buffer-mode-display-name)
+
 (defun mmm-set-mode-line ()
   "Set the mode line display correctly for the current submode,
-according to `mmm-submode-mode-line-format."
-  (let ((primary (get mmm-primary-mode 'mmm-mode-name))
-       (submode (if mmm-current-overlay
-                    (or (overlay-get mmm-current-overlay 'display-name)
-                        (get mmm-current-submode 'mmm-mode-name))
-                  mmm-primary-mode-display-name)))
-    (if submode
+according to `mmm-submode-mode-line-format'."
+  (let ((primary (or mmm-primary-mode-display-name
+                    (get mmm-primary-mode 'mmm-mode-name)))
+       (submode (and mmm-current-overlay
+                     (or (overlay-get mmm-current-overlay 'display-name)
+                         (get mmm-current-submode 'mmm-mode-name)))))
+    (if mmm-buffer-mode-display-name
        (setq mode-name
              (mmm-format-string mmm-submode-mode-line-format
-                                `(("~M" . ,primary)
-                                  ("~m" . ,submode))))
-      (setq mode-name primary)))
+                                `(("~M" . ,mmm-buffer-mode-display-name)
+                                  ("~m" . ,(or submode primary)))))
+      (if submode
+         (setq mode-name
+               (mmm-format-string mmm-submode-mode-line-format
+                                  `(("~M" . ,primary)
+                                    ("~m" . ,submode))))
+       (setq mode-name primary))))
   (force-mode-line-update))
 
 ;;}}}
@@ -472,6 +490,16 @@ first `fboundp' element of the `cdr' is returned, or nil 
if none."
           (cdr (assq mode mmm-major-mode-preferences))))))
 
 ;;}}}
+;;{{{ Delimiter Regions
+
+(defcustom mmm-delimiter-mode 'fundamental-mode
+  "Major mode used by default for delimiter regions.
+Classes are encouraged to override this by providing a delimiter-mode
+parameter-- see `mmm-classes-alist'."
+  :group 'mmm
+  :type 'function)
+
+;;}}}
 ;;{{{ Key Bindings
 
 (defcustom mmm-mode-prefix-key [(control ?c) ?%]
@@ -672,7 +700,10 @@ Do not set this variable directly; use the function 
`mmm-mode'.")
 ;;}}}
 ;;{{{ Classes Alist
 
-;; :parent could be an all-class argument.  Same with :keymap.
+;; Notes:
+;; 1. :parent could be an all-class argument.  Same with :keymap.
+;; 2. :match-submode really does have to be distinct from :submode,
+;; because 'functionp' isn't enough to distinguish which is meant.
 (defvar mmm-classes-alist nil
   "Alist containing all defined mmm submode classes.
 A submode class is a named recipe for parsing a document into submode
@@ -703,8 +734,8 @@ are `mmm-*-submode-face' where * is one of `init', 
`cleanup',
 flexible alternative is the argument MATCH-FACE.  MATCH-FACE can be a
 function, which is called with one argument, the form of the front
 delimiter \(found from FRONT-FORM, below), and should return the face
-to use.  It can also be an alist, each element of the form \(DELIM
-. FACE).
+to use.  It can also be an alist, with each element of the form
+\(DELIM . FACE).
 
 If neither CLASSES nor HANDLER are supplied, either SUBMODE or
 MATCH-SUBMODE must be.  SUBMODE specifies the submode to use for the
@@ -724,14 +755,19 @@ named classes. \(Unnamed classes are created by 
interactive commands
 in `mmm-interactive-history').
 
 If FRONT is a regexp, then that regexp is searched for, and the end of
-its match \(or the beginning, if INCLUDE-FRONT is non-nil), plus
-FRONT-OFFSET, becomes the beginning of the submode region.  If FRONT
-is a function, that function is called instead, and must act somewhat
-like a search, in that it should start at point, take one argument as
-a search bound, and set the match data.  A similar pattern is followed
-for BACK \(the search starts at the beginning of the submode region),
-save that the beginning of its match \(or the end, if INCLUDE-BACK is
-non-nil) becomes the end of the submode region, plus BACK-OFFSET.
+its FRONT-MATCH'th match \(or the beginning thereof, if INCLUDE-FRONT
+is non-nil), plus FRONT-OFFSET, becomes the beginning of the submode
+region.  If FRONT is a function, that function is called instead, and
+must act somewhat like a search, in that it should start at point,
+take one argument as a search bound, and set the match data.  A
+similar pattern is followed for BACK \(the search starts at the
+beginning of the submode region), save that the beginning of its
+BACK-MATCH'th match \(or the end, if INCLUDE-BACK is non-nil) becomes
+the end of the submode region, plus BACK-OFFSET.
+
+If SAVE-MATCHES is non-nil, then BACK, if it is a regexp, is formatted
+by replacing strings of the form \"~N\" by the corresponding value of
+\(match-string n) after matching FRONT.
 
 FRONT-MATCH and BACK-MATCH default to zero.  They specify which
 sub-match of the FRONT and BACK regexps to treat as the delimiter.
@@ -750,9 +786,19 @@ FRONT-VERIFY and BACK-VERIFY, if supplied, must be 
functions that
 inspect the match data to see if a match found by FRONT or BACK
 respectively is valid.
 
-If SAVE-MATCHES is non-nil, BACK, if it is a regexp, is formatted by
-replacing strings of the form \"~N\" by the corresponding value of
-\(match-string n) after matching FRONT.
+FRONT-DELIM \(resp. BACK-DELIM), if supplied, can take values like
+those of FRONT-OFFSET \(resp. BACK-OFFSET), specifying the offset from
+the start \(resp. end) of the match for FRONT \(resp. BACK) to use as
+the starting \(resp. ending) point for the front \(resp. back)
+delimiter.  If nil, it means not to make a region for the respective
+delimiter at all.
+
+DELIMITER-MODE, if supplied, specifies what submode to use for the
+delimiter regions, if any.  If `nil', the primary mode is used.  If
+not supplied, `mmm-delimiter-mode' is used.
+
+FRONT-FACE and BACK-FACE specify faces to use for displaying the
+delimiter regions, under high decoration.
 
 FRONT-FORM and BACK-FORM, if given, must supply a regexp used to match
 the *actual* delimiter.  If they are strings, they are used as-is.  If
@@ -795,6 +841,20 @@ the end of the submode region, and the end of the back 
delimiter.
 If END-NOT-BEGIN is non-nil, it specifies that a BACK delimiter cannot
 begin a new submode region.
 
+MATCH-NAME, if supplied, specifies how to determine the \"name\" for
+each submode region.  It must be a string or a function.  If it is a
+function, it is passed the value of FRONT-FORM and must return the
+name to use.  If it is a string, it is used as-is unless SAVE-NAME has
+a non-nil value, in which case, the string is interpreted the same as
+BACK when SAVE-MATCHES is non-nil.  If MATCH-NAME is not specified,
+the regions are unnamed.  Regions with the same name are considered
+part of the same chunk of code, and formatted as such, while unnamed
+regions are not grouped with any others.
+
+As a special optimization for insertion, if SKEL-NAME is non-nil, the
+insertion code will use the user-prompted string value as the region
+name, instead of going through the normal matching procedure.
+
 PRIVATE, if supplied and non-nil, means that this class is a private
 or internal class, usually one invoked by another class via :classes,
 and is not for the user to see.")
diff --git a/mmm.texinfo b/mmm.texinfo
index bd76088..aa0b0ea 100644
--- a/mmm.texinfo
+++ b/mmm.texinfo
@@ -158,8 +158,9 @@ Writing Submode Classes
 * Calculated Submodes::         Deciding the submode at run-time.
 * Calculated Faces::            Deciding the display face at run-time.
 * Insertion Commands::          Inserting regions automatically.
+* Region Names::                Naming regions for syntax grouping.
 * Other Hooks::                 Running code at arbitrary points.
-* Delimiter Forms::             Storing the form of the delimiters.
+* Delimiters::                  Controlling delimiter overlays.
 * Misc Keywords::               Other miscellaneous options.
 
 Indices
@@ -185,25 +186,46 @@ major mode is a customization of Emacs for editing a 
certain type of
 text, such as code for a specific programming language. @xref{Major
 Modes, , , emacs, The Emacs Manual}, for details.
 
-MMM Mode is a general extension to Emacs which has many uses. Currently,
-its most common usage is to edit Mason components. Mason is a
-``Perl-based web site development and delivery engine'' which executes
-Perl code embedded in HTML and other types of documents. For more
-information, see @uref{http://www.masonhq.com}. MMM Mode comes with a
-submode class (@pxref{Submode Classes}) for editing Mason components
-(@pxref{Mason}).
-
-More generally, however, MMM Mode is useful whenever one file contains
-text in two or more programming languages, or that should be in two or
-more different modes. For example, CGI scripts written in any language,
-such as Perl or PL/SQL, may want to output verbatim HTML, and the writer
-of such scripts may want to use Emacs' html-mode to edit this HTML code.
+MMM Mode is a general extension to Emacs which is useful whenever one
+file contains text in two or more programming languages, or that
+should be in two or more different modes.  For example:
+
address@hidden @bullet
address@hidden
+CGI scripts written in any language, from Perl to PL/SQL, may want to
+output verbatim HTML, and the writer of such scripts may want to use
+Emacs' html-mode or sgml-mode to edit this HTML code, while remaining
+in the appropriate programming language mode for the rest of the
+file.  @xref{Here-documents}, for example.
+
address@hidden
+There are now many ``content delivery systems'' which turn the CGI
+script idea around and simply add extra commands to an HTML file,
+often in some programming language, which are interpreted on the
+server.  @xref{Mason}, @xref{Embperl}, @xref{ePerl}, @xref{JSP}.
+
address@hidden
 HTML itself can also contain embedded languages such as Javascript and
-CSS styles, for which Emacs has different major modes. Emacs also allows
-files of any type to contain `local variables', which can include Emacs
-Lisp code to be evaluated. @xref{File Variables, , , emacs, The Emacs
-Manual}. It may be easier to edit this code in Emacs Lisp mode than in
-whatever mode is used for the rest of the file.
+CSS styles, for which Emacs has different major modes.
address@hidden, and @xref{Embedded CSS}, for example.
+
address@hidden
+The idea of ``literate programming'' requires the same file to contain
+documentation (written as text, html, latex, etc.) and code (in an
+appropriate programming language).  @xref{Noweb}, for example.
+
address@hidden
+Emacs allows files of any type to contain `local variables', which can
+include Emacs Lisp code to be evaluated. @xref{File Variables, , ,
+emacs, The Emacs Manual}. It may be easier to edit this code in Emacs
+Lisp mode than in whatever mode is used for the rest of the file.
address@hidden Variables}.
+
address@hidden
+There are many more possible uses for MMM Mode.  RPM spec files can
+contain shell scripts (@pxref{RPM}).  Email or newsgroup messages may
+contain sample code.  And so on.  We encourage you to experiment.
address@hidden itemize
 
 @menu
 * Basic Concepts::              A simple explanation of how it works.
@@ -1446,7 +1468,7 @@ Suggested setup code:
 Thanks to Marcus Harnisch <Marcus.Harnisch@@gmx.net> for contributing
 this submode class.
 
address@hidden Noweb, , RPM, Supplied Classes
address@hidden Noweb,  , RPM, Supplied Classes
 @comment  node-name,  next,  previous,  up
 @section Noweb literate programming
 
@@ -1553,8 +1575,9 @@ with examples.
 * Calculated Submodes::         Deciding the submode at run-time.
 * Calculated Faces::            Deciding the display face at run-time.
 * Insertion Commands::          Inserting regions automatically.
+* Region Names::                Naming regions for syntax grouping.
 * Other Hooks::                 Running code at arbitrary points.
-* Delimiter Forms::             Storing the form of the delimiters.
+* Delimiters::                  Controlling delimiter overlays.
 * Misc Keywords::               Other miscellaneous options.
 @end menu
 
@@ -1779,7 +1802,7 @@ It is invoked immediately after a match is found for 
@code{:front}, and
 is passed one argument: a string representing the front delimiter.
 Normally this string is simply whatever was matched by @code{:front},
 but this can be changed with the keyword @code{:front-form}
-(@pxref{Delimiter Forms}).  The function should then return a symbol
+(@pxref{Delimiters}).  The function should then return a symbol
 that would be a valid argument to @code{:submode}: either the name of a
 mode, or that of a language to look up a preferred mode.  If it detects
 an invalid match---for example, the user has specified a mode which is
@@ -1841,7 +1864,7 @@ highlighted as simple executed code, and so on.  Note that
 for different faces to be displayed.
 
 
address@hidden Insertion Commands, Other Hooks, Calculated Faces, Writing 
Classes
address@hidden Insertion Commands, Region Names, Calculated Faces, Writing 
Classes
 @comment  node-name,  next,  previous,  up
 @section Specifying Insertion Commands
 
@@ -1903,7 +1926,34 @@ fourth (dotted) element (@code{"+"}) as the `str' 
variable; the user is
 not prompted.
 
 
address@hidden Other Hooks, Delimiter Forms, Insertion Commands, Writing Classes
address@hidden Region Names, Other Hooks, Insertion Commands, Writing Classes
address@hidden  node-name,  next,  previous,  up
address@hidden Giving Names to Submode Regions for Grouping
+
+Submode regions can be given ``names'' which are used for grouping.
+Names are always strings and are compared as strings.  Regions with
+the same name are considered part of the same chunk of code.  This is
+used by the syntax and fontification functions.  Unnamed regions are
+not grouped with any others.
+
+By default, regions are nameless, but with the @code{:match-name}
+keyword argument a name can be supplied.  This argument must be a
+string or a function.  If it is a function, it is passed a string
+representing the front delimiter found, and must return the name to
+use.  If it is a string, it is used as-is for the name, unless
address@hidden:save-name} has a non-nil value, in which case expressions such
+as @samp{~1} are substituted with the corresponding matched
+subexpression from @code{:front}.  This is the same as how
address@hidden:back} is interpreted when @code{:save-matches} is non-nil.
+
+As a special optimization for region insertion (@pxref{Insertion
+Commands}), the argument @code{:skel-name} can be set to a non-nil
+value, in which case the insertion code will use the user-prompted
+string value as the region name, instead of going through the normal
+matching procedure.
+
+
address@hidden Other Hooks, Delimiters, Region Names, Writing Classes
 @comment  node-name,  next,  previous,  up
 @section Other Hooks into the Scanning Process
 
@@ -1942,16 +1992,66 @@ write a handler function, I suggest looking at the 
source for
 @code{mmm-ify} to get an idea of what must be done.
 
 
address@hidden Delimiter Forms, Misc Keywords, Other Hooks, Writing Classes
address@hidden Delimiters, Misc Keywords, Other Hooks, Writing Classes
 @comment  node-name,  next,  previous,  up
address@hidden Controlling the Form of the Delimiters
address@hidden Controlling the Delimiter Regions and Forms
+
+MMM also makes overlays for the delimiter regions, to keep track of
+their position and form.  Normally, the front delimiter overlay starts
+at the beginning of the match for @code{:front} and ends at the
+beginning of the submode region overlay, while the back delimiter
+overlay starts at the end of the submode region overlay and ends at
+the end of the match for @code{:back}.  You can supply offsets from
+these positions using the keyword arguments @code{:front-delim} and
address@hidden:back-delim}, which take values of the same sort as
address@hidden:front-offset} and @code{:back-offset}.
+
+In addition, the delimiter regions can be in a major mode of their
+own.  There are usually only two meaningful modes to use: the primary
+mode or a non-mode like fundamental-mode.  These correspond to the
+following two situations:
+
address@hidden
address@hidden
+If the delimiter syntax which specifies the submode regions is
+something @emph{added to} the syntax of the primary mode by a
+pre-interpreter, then the delimiter regions should be in a non-mode.
+This is the case, for example, with all server-side HTML script
+extensions, such as @xref{Mason}, @xref{Embperl}, and @xref{ePerl}.
+It is also the case for literate programming such as @xref{Noweb}.
+This is the default behavior.  The non-mode used is controlled by the
+variable @code{mmm-delimiter-mode}, which defaults to
+fundamental-mode.
 
-On each submode region overlay, MMM Mode stores the ``form'' of the
-front and back delimiters, which are regular expressions that match the
-delimiters.  At present these are not used for much, but in the future
-they may be used to help with automatic updating of regions as you type.
-Normally, the form stored is the result of evaluating the expression
address@hidden(regexp-quote (match-string 0))} after each match is found.
address@hidden
+If, on the other hand, the delimiter syntax and inclusion of different
+modes is an @emph{intrinsic part} of the primary mode, then the
+delimiter regions should remain in the primary mode.  This is the
+case, for example, with @xref{Embedded CSS}, and @xref{Javascript},
+since the @code{<style>} and @code{<script>} tags are perfectly valid
+HTML.  In this case, you should give the keyword parameter
address@hidden:delimiter-mode} with a value of @code{nil}, meaning to use the
+primary mode.
address@hidden itemize
+
+The keyword parameter @code{:delimiter-mode} can be given any major
+mode as an argument, but the above two situations should cover the
+vast majority of cases.
+
+The delimiter regions can also be highlighted, if you wish.  The
+keyword parameters @code{:front-face} and @code{:back-face} may be
+faces specifying how to highlight these regions under high
+decoration.  Under low decoration, the value of the variable
address@hidden is used (by default, nothing), and of course
+under no decoration there is no coloring.
+
+Finally, for each submode region overlay, MMM Mode stores the ``form''
+of the front and back delimiters, which are regular expressions that
+match the delimiters.  At present these are not used for much, but in
+the future they may be used to help with automatic updating of regions
+as you type.  Normally, the form stored is the result of evaluating
+the expression @code{(regexp-quote (match-string 0))} after each match
+is found.
 
 You can customize this with the keyword argument @code{:front-form}
 (respectively, @code{:back-form}).  If it is a string, it is used
@@ -1968,7 +2068,7 @@ adjust the overlay; if nil it means to match the 
delimiter and return
 the result in the match data.
 
 
address@hidden Misc Keywords,  , Delimiter Forms, Writing Classes
address@hidden Misc Keywords,  , Delimiters, Writing Classes
 @comment  node-name,  next,  previous,  up
 @section Miscellaneous Other Keyword Arguments
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]