Endless loop after ecb-activate on 21.5

Aidan Kehoe kehoea at parhasard.net
Fri Apr 20 09:56:26 EDT 2007


 Ar an fichiú lá de mí Aibréan, scríobh Mats Lidell: 

 > ecb-activate makes XEmacs go into an endless loop. Start with -vanilla
 > and do M-x ecb-activate. That's it.

Confirmed. The issue is that ecb-get-current-visible-ecb-buffers is part of
current-window-configuration’s advice, but it can also indirectly call
current-window-configuration itself, by the chain
ecb-canonical-ecb-windows-list -> ecb-canonical-windows-list ->
ecb-window-list -> save-window-excursion (previously a subr) ->
current-window-configuration.

This is a consequence of Michael moving more of the window configuration
code to lisp. The below patch fixes the infinite loop, but I get this
backtrace on startup nonetheless:

Debugger entered--Lisp error: (error "ECB 2.31: Errors during the basic setup of ECB. (error-type: void-variable, error-data: (oops))")
  signal(error ("ECB 2.31: Errors during the basic setup of ECB. (error-type: void-variable, error-data: (oops))"))
  cerror("ECB %s: %s (error-type: %S, error-data: %S)" "2.31" "Errors during the basic setup of ECB." void-variable (oops))
  apply(cerror "ECB %s: %s (error-type: %S, error-data: %S)" ("2.31" "Errors during the basic setup of ECB." void-variable (oops)))
  error("ECB %s: %s (error-type: %S, error-data: %S)" "2.31" "Errors during the basic setup of ECB." void-variable (oops))
  ecb-clean-up-after-activation-failure("Errors during the basic setup of ECB." (void-variable oops))
  ecb-activate--impl()
  ecb-activate-internal()
  ecb-minor-mode(1)
  #<compiled-function nil "...(4)" [ecb-minor-mode 1] 2 ("/usr/local/lib/xemacs/xemacs-packages/lisp/ecb/ecb.elc" . 38434) nil>()
  call-interactively(ecb-activate)
  command-execute(ecb-activate t)
  execute-extended-command(nil)
  call-interactively(execute-extended-command)
  (dispatch-event "[internal]")


--- ecb-util.el at rev=1.13	2007-04-20 15:53:34.390625000 +0200
+++ ecb-util.el	2007-04-20 15:45:15.453125000 +0200
@@ -340,8 +340,8 @@
                                             (pop-to-buffer . around)
                                             (find-file . around)
                                             (find-file-other-window . around)
-                                            (current-window-configuration . after)
-                                            (set-window-configuration . after)
+                                            (current-window-configuration . around)
+                                            (set-window-configuration . around)
                                             (scroll-other-window . around)
                                             (custom-save-all . around)
                                             (count-windows . around)
@@ -355,8 +355,8 @@
                                           (pop-to-buffer . around)
                                           (find-file . around)
                                           (find-file-other-window . around)
-                                          (current-window-configuration . after)
-                                          (set-window-configuration . after)
+                                          (current-window-configuration . around)
+                                          (set-window-configuration . around)
                                           (enlarge-window . around)
                                           (shrink-window . around)
                                           (tmm-prompt . around)
@@ -1622,7 +1622,6 @@
                    (ecb-current-buffer-archive-extract-p))
                (ecb-current-buffer-archive-extract-p))))))
 
-
 ;;; ----- Windows ------------------------------------------
 
 ;; Emacs 20 has no window-list function and the XEmacs and Emacs 21 one has no
--- ecb-layout.el at rev=1.16	2007-04-20 15:17:52.703125000 +0200
+++ ecb-layout.el	2007-04-20 15:48:42.187500000 +0200
@@ -4523,71 +4523,98 @@
               (list ecb-frame ecb-layout-name ecb-compile-window-height
                     ecb-compile-window-width
                     ecb-windows-width ecb-windows-height))))
-              
-(defadvice current-window-configuration (after ecb)
+
+(defvar ecb-in-current-window-configuration-advice nil 
+  "Dynamically scoped variable to prevent `current-window-configuration'
+advice recursing.")
+
+(defadvice current-window-configuration (around ecb)
   "Stores some additional informations about the window-configurations needed
 by ECB."
-  (condition-case oops
-      (let ((f (or (ad-get-arg 0) (selected-frame))))
-        (when (equal f ecb-frame)
-          (ecb-window-config-cache-add
-           (list ad-return-value
-                 (if ecb-windows-hidden
-                     nil
-                   (ecb-get-current-visible-ecb-buffers))
-                 (if (ecb-compile-window-live-p)
+  (let ((ecb-in-current-window-configuration-advice
+         ecb-in-current-window-configuration-advice)
+        (execute-advice nil))
+    (unless ecb-in-current-window-configuration-advice
+      (setq ecb-in-current-window-configuration-advice t
+            execute-advice t))
+    ad-do-it
+    (when execute-advice
+      (condition-case oops
+          (let ((f (or (ad-get-arg 0) (selected-frame))))
+            (when (equal f ecb-frame)
+              (ecb-window-config-cache-add
+               (list ad-return-value
+                     (if ecb-windows-hidden
+                         nil
+                       (ecb-get-current-visible-ecb-buffers))
+                     (if (ecb-compile-window-live-p)
                      (ecb-position (ecb-canonical-windows-list)
                                    ecb-compile-window))
-                 ;; We add here as first element `ecb-frame' and also in the
-                 ;; check of `ecb-window-configuration-invalidp'! Then a
-                 ;; ecb-window-config made from a frame which is now deleted
-                 ;; would be always invalid, which would be more consistency
-                 ;; with the return-value of `set-window-configuration' (see
-                 ;; docstring)
-                 ;;
-                 ;; This element is only used in
-                 ;; `ecb-window-configuration-invalidp'!
-                 (list ecb-frame ecb-layout-name ecb-compile-window-height
-                       ecb-compile-window-width
-                       ecb-windows-width ecb-windows-height)
-                 ecb-edit-area-creators
-                 ecb-windows-hidden
-                 (ecb-window-configuration-data)))))
-    (error
-     (ecb-layout-debug-error "advice of current-window-configuration failed: (error-type: %S, error-data: %S)"
-                             (car oops) (cdr oops))))
-  ad-return-value)
-
-
-(defadvice set-window-configuration (after ecb)
+                     ;; We add here as first element `ecb-frame' and also in
+                     ;; the check of `ecb-window-configuration-invalidp'! 
+                     ;; Then a ecb-window-config made from a frame which is
+                     ;; now deleted would be always invalid, which would be
+                     ;; more consistency with the return-value of
+                     ;; `set-window-configuration' (see docstring)
+                     ;;
+                     ;; This element is only used in
+                     ;; `ecb-window-configuration-invalidp'!
+                     (list ecb-frame ecb-layout-name ecb-compile-window-height
+                     ecb-compile-window-width
+                     ecb-windows-width ecb-windows-height)
+                     ecb-edit-area-creators
+                     ecb-windows-hidden
+                     (ecb-window-configuration-data)))))
+        (error
+         (ecb-layout-debug-error "advice of current-window-configuration failed: (error-type: %S, error-data: %S)"
+                                 (car oops) (cdr oops)))))
+    ad-return-value))
+
+(defvar ecb-in-set-window-configuration-advice nil
+   "Dynamically scoped variable to prevent `set-window-configuration' advice 
+recursing. " )
+ 
+(defadvice set-window-configuration (around ecb)
   "Resets some internal window-configuration-states needed by ECB. These
 internal ECB-states were stored by `current-window-configuration' in a
 ring-cache as add-on to CONFIGURATION."
-  (condition-case oops
-      (when (equal (selected-frame) ecb-frame)
-        (let ((config (ecb-window-config-cache-get (ad-get-arg 0))))
-          (when (and config
-                     (not (ecb-window-configuration-invalidp config)))
-            (ecb-make-windows-not-dedicated ecb-frame)
-            ;; we have to reset the dedicated state because it is not
-            ;; preserved by `current-window-configuration' and
-            ;; `set-window-configuration'! At least not with GNU Emacs 21.X,
-            ;; In addition we have to reset ecb-compile-window and also to set
-            ;; ecb-windows-hidden correctly
-            (and (nth 1 config)
-                 (ecb-set-windows-dedicated-state (nth 1 config) t))
-            (when (nth 2 config)
-              (let ((win-list (ecb-canonical-windows-list)))
-                (and ecb-compile-window-height
-                     (setq ecb-compile-window (nth (nth 2 config) win-list)))))
-            ;; (nth 3 config) is not used and needed within this function!
-            (setq ecb-edit-area-creators (nth 4 config))
-            (setq ecb-windows-hidden (nth 5 config))
-            (ecb-set-minor-mode-text))))
-    (error
-     (ecb-layout-debug-error "advice of set-window-configuration failed: (error-type: %S, error-data: %S)"
-                             (car oops) (cdr oops))))
-  ad-return-value)
+  (let ((ecb-in-set-window-configuration-advice 
+         ecb-in-set-window-configuration-advice)
+        (execute-advice nil))
+    (unless ecb-in-set-window-configuration-advice
+      (setq ecb-in-set-window-configuration-advice t
+            execute-advice t))
+    ad-do-it
+    (when execute-advice
+      (condition-case oops
+          (when (equal (selected-frame) ecb-frame)
+            (let ((config (ecb-window-config-cache-get (ad-get-arg 0))))
+              (when (and config
+                         (not (ecb-window-configuration-invalidp config)))
+                (ecb-make-windows-not-dedicated ecb-frame)
+
+                ;; we have to reset the dedicated state because it is not
+                ;; preserved by `current-window-configuration' and
+                ;; `set-window-configuration'! At least not with GNU Emacs
+                ;; 21.X, In addition we have to reset ecb-compile-window and
+                ;; also to
+                ;; set
+                ;; ecb-windows-hidden correctly
+                (and (nth 1 config)
+                     (ecb-set-windows-dedicated-state (nth 1 config) t))
+                (when (nth 2 config)
+                  (let ((win-list (ecb-canonical-windows-list)))
+                    (and ecb-compile-window-height
+                         (setq ecb-compile-window
+                               (nth (nth 2 config) win-list)))))
+                ;; (nth 3 config) is not used and needed within this function!
+                (setq ecb-edit-area-creators (nth 4 config))
+                (setq ecb-windows-hidden (nth 5 config))
+                (ecb-set-minor-mode-text)))))
+      (error
+       (ecb-layout-debug-error "advice of set-window-configuration failed: (error-type: %S, error-data: %S)"
+                               (car oops) (cdr oops))))
+    ad-return-value))
 
 (defun ecb-current-window-configuration ()
   "Return the current ecb-window-configuration"


-- 
On the quay of the little Black Sea port, where the rescued pair came once
more into contact with civilization, Dobrinton was bitten by a dog which was
assumed to be mad, though it may only have been indiscriminating. (Saki)



More information about the XEmacs-Beta mailing list