diff options
author | Juri Linkov <juri@jurta.org> | 2010-04-22 11:07:41 +0300 |
---|---|---|
committer | Juri Linkov <juri@jurta.org> | 2010-04-22 11:07:41 +0300 |
commit | bda251782971a8b6c35d2006f6e5183430c6c268 (patch) | |
tree | efbbb802e188c7eca4dbf5f7912405eb34f5103f | |
parent | 6c06a283e29c0b8f0c6a796b085f687fb3dbe3fe (diff) | |
download | emacs-bda251782971a8b6c35d2006f6e5183430c6c268.tar.gz |
Add `set-window-configuration-from-sexp'.
-rw-r--r-- | README.TABS | 9 | ||||
-rw-r--r-- | src/window.c | 285 |
2 files changed, 290 insertions, 4 deletions
diff --git a/README.TABS b/README.TABS index fe3f74aabe0..99f02a4de6f 100644 --- a/README.TABS +++ b/README.TABS @@ -48,3 +48,12 @@ will open each file in a new tab. creates a new tab on the current Emacs frame. +* Window configuration functions: + + (current-window-configuration-to-sexp frame) - + returns a Lisp expression that represents the current window configuration. + + (set-window-configuration-from-sexp configuration) - + sets the configuration of windows and buffers from Lisp expression. + + diff --git a/src/window.c b/src/window.c index c8d5996edae..eb54637c747 100644 --- a/src/window.c +++ b/src/window.c @@ -6370,6 +6370,282 @@ delete_all_subwindows (w) Vwindow_list = Qnil; } + +static Lisp_Object +set_window_from_sexp (data, prev, parent, new_current_window) + Lisp_Object data, prev, parent, *new_current_window; +{ + register Lisp_Object tem; + register Lisp_Object window; + register struct window *w; + + if (!CONSP (data) + || !EQ (XCAR (data), intern ("saved-window"))) + wrong_type_argument (intern ("saved-window"), data); + + data = Fcdr (data); + + window = make_window (); + w = XWINDOW (window); + w->frame = selected_frame; + w->prev = prev; + w->parent = parent; + + tem = Fcdr (Fassq (intern ("current-window"), data)); + if (!NILP (tem)) + *new_current_window = window; + + tem = Fcdr (Fassq (intern ("next"), data)); + if (!NILP (tem)) + w->next = set_window_from_sexp (tem, window, Qnil, new_current_window); + + tem = Fcdr (Fassq (intern ("hchild"), data)); + if (!NILP (tem)) + w->hchild = set_window_from_sexp (tem, Qnil, window, new_current_window); + + tem = Fcdr (Fassq (intern ("vchild"), data)); + if (!NILP (tem)) + w->vchild = set_window_from_sexp (tem, Qnil, window, new_current_window); + + tem = Fassq (intern ("left-col"), data); + if (!NILP (tem)) + w->left_col = Fcdr (tem); + tem = Fassq (intern ("top-line"), data); + if (!NILP (tem)) + w->top_line = Fcdr (tem); + tem = Fassq (intern ("total-cols"), data); + if (!NILP (tem)) + w->total_cols = Fcdr (tem); + tem = Fassq (intern ("total-lines"), data); + if (!NILP (tem)) + w->total_lines = Fcdr (tem); + tem = Fassq (intern ("hscroll"), data); + if (!NILP (tem)) + w->hscroll = Fcdr (tem); + tem = Fassq (intern ("min-hscroll"), data); + if (!NILP (tem)) + w->min_hscroll = Fcdr (tem); + tem = Fassq (intern ("display-table"), data); + if (!NILP (tem)) + w->display_table = Fcdr (tem); + tem = Fassq (intern ("orig-top-line"), data); + if (!NILP (tem)) + w->orig_top_line = Fcdr (tem); + tem = Fassq (intern ("orig-total-lines"), data); + if (!NILP (tem)) + w->orig_total_lines = Fcdr (tem); + tem = Fassq (intern ("left-margin-cols"), data); + if (!NILP (tem)) + w->left_margin_cols = Fcdr (tem); + tem = Fassq (intern ("right-margin-cols"), data); + if (!NILP (tem)) + w->right_margin_cols = Fcdr (tem); + tem = Fassq (intern ("left-fringe-width"), data); + if (!NILP (tem)) + w->left_fringe_width = Fcdr (tem); + tem = Fassq (intern ("right-fringe-width"), data); + if (!NILP (tem)) + w->right_fringe_width = Fcdr (tem); + tem = Fassq (intern ("fringes-outside-margins"), data); + if (!NILP (tem)) + w->fringes_outside_margins = Fcdr (tem); + tem = Fassq (intern ("scroll-bar-width"), data); + if (!NILP (tem)) + w->scroll_bar_width = Fcdr (tem); + tem = Fassq (intern ("vertical-scroll-bar-type"), data); + if (!NILP (tem)) + w->vertical_scroll_bar_type = Fcdr (tem); + tem = Fassq (intern ("dedicated"), data); + if (!NILP (tem)) + w->dedicated = Fcdr (tem); + tem = Fassq (intern ("resize-proportionally"), data); + if (!NILP (tem)) + w->resize_proportionally = Fcdr (tem); + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); + + /* Reinstall the saved buffer and pointers into it. */ + tem = Fcdr (Fassq (intern ("buffer"), data)); + if (NILP (tem)) + w->buffer = Qnil; + else + { + w->buffer = Fget_buffer_create (tem); + + tem = Fcdr (Fassq (intern ("start-at-line-beg"), data)); + if (!NILP (tem)) + w->start_at_line_beg = tem; + tem = Fcdr (Fassq (intern ("start"), data)); + if (!NILP (tem)) + set_marker_restricted (w->start, tem, w->buffer); + tem = Fcdr (Fassq (intern ("pointm"), data)); + if (!NILP (tem)) + set_marker_restricted (w->pointm, tem, w->buffer); + else + Fgoto_char (1); + tem = Fcdr (Fassq (intern ("mark"), data)); + if (!NILP (tem)) + Fset_marker (XBUFFER (w->buffer)->mark, + tem, w->buffer); + } + + return (window); +} + +DEFUN ("set-window-configuration-from-sexp", Fset_window_configuration_from_sexp, + Sset_window_configuration_from_sexp, 1, 1, 0, + doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. +CONFIGURATION must be a Lisp expression previously returned +by `current-window-configuration-to-sexp' (which see). */) + (configuration) + Lisp_Object configuration; +{ + register Lisp_Object data; + register Lisp_Object tem, tem2; + Lisp_Object saved_windows; + Lisp_Object new_current_buffer; + Lisp_Object new_current_window; + Lisp_Object frame; + FRAME_PTR f; + + if (!CONSP (configuration) + || !EQ (XCAR (configuration), intern ("window-configuration"))) + wrong_type_argument (intern ("window-configuration"), configuration); + + data = Fcdr (configuration); + saved_windows = Fcdr (Fassq (intern ("saved-windows"), data)); + + new_current_buffer = Fcdr (Fassq (intern ("current-buffer"), data)); + new_current_window = Qnil; + + frame = selected_frame; + CHECK_LIVE_FRAME (frame); + f = XFRAME (frame); + + /* Rebuild the window tree in the selected frame. */ + if (FRAME_LIVE_P (f)) + { + register struct window *w; + register struct saved_window *p; + int k, i, n; + + /* If the frame has different sizes than in the window configuration, + we change the frame to the size specified in the + configuration, restore the configuration, and then resize it + back. We keep track of the prevailing height in these variables. */ + int previous_frame_lines = FRAME_LINES (f); + int previous_frame_cols = FRAME_COLS (f); + int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); + int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); + int previous_frame_tab_bar_lines = FRAME_TAB_BAR_LINES (f); + + /* The mouse highlighting code could get screwed up + if it runs during this. */ + BLOCK_INPUT; + + tem = Fcdr (Fassq (intern ("frame-lines"), data)); + if (!NILP (tem)) + { + CHECK_NUMBER (tem); + tem2 = Fcdr (Fassq (intern ("frame-cols"), data)); + if (!NILP (tem2)) + { + CHECK_NUMBER (tem2); + if (XINT (tem) != previous_frame_lines + || XINT (tem2) != previous_frame_cols) + change_frame_size (f, XINT (tem), + XINT (tem2), 0, 0, 0); + } + } + +#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS) + tem = Fcdr (Fassq (intern ("frame-menu-bar-lines"), data)); + if (!NILP (tem)) + { + CHECK_NUMBER (tem); + if (XINT (tem) != previous_frame_menu_bar_lines) + x_set_menu_bar_lines (f, tem, make_number (0)); + } +#ifdef HAVE_WINDOW_SYSTEM + tem = Fcdr (Fassq (intern ("frame-tool-bar-lines"), data)); + if (!NILP (tem)) + { + CHECK_NUMBER (tem); + if (XINT (tem) != previous_frame_tool_bar_lines) + x_set_tool_bar_lines (f, tem, make_number (0)); + } + tem = Fcdr (Fassq (intern ("frame-tab-bar-lines"), data)); + if (!NILP (tem)) + { + CHECK_NUMBER (tem); + if (XINT (tem) != previous_frame_tab_bar_lines) + x_set_tab_bar_lines (f, tem, make_number (0)); + } +#endif +#endif + + windows_or_buffers_changed++; + FRAME_WINDOW_SIZES_CHANGED (f) = 1; + + /* Mark all windows now on frame as "deleted". + Restoring the new configuration "undeletes" any that are in it. */ + delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f))); + + FRAME_ROOT_WINDOW (f) = set_window_from_sexp (saved_windows, Qnil, Qnil, + &new_current_window); + + if (!NILP (new_current_window)) + { + Fselect_window (new_current_window, Qnil); + XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window + = selected_window; + } + else + { + /* FIXME: what else? */ + /* Fselect_window (FRAME_ROOT_WINDOW (f), Qnil); */ + /* Fselect_window (XWINDOW (FRAME_ROOT_WINDOW (f))->hchild, Qnil); */ + } + + /* Set the screen height to the value it had before this function. */ + if (previous_frame_lines != FRAME_LINES (f) + || previous_frame_cols != FRAME_COLS (f)) + change_frame_size (f, previous_frame_lines, previous_frame_cols, + 0, 0, 0); +#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS) + if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) + x_set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines), + make_number (0)); +#ifdef HAVE_WINDOW_SYSTEM + if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f)) + x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines), + make_number (0)); + if (previous_frame_tab_bar_lines != FRAME_TAB_BAR_LINES (f)) + x_set_tab_bar_lines (f, make_number (previous_frame_tab_bar_lines), + make_number (0)); +#endif +#endif + + adjust_glyphs (f); + + UNBLOCK_INPUT; + + run_window_configuration_change_hook (f); + } + + if (!NILP (new_current_buffer)) + Fset_buffer (Fget_buffer_create (new_current_buffer)); + + tem = Fassq (intern ("minibuf-scroll-window"), data); + if (!NILP (tem)) + Vminibuf_scroll_window = Fcdr (tem); + tem = Fassq (intern ("minibuf-selected-window"), data); + if (!NILP (tem)) + minibuf_selected_window = Fcdr (tem); + + return (FRAME_LIVE_P (f) ? Qt : Qnil); +} + static int count_windows (window) @@ -6569,7 +6845,7 @@ redirection (see `redirect-frame-focus'). */) return (tem); } -static int +static Lisp_Object save_window_save_to_sexp (window) Lisp_Object window; { @@ -6663,9 +6939,9 @@ DEFUN ("current-window-configuration-to-sexp", Fcurrent_window_configuration_to_ Scurrent_window_configuration_to_sexp, 0, 1, 0, doc: /* Return a sexp representing the current window configuration of FRAME. If FRAME is nil or omitted, use the selected frame. -This describes the number of windows, their sizes and current buffers, -and for each displayed buffer, where display starts, and the positions of -point and mark. */) +This Lisp expression describes the number of windows, their sizes and +current buffers, and for each displayed buffer, where display starts, +and the positions of point and mark. */) (frame) Lisp_Object frame; { @@ -7507,6 +7783,7 @@ frame to be redrawn only if it is a tty frame. */); defsubr (&Swindow_configuration_p); defsubr (&Swindow_configuration_frame); defsubr (&Sset_window_configuration); + defsubr (&Sset_window_configuration_from_sexp); defsubr (&Scurrent_window_configuration); defsubr (&Scurrent_window_configuration_to_sexp); defsubr (&Ssave_window_excursion); |