]> git.eshelyaron.com Git - emacs.git/commitdiff
(run_funs): New fun.
authorStefan Monnier <monnier@iro.umontreal.ca>
Wed, 19 Mar 2008 15:18:30 +0000 (15:18 +0000)
committerStefan Monnier <monnier@iro.umontreal.ca>
Wed, 19 Mar 2008 15:18:30 +0000 (15:18 +0000)
(run_window_configuration_change_hook): Use it to run the buffer-local
and the global part of the hook.

src/ChangeLog
src/window.c

index 0dc18c838801ac19e1091c7d1da27a616b59a7eb..875e8b7943476632e728177b02d8fa0c569f189b 100644 (file)
@@ -1,5 +1,9 @@
 2008-03-19  Stefan Monnier  <monnier@iro.umontreal.ca>
 
+       * window.c (run_funs): New fun.
+       (run_window_configuration_change_hook): Use it to run the buffer-local
+       and the global part of the hook.
+
        * xdisp.c (format_mode_line_unwind_data): Add window argument.
        (unwind_format_mode_line): Restore selected window.
        (x_consider_frame_title, Fformat_mode_line): Set selected window.
index bceb41faf062d5d42583c5e024bec98c5ce9b9d3..8cf2a45e6f2fe189bf3e65964fe22d56cf76e488 100644 (file)
@@ -3306,25 +3306,62 @@ Fset_window_buffer_unwind (obuf)
 EXFUN (Fset_window_fringes, 4);
 EXFUN (Fset_window_scroll_bars, 4);
 
+static void
+run_funs (Lisp_Object funs)
+{
+  for (; CONSP (funs); funs = XCDR (funs))
+    if (!EQ (XCAR (funs), Qt))
+      call0 (XCAR (funs));
+}
+
+static Lisp_Object select_window_norecord (Lisp_Object window);
+
 void
 run_window_configuration_change_hook (struct frame *f)
 {
-  /* FIXME: buffer-local values of Vwindow_configuration_change_hook
-     aren't handled properly.  */
-  if (! NILP (Vwindow_configuration_change_hook)
-      && ! NILP (Vrun_hooks))
-    {
       int count = SPECPDL_INDEX ();
+  Lisp_Object frame, global_wcch
+    = Fdefault_value (Qwindow_configuration_change_hook);
+  XSETFRAME (frame, f);
+
+  if (NILP (Vrun_hooks))
+    return;
+
       if (SELECTED_FRAME () != f)
        {
-         Lisp_Object frame;
-         XSETFRAME (frame, f);
          record_unwind_protect (Fselect_frame, Fselected_frame ());
          Fselect_frame (frame);
        }
-      call1 (Vrun_hooks, Qwindow_configuration_change_hook);
+
+  /* Use the right buffer.  Matters when running the local hooks.  */
+  if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
+    {
+      record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+      Fset_buffer (Fwindow_buffer (Qnil));
+    }
+
+  /* Look for buffer-local values.  */
+  {
+    Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
+    for (; CONSP (windows); windows = XCDR (windows))
+      {
+       Lisp_Object window = XCAR (windows);
+       Lisp_Object buffer = Fwindow_buffer (window);
+       if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
+                                     buffer)))
+         {
+           int count = SPECPDL_INDEX ();
+           record_unwind_protect (select_window_norecord, Fselected_window ());
+           select_window_norecord (window);
+           run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
+                                          buffer));
       unbind_to (count, Qnil);
     }
+      }
+  }
+  
+  run_funs (global_wcch);
+  unbind_to (count, Qnil);
 }
 
 /* Make WINDOW display BUFFER as its contents.  RUN_HOOKS_P non-zero
@@ -7586,7 +7623,9 @@ Any other value means point always keeps its screen position.  */);
   DEFVAR_LISP ("window-configuration-change-hook",
               &Vwindow_configuration_change_hook,
               doc: /* Functions to call when window configuration changes.
-The selected frame is the one whose configuration has changed.  */);
+The buffer-local part is run once per window, with the relevant window
+selected; while the global part is run only once for the modified frame,
+with the relevant frame selected.  */);
   Vwindow_configuration_change_hook = Qnil;
 
   defsubr (&Sselected_window);