MultilineFontLock

The first try:

 (defun my-mode () "my-mode" (interactive)
   (kill-all-local-variables)
   (make-local-variable 'font-lock-defaults)
   (setq font-lock-defaults  '(my-mode-font-lock-keywords t))
   (make-local-variable 'font-lock-extend-region-functions)
   (add-hook 'font-lock-extend-region-functions
	     'my-font-lock-extend-region))
 (defun my-font-lock-extend-region ()
   (save-excursion
     (goto-char font-lock-beg)
     (let ((found-point (re-search-backward "^#begin\n" nil t)))
       (if found-point
 	  (progn
	    (goto-char font-lock-end)
	    (if (re-search-forward "^#end\n" nil t)
		(progn
		  (beginning-of-line)
		  (setq font-lock-end (point))))
	    (setq font-lock-beg found-point))))))
 (defvar my-mode-font-lock-keywords nil
   "Keywords/Regexp for fontlocking of my-mode")
 (setq my-mode-font-lock-keywords
	  (list
       '(my-font-lock-matcher
		 (0 'italic)
		 (1 'underline))))
 ;;  Original idea from font-latex-match-math-env command in font-latex.el.
 (defun my-font-lock-matcher (limit)
   "
 #begin
 make me italic
 me too
 #middle
 make me underline
 me too
 #end
 "
  ;; search for the begin of the first region
  (when (re-search-forward "^#begin\n" limit t)
    (let ((beg (match-end 0)) end ; 1st Region
		  beg2 end2 ; 2nd Region
		)
	  ;; search for end of region 1 and start of region 2
      (if (re-search-forward "^#middle\n" limit t)
		  (progn
			(setq end (match-beginning 0)
				  beg2 (match-end 0))
			;; search for end of region 2
			(if (re-search-forward "^#end\n" limit t)
				(setq end2 (- (match-beginning 0) 1))
			  ;; no match -> length of region 2 = 0
			  (setq end2 beg2)))
		;; no match -> length of region 1 = 0
        (setq end (point)))
	  ;; save the regions
	  (store-match-data (list beg end beg2 end2))
      t)))

Test it with Alt-x my-mode RET

 #begin
 make me italic
 me too
 #middle
 make me underline
 me too
 #end

But it doesn’t work all the time, esp. the refreshing. Any better idea? – Haskell

We aren’t the only people with this problem: google groups may give you some hints. font-lock doesn’t support highlighting of multiple lines. There are implementations that work around the problem: font-latex.el and the font locking in XSymbolMode. If someone knows a smaller (and easier to understand) implementations please drop a note. – DavidHansen
At least it’s a lot better with my-font-lock-extend-region. You still have to hit Ctrl-L or change something to refresh, but it does that quite reliably. – StefanRing

Multi-line font lock in XEmacs

works in general much more reliably than in Emacs. Can Emacs hackers please look into how it’s done in XEmacs and fix the Emacs implementation? This is a long-standing problem that needs to be addressed centrally, not with ad-hoc fixes.

Another thing that XEmacs does better is only applying font lock faces to the lines themselves, not to empty space. So if you have a different background color via font lock that spans two lines, that color only goes as far as the last character of the first line and not further. In Emacs, on the other hand, it spreads from the end of the line into infinity, which is noisy and annoying. The same applies to the plain shift-arrows selection of text. – blk-222-216-226.eastlink.ca

Suggestion: Send your suggestion to emacs-devel@gnu.org. GnuEmacs developers discuss Emacs development there. It is much less likely that they will see your post here. – DrewAdams


CategoryFaces