[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
- [elpa] master ff4c564 344/433: * mmm-noweb.el: Add the FIXME note., (continued)
- [elpa] master ff4c564 344/433: * mmm-noweb.el: Add the FIXME note., Dmitry Gutov, 2018/03/15
- [elpa] master 5c152e0 334/433: Merge pull request #20 from dgutov/overlays, Dmitry Gutov, 2018/03/15
- [elpa] master 16907a3 368/433: Delete .cvsignore, move almost everything to .gitignore, Dmitry Gutov, 2018/03/15
- [elpa] master df0d56b 406/433: Fix regression from the previous commit, Dmitry Gutov, 2018/03/15
- [elpa] master 50764ae 269/433: Fixed back recognition of output regions., Dmitry Gutov, 2018/03/15
- [elpa] master cb905bd 431/433: Add copyright blurbs to the test files, Dmitry Gutov, 2018/03/15
- [elpa] master 38f1f2a 390/433: Update TODO, Dmitry Gutov, 2018/03/15
- [elpa] master 6406e1a 357/433: Update NEWS, Dmitry Gutov, 2018/03/15
- [elpa] master a57afa3 421/433: Release 0.5.5, Dmitry Gutov, 2018/03/15
- [elpa] master fd3c992 378/433: Fix sporadic keywords mishighlighting in sql-mode, Dmitry Gutov, 2018/03/15
- [elpa] master 8ed11ab 262/433: Added delimiter regions and region name matching.,
Dmitry Gutov <=
- [elpa] master cb10b47 165/433: (mmm-set-buffer-file-name-p): Added to control file name setting., Dmitry Gutov, 2018/03/15
- [elpa] master ca87dd4 187/433: (mmm-update-mode-info): Hacked so `font-lock-keywords-alist' works., Dmitry Gutov, 2018/03/15
- [elpa] master cf82d88 423/433: Add to TODO, Dmitry Gutov, 2018/03/15
- [elpa] master 3ef8864 374/433: Expected results depend on the Emacs version, Dmitry Gutov, 2018/03/15
- [elpa] master c563b85 377/433: mmm-beginning-of-syntax: Don't consider overlays ending at point, Dmitry Gutov, 2018/03/15
- [elpa] master b8c18c2 227/433: Defined new submode placement error conditions., Dmitry Gutov, 2018/03/15
- [elpa] master 4e21882 403/433: mmm-match-region: Return front-pos even without front-delim; likewise for back, Dmitry Gutov, 2018/03/15
- [elpa] master b3c3510 289/433: Fix fontification of the first subregion line, Dmitry Gutov, 2018/03/15
- [elpa] master 4d41181 405/433: Make c-mode raise fewer errors, Dmitry Gutov, 2018/03/15
- [elpa] master 6115059 288/433: Refontify buffer when creating new region, Dmitry Gutov, 2018/03/15