Sam Tregar [28/05/02 14:41 -0400]:
> So, before I dive in and get all fouled with Lisp, has someone already
> done this or something functionally equivalent?

Mitchell Charity posted a partial solution to the list a while ago. I've
included it below. Wanna finish what you started, Mitchell? :)

Later,
Neil

----- Forwarded message from Mitchell N Charity <[EMAIL PROTECTED]> -----

From: Mitchell N Charity <[EMAIL PROTECTED]>
Date: Tue, 3 Jul 2001 13:52:38 -0400
To: [EMAIL PROTECTED]
Subject: Re: multimode syntax highlighting - emacs MMM-mode
Reply-to: [EMAIL PROTECTED]

    Date: Thu, 21 Jun 2001 20:31:00 -0700
    From: Fletch <[EMAIL PROTECTED]>
    Subject: Re: multimode syntax highlighting not needed
  [...]
       There's also MMM-mode for emacs that allows multiple modes in
    the same buffer.  I haven't gotten it working for Inline yet, but

Nifty mode - thanks.

Here is quick and partial solution.

   ;;; MMM and Perl
   (require 'mmm-auto) ;(require 'mmm-mode) ;
   (setq mmm-global-mode 'maybe)
   (mmm-add-mode-ext-class nil ".pl" 'perl-file-marker)
   (mmm-add-mode-ext-class nil ".pl" 'perl-here-doc)
   ;(mmm-add-mode-ext-class nil ".pl" 'perl-here-doc-aggressive)

   (require 'mmm-sample)
   (defun mmm-here-doc-get-mode-works-on-match-p ()
     (condition-case nil
         (mmm-here-doc-get-mode (match-string 0))
       (mmm-no-matching-submode nil)))

   (mmm-add-classes
    '((perl-file-marker
       :match-submode mmm-here-doc-get-mode
       :front-verify  mmm-here-doc-get-mode-works-on-match-p
       :front "^__[a-zA-Z0-9_-]+__$"
       :front-offset (end-of-line 1)
       :back "^__[a-zA-Z0-9_-]+$\\|\\'"
       :back-offset (beginning-of-line -1)
       :face mmm-code-submode-face
       )))
   (mmm-add-classes
    '((perl-here-doc
       :match-submode mmm-here-doc-get-mode
       :front-verify  mmm-here-doc-get-mode-works-on-match-p
       :front "<<[\"\'\`]?\\([a-zA-Z0-9_-]+\\)"
       :front-offset (end-of-line 1)
       :back "^~1$"
       :save-matches 1
       :back-offset (beginning-of-line -1)
       :face mmm-code-submode-face
       :insert ((?d here-doc "Here-document Name: " @ "<<" str _ "\n"
                    @ "\n" @ str "\n" @))
       )))
   (mmm-add-classes
    '((perl-here-doc-aggressive
       :match-submode mmm-here-doc-get-mode
       :front-verify  mmm-here-doc-get-mode-works-on-match-p
       :front "[a-zA-Z0-9_-]+\\s-*=>\\s-*<<[\"\'\`]?\\([a-zA-Z0-9_-]+\\)"
       :front-offset (end-of-line 1)
       :back "^~1$"
       :save-matches 1
       :back-offset (beginning-of-line -1)
       :face mmm-code-submode-face
       )))
   (mmm-add-classes
    '((perl-pod-doesnt-nest
       :submode perl-mode
       :front "^=[a-zA-Z0-9_]+"
       :back "^=cut"
       :end-not-begin t
       )))

   ;(setq mmm-submode-decoration-level 0)

Caveat - I just started using MMM this morning, so the most I can say
is this code seems to work on my toy test cases under GNU Emacs 20.7.1.

Misfeatures:
  Pod text embedded in an Inline language region is not "escaped".
  perl-here-doc doesn't even try to deal with stacked docs.
       &foo(<<ONE,<<TWO);
       ONE
       TWO
     ONE will work.  TWO won't.

perl-file-marker is like here-doc, but for file marker regions.
It uses mmm-here-doc-get-mode, and its mmm-here-doc-mode-alist,
both in mmm-sample.el.  It basically looks for a mumble-mode for
each MUMBLE word in the :front match.  So Inline language modes
are found automagically.  But having a file marker __RMAIL__ is
perhaps not the right thing ;).  Fortunately, the foo-mode
namespace is rather sparse.

perl-here-doc differs from mmm-sample.el's here-doc in three ways.
It accepts punctuation (<<"END"; rather than only <<END;); it
avoids including the first character of the terminating marker in
the region (an mmm bug?); and it only matches if mmm-here-doc-get-mode
is going to succeed.  This last may qualify as a here-doc bug fix,
for without it, one gets pathology like
   # Using here-doc from mmm-sample.el ...
   $foo = <<C_END; #matches
   int foo () {}
   C_END
   $foo = <<C_END; #same, matches
   int foo () {}
   C_END
   $foo = <<THE_END; #different, doesn't match
   int foo () {}
   THE_END
   $foo = <<C_END; #same, Boom, Doesn't match!
   int foo () {}
   C_END
   #The last C_END has been broken by the THE_END mode lookup failure.

perl-here-doc-aggressive handles the narrow case of
   [...use Inline...?] C => <<UNINFORMATIVE_MARKER;
   UNINFORMATIVE_MARKER
but since it doesn't actually check for "use Inline",
there _will_ be false matches.  So I left it disabled above.
Uncomment the appropriate mmm-add-mode-ext-class if you want it.

perl-pod-first-try-doesnt-nest unfortunately prevents any
enclosing perl-file-marker region from matching.  So it's disabled.
I've not yet explored the issue.

I setq mmm-submode-decoration-level to 0 when not debugging, as I
haven't yet changed the default code background color to something
which doesn't clash violently with my usual background.

If folks find this useful (and tell me so:), I can cons up a .el file.

Cheers,
Mitchell Charity

----- End forwarded message -----

Reply via email to