Implement full support for frame-local `next-buffer' and `previous-buffer'.
authorKaroly Lorentey <lorentey@elte.hu>
Tue, 20 Dec 2005 21:35:03 +0000 (21:35 +0000)
committerKaroly Lorentey <lorentey@elte.hu>
Tue, 20 Dec 2005 21:35:03 +0000 (21:35 +0000)
* frame.h (frame): New field `buried_buffer_list'.
* alloc.c (mark_object): Mark it.
* frame.c (make_frame): Initialize it.

* frame.h (Qburied_buffer_list): New symbol declaration.

* buffer.c (Fbuffer_list): Handle the buried-buffer-list frame parameter.

* buffer.c (record_buffer): Delete the buffer from the buried_buffer_list.

* buffer.c (Fbury_buffer): Add buffer to buried_buffer_list.

* frame.c (Qburied_buffer_list): New symbol.
  (syms_of_frame): Initialize and staticpro it.
  (frames_discard_buffer): Also remove buffer from buried-buffer-list.
  (store_frame_param): Handle `buried-buffer-list' specially.
  (Fframe_parameters): Handle `buried-buffer-list' specially.

* simple.el (last-buffer): Don't look at buried-buffer-list, rely on
  `buffer-list' doing that for us.
  (next-buffer): Simplify.
  (previous-buffer): Simplify.

git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-455

lisp/simple.el
src/alloc.c
src/buffer.c
src/frame.c
src/frame.h

index 77c008b..bfbdaf1 100644 (file)
@@ -85,34 +85,22 @@ If the optional third argument FRAME is non-nil, use that frame's
 buffer list instead of the selected frame's buffer list.
 If no other buffer exists, the buffer `*scratch*' is returned."
   (setq frame (or frame (selected-frame)))
-  (or (get-next-valid-buffer (frame-parameter frame 'buried-buffer-list)
-                            buffer visible-ok frame)
-      (get-next-valid-buffer (nreverse (buffer-list frame))
-                            buffer visible-ok frame)
+  (or (get-next-valid-buffer (nreverse (buffer-list frame))
+                            buffer visible-ok frame)
       (progn
        (set-buffer-major-mode (get-buffer-create "*scratch*"))
        (get-buffer "*scratch*"))))
-
 (defun next-buffer ()
   "Switch to the next buffer in cyclic order."
   (interactive)
-  (let ((buffer (current-buffer))
-       (bbl (frame-parameter nil 'buried-buffer-list)))
+  (let ((buffer (current-buffer)))
     (switch-to-buffer (other-buffer buffer t))
-    (bury-buffer buffer)
-    (set-frame-parameter nil 'buried-buffer-list
-                        (cons buffer (delq buffer bbl)))))
+    (bury-buffer buffer)))
 
 (defun previous-buffer ()
   "Switch to the previous buffer in cyclic order."
   (interactive)
-  (let ((buffer (last-buffer (current-buffer) t))
-       (bbl (frame-parameter nil 'buried-buffer-list)))
-    (switch-to-buffer buffer)
-    ;; Clean up buried-buffer-list up to and including the chosen buffer.
-    (while (and bbl (not (eq (car bbl) buffer)))
-      (setq bbl (cdr bbl)))
-    (set-frame-parameter nil 'buried-buffer-list bbl)))
+  (switch-to-buffer (last-buffer (current-buffer) t)))
 
 \f
 ;;; next-error support framework
index 5d8ccdc..83ba062 100644 (file)
@@ -5373,6 +5373,7 @@ mark_object (arg)
          mark_object (ptr->menu_bar_vector);
          mark_object (ptr->buffer_predicate);
          mark_object (ptr->buffer_list);
+         mark_object (ptr->buried_buffer_list);
          mark_object (ptr->menu_bar_window);
          mark_object (ptr->tool_bar_window);
          mark_face_cache (ptr->face_cache);
index d52a710..d0719ec 100644 (file)
@@ -212,25 +212,38 @@ frame parameter come first, followed by the rest of the buffers.  */)
      (frame)
      Lisp_Object frame;
 {
-  Lisp_Object framelist, general;
+  Lisp_Object general;
   general = Fmapcar (Qcdr, Vbuffer_alist);
 
   if (FRAMEP (frame))
     {
-      Lisp_Object tail;
+      Lisp_Object framelist, prevlist, tail;
+      Lisp_Object args[3];
 
       CHECK_FRAME (frame);
 
       framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
+      prevlist = Fnreverse (Fcopy_sequence (XFRAME (frame)->buried_buffer_list));
 
-      /* Remove from GENERAL any buffer that duplicates one in FRAMELIST.  */
+      /* Remove from GENERAL any buffer that duplicates one in
+         FRAMELIST or PREVLIST.  */
       tail = framelist;
-      while (! NILP (tail))
+      while (CONSP (tail))
        {
          general = Fdelq (XCAR (tail), general);
          tail = XCDR (tail);
        }
-      return nconc2 (framelist, general);
+      tail = prevlist;
+      while (CONSP (tail))
+       {
+         general = Fdelq (XCAR (tail), general);
+         tail = XCDR (tail);
+       }
+
+      args[0] = framelist;
+      args[1] = general;
+      args[2] = prevlist;
+      return Fnconc (3, args);
     }
 
   return general;
@@ -1545,6 +1558,23 @@ record_buffer (buf)
   XSETCDR (link, Vbuffer_alist);
   Vbuffer_alist = link;
 
+  /* Effectively do a delq on buried_buffer_list.  */
+  
+  prev = Qnil;
+  for (link = XFRAME (frame)->buried_buffer_list; CONSP (link);
+       link = XCDR (link))
+    {
+      if (EQ (XCAR (link), buf))
+        {
+          if (NILP (prev))
+            XFRAME (frame)->buried_buffer_list = XCDR (link);
+          else
+            XSETCDR (prev, XCDR (XCDR (prev)));
+          break;
+        }
+      prev = link;
+    }
+
   /* Now move this buffer to the front of frame_buffer_list also.  */
 
   prev = Qnil;
@@ -2016,10 +2046,10 @@ selected window if it is displayed there.  */)
       XSETCDR (link, Qnil);
       Vbuffer_alist = nconc2 (Vbuffer_alist, link);
 
-      /* Removing BUFFER from frame-specific lists
-        has the effect of putting BUFFER at the end
-        of the combined list in each frame.  */
-      frames_discard_buffer (buffer);
+      XFRAME (selected_frame)->buffer_list
+        = Fdelq (buffer, XFRAME (selected_frame)->buffer_list);
+      XFRAME (selected_frame)->buried_buffer_list
+        = Fcons (buffer, Fdelq (buffer, XFRAME (selected_frame)->buried_buffer_list));
     }
 
   return Qnil;
index 8d45ddc..9c83f96 100644 (file)
@@ -107,7 +107,7 @@ Lisp_Object Qtitle, Qname;
 Lisp_Object Qunsplittable;
 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
 Lisp_Object Qleft_fringe, Qright_fringe;
-Lisp_Object Qbuffer_predicate, Qbuffer_list;
+Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
 Lisp_Object Qtty_color_mode;
 Lisp_Object Qtty, Qtty_type;
 Lisp_Object Qwindow_system;
@@ -303,6 +303,7 @@ make_frame (mini_p)
   f->menu_bar_items_used = 0;
   f->buffer_predicate = Qnil;
   f->buffer_list = Qnil;
+  f->buried_buffer_list = Qnil;
   f->namebuf = 0;
   f->title = Qnil;
   f->menu_bar_window = Qnil;
@@ -2134,7 +2135,7 @@ set_frame_buffer_list (frame, list)
   XFRAME (frame)->buffer_list = list;
 }
 
-/* Discard BUFFER from the buffer-list of each frame.  */
+/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame.  */
 
 void
 frames_discard_buffer (buffer)
@@ -2146,6 +2147,8 @@ frames_discard_buffer (buffer)
     {
       XFRAME (frame)->buffer_list
        = Fdelq (buffer, XFRAME (frame)->buffer_list);
+      XFRAME (frame)->buried_buffer_list
+        = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
     }
 }
 
@@ -2233,13 +2236,18 @@ store_frame_param (f, prop, val)
 {
   register Lisp_Object old_alist_elt;
 
-  /* The buffer-alist parameter is stored in a special place and is
-     not in the alist.  */
+  /* The buffer-list parameters are stored in a special place and not
+     in the alist.  */
   if (EQ (prop, Qbuffer_list))
     {
       f->buffer_list = val;
       return;
     }
+  if (EQ (prop, Qburied_buffer_list))
+    {
+      f->buried_buffer_list = val;
+      return;
+    }
 
   /* If PROP is a symbol which is supposed to have frame-local values,
      and it is set up based on this frame, switch to the global
@@ -2379,6 +2387,7 @@ If FRAME is omitted, return information on the currently selected frame.  */)
                   : FRAME_MINIBUF_WINDOW (f)));
   store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
   store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
+  store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -4199,6 +4208,8 @@ syms_of_frame ()
   staticpro (&Qbuffer_predicate);
   Qbuffer_list = intern ("buffer-list");
   staticpro (&Qbuffer_list);
+  Qburied_buffer_list = intern ("buried-buffer-list");
+  staticpro (&Qburied_buffer_list);
   Qdisplay_type = intern ("display-type");
   staticpro (&Qdisplay_type);
   Qbackground_mode = intern ("background-mode");
index e8155ac..c63b0be 100644 (file)
@@ -161,6 +161,10 @@ struct frame
   /* List of buffers viewed in this frame, for other-buffer.  */
   Lisp_Object buffer_list;
 
+  /* List of buffers that were viewed, then buried in this frame.  The
+     most recently buried buffer is first.  For last-buffer.  */
+  Lisp_Object buried_buffer_list;
+  
   /* A dummy window used to display menu bars under X when no X
      toolkit support is available.  */
   Lisp_Object menu_bar_window;
@@ -981,7 +985,7 @@ extern Lisp_Object selected_frame;
 
 extern Lisp_Object Qauto_raise, Qauto_lower;
 extern Lisp_Object Qborder_color, Qborder_width;
-extern Lisp_Object Qbuffer_predicate, Qbuffer_list;
+extern Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
 extern Lisp_Object Qcursor_color, Qcursor_type;
 extern Lisp_Object Qfont;
 extern Lisp_Object Qbackground_color, Qforeground_color;