;; two-mode-mode.el -- switches between tcl and sgml(html) modes
;; $Id: two-mode-mode.el,v 1.4 2004/11/19 17:00:12 davidw Exp $
;; Copyright 1999-2004 The Apache Software Foundation
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; These same concepts could be used to do a number of neat 2-mode
;; modes, for things like PHP, or anything else where you have a
;; couple of modes you'd like to use.
;; Use of 'psgml-mode' is highly recommended. It is, of course, a
;; part of Debian GNU/Linux.
;; Author: David N. Welton <firstname.lastname@example.org>
;; Modified by Marco Pantaleoni <email@example.com>
;; to allow execution of an hook on mode switching.
;; Also added a standard mode hook and some documentation strings.
;; Janko Heilgeist <firstname.lastname@example.org> and Stefan Schimanski
;; <email@example.com> submitted modifications that enable the use of
;; multiple modes, so I suppose that 'two-mode-mode' isn't strictly
;; accurate anymore.
;; configure these:
(defvar default-mode (list "nXHTML" 'nxhtml-mode))
(defvar second-modes (list
(list "Python" "#" "\x0c" 'python-mode)
(defvar two-mode-update 0)
(defvar two-mode-mode-idle-timer nil)
(defvar two-mode-bool nil)
(defvar two-mode-mode-delay (/ (float 1) (float 8)))
;; Two mode hook
(defvar two-mode-hook nil
"*Hook called by `two-mode'.")
(setq two-mode-hook nil)
;; Mode switching hook
(defvar two-mode-switch-hook nil
"*Hook called upon mode switching.")
(setq two-mode-switch-hook nil)
(defun two-mode-mode-setup ()
(add-hook 'post-command-hook 'two-mode-mode-need-update nil t)
(setq two-mode-bool t)
(run-with-idle-timer two-mode-mode-delay t
(or (assq 'two-mode-bool minor-mode-alist)
(cons '(two-mode-bool " two-mode") minor-mode-alist))))
(defun two-mode-mode-need-update ()
(setq two-mode-update 1))
(defun two-mode-change-mode (to-mode func)
(if (string= to-mode mode-name)
;; After the mode was set, we reread the "Local Variables" section.
;; We do need this for example in SGML-mode if "sgml-parent-document"
;; was set, or otherwise it will be reset to nil when sgml-mode is left.
(if (eq font-lock-mode t)
(defun two-mode-mode-update-mode ()
(when (and two-mode-bool two-mode-update)
(setq two-mode-update 0)
(let ((mode-list second-modes)
(let ((mode (car mode-list))
(if (search-backward (cadr mode) nil t)
(setq lm (point))
(setq lm -1)))
(if (search-backward (car (cddr mode)) nil t)
(setq rm (point))
(setq rm -1)))
(if (and (not (and (= lm -1) (= rm -1))) (>= lm rm))
(setq flag 1)
(setq mode-list '())
(two-mode-change-mode (car mode) (car (cdr (cddr mode)))))))
(setq mode-list (cdr mode-list)))
(if (= flag 0)
(two-mode-change-mode (car default-mode) (cadr default-mode))))))
(defun two-mode-mode ()
"Turn on two-mode-mode"
(funcall (cadr default-mode))