unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alin Soare <as1789@gmail.com>
To: Emacs Dev <emacs-devel@gnu.org>
Subject: Tabs for console.
Date: Fri, 3 Dec 2010 00:45:30 +0200	[thread overview]
Message-ID: <AANLkTikpZ53S2Ejs=4P1i3dK7RUic3W3QFNwPA-okD5f@mail.gmail.com> (raw)
In-Reply-To: <AANLkTimu7ki7YNian0Fxdcju=R=hMRUd9XUeDii0esRv@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 1625 bytes --]

Here it is. I spent 2 weeks to learn git, in order to be able to work with
emacs confortably, and now I am almost? expert in git LOL.

A first functional version. It is difficult to believe, isn't it? Those who
love the console will enjoy.

It is the 3rd time when I restart the tabs from scratch, and the first time
when I manage to get a result.

The first time I started coding tabs as frames. Every frame had a list of
frames, and those secondary frames appeared as tabs. I realized the idea was
bad and gave up.

The second try, I modified the Vframe_list. From a list of frames, I
transformed it into a list of lists of frames. Every such list represented a
group of tabs. Every frame had as tabs the frames from the same group with
it. It worked, but to develop the idea should have been modified half of
emacs!

Next, I had the idea, after a discussion with Stefan Monnier that tabs must
be implemented programmable.

I attach you an example. Tabs that implement window configuration.

The tabs are not finished. this is just the beginning.

The programmable tabs should implement everything, from window
configurations up to compilations and frames, and many more.

In order to be able to implement tabs as frames, the frames functionality
must be extended.

Every tab should have its own environment (see the conflict of the variable
cwc). Actor model of evaluation is good for this, but emacs does not have
lexical scope yet.

The code is not completed yet. I did not add comments yet.

Please look over the code. I will send a commented version next days. Until
then , I hope to receive your suggestion.




Alin

[-- Attachment #1.2: Type: text/html, Size: 1828 bytes --]

[-- Attachment #2: test-tabs.el --]
[-- Type: text/x-emacs-lisp, Size: 1710 bytes --]


;; evaluate this file sexp after sexp and follow the comments.

;; set a minimal environment
(progn
  (custom-set-faces
   '(current-tab-face ((t ( :inherit 'default-face  :foreground "lightblue" :bold t :underline t))))
   '(odd-tab-face    ((t ( :background "red"    :foreground "white" ))))
   '(even-tab-face   ((t ( :background "green"  :foreground "black")))))
  (set-frame-parameter (selected-frame) 'tab-bar-lines 4)
  (set-frame-parameter (selected-frame) 'menu-bar-lines 0))

;;make a few tabs from index #0 up to #9
(dotimes (i 10)
  (make-terminal-frame '((tab . t))))

;; make a tab #10 that keeps a window configuration. When it is created,
;; it memories the current win config. When it is activated, it
;; restores the memorized win config
(make-terminal-frame
 '((tab . t)
   (tab:init . (lambda () (setq cwce (current-window-configuration))))
   (tab:activate . (lambda () (set-window-configuration cwce)))
   (tab:deactivate . (lambda () (message "qqq")))))

;; change the window configuration
((lambda nil
   (split-window-vertically)
   (split-window-vertically)
   (split-window-horizontally)))
 
;; now activate the tab that keeps the memorized win config.  this
;; function disovered a bug in window configuration . LOL.  If you
;; change the tab-bar-lines or menu-bar-lines after creating the tab
;; #10 and before activatin it here, emacs crashes. LOL.
(set-frame-parameter (selected-frame) 'current-tab 10)

;; try it: now try to change the window config, activate tab #0, and
;; reactivate tab #10.

;; dump frame params
(progn
  (setq  eval-expression-print-length 5000
	 eval-expression-print-level  5000
	 print-level 5000
	 )
  (frame-parameters) )

;; that's all for now.





[-- Attachment #3: 0001-tabs-for-console.patch --]
[-- Type: text/x-patch, Size: 18265 bytes --]

From 3ecdbb0c879ebcf6d011211d14d89392993fd503 Mon Sep 17 00:00:00 2001
From: root <root@alin.(none)>
Date: Thu, 2 Dec 2010 23:53:41 +0200
Subject: [PATCH] tabs for console

---
 src/dispextern.h |    3 +
 src/frame.c      |  224 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/frame.h      |   25 +++++-
 src/window.c     |    5 +
 src/xdisp.c      |   76 ++++++++++++++++++
 src/xfaces.c     |   10 +++
 6 files changed, 333 insertions(+), 10 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 7426c03..2a87044 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1697,6 +1697,9 @@ enum face_id
   MOUSE_FACE_ID,
   MENU_FACE_ID,
   VERTICAL_BORDER_FACE_ID,
+  CURRENT_TAB_FACE_ID,
+  ODD_TAB_FACE_ID,
+  EVEN_TAB_FACE_ID,
   BASIC_FACE_ID_SENTINEL
 };
 
diff --git a/src/frame.c b/src/frame.c
index ba675be..a012066 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -118,16 +118,19 @@ Lisp_Object Qwindow_id;
 Lisp_Object Qouter_window_id;
 #endif
 Lisp_Object Qparent_id;
-Lisp_Object Qtitle, Qname;
+Lisp_Object Qtitle, Qname, Qtab_name, Qtab, Qcurrent_tab;
+Lisp_Object Qtab_code_init, Qtab_code_activate, Qtab_code_deactivate;
 Lisp_Object Qexplicit_name;
 Lisp_Object Qunsplittable;
-Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
+Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position, Qtab_bar_lines;
 Lisp_Object Vmenu_bar_mode, Vtool_bar_mode;
 Lisp_Object Qleft_fringe, Qright_fringe;
 Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
 Lisp_Object Qtty_color_mode;
 Lisp_Object Qtty, Qtty_type;
 
+Lisp_Object Qtab_activate, Qtab_deactivate, Qtab_init;
+
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
 Lisp_Object Qsticky;
 Lisp_Object Qfont_backend;
@@ -197,6 +200,146 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       adjust_glyphs (f);
     }
 }
+
+/* this is identical to set_menu_bar_lines_1 */
+static void
+set_tab_bar_lines_1 ( Lisp_Object window, int n)
+{
+  struct window *w = XWINDOW (window);
+
+  XSETFASTINT (w->last_modified, 0);
+  XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
+  XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
+
+  if (INTEGERP (w->orig_top_line))
+    XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
+  if (INTEGERP (w->orig_total_lines))
+    XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
+
+  /* Handle just the top child in a vertical split.  */
+  if (!NILP (w->vchild))
+    set_tab_bar_lines_1 (w->vchild, n);
+
+  /* Adjust all children in a horizontal split.  */
+  for (window = w->hchild; !NILP (window); window = w->next)
+    {
+      w = XWINDOW (window);
+      set_tab_bar_lines_1 (window, n);
+    }
+}
+
+static void
+set_tab_bar_lines (struct frame *f, Lisp_Object value)
+{
+    int nlines, olines, maxlines;
+    Lisp_Object frame, tab, dummy;
+
+    if (FRAME_MINIBUF_ONLY_P (f))
+	return;
+
+    XSETFRAME(frame, f);
+
+    if (INTEGERP (value))
+	nlines = XINT (value);
+    else
+	nlines = 0;
+
+    maxlines = FRAME_LINES (f) - 3 - /* editline + modeline + minibuf line = 3 */
+	FRAME_MENU_BAR_LINES (f) -
+	FRAME_TOOL_BAR_LINES (f);
+
+    (nlines > maxlines) && (nlines = maxlines);
+
+    struct frame *this;
+    this = XFRAME(frame);
+    olines = FRAME_TAB_BAR_LINES (this);
+    if (nlines != olines)
+    {
+	if (EQ (frame, selected_frame))
+            /* redisplay is required only when one changes the
+               selected tab */
+            windows_or_buffers_changed++;
+	FRAME_WINDOW_SIZES_CHANGED (this) = 1;
+	FRAME_TAB_BAR_LINES (this) = nlines;
+	set_tab_bar_lines_1 (this->root_window, nlines - olines);
+	adjust_glyphs (this);
+    }
+
+}
+
+void
+activate_tab (struct frame *f, int tab_index)
+{
+    Lisp_Object activatecode, tab;
+
+    FRAME_CURRENT_TAB (f) = tab_index;
+
+    tab = XCDR (AREF ( f->tab_bar_items, f->current_tab ) ) ;
+    
+    activatecode = Fassq (Qtab_activate, tab);
+    
+    if (! EQ (Qnil, activatecode))
+    {
+	activatecode = XCDR (activatecode);
+	return (void) Ffuncall (1, &activatecode);
+    }
+
+}
+
+void
+deactivate_tab (struct frame *f)
+{
+    Lisp_Object deactivatecode, tab;
+
+    tab = XCDR (AREF ( f->tab_bar_items, f->current_tab ) ) ;
+    
+    deactivatecode = Fassq (Qtab_deactivate, tab);
+    
+    if (! EQ (Qnil, deactivatecode))
+    {
+	deactivatecode = XCDR (deactivatecode);
+	return (void) Ffuncall (1, &deactivatecode);
+    }
+
+}
+
+void
+set_current_tab (struct frame *f, Lisp_Object value)
+{
+    int otab, tab;
+
+    if (FRAME_MINIBUF_ONLY_P (f))
+	return;
+
+    Lisp_Object frame;
+    XSETFRAME(frame, f);
+
+    if (INTEGERP (value))
+	tab = XINT (value);
+    else
+	return (void) deactivate_tab (f);
+
+    otab = FRAME_CURRENT_TAB (f);
+
+    /* no tag is active */
+    if (ASIZE (FRAME_TAB_BAR_ITEMS (f)) <= tab)
+	return (void) deactivate_tab (f);
+    
+    if (tab != otab)
+    {
+	if (EQ (frame, selected_frame))
+            /* redisplay is required only when one changes the
+               selected tab */
+            windows_or_buffers_changed++;
+	FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+	deactivate_tab (f);
+	activate_tab (f, tab);
+	adjust_glyphs (f);
+    }
+
+}
+
+
 \f
 Lisp_Object Vframe_list;
 
@@ -348,6 +491,10 @@ make_frame (int mini_p)
   f->font_driver_list = NULL;
   f->font_data_list = NULL;
 
+  f->tab_bar_items = Qnil;
+  f->current_tab = 0;
+  f->last_tab = 0;
+
   root_window = make_window ();
   if (mini_p)
     {
@@ -570,7 +717,6 @@ make_initial_frame (void)
   return f;
 }
 
-
 struct frame *
 make_terminal_frame (struct terminal *terminal)
 {
@@ -650,6 +796,44 @@ get_future_frame_param (Lisp_Object parameter,
   return result;
 }
 
+Lisp_Object
+add_tab (Lisp_Object parms)
+{
+  Lisp_Object tab, initcode, activatecode, deactivatecode;
+
+  Lisp_Object tab_object[4];
+
+
+  struct frame *sf = SELECTED_FRAME ();
+  if (sf->last_tab == 1000)
+    return;
+  char tab_name[]=" tab";
+
+  if (NILP (sf->tab_bar_items))
+    sf->tab_bar_items = Fmake_vector (make_number (1000), Qnil);
+
+  activatecode = Fassq (Qtab_activate, parms);
+  deactivatecode = Fassq (Qtab_deactivate, parms);
+
+  //tab = Fcons (make_string (tab_name, sizeof (tab_name)-1), Qnil);
+  tab_object[0] = make_string (tab_name, sizeof (tab_name)-1);
+  tab_object[1] = activatecode;
+  tab_object[2] = deactivatecode;
+  tab = Flist ( 3, tab_object );
+
+  ASET (sf->tab_bar_items, sf->last_tab++, tab);
+
+  initcode = Fassq (Qtab_init, parms);
+
+  if (! EQ (Qnil, initcode))
+    {
+      initcode = XCDR (initcode);
+      return Ffuncall (1, &initcode);
+    }
+
+  return Qnil;
+}
+
 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
        1, 1, 0,
        doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -674,10 +858,17 @@ affects all frames on the same terminal device.  */)
   Lisp_Object frame, tem;
   struct frame *sf = SELECTED_FRAME ();
 
+  Lisp_Object tab;
+
+  tab = Fassq (Qtab, parms);
+  if (! EQ (Qnil, tab))
+      return add_tab (parms);
+
+
 #ifdef MSDOS
   if (sf->output_method != output_msdos_raw
       && sf->output_method != output_termcap)
-    abort ();
+      abort ();
 #else /* not MSDOS */
 
 #ifdef WINDOWSNT                           /* This should work now! */
@@ -2286,9 +2477,13 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
   if (! FRAME_WINDOW_P (f))
     {
       if (EQ (prop, Qmenu_bar_lines))
-	set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
+	  set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
+      else if (EQ (prop, Qtab_bar_lines))
+	  set_tab_bar_lines (f, val);
       else if (EQ (prop, Qname))
 	set_term_frame_name (f, val);
+      else if (EQ (prop, Qcurrent_tab))
+      	set_current_tab (f, val);
     }
 
   if (EQ (prop, Qminibuffer) && WINDOWP (val))
@@ -2394,11 +2589,14 @@ If FRAME is omitted, return information on the currently selected frame.  */)
 #endif
     {
       /* This ought to be correct in f->param_alist for an X frame.  */
-      Lisp_Object lines;
+	Lisp_Object lines, items;
       XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
       store_in_alist (&alist, Qmenu_bar_lines, lines);
+      XSETFASTINT (lines, FRAME_TAB_BAR_LINES (f));
+      store_in_alist (&alist, Qtab_bar_lines, lines);
+      XSETFASTINT (lines, FRAME_CURRENT_TAB (f));
+      store_in_alist (&alist, Qcurrent_tab, lines);
     }
-
   UNGCPRO;
   return alist;
 }
@@ -2822,6 +3020,8 @@ static const struct frame_parm_table frame_parms[] =
   {"icon-type",			&Qicon_type},
   {"internal-border-width",	&Qinternal_border_width},
   {"menu-bar-lines",		&Qmenu_bar_lines},
+  {"tab-bar-lines",		&Qtab_bar_lines},
+  {"current-tab",		&Qcurrent_tab},
   {"mouse-color",		&Qmouse_color},
   {"name",			&Qname},
   {"scroll-bar-width",		&Qscroll_bar_width},
@@ -4443,6 +4643,16 @@ syms_of_frame (void)
   Qterminal_live_p = intern_c_string ("terminal-live-p");
   staticpro (&Qterminal_live_p);
 
+  Qtab = intern_c_string ("tab");
+  staticpro (&Qtab);
+
+  Qtab_activate = intern_c_string ("tab:activate");
+  staticpro (&Qtab_activate);
+  Qtab_deactivate = intern_c_string ("tab:deactivate");
+  staticpro (&Qtab_deactivate);
+  Qtab_init = intern_c_string ("tab:init");
+  staticpro (&Qtab_init);
+
 #ifdef HAVE_NS
   Qns_parse_geometry = intern_c_string ("ns-parse-geometry");
   staticpro (&Qns_parse_geometry);
diff --git a/src/frame.h b/src/frame.h
index 31f6017..b9084a2 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -171,6 +171,12 @@ struct frame
      Only the X toolkit version uses this.  */
   Lisp_Object menu_bar_vector;
 
+    /*
+     * a list with conses of the form ("string_tab_name" . (alist_tab_parameters))
+     */
+    Lisp_Object tab_bar_items;
+
+
   /* Predicate for selecting buffers for other-buffer.  */
   Lisp_Object buffer_predicate;
 
@@ -203,6 +209,13 @@ struct frame
   /* Cache of realized faces.  */
   struct face_cache *face_cache;
 
+    /*
+      the index of the last activated tab.
+     */
+    int current_tab;
+
+    int last_tab;
+
   /* Number of elements in `menu_bar_vector' that have meaningful data.  */
   EMACS_INT menu_bar_items_used;
 
@@ -360,6 +373,8 @@ struct frame
   /* Number of lines of menu bar.  */
   int menu_bar_lines;
 
+    int tab_bar_lines;
+
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
     || defined (HAVE_NS) || defined (USE_GTK)
   /* Nonzero means using a menu bar that comes from the X toolkit.  */
@@ -590,6 +605,11 @@ typedef struct frame *FRAME_PTR;
    These lines are counted in FRAME_LINES.  */
 #define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
 
+#define FRAME_CURRENT_TAB(f) f -> current_tab
+#define FRAME_TAB_BAR_ITEMS(f) f -> tab_bar_items
+#define FRAME_TAB_BAR_LINES(f) f -> tab_bar_lines
+
+
 /* Nonzero if this frame should display a tool bar
    in a way that does not use any text lines.  */
 #if defined (USE_GTK) || defined (HAVE_NS)
@@ -606,7 +626,7 @@ typedef struct frame *FRAME_PTR;
 /* Lines above the top-most window in frame F.  */
 
 #define FRAME_TOP_MARGIN(F) \
-     (FRAME_MENU_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F))
+     (FRAME_MENU_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F) + FRAME_TAB_BAR_LINES(F))
 
 /* Pixel height of the top margin above.  */
 
@@ -835,10 +855,9 @@ typedef struct frame *FRAME_PTR;
 #define FOR_EACH_FRAME(list_var, frame_var)			\
   for ((list_var) = Vframe_list;				\
        (CONSP (list_var)					\
-	&& (frame_var = XCAR (list_var), 1));		\
+	&& (frame_var = XCAR (list_var), 1));			\
        list_var = XCDR (list_var))
 
-
 extern Lisp_Object Qframep, Qframe_live_p;
 extern Lisp_Object Qtty, Qtty_type;
 extern Lisp_Object Qtty_color_mode;
diff --git a/src/window.c b/src/window.c
index a2a0c79..7096488 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5832,6 +5832,7 @@ struct save_window_data
 
     int frame_cols, frame_lines, frame_menu_bar_lines;
     int frame_tool_bar_lines;
+    int frame_tab_bar_lines;
   };
 
 /* This is saved as a Lisp_Vector  */
@@ -5963,6 +5964,7 @@ the return value is nil.  Otherwise the value is t.  */)
       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.  */
@@ -6414,6 +6416,7 @@ redirection (see `redirect-frame-focus').  */)
   data->frame_lines = FRAME_LINES (f);
   data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
   data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
+  data->frame_tab_bar_lines = FRAME_TAB_BAR_LINES (f);
   data->selected_frame = selected_frame;
   data->current_window = FRAME_SELECTED_WINDOW (f);
   XSETBUFFER (data->current_buffer, current_buffer);
@@ -6910,6 +6913,8 @@ compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positi
     return 0;
   if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines)
     return 0;
+  if (d1->frame_tab_bar_lines != d2->frame_tab_bar_lines)
+    return 0;
   if (! EQ (d1->selected_frame, d2->selected_frame))
     return 0;
   /* Don't compare the current_window field directly.
diff --git a/src/xdisp.c b/src/xdisp.c
index 77e9db2..1865eb0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1059,6 +1059,8 @@ static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lis
 static const char *decode_mode_spec (struct window *, int, int, int,
 				     Lisp_Object *);
 static void display_menu_bar (struct window *);
+static void display_tab_bar (struct window *w);
+
 static int display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT, int,
 				EMACS_INT *);
 static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
@@ -14575,6 +14577,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       && EQ (FRAME_SELECTED_WINDOW (f), window))
     {
       int redisplay_menu_p = 0;
+      int redisplay_tab_p = 0;
       int redisplay_tool_bar_p = 0;
 
       if (FRAME_WINDOW_P (f))
@@ -14589,9 +14592,14 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       else
         redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
 
+      redisplay_tab_p = FRAME_TAB_BAR_LINES (f) > 0;
+
       if (redisplay_menu_p)
         display_menu_bar (w);
 
+      if (redisplay_tab_p)
+	  display_tab_bar (w);
+
 #ifdef HAVE_WINDOW_SYSTEM
       if (FRAME_WINDOW_P (f))
         {
@@ -18176,6 +18184,74 @@ See also `bidi-paragraph-direction'.  */)
     }
 }
 
+void
+display_tab_bar (struct window *w)
+{
+    const int tab_length = 10;
+
+    struct frame *fr = XFRAME (WINDOW_FRAME (w));
+
+    struct it it;
+    int index;
+    init_iterator (&it, w, -1, -1,
+		   fr->desired_matrix->rows + FRAME_MENU_BAR_LINES (fr),
+		   DEFAULT_FACE_ID);
+    it.first_visible_x = 0;
+    it.last_visible_x = FRAME_COLS (fr);
+
+  /* Clear all rows of the menu bar.  */
+  for (index = 0;
+       index < FRAME_TAB_BAR_LINES (fr);
+       ++index)
+    {
+      struct glyph_row *row = it.glyph_row + index;
+      clear_glyph_row (row);
+      row->enabled_p = 1;
+      row->full_width_p = 1;
+    }
+
+  int ii=0, oddrow=0, oddcol=0;
+  Lisp_Object tab, s;
+  while (!NILP (tab = AREF (fr->tab_bar_items, ii))) 
+  {
+      if (it. hpos + tab_length > FRAME_COLS (fr))
+      {
+	  /* Fill out the line with spaces.  */
+	  it.base_face_id = DEFAULT_FACE_ID;
+	  while (it.current_x < it.last_visible_x)
+	      display_string (" ", Qnil, Qnil, 0, 0,  &it, 1, 0, 0, -1);
+
+  	  if (unix == (it.current_y + 1))
+	      oddcol = ii % 2;
+
+	  oddrow = (oddcol)? (ii%2) : !oddrow;
+
+      	  it.hpos = it.current_x = 0;
+	  it.current_y ++;
+      	  ++it.vpos;
+      	  it.glyph_row++;
+	  if (it.current_y > FRAME_TAB_BAR_LINES (fr))
+      	      break;
+      }
+
+      it.base_face_id = (ii == FRAME_CURRENT_TAB (fr)) ? CURRENT_TAB_FACE_ID :
+      	   oddrow ? ODD_TAB_FACE_ID :
+      	  EVEN_TAB_FACE_ID;
+      
+      int len = SCHARS (XCAR(tab)) > tab_length ? tab_length: SCHARS (XCAR (tab));
+      s = Fsubstring (XCAR (tab), make_number(0), make_number (len));
+      display_string (NULL, s, Qnil, 0, 0, &it, tab_length, 0, 0, -1);
+
+      oddrow = ! oddrow;
+      ii++;
+  }
+
+  
+  /* Compute the total height of the lines.  */
+  compute_line_metrics (&it);
+
+}
+
 
 \f
 /***********************************************************************
diff --git a/src/xfaces.c b/src/xfaces.c
index 5c7cfe6..3e14a64 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -348,6 +348,7 @@ Lisp_Object Qframe_set_background_mode;
 Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
 Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
 Lisp_Object Qmode_line_inactive, Qvertical_border;
+Lisp_Object Qodd_tab_face, Qeven_tab_face, Qcurrent_tab_face;
 
 /* The symbol `face-alias'.  A symbols having that property is an
    alias for another face.  Value of the property is the name of
@@ -5389,6 +5390,9 @@ realize_basic_faces (struct frame *f)
       realize_named_face (f, Qmouse, MOUSE_FACE_ID);
       realize_named_face (f, Qmenu, MENU_FACE_ID);
       realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
+      realize_named_face (f, Qcurrent_tab_face, CURRENT_TAB_FACE_ID);
+      realize_named_face (f, Qodd_tab_face, ODD_TAB_FACE_ID);
+      realize_named_face (f, Qeven_tab_face, EVEN_TAB_FACE_ID);
 
       /* Reflect changes in the `menu' face in menu bars.  */
       if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
@@ -6659,6 +6663,12 @@ syms_of_xfaces (void)
   staticpro (&Qmode_line_inactive);
   Qvertical_border = intern_c_string ("vertical-border");
   staticpro (&Qvertical_border);
+  Qcurrent_tab_face = intern ("current-tab-face");
+  staticpro (&Qcurrent_tab_face);
+  Qodd_tab_face = intern ("odd-tab-face");
+  staticpro (&Qodd_tab_face);
+  Qeven_tab_face = intern ("even-tab-face");
+  staticpro (&Qeven_tab_face);
   Qtty_color_desc = intern_c_string ("tty-color-desc");
   staticpro (&Qtty_color_desc);
   Qtty_color_standard_values = intern_c_string ("tty-color-standard-values");
-- 
1.7.1


  reply	other threads:[~2010-12-02 22:45 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <AANLkTim8zuFRh2L81g9KgtDon=U5Mvr+QO+HWGE1nqXP@mail.gmail.com>
2010-10-27 16:39 ` Fwd: Tabs for console Alin Soare
2010-11-08 19:22   ` Stefan Monnier
2010-11-08 19:51     ` Alin Soare
     [not found]       ` <AANLkTim8BoGpECQUUNfPidbn2k_HP77sykR=HYqw9BOE@mail.gmail.com>
     [not found]         ` <AANLkTinPBfV8OC7d9qOBWGW6130D2nXjg+=Nv2rKqMr1@mail.gmail.com>
     [not found]           ` <jwvhbewqnjj.fsf-monnier+emacs@gnu.org>
2010-12-02 22:43             ` Alin Soare
2010-12-02 22:45               ` Alin Soare [this message]
2010-12-03  8:19                 ` martin rudalics
2010-12-03  9:37                 ` Andreas Schwab
2010-12-04 21:48                   ` Alin Soare
2010-12-03  9:52                 ` Andreas Schwab
2010-12-03 11:11                   ` Alin Soare
2010-12-03 12:29                     ` Dimitri Fontaine
2010-12-04 21:42                       ` Alin Soare
2010-12-04 21:55                       ` Alin Soare
2011-03-11  8:52       ` A Soare
     [not found]     ` <AANLkTikwua2bfyvJkt+sn2vR_CzTZA6Hs0Lw=NJSVwT4@mail.gmail.com>
     [not found]       ` <jwvd3peoig0.fsf-monnier+emacs@gnu.org>
     [not found]         ` <AANLkTikPRKbvq0mg2X1Huio1z5sF3UvF6+cpT10mH-H-@mail.gmail.com>
     [not found]           ` <jwvzksilkfd.fsf-monnier+emacs@gnu.org>
     [not found]             ` <AANLkTi=MiubmGJ_Gk9OVzHY7uc+DOkHHpj5Ht+j7uNx8@mail.gmail.com>
     [not found]               ` <jwvtyiqk2al.fsf-monnier+emacs@gnu.org>
     [not found]                 ` <AANLkTi=0g00xn2P_yKE0gGkH-ZaZSvz+8yY=yy2=-6W=@mail.gmail.com>
     [not found]                   ` <jwvsjyai7lv.fsf-monnier+emacs@gnu.org>
2010-12-07  4:47                     ` Fwd: " Alin Soare
2010-12-07  4:50                       ` Alin Soare
2010-12-07 17:06                       ` Stefan Monnier
2010-12-08  8:14                         ` Alin Soare
     [not found]                           ` <AANLkTikaXr_4bVR2_v7HVFfPB93Sw10e63cKqTRwOunS@mail.gmail.com>
2010-12-08 11:16                             ` Alin Soare
2010-12-09  4:29                           ` Fwd: " Stefan Monnier
2010-12-09  8:26                             ` Alin Soare
2010-12-10  3:35                               ` Stefan Monnier
2010-12-10  8:15                                 ` Alin Soare
2010-12-10 20:13                                   ` Stefan Monnier
2010-12-10 21:09                                     ` Alin Soare
2010-12-10 21:23                                       ` Davis Herring
2010-12-10 21:34                                         ` Alin Soare
2010-12-12 20:02                                           ` Alin Soare
2010-12-13 17:23                                             ` Stefan Monnier
2010-12-13 21:01                                               ` Alin Soare
2010-12-14 15:25                                 ` Alin Soare
2010-10-27 20:34 ` Alin Soare
2010-10-29  7:49 Alin Soare
  -- strict thread matches above, loose matches on Subject: below --
2010-12-21  1:14 Richard Stallman

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='AANLkTikpZ53S2Ejs=4P1i3dK7RUic3W3QFNwPA-okD5f@mail.gmail.com' \
    --to=as1789@gmail.com \
    --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).