From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Lennart Borgman (gmail)" Newsgroups: gmane.emacs.devel Subject: Re: Feature request: permanent-local values in hooks buffer local values Date: Fri, 07 Dec 2007 01:25:51 +0100 Message-ID: <4758930F.4060308@gmail.com> References: <475439BD.7070000@gmail.com> <475598CF.4050200@gmail.com> <47565186.8080909@gmail.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1196987177 24414 80.91.229.12 (7 Dec 2007 00:26:17 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 7 Dec 2007 00:26:17 +0000 (UTC) Cc: emacs-devel@gnu.org To: rms@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Dec 07 01:26:26 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1J0R2t-0004yY-Sd for ged-emacs-devel@m.gmane.org; Fri, 07 Dec 2007 01:26:24 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1J0R2c-0001Pj-S6 for ged-emacs-devel@m.gmane.org; Thu, 06 Dec 2007 19:26:06 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1J0R2Z-0001Nl-4O for emacs-devel@gnu.org; Thu, 06 Dec 2007 19:26:03 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1J0R2Y-0001NJ-IN for emacs-devel@gnu.org; Thu, 06 Dec 2007 19:26:02 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1J0R2Y-0001N7-Fn for emacs-devel@gnu.org; Thu, 06 Dec 2007 19:26:02 -0500 Original-Received: from ch-smtp02.sth.basefarm.net ([80.76.149.213]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1J0R2T-00088Y-DP; Thu, 06 Dec 2007 19:25:58 -0500 Original-Received: from c83-254-148-228.bredband.comhem.se ([83.254.148.228]:62329 helo=[127.0.0.1]) by ch-smtp02.sth.basefarm.net with esmtp (Exim 4.68) (envelope-from ) id 1J0R2R-0001AT-7c; Fri, 07 Dec 2007 01:25:56 +0100 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071031 Thunderbird/2.0.0.9 Mnenhy/0.7.5.666 In-Reply-To: X-Antivirus: avast! (VPS 071206-0, 2007-12-06), Outbound message X-Antivirus-Status: Clean X-Originating-IP: 83.254.148.228 X-Scan-Result: No virus found in message 1J0R2R-0001AT-7c. X-Scan-Signature: ch-smtp02.sth.basefarm.net 1J0R2R-0001AT-7c aa9aa505c8c98288f32c04a6578a3d4d X-detected-kernel: by monty-python.gnu.org: Linux 2.6? (barebone, rare!) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:84819 Archived-At: Richard Stallman wrote: > In a way, yes. But remember the goal. It is to let a minor mode that is > turned on in the buffer survive changing major mode. > > There are two kind of things to survive: > > 1) buffer local variable values, which are survived by using (put > 'VARIABLE 'permanent-local t) > > 2) buffer local entries in hooks. Those are what I am asking about here. > > I see. I did not understand your aim before. > Here's a possible implementation. > > 1. Put a property on hook variables to identify them for this > special processing. > > 2. Put another property (as you suggested) on hook functions > to indicate they should be preserved. > > 3. Now it is possible for kill-all-local-variables > to identify hook variables, scan their local values, > and preserve specific hooks. I have tested another solution, defining a macro instead for minor mode authors to use if they want their minor mode to survive changes in major mode. The advantage of that is that it makes it very clear what is needed. And I do not think there is any big performance penalty. A disadvantage is however that the minor mode initialization will be a bit different whether this macro is available or not. Therefore it would be good if the macro were added to Emacs. Here is the macro: (defmacro mumamo-make-change-major-survivor (name hook-fun-list var-list) "Define functions for major mode change survival. Minor mode authors that want their buffer local minor mode to survive when the major mode in the buffer is changed can use this macro. An example of such a minor mode may be flymake minor mode. For flymake this call can be used: (eval-after-load 'mumamo (mumamo-make-change-major-survivor flymake '((after-change-functions flymake-after-change-function) (after-save-hook flymake-after-save-hook) (kill-buffer-hook flymake-kill-buffer-hook)) '(flymake-mode flymake-is-running flymake-timer flymake-last-change-time flymake-check-start-time flymake-check-was-interrupted flymake-err-info flymake-new-err-info flymake-output-residual flymake-mode-line flymake-mode-line-e-w flymake-mode-line-status flymake-temp-source-file-name flymake-master-file-name flymake-temp-master-file-name flymake-base-dir ))) Then in `flymake-mode' a call to the functions `flymake-add-survivor' and `flymake-remove-survivor \(which was defined by the macro called above) must be done. The macro defines two functions for the user of this macro to call, NAME-add-survivor and NAME-remove-survivor. A typical use is for a minor mode to use the first when turning on and the second when turning off. NAME-add-survivor will add to local hooks according to the list HOOK-FUN-LIST and arrange so that those additions to the local hooks will be setup again after a major mode change. Also make sure that the local values of the variables in VAR-LIST survives a major mode change. NAME-remove-survivor does the opposite of this. NAME should be a symbol. HOOK-FUN-LIST should be a list where each record has the format \(HOOK-NAME HOOK-FUNCTION) where HOOK-NAME is the name of the hook to which HOOK-FUNCTION should be added locally. VAR-LIST should be a list of variable symbols." (let* ((sname (symbol-name name)) (NAME-add-survivor (intern (concat sname "-add-survivor"))) (NAME-remove-survivor (intern (concat sname "-remove-survivor"))) (NAME-acmmh-f (intern (concat sname "-acmmh-f"))) (NAME-cmmh-f (intern (concat sname "-cmmh-f")))) `(progn (defun ,NAME-add-survivor () "Add major mode change surviving. This function should be called by the code that calls the macro `make-change-major-survivor'." (dolist (rec ,hook-fun-list) (let ((hook (nth 0 rec)) (func (nth 1 rec))) (add-hook hook func nil t))) ;; Set up to survive major mode change (add-hook 'change-major-mode-hook ',NAME-cmmh-f nil t) ;;(lwarn t :warning "add survivor, cmmh=%S" change-major-mode-hook) ) (defun ,NAME-remove-survivor () "Remove major mode change surviving. This function should be called by the code that calls the macro `make-change-major-survivor'." (dolist (rec ,hook-fun-list) (let ((hook (nth 0 rec)) (func (nth 1 rec))) (remove-hook hook func t))) ;; Set up to survive major mode change (remove-hook 'change-major-mode-hook ',NAME-cmmh-f t) ;;(lwarn t :warning "rem survivor, cmmh=%S" change-major-mode-hook) ) (defun ,NAME-acmmh-f () "Restore after changing major mode. This function is added locally to `after-change-major-mode-hook'." ;;(remove-hook 'after-change-major-mode-hook ',NAME-acmmh-f t) (,NAME-add-survivor) ;; Remove 'permanent-local t (dolist (sym ,var-list) (put sym 'permanent-local nil))) (defun ,NAME-cmmh-f () "Set up to restore after changing major mode. This function is added locally to `change-major-mode-hook'." (add-hook 'after-change-major-mode-hook ',NAME-acmmh-f nil t) ;;(lwarn t :warning "cmmh-f, acmmh=%S" after-change-major-mode-hook) (put 'after-change-major-mode-hook 'permanent-local t) ;; Note: I can see no way to later remove the ;; 'permanent-local property that is set here without ;; getting potential problems. ;; ;; Add 'permanent-local t (dolist (sym ,var-list) (put sym 'permanent-local t))))))