]> git.eshelyaron.com Git - emacs.git/commitdiff
New functions to get current tab, window configurations and
authorJan Djärv <jan.h.d@swipnet.se>
Fri, 2 Apr 2010 14:55:34 +0000 (16:55 +0200)
committerJan Djärv <jan.h.d@swipnet.se>
Fri, 2 Apr 2010 14:55:34 +0000 (16:55 +0200)
to switch to a tab showing buffer.
Focus border around tabs removed.

lisp/native-tabs.el
src/gtkutil.c
src/gtkutil.h
src/window.c
src/xfns.c

index b271f9466aac60fbcc038954b75ace260e727b85..fffcd156d2e432f935b61df23c2a1a66741e8ef7 100644 (file)
@@ -88,6 +88,36 @@ documentation for additional customization information."
                         norecord)
          (delete-other-windows)))))
 
+
+(defun display-existing-buffer-in-tab (buffer-or-name &optional frame)
+  "Switch to a tab that shows BUFFER-OR-NAME on FRAME.
+FRAME nil means selected frame.
+
+Returns the key for the tab switch to, or nil if no tab displays 
+BUFFER-OR-NAME."
+  (let* ((buffer (if (bufferp buffer-or-name)
+                    buffer-or-name
+                  (get-buffer buffer-or-name)))
+        (tabs (if buffer (tab-configuration frame) nil))
+        (tab-key))
+    (while (and tabs (null tab-key))
+      (let* ((elt (car tabs))
+            (winconf (cadr elt))
+            (buffers (buffers-in-window-configuration winconf)))
+       (if (memq buffer buffers)
+           (setq tab-key (car elt))
+         (setq tabs (cdr tabs)))))
+    (if (and tab-key (not (equal tab-key (tab-current frame))))
+       (progn
+         (tab-show tab-key frame)
+         tab-key)
+      nil)))
+
+(defun switch-to-buffer-tab (buffer-or-name &optional frame)
+  (interactive "BSwitch to buffer:\nP")
+  (if (not (display-existing-buffer-in-tab buffer-or-name frame))
+      (switch-to-buffer buffer-or-name)))
+
 (defun handle-tab-event (event)
   "Handle tab-event to change tabs on the frame in EVENT."
   (interactive "e")
@@ -122,6 +152,7 @@ documentation for additional customization information."
       (global-set-key "\C-x70" 'tab-delete)
       (global-set-key "\C-x71" 'tab-delete-other)
       (global-set-key "\C-x72" 'tab-new)
+      (global-set-key "\C-x73" 'switch-to-buffer-tab)
       (global-set-key "\C-x7b" 'switch-to-buffer-other-tab)
       (global-set-key "\C-x7f" 'find-file-new-tab)
       (global-set-key "\C-x7o" 'tab-next)
index 13a12f172552aa34267955f9935bdd26f04f670c..2757a8acf3debfe3c38c7141f670f8384ca2fdce 100644 (file)
@@ -770,6 +770,21 @@ typedef struct tabs_gc_data_
 } tabs_gc_data;
   
 
+/* Store the current window configuration for frame F in widget W.  */
+
+static tabs_gc_data *
+xg_store_win_config (GtkWidget *w, FRAME_PTR f)
+{
+  Lisp_Object frame;
+  tabs_gc_data *conf = xmalloc (sizeof(*conf));
+  XSETFRAME (frame, f);
+  g_object_set_data (G_OBJECT (w), XG_TAB_CONFIG_KEY, conf);
+  xg_list_insert (&tabs_gc_list, &conf->ptrs);
+  conf->object = Fcurrent_window_configuration (frame);
+
+  return conf;
+}
+
 static void
 xg_check_show_tabs (FRAME_PTR f,
                     GtkNotebook *wnote)
@@ -893,14 +908,9 @@ xg_switch_page_cb (GtkNotebook     *wnote,
           tabs_gc_data *oconf = g_object_get_data (G_OBJECT (old),
                                                    XG_TAB_CONFIG_KEY);
           if (!oconf)
-            {
-              oconf = xmalloc (sizeof(*oconf));
-              g_object_set_data (G_OBJECT (old), XG_TAB_CONFIG_KEY, oconf);
-              xg_list_insert (&tabs_gc_list, &oconf->ptrs);
-            }
+            oconf = xg_store_win_config (old, f);
 
           XSETFRAME (frame, f);
-          oconf->object = Fcurrent_window_configuration (frame);
 
           EVENT_INIT (event);
           event.kind = TAB_EVENT;
@@ -1225,13 +1235,8 @@ xg_nb_window_create (GtkNotebook *source,
   tabs_gc_data *oconf = g_object_get_data (G_OBJECT (page),
                                            XG_TAB_CONFIG_KEY);
   XSETFRAME (frame, f);
-  if (!oconf)
-    {
-      oconf = xmalloc (sizeof(*oconf));
-      g_object_set_data (G_OBJECT (page), XG_TAB_CONFIG_KEY, oconf);
-      xg_list_insert (&tabs_gc_list, &oconf->ptrs);
-      oconf->object = Fcurrent_window_configuration (frame);
-    }
+  if (!oconf) oconf = xg_store_win_config (page, f);
+
 
   EVENT_INIT (event);
   event.kind = TAB_EVENT;
@@ -1244,6 +1249,88 @@ xg_nb_window_create (GtkNotebook *source,
   return notebook_on_hold = GTK_NOTEBOOK (gtk_notebook_new ());
 }
 
+int
+xg_tab_count (FRAME_PTR f)
+{
+  GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+  return wnote ? gtk_notebook_get_n_pages (wnote) : 1;
+}
+
+int
+xg_current_tab (FRAME_PTR f)
+{
+  GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+  return wnote ? gtk_notebook_get_current_page (wnote) : 0;
+}
+
+void
+xg_set_current_tab (FRAME_PTR f, const char *key)
+{
+  GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+  int i, pages = gtk_notebook_get_n_pages (wnote);
+  int page = -1;
+  int current_page = gtk_notebook_get_current_page (wnote);
+  if (pages == 1 || !key) return;
+
+  for (i = 0; i < pages; ++i) 
+    {
+      GtkWidget *w = gtk_notebook_get_nth_page (wnote, i);
+      char *k;
+      if (!w) continue;
+      k =  g_object_get_data (G_OBJECT (w), XG_TAB_KEY);
+      if (k && strcmp (k, key) == 0)
+        {
+              page = i;
+              break;
+        }
+    }
+  
+  if (page >= 0 && page < pages && page != current_page)
+    {
+      gtk_notebook_set_current_page (wnote, page);
+      xg_switch_page_cb (wnote, NULL, page, f);
+    }
+}
+
+
+
+const char *
+xg_get_tab_key (FRAME_PTR f, int nr)
+{
+  GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+  GtkWidget *w;
+
+  if (!wnote || nr >= gtk_notebook_get_n_pages (wnote)
+      || (w = gtk_notebook_get_nth_page (wnote, nr)) == NULL)
+    return NULL;
+
+  return (const char *)g_object_get_data (G_OBJECT (w), XG_TAB_KEY);
+}
+
+Lisp_Object
+xg_tab_get_win_config (FRAME_PTR f, int nr)
+{
+  GtkNotebook *wnote = GTK_NOTEBOOK (f->output_data.x->notebook_widget);
+  GtkWidget *w;
+  tabs_gc_data *conf;
+  
+  if (!wnote || nr >= gtk_notebook_get_n_pages (wnote)
+      || (w = gtk_notebook_get_nth_page (wnote, nr)) == NULL)
+    return Qnil;
+
+  conf = g_object_get_data (G_OBJECT (w), XG_TAB_CONFIG_KEY);
+  if (!conf) conf = xg_store_win_config (w, f);
+  else if (w == FRAME_GTK_WIDGET (f))
+    {
+      Lisp_Object frame;
+      XSETFRAME (frame, f);
+      conf->object = Fcurrent_window_configuration (frame);
+    }
+  return conf ? conf->object : Qnil;
+}
+
+
+
 /* Create and set up the GTK widgets for frame F.
    Return 0 if creation failed, non-zero otherwise.  */
 
index 194f2df9eef0bae190a3c813e53e652916637e9d..087f7d6df55d6180fcd1d77cee0384658394958a 100644 (file)
@@ -141,6 +141,12 @@ extern void xg_delete_all_tabs P_ ((FRAME_PTR f));
 extern void xg_set_tab_label P_ ((FRAME_PTR f, const char *label));
 extern void xg_tab_next P_ ((FRAME_PTR f));
 extern void xg_tab_previous P_ ((FRAME_PTR f));
+extern int xg_tab_count P_ ((FRAME_PTR f));
+extern int xg_current_tab P_ ((FRAME_PTR f));
+extern const char *xg_get_tab_key P_ ((FRAME_PTR f, int nr));
+extern void xg_set_current_tab P_ ((FRAME_PTR f, const char *key));
+
+extern Lisp_Object xg_tab_get_win_config P_ ((FRAME_PTR f, int nr));
 
 extern GtkWidget *xg_create_widget P_ ((char *type,
                                         char *name,
index 85b289558f608fafd0e22d2328ae26564e8280c3..4874b1c7ff61a2355c5b5ac1121c43b6cf862208 100644 (file)
@@ -6068,6 +6068,42 @@ DEFUN ("change-window-configuration-frame", Fchange_window_configuration_frame,
 #undef MAP_WINDOW
 }
 
+DEFUN ("buffers-in-window-configuration", Fbuffers_in_window_configuration,
+       Sbuffers_in_window_configuration, 1, 1, 0,
+       doc: /* Return a list of buffers that CONFIGURATION is showing.
+CONFIGURATION must be a value previously returned
+by `current-window-configuration' (which see).  */)
+     (configuration)
+     Lisp_Object configuration;
+{
+  struct save_window_data *data;
+  struct Lisp_Vector *saved_windows;
+  int k;
+  struct saved_window *p;
+  Lisp_Object buffers = Qnil, tail;
+
+  CHECK_WINDOW_CONFIGURATION (configuration);
+
+  data = (struct save_window_data *) XVECTOR (configuration);
+  saved_windows = XVECTOR (data->saved_windows);
+  for (k = 0; k < saved_windows->size; k++)
+    {
+      p = SAVED_WINDOW_N (saved_windows, k);
+      if (!NILP (p->buffer))
+        {
+          if (NILP (buffers))
+            tail = buffers = Fcons (p->buffer, Qnil);
+          else
+            {
+              XSETCDR (tail, Fcons (p->buffer, Qnil));
+              tail = XCDR (tail);
+            }
+        }
+    }
+
+  return buffers;
+}
+
 DEFUN ("set-window-configuration", Fset_window_configuration,
        Sset_window_configuration, 1, 1, 0,
        doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
@@ -7448,6 +7484,7 @@ frame to be redrawn only if it is a tty frame.  */);
   defsubr (&Swindow_configuration_p);
   defsubr (&Swindow_configuration_frame);
   defsubr (&Schange_window_configuration_frame);
+  defsubr (&Sbuffers_in_window_configuration);
   defsubr (&Sset_window_configuration);
   defsubr (&Scurrent_window_configuration);
   defsubr (&Ssave_window_excursion);
index 16a1958a40c9fe25efcf022ae5e7c4f5bff5405b..09f333ba400cfc92aeb35a9b5105fbb29602e549 100644 (file)
@@ -5991,6 +5991,93 @@ FRAME nil means use the selected frame.  */)
   return Qnil;
 }
 
+DEFUN ("tab-nr-of-tabs", Ftab_nr_of_tabs,
+       Stab_nr_of_tabs, 0, 1, 0,
+       doc: /* Return the number of tabs on FRAME.
+FRAME nil means use the selected frame.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  FRAME_PTR f = check_x_frame (frame);
+  int nr = 1;
+  Lisp_Object o;
+
+  
+  if (!f->no_tabs)
+    nr = xg_tab_count (f);
+  
+  XSETFASTINT (o, nr);
+  return o;
+}
+
+DEFUN ("tab-configuration", Ftab_configuration,
+       Stab_configuration, 0, 1, 0,
+       doc: /* Return the tab configuration on FRAME.
+FRAME nil means use the selected frame.
+Returns an alist where each element is of type (KEY  WINDOWCONFIG).
+KEY is the name of the tab as returned by `tab_new´.
+WINDOWCONFIG is the window configuration for the tab.
+
+If FRAME is a tab-less frame, returns nil.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  FRAME_PTR f = check_x_frame (frame);
+  int nr, i;
+  Lisp_Object cc = Qnil;
+
+  if (f->no_tabs) return Qnil;
+  nr = xg_tab_count (f);
+  for (i = 0; i < nr; ++i) 
+    {
+      Lisp_Object wc = xg_tab_get_win_config (f, i);
+      const char *key = xg_get_tab_key (f, i);
+
+      cc = Fcons (Fcons (key ? make_string (key, strlen (key)) : Qnil,
+                         NILP (wc) ? wc : Fcons (wc, Qnil)),
+                  cc);
+    }
+
+  return cc;
+}
+
+DEFUN ("tab-current", Ftab_current,
+       Stab_current, 0, 1, 0,
+       doc: /* Return the key for the current tab on FRAME.
+FRAME nil means use the selected frame.
+If FRAME is a tab-less frame, returns nil.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  FRAME_PTR f = check_x_frame (frame);
+  Lisp_Object cc = Qnil;
+  int nr;
+
+  if (f->no_tabs) return Qnil;
+  nr = xg_current_tab (f);
+  const char *key = xg_get_tab_key (f, nr);
+  return key ? make_string (key, strlen (key)) : Qnil;
+}
+
+DEFUN ("tab-show", Ftab_show,
+       Stab_show, 0, 2, 0,
+       doc: /* Make tab with key the current tab on FRAME.
+FRAME nil means use the selected frame.
+If FRAME is a tab-less frame or the key doesn't refer to a tab, do nothing.  */)
+     (key, frame)
+     Lisp_Object key, frame;
+{
+  FRAME_PTR f = check_x_frame (frame);
+  if (f->no_tabs) return Qnil;
+  CHECK_STRING (key);
+
+  BLOCK_INPUT;
+  xg_set_current_tab (f, SDATA (key));
+  UNBLOCK_INPUT;
+
+  return Qnil;
+}
+
 #endif
 
 void
@@ -6158,6 +6245,10 @@ the tool bar buttons.  */);
   defsubr (&Stab_next);
   defsubr (&Stab_previous);
   defsubr (&Stab_set_label);
+  defsubr (&Stab_nr_of_tabs);
+  defsubr (&Stab_configuration);
+  defsubr (&Stab_current);
+  defsubr (&Stab_show);
 
 #endif /* USE_GTK */