From: joakim@verona.se
To: emacs-devel@gnu.org
Subject: [PATCH] Window-groups
Date: Sun, 22 Jun 2008 21:07:12 +0200 [thread overview]
Message-ID: <m31w2p2srj.fsf@verona.se> (raw)
[-- Attachment #1: Type: text/plain, Size: 554 bytes --]
Heres a patch to implement Window-groups in Emacs, which I submit for
review. Theres comments in the patch to explain what Window-groups are
in practice. In brief, the aim is to create Emacs primitives useful to ECB
like frameworks.
The code builds on top of the already comitted window-properties code.
The patch has C level changes and an elisp interface.
To understand the design rationale, please read previous rather
long-winded window group threads. The patch is a joint effort between
me, Stefan Monnier, Chong Yidong, and Martin Rudalics.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: emacs-winprop.diff --]
[-- Type: text/x-patch, Size: 8389 bytes --]
=== modified file 'lisp/window.el'
--- lisp/window.el 2008-06-17 22:33:06 +0000
+++ lisp/window.el 2008-06-22 12:25:44 +0000
@@ -1625,5 +1625,77 @@
(define-key ctl-x-map "+" 'balance-windows)
(define-key ctl-x-4-map "0" 'kill-buffer-and-window)
+
+;; Below are functions for managing window-groups. Window
+;; groups allow windows in a frame a degree of separation from other
+;; windows in the same frame, similar to the way windows in different
+;; frames are separated from each other.
+
+;; Here's some examples.
+
+;; Make a new frame and split it vertically:
+;; (split-window-horizontally)
+;; Call the left side the "Context Area" and the left one the "Edit Area".
+;; Now make the "Context Area" into a group:
+;; (window-group-create (selected-window))
+;; Theres actually two groups now, the "Context Area" and the default "Edit Area".
+;; Now try "c-x o". Notice that you dont go to the "Edit Area".
+;; Now try splitting the "Context Area" with "c-x 2", and switch buffers a bit
+;; Now try removing windows with "c-x 0". Notice that only windows in the
+;; current group are affected.
+;; To return the state as it was:
+;; (window-group-dissolve (window-group (selected-window)))
+
+
+(defun window-group (window)
+ "Return the window group object that WINDOW belongs to.
+Return nil if WINDOW is not in a window group."
+ (window-parameter window 'group))
+
+(defun window-group-member-p (window group)
+ "Non nil if WINDOW is a member of GROUP."
+ (eq group (window-group window)))
+
+(defun window-group-members (group)
+ "Return all windows in GROUP.
+Must be in selected frame."
+ (let ((group-windows ()))
+ (walk-windows
+ (lambda (w)
+ (when (window-group-member-p w group )
+ (push w group-windows))))
+ group-windows))
+
+(defvar window-group--counter 0
+ "An internal variable to keep track of window groups.")
+
+(defun window-group-create (window)
+ "Return a window group object with WINDOW as its only member.
+An error is signalled if WINDOW is not visible or already part of
+a group."
+ (if (window-group window)
+ (error "Window %s is already part of group %s"
+ ;;TODO check that the resulting error is not nonsensical
+ window (window-group window)))
+ ;;TODO we should now test for window visibility
+ (setq window-group--counter (1+ window-group--counter))
+ (let* ((name (concat "group-" (number-to-string window-group--counter)))
+ (group (make-symbol name)))
+ (set-window-parameter window 'group group)
+ group))
+
+(defun window-group-dissolve (group)
+ "Dissolve the window group object GROUP.
+The windows in the group are not deleted."
+ (let ((group-windows (window-group-members group)))
+ (if (null group-windows)
+ (error "No group %s on current frame" group)
+ ;;TODO I think the group id is not suitable for printing!
+ (dolist (win group-windows)
+ (set-window-parameter win 'group nil)))))
+
+(provide 'window-group)
+
+
;; arch-tag: b508dfcc-c353-4c37-89fa-e773fe10cea9
;;; window.el ends here
=== modified file 'src/window.c'
--- src/window.c 2008-06-10 22:08:42 +0000
+++ src/window.c 2008-06-19 13:25:41 +0000
@@ -54,6 +54,7 @@
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
Lisp_Object Qdisplay_buffer;
Lisp_Object Qscroll_up, Qscroll_down;
+Lisp_Object Qgroup;
Lisp_Object Qwindow_size_fixed;
extern Lisp_Object Qleft_margin, Qright_margin;
@@ -82,7 +83,8 @@
Lisp_Object *));
static int foreach_window_1 P_ ((struct window *,
int (* fn) (struct window *, void *),
- void *));
+ void *,
+ int));
static Lisp_Object window_list_1 P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
/* This is the window in which the terminal's cursor should
@@ -1041,7 +1043,7 @@
window = Qnil;
cw.window = &window, cw.x = &x, cw.y = &y; cw.part = part;
- foreach_window (f, check_window_containing, &cw);
+ foreach_window (f, check_window_containing, &cw, 1);
/* If not found above, see if it's in the tool bar window, if a tool
bar exists. */
@@ -1733,7 +1735,8 @@
static Lisp_Object
window_list ()
{
- if (!CONSP (Vwindow_list))
+ //if(!CONSP (Vwindow_list))
+ if (1) //never cache the window list for now FIXME
{
Lisp_Object tail;
@@ -1746,7 +1749,7 @@
new windows at the front of args[1], which means we
have to reverse this list at the end. */
args[1] = Qnil;
- foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1]);
+ foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1], 0);
args[0] = Vwindow_list;
args[1] = Fnreverse (args[1]);
Vwindow_list = Fnconc (2, args);
@@ -2213,7 +2216,7 @@
break;
case DELETE_OTHER_WINDOWS:
- if (!EQ (window, obj))
+ if (!EQ (window, obj) )
Fdelete_window (window);
break;
@@ -3882,6 +3885,12 @@
adjust_glyphs (fo);
Fset_window_buffer (new, o->buffer, Qt);
+ /* make the new window inherit group properties. We
+ inherit only those atm, because its not obvious that all
+ properties should be inherited
+ */
+ if(!NILP(Fwindow_parameter(window, Qgroup)))
+ Fset_window_parameter(new, Qgroup, Fwindow_parameter(window, Qgroup));
return new;
}
\f
@@ -6826,17 +6835,20 @@
\f
/* Call FN for all leaf windows on frame F. FN is called with the
first argument being a pointer to the leaf window, and with
- additional argument USER_DATA. Stops when FN returns 0. */
+ additional argument USER_DATA. Stops when FN returns 0.
+ ALLWINDOWS 1 means iterate every window, else only the group of the selected window
+*/
void
-foreach_window (f, fn, user_data)
+foreach_window (f, fn, user_data, allwindows)
struct frame *f;
int (* fn) P_ ((struct window *, void *));
void *user_data;
+ int allwindows;
{
/* Fdelete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
if (WINDOWP (FRAME_ROOT_WINDOW (f)))
- foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data);
+ foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data,allwindows);
}
@@ -6846,22 +6858,31 @@
Stop when FN returns 0. Value is 0 if stopped by FN. */
static int
-foreach_window_1 (w, fn, user_data)
+foreach_window_1 (w, fn, user_data, allwindows)
struct window *w;
int (* fn) P_ ((struct window *, void *));
void *user_data;
+ int allwindows;
{
int cont;
-
+ struct window *current_window=XWINDOW(selected_window);
+ register Lisp_Object group = Fcdr(Fassq(Qgroup, current_window->window_parameters));
+ Lisp_Object group2;
for (cont = 1; w && cont;)
{
if (!NILP (w->hchild))
- cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data);
+ cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data,allwindows);
else if (!NILP (w->vchild))
- cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data);
- else
- cont = fn (w, user_data);
-
+ cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data,allwindows);
+ else{
+ //only call fn if the group of the frames selected window
+ //is the same as the group of the current window in the loop.
+ group2=Fcdr(Fassq(Qgroup,w->window_parameters));
+ debug_print(group);
+ debug_print(group2);
+ if (allwindows || EQ(group , group2 ))
+ cont = fn (w, user_data);
+ }
w = NILP (w->next) ? 0 : XWINDOW (w->next);
}
@@ -6900,7 +6921,7 @@
struct frame *f;
int freeze_p;
{
- foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
+ foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0),1);
}
\f
@@ -7061,6 +7082,10 @@
void
syms_of_window ()
{
+
+ Qgroup = intern ("group");
+ staticpro (&Qgroup);
+
Qscroll_up = intern ("scroll-up");
staticpro (&Qscroll_up);
=== modified file 'src/window.h'
--- src/window.h 2008-06-06 00:00:29 +0000
+++ src/window.h 2008-06-07 22:28:47 +0000
@@ -784,7 +784,8 @@
extern void freeze_window_starts P_ ((struct frame *, int));
extern void foreach_window P_ ((struct frame *,
int (* fn) (struct window *, void *),
- void *));
+ void *,
+ int allwindows));
extern void grow_mini_window P_ ((struct window *, int));
extern void shrink_mini_window P_ ((struct window *));
[-- Attachment #3: Type: text/plain, Size: 20 bytes --]
--
Joakim Verona
next reply other threads:[~2008-06-22 19:07 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-22 19:07 joakim [this message]
2008-06-23 14:14 ` [PATCH] Window-groups Richard M Stallman
2008-06-23 14:14 ` Richard M Stallman
2008-06-23 14:14 ` Richard M Stallman
2008-06-23 14:29 ` joakim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m31w2p2srj.fsf@verona.se \
--to=joakim@verona.se \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).