unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Tabs for console.
       [not found] <AANLkTim8zuFRh2L81g9KgtDon=U5Mvr+QO+HWGE1nqXP@mail.gmail.com>
  2010-10-27 16:39 ` Fwd: " Alin Soare
@ 2010-10-27 20:34 ` Alin Soare
  1 sibling, 0 replies; 15+ messages in thread
From: Alin Soare @ 2010-10-27 20:34 UTC (permalink / raw)
  To: Emacs Dev

[-- Attachment #1: Type: text/plain, Size: 3605 bytes --]

I send again my previous message, because my previous message contained the
attachments, and on emacs-devel lists seems there were errors inside the
text.


I do not attach the patch again (it has unciompressed more than 700K, and it
is not complete ). I hope to send it without errors now.

------


I worked long time ago on tabs for console, as many of you already know.

1 year ago I reopened the tabs, and started from scratch, having a different
idea. Afterwards I realized the idea was not good, and gave up again.

3 days ago I reopened the problem, and started to re-written it again from
scratch.

Concretely, this time I do not want to miss again.

I do not want to work alone this time. I want to receive your suggestions.

I have already talked about this with Stefan Monnier, and I want to
implement it as agreed with him.

A tab is a formed from a few scripts: an initialization script, an
activation script, a deactivation script, etc.

Here is the patch.

I tried to create a tab that represents a frame with this code:

(setq init-tab
      '( (+ 1 2)
     (setq fr (make-terminal-frame '((tab . t)))) ) )

(setq act-tab
      '( (message "activate")
     (select-frame fr) ) )

(setq deact-tab
      '( (message "hide tab") ) )

(make-tab (list (cons 'tab-code:init init-tab )
        (cons 'tab-code:activate act-tab )
        (cons 'tab-code:deactivate deact-tab )
        ) )

(activate-tab 0)

The parameter '0' of `activate-tab' means to activate the first TAB of the
selected frame. It calls the activation script of the first tab, after it
calls the deactivation script of the last activated tab (if any).

I attach the output of git diff, and a test file test-tabs.el.

In order to test it, you have to evaluate make-tab a few times, and
afterwards (activate-tab 0)

There is some code inserted in patch, and commented . It rested from the
previous tries to do the tabs, and it is no longer useful.

Do not expect too much ; the patch I send today makes emacs crash after a
short period of use of tabs :). Do not install it on your good sources :).
(the garbage collector makes it crash, and i do not see what variable is not
protected using gcpro..). This is of second importance for now. The bugs
will be corrected. Also, take care that the cashes of fonts are not cleared,
and when you switch to the tab-frame, the redisplay-internal will not
display correctly, and crashes. I forgot how to initialize the fonts for a
frame. When you switch back with a command like

 (let ((f (car
(frame-list))))

  (select-frame f))

it displays the main frame correctly.

For me to be able to finish this work, it is important/crucial for you to
suggest me how to do it, in order to agree on the behavior of tabs. It is
sure I cannot do this job alone. On the other hand, please report me bugs,
and suggestions to solve them :) )

I definitively want to make the tabs as scripts. A particular set of scripts
will create tabs as frames, another set as window-configurations, another
set will be tabs for compilation, etc. Had emacs had lexical scoping, it
would be easier to define the scripts. In dynamic scoping, for each tab one
needs a variable with a different name to keep a tab-frame inside the
scripts of that tab. I also modified make-terminal-frame, in order to be
able to create frames that are not linked into frame-list. I call the frames
of frame-list "main frames" (as you see in frame.h).

For the next period of time I am able to work on this. I am waiting for your
suggestions. It depends only on you if I continue to work and finish the
tabs for console or not.


Alin.

[-- Attachment #2: Type: text/html, Size: 4535 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
@ 2010-10-29  7:49 Alin Soare
  0 siblings, 0 replies; 15+ messages in thread
From: Alin Soare @ 2010-10-29  7:49 UTC (permalink / raw)
  To: Emacs Dev

[-- Attachment #1: Type: text/plain, Size: 437 bytes --]

How can I create the diff using git, such that I see the hunks in the diff
file in Berkeley context format, and see only the changes I did ?

Please try to propose me scripts of creating tabs that keep frames. It is
not too clear for me how such scripts can be created , such that you find
the tabs of type frame useful for you. If you propose me such scripts as you
need it, I can modify the code to make it behave on your needs.

Alin

[-- Attachment #2: Type: text/html, Size: 476 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Tabs for console.
       [not found]           ` <jwvhbewqnjj.fsf-monnier+emacs@gnu.org>
@ 2010-12-02 22:43             ` Alin Soare
  2010-12-02 22:45               ` Alin Soare
  0 siblings, 1 reply; 15+ messages in thread
From: Alin Soare @ 2010-12-02 22:43 UTC (permalink / raw)
  To: Emacs Dev

[-- Attachment #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 #2: Type: text/html, Size: 1742 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Tabs for console.
  2010-12-02 22:43             ` Alin Soare
@ 2010-12-02 22:45               ` Alin Soare
  2010-12-03  8:19                 ` martin rudalics
                                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Alin Soare @ 2010-12-02 22:45 UTC (permalink / raw)
  To: Emacs Dev


[-- 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


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  2010-12-02 22:45               ` Alin Soare
@ 2010-12-03  8:19                 ` martin rudalics
  2010-12-03  9:37                 ` Andreas Schwab
  2010-12-03  9:52                 ` Andreas Schwab
  2 siblings, 0 replies; 15+ messages in thread
From: martin rudalics @ 2010-12-03  8:19 UTC (permalink / raw)
  To: Alin Soare; +Cc: Emacs Dev

FWIW the code for set_menu_bar_lines has a bug which allows it to
virtually remove a one line high window at the top of a frame.  I never
investigated the consequences of this but would strongly advise you to
not do the same in set_tab_bar_lines.

martin



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  2010-12-02 22:45               ` Alin Soare
  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
  2 siblings, 1 reply; 15+ messages in thread
From: Andreas Schwab @ 2010-12-03  9:37 UTC (permalink / raw)
  To: Alin Soare; +Cc: Emacs Dev

Alin Soare <as1789@gmail.com> writes:

> From 3ecdbb0c879ebcf6d011211d14d89392993fd503 Mon Sep 17 00:00:00 2001
> From: root <root@alin.(none)>

Never work as root.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  2010-12-02 22:45               ` Alin Soare
  2010-12-03  8:19                 ` martin rudalics
  2010-12-03  9:37                 ` Andreas Schwab
@ 2010-12-03  9:52                 ` Andreas Schwab
  2010-12-03 11:11                   ` Alin Soare
  2 siblings, 1 reply; 15+ messages in thread
From: Andreas Schwab @ 2010-12-03  9:52 UTC (permalink / raw)
  To: Alin Soare; +Cc: Emacs Dev

frame.c: In function ‘set_tab_bar_lines’:
frame.c:251: warning: value computed is not used
frame.c:253: warning: ISO C90 forbids mixed declarations and code
frame.c:235: warning: unused variable ‘dummy’
frame.c:235: warning: unused variable ‘tab’
frame.c: In function ‘set_current_tab’:
frame.c:314: warning: ISO C90 forbids mixed declarations and code
frame.c: In function ‘add_tab’:
frame.c:809: warning: ‘return’ with no value, in function returning non-void
frame.c:810: warning: ISO C90 forbids mixed declarations and code
frame.c: In function ‘Fframe_parameters’:
frame.c:2592: warning: unused variable ‘items’

xdisp.c: In function ‘display_tab_bar’:
xdisp.c:18213: warning: ISO C90 forbids mixed declarations and code
xdisp.c:18241: warning: ISO C90 forbids mixed declarations and code

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  2010-12-03  9:52                 ` Andreas Schwab
@ 2010-12-03 11:11                   ` Alin Soare
  2010-12-03 12:29                     ` Dimitri Fontaine
  0 siblings, 1 reply; 15+ messages in thread
From: Alin Soare @ 2010-12-03 11:11 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Emacs Dev

[-- Attachment #1: Type: text/plain, Size: 1271 bytes --]

2010/12/3 Andreas Schwab <schwab@linux-m68k.org>

> frame.c: In function ‘set_tab_bar_lines’:
> frame.c:251: warning: value computed is not used
> frame.c:253: warning: ISO C90 forbids mixed declarations and code
> frame.c:235: warning: unused variable ‘dummy’
> frame.c:235: warning: unused variable ‘tab’
> frame.c: In function ‘set_current_tab’:
> frame.c:314: warning: ISO C90 forbids mixed declarations and code
> frame.c: In function ‘add_tab’:
> frame.c:809: warning: ‘return’ with no value, in function returning
> non-void
> frame.c:810: warning: ISO C90 forbids mixed declarations and code
> frame.c: In function ‘Fframe_parameters’:
> frame.c:2592: warning: unused variable ‘items’
>
> xdisp.c: In function ‘display_tab_bar’:
> xdisp.c:18213: warning: ISO C90 forbids mixed declarations and code
> xdisp.c:18241: warning: ISO C90 forbids mixed declarations and code
>
>
I compiled using

CFLAGS="-g -O0 -Wdeclaration-after-statement -Wno-pointer-sign
-fno-crossjumping -g3 -gdwarf-2" ./configure --without-x

and I ommited -Wall...

I send another version soon.

Please come with ideas about extending the frames, such that to be able to
write scripts to create tabs that play with frames...

[-- Attachment #2: Type: text/html, Size: 1665 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  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
  0 siblings, 2 replies; 15+ messages in thread
From: Dimitri Fontaine @ 2010-12-03 12:29 UTC (permalink / raw)
  To: Alin Soare; +Cc: Andreas Schwab, Emacs Dev

Alin Soare <as1789@gmail.com> writes:
> Please come with ideas about extending the frames, such that to be able to
> write scripts to create tabs that play with frames...

What do you think about solutions such as escreen, elscreen or
workgroups?

  http://www.splode.com/~friedman/software/emacs-lisp/src/escreen.el
  http://www.morishima.net/~naoto/software/elscreen/index.php.en
  https://github.com/tlh/workgroups.el

Regards,
-- 
dim



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  2010-12-03 12:29                     ` Dimitri Fontaine
@ 2010-12-04 21:42                       ` Alin Soare
  2010-12-04 21:55                       ` Alin Soare
  1 sibling, 0 replies; 15+ messages in thread
From: Alin Soare @ 2010-12-04 21:42 UTC (permalink / raw)
  To: Emacs Dev


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

This is a version in which I added an environment for every tab. For now,
there is no reason to make the environment an obarray, but this will be
required if others want to write scripts that give other definitions for a
tab, but for window configurations. For me, it is enough to know that only
the tab:init function changes that environment, and I find the winconfig
variable on the cadr position.

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

[-- Attachment #2: 0001-tabs-for-console-tabs-as-window-configuration.patch --]
[-- Type: text/x-patch, Size: 19720 bytes --]

From e369ad3fc8c95e81e0d84758896297cf970b324a 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 - tabs as window configuration

---
 src/dispextern.h |    3 +
 src/frame.c      |  240 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/frame.h      |   31 ++++++-
 src/window.c     |    5 +
 src/xdisp.c      |   79 ++++++++++++++++++
 src/xfaces.c     |   10 ++
 6 files changed, 359 insertions(+), 9 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..b90bff3 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -118,16 +118,20 @@ 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_env;
+Lisp_Object Qtab_list;
 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 +201,149 @@ 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;
+
+    if (FRAME_MINIBUF_ONLY_P (f))
+	return;
+
+    XSETFRAME(frame, f);
+
+    if (INTEGERP (value))
+	nlines = XINT (value);
+    else
+	nlines = 0;
+
+    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) = XINT (tab_index);
+    tab = Fnth ( tab_index, f -> tab_bar_items ) ;
+    activatecode = Fassq (Qtab_activate, tab);
+    if (! EQ (Qnil, activatecode))
+    {
+	activatecode = XCDR (activatecode);
+	return (void) Ffuncall (1, &activatecode);
+    }
+}
+
+void
+deactivate_tab (struct frame *f)
+{
+    return;
+    Lisp_Object deactivatecode, tab;
+    tab = 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 (Flength (FRAME_TAB_BAR_ITEMS (f)) <= value)
+	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, value);
+	adjust_glyphs (f);
+    }
+
+}
+
+void
+add_tab_environment (struct frame *f,
+		     Lisp_Object prop)
+{
+    Lisp_Object env, l;
+    l = Fnth (make_number (f->current_tab), f->tab_bar_items);
+    if (NILP(prop))
+	return;
+    return;
+    env = Fcons (prop,
+		 XCDR (Fassq (Qtab_env,
+			      XCDR ( AREF (f->tab_bar_items, f->current_tab)))));
+//    env = Fcons (Qtab_env, Fcons ( prop, XCDR (env) ) );
+    store_in_alist (&l, Qtab_env, env);
+    
+}
+
+
 \f
 Lisp_Object Vframe_list;
 
@@ -348,6 +495,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 +721,6 @@ make_initial_frame (void)
   return f;
 }
 
-
 struct frame *
 make_terminal_frame (struct terminal *terminal)
 {
@@ -650,6 +800,44 @@ get_future_frame_param (Lisp_Object parameter,
   return result;
 }
 
+Lisp_Object
+add_tab (Lisp_Object parms)
+{
+    Lisp_Object tab_name, initcode, activatecode, deactivatecode, tab, env, name;
+    
+    Lisp_Object tab_object[4];
+
+  struct frame *sf = SELECTED_FRAME ();
+  if (sf->last_tab == 1000)
+    return Qnil;
+
+  activatecode = Fassq (Qtab_activate, parms);
+  deactivatecode = Fassq (Qtab_deactivate, parms);
+  env = Fassq (Qtab_env, parms);
+  name = Fassq (Qtab_name, parms);
+  
+  name = NILP (name) ? make_string (" tab", 4) : XCDR (name);
+
+  tab_name = Fcons (Qtab_name, name);
+  tab_object[0] = NILP (tab_name) ? Qnil:Fcons (tab_name, Qnil);
+  tab_object[1] = NILP (activatecode) ? Qnil: Fcons (activatecode, Qnil);
+  tab_object[2] = NILP (deactivatecode) ? Qnil:Fcons (deactivatecode, Qnil);
+  tab_object[3] = NILP (env) ? Qnil:Fcons (env, Qnil);
+  tab = Fappend ( 4, tab_object );
+
+  /* ASET (sf->tab_bar_items, sf->last_tab++, tab); */
+  Lisp_Object new[2];
+  new[0] = sf->tab_bar_items;
+  new[1] = Fcons (tab, Qnil);
+
+  sf->tab_bar_items = Fappend ( 2,  new);
+
+  initcode = Fassq (Qtab_init, parms);
+
+  /* sf->last_tab++; */
+  return make_number (sf->last_tab++);
+}
+
 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
        1, 1, 0,
        doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -674,6 +862,13 @@ 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)
@@ -2286,9 +2481,15 @@ 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);
+      else if (EQ (prop, Qtab_env))
+      	add_tab_environment (f, val);
     }
 
   if (EQ (prop, Qminibuffer) && WINDOWP (val))
@@ -2394,11 +2595,19 @@ 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, tabenv;
       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);
+      tabenv= Fcdr ( Fassq (Qtab_env,
+			    Fnth (make_number (f->current_tab), f->tab_bar_items)));
+      store_in_alist (&alist, Qtab_env, tabenv);
+      /* provide an informal reference to tabs. */
+      store_in_alist (&alist, Qtab_list, f->tab_bar_items);
     }
-
   UNGCPRO;
   return alist;
 }
@@ -2822,6 +3031,9 @@ 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},
+  {"tab-list",                  &Qtab_list},
   {"mouse-color",		&Qmouse_color},
   {"name",			&Qname},
   {"scroll-bar-width",		&Qscroll_bar_width},
@@ -4443,6 +4655,22 @@ 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_env = intern_c_string ("tab:env");
+  staticpro (&Qtab_env);
+
+  Qtab_name = intern_c_string ("tab:name");
+  staticpro (&Qtab_name);
+
+  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..3110fd4 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.  */
 
@@ -832,13 +852,18 @@ typedef struct frame *FRAME_PTR;
    supported.  An alternate definition of the macro would expand to
    something which executes the statement once.  */
 
+#define FOR_EACH_TAB(frame, list_var, tab_var)			\
+    for ((list_var) = frame->tab_bar_items;			\
+	 (CONSP (list_var)					\
+	  && (tab_var = XCAR (list_var), 1));			\
+	 list_var = XCDR (list_var))
+
 #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..bbd8bd3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -330,6 +330,8 @@ Lisp_Object Qinhibit_eval_during_redisplay;
 Lisp_Object Qbuffer_position, Qposition, Qobject;
 Lisp_Object Qright_to_left, Qleft_to_right;
 
+Lisp_Object Qtab_name;
+
 /* Cursor shapes */
 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
 
@@ -1059,6 +1061,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 +14579,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 +14594,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 +18186,75 @@ 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, tab_list, s;
+  FOR_EACH_TAB (fr, tab_list, tab)
+  {
+      Lisp_Object tabname = Fcdr (Fassq (Qtab_name, tab));
+      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 (tabname) > tab_length ? tab_length: SCHARS (tabname);
+      s = Fsubstring (tabname, 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


[-- Attachment #3: test-tabs.el --]
[-- Type: text/x-emacs-lisp, Size: 2221 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))

;; this is a definition of a tab as a window configuration
(defun make-wc-tab (parms)
  ;; save curent win config
  (setq sym (make-symbol "winconfig"))
  (set sym  (current-window-configuration))
  ;; make a tab 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
   (list '(tab . t)
	 '(tab:name . "WinC")
	 '(tab:activate
	   .
	   (lambda ()
	     (set-window-configuration
	      (eval (cdr (assoc 'tab:env (frame-parameters) ) ) ) ) ) )
	 ;; save the current win config into the tab environment
	 (cons 'tab:env sym) ) ) )

;; make a first tab keeping current win config
(make-wc-tab nil)

;; alter the window configuration
((lambda nil
   (split-window-vertically)))

;; make a second tab keeping current win config
(make-wc-tab nil)

;; alter the window configuration
((lambda nil
   (split-window-horizontally)))

;; make a third tab keeping current win config
(make-wc-tab nil)

;; keep only the current window
(delete-other-windows)

;; now activate the tabs that keep 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 a tab
;; and before activatin it here, emacs crashes. LOL.

;; activate the second
(set-frame-parameter (selected-frame) 'current-tab 1)

;; the third
(set-frame-parameter (selected-frame) 'current-tab 2)

;; the first again
(set-frame-parameter (selected-frame) 'current-tab 0)

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





^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  2010-12-03  9:37                 ` Andreas Schwab
@ 2010-12-04 21:48                   ` Alin Soare
  0 siblings, 0 replies; 15+ messages in thread
From: Alin Soare @ 2010-12-04 21:48 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Emacs Dev

[-- Attachment #1: Type: text/plain, Size: 110 bytes --]

>
>
> Never work as root.
>

If sombody manages to crash my home network , I grant him 10 mugs of black
beer.

[-- Attachment #2: Type: text/html, Size: 307 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
  2010-12-03 12:29                     ` Dimitri Fontaine
  2010-12-04 21:42                       ` Alin Soare
@ 2010-12-04 21:55                       ` Alin Soare
  1 sibling, 0 replies; 15+ messages in thread
From: Alin Soare @ 2010-12-04 21:55 UTC (permalink / raw)
  To: Dimitri Fontaine; +Cc: Andreas Schwab, Emacs Dev

[-- Attachment #1: Type: text/plain, Size: 959 bytes --]

>
> Alin Soare <as1789@gmail.com> writes:
> > Please come with ideas about extending the frames, such that to be able
> to
> > write scripts to create tabs that play with frames...
>
> What do you think about solutions such as escreen, elscreen or
> workgroups?
>
>  http://www.splode.com/~friedman/software/emacs-lisp/src/escreen.el<http://www.splode.com/%7Efriedman/software/emacs-lisp/src/escreen.el>
>  http://www.morishima.net/~naoto/software/elscreen/index.php.en<http://www.morishima.net/%7Enaoto/software/elscreen/index.php.en>
>  https://github.com/tlh/workgroups.el
>
>
Hi,

I did look a little on the web , and googled images to see what these are
about, but I do not understand too much about them.

My purpose was to make graphical tabs, and to attach to every such tab a
general action, whatever could be possible..

For now I attached only minimal window configuration to every tab, and in
the same time keeping it as simple as possible.

Alin

[-- Attachment #2: Type: text/html, Size: 1410 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Tabs for console.
       [not found]                           ` <AANLkTikaXr_4bVR2_v7HVFfPB93Sw10e63cKqTRwOunS@mail.gmail.com>
@ 2010-12-08 11:16                             ` Alin Soare
  0 siblings, 0 replies; 15+ messages in thread
From: Alin Soare @ 2010-12-08 11:16 UTC (permalink / raw)
  To: Stefan Monnier, Emacs Dev

[-- Attachment #1: Type: text/plain, Size: 1404 bytes --]

> >> I don't understand the above call to `make-terminal-frame': does it
> >> create a new frame, or just a new tab?  If the first, then I don't
> >> understand how it works, and if the second, it's wrong because adding
> >> a tab should have nothing to do with frame creation.
> > The fact that make-tab calls directly make-terminal-frame is just a
> legacy
> > of the old code, when a tab used to be just a frame.
>
> So it will need to change.  But does `make-tab' create a new tab or
> a tabbar?  If a tab, then I don't understand any more why the init-code
> is needed.
>

I did not insert :initcode inside the tab, because I should have written
more C code. I should add the :initcode after the (make-terminal-frame '(tab
. t)), or I should have written code to commute temporarly to a tab without
activating it.

This is why I executed the :initcode before calling (make-terminal-frame....
)

In my case the :initcode should be

  ;; save curent win config
  (setq sym (make-symbol "winconfig"))
  (set sym  (current-window-configuration))


My actual C code does not allow me to insert :initcode as parameter to
(make-terminal-frame (tab . t)), and this is why I created make-tab and
separated the :initcode.

I come into a vicious circle if I pass :initcode to make-terminal frame, and
I did not want to write more C code before to clarify with other emacs
developers how tabs should look like.

[-- Attachment #2: Type: text/html, Size: 1907 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Tabs for console
@ 2010-12-21  1:14 Richard Stallman
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Stallman @ 2010-12-21  1:14 UTC (permalink / raw)
  To: emacs-devel

Could someone please look at Alin Soare's tabs code and
give him feedback?

-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Tabs for console.
  2010-11-08 19:51     ` Alin Soare
       [not found]       ` <AANLkTim8BoGpECQUUNfPidbn2k_HP77sykR=HYqw9BOE@mail.gmail.com>
@ 2011-03-11  8:52       ` A Soare
  1 sibling, 0 replies; 15+ messages in thread
From: A Soare @ 2011-03-11  8:52 UTC (permalink / raw)
  To: emacs-devel


I wish to re-open the patch for tabs for console.

Does somebody want to help me to finish it , please ?


Alin.






^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-03-11  8:52 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-29  7:49 Tabs for console Alin Soare
  -- strict thread matches above, loose matches on Subject: below --
2010-12-21  1:14 Richard Stallman
     [not found] <AANLkTim8zuFRh2L81g9KgtDon=U5Mvr+QO+HWGE1nqXP@mail.gmail.com>
2010-10-27 16:39 ` Fwd: " 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
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 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-10-27 20:34 ` Alin Soare

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