Commit a18b8cb5 authored by Karoly Lorentey's avatar Karoly Lorentey

Implement full support for frame-local `next-buffer' and `previous-buffer'.

* 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.

parent e93b2956
......@@ -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)
(set-buffer-major-mode (get-buffer-create "*scratch*"))
(get-buffer "*scratch*"))))
(defun next-buffer ()
"Switch to the next buffer in cyclic order."
(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."
(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)))
;;; next-error support framework
......@@ -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);
......@@ -212,25 +212,38 @@ frame parameter come first, followed by the rest of the buffers. */)
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
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);
XSETCDR (prev, XCDR (XCDR (prev)));
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;
......@@ -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. */
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;
if (EQ (prop, Qburied_buffer_list))
f->buried_buffer_list = val;
/* 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. */)
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. */
......@@ -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");
......@@ -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;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment