unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alin Soare <as1789@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Emacs Dev <emacs-devel@gnu.org>
Subject: Re: Fwd: Tabs for console.
Date: Wed, 8 Dec 2010 10:14:01 +0200	[thread overview]
Message-ID: <AANLkTinX9jJ6K5KCncFx+G9+uQYbswzVs7tb4o-2c3Do@mail.gmail.com> (raw)
In-Reply-To: <jwvbp4xh798.fsf-monnier+emacs@gnu.org>

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

> >> > The idea is that I added to struct frame a list of tabs.
> >> Where is it?  In the frame's parameters?  Or is it accessed via a new
> >> frame-tabs and set-frame-tabs?
> >>
> >> struct frame
> > {
> > ...
> >     /*
> >      * an alist  of the form ((alist_tab_parameters))
> >      */
> >     Lisp_Object tab_bar_items;
> > ...
> > }
>
> So it's not in the frame's parameters: how is it accessible from Elisp?
>

I defined the tabs inside the struct frame, because I thought that their
names are displayed on the upperside of a frame. Despite this, they have
nothing in common with a frame.

tab_bar_items is a list of tabs, so it looks like this:


(

 (
   (:name "tab1")
   (:init-code (lambda () ... code) )
   (:activate-code (lambda() ... code) )
   (:deactivate-code ... )
   (:environment list-of-symbols)
 )


 (
   (:name "tab2")
   (:init-code (lambda () ... code) )
   (:activate-code (lambda() ... code) )
   (:deactivate-code ... )
   (:environment list-of-symbols)
 )

)

So far it is accesible via frame-parameters, but in my code this access is
not useful/used.

I could separate all tabs parameters into a struct tab, and keep inside
struct frame only 3 fields.

struct frame
{

   bool subscribe_to_tabs;
   int tab_bar_lines;
   char *regexp;
}

when f->subscribe_to_tabs is true, then it is displayed on `tab_bar_lines'
the tabs that match regexp for example.

It is not required to keep a fixed number of parameters for a tab, like
:activate-code, :init-code, etc. One can add a parameter (:kill-buffer-xyz
(lambda () ... )) that is called when an event, like kill-buffer of a buffer
named "xyz" produces.

But for now we can suppose the number is fixed.


>
> >> > A tab is an alist of
> >>
> >> > (
> >> >   (:name "string-name")
> >> >   (:init-code (lambda () ... code) )
> >> >   (:activate-code (lambda() ... code) )
> >> >   (:deactivate-code ... )
> >> >   (:environment list-of-symbols)
> >> > )
> >>
> >> What's the init-code for?
>
> > The init code is executed only when the tab is created. In my script it
> is
> > used to memorize the current window config into a variable 'sym. The
> > variable sym must be tab-local during the tab existence.
>
> Who creates such a tab and how, then?  If the tab is created from Elisp
> code, then that code can run the init-code without any special support in
> the
> tabs code.  So why is there such a special init-code?
>
> Oh, I think maybe I see: the tab creation is done in C and it calls this
> init-code to setup the new tab.  I.e. when you wrote "a tab is an
> alist", what you really meant was "a tabbar is an alist", is that right?
>

Yes, like this. Or the :initcode is executed from (make-tab, like in my
example, and for my example there is no reason to keep it memorized as a
parameter in tab's alist parameters, because in this example it is not
useful any more).

But the :initcode can be very useful, because a tab should be re-initialized
sometimes.

Yes, I keep a tab as an alist, and all tabs as list of tabs.



>
> >> I suspect activate is run when you click on the tab and deactivate is
> >> run when you click on some other tab.
> >> What's environment and how is it used?
> > An environment keeps tab-local variables.
>
> I'm trying to move away from the "foo-local variable" business, so let's
> not introduce new ones.
>

OK


>
> > For example , every tabmust know about the window-configuration when
> > it was created , and extract from its own environment the value of
> > that win config.
>
> But the :environment is shared by all tabs of the same tabbar, isn't it?
> Rather than "environment" I'd rather use some other word, not
> associated with variables.  It's basically just some data specific to
> the activate/deactivate code, so we could call it "aux data" or "private
> data", tho of course, this all still depends on whether that data is
> tab-specific or tabbar-specific.
>

Every tab to me has a parameter :environment, and after it the symbols from
that env. Evaluating the first symbol, I got the value of the
tab-configuration, and pass it to set-win-config.



>
> >> > This is the function that defines a tab. It initialize a symbol sym
> >> > with the value of current-window-config. The symbol 'sym is passed
> >> > to (make-terminal-frame), that creates the tab.
> >> I don't understand this "symbol sym" business.
> > I have just explained. It is not interned in the main obarray, and it is
> > passed to the environment of the tab.
>
> No you haven't because you haven't explained why you need *variables*.
> You explained what you need to store some auxiliary data, but usually
> that's stored in a data-structure, not in a variable.


Yes, one can store private data, but if we need more private data than a
variable, we need to name every stored value.

A stored value can be stored

- using a plist
- using an alist
-using a list of symbols with values (as I did)
- using an actor
- probably more



>
>
>> > ;; 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"))
> >>
> >> Here, you're setting a global variable, which is wrong.  It's also very
> >> unclear why you want a symbol here.
> > It is not global. It is not interned, and it becomes tab-local.
>
> Yes, the symbol `sym' assigned by `setq' above is a global variable.
> It is assigned a value which is itself a symbol and that symbol is
> indeed uninterned, but I'm talking about the symbol `sym' not about the
> value stored into its value cell.
>

This is a mistake in my code, it should not be . I forgot to call  a
(make-unbound 'sym)



>
> >> How do "tab:activate" and friends relate to the
> >> previous :activate-code thingies?
> > Via tab-local variables.
>
> That doesn't really answer my question, because we're not understanding
> each other.
> So from your answer I understand that they are indeed different things
> (rather than typos, for example), but that doesn't tell me how they
> relate: you described a tab(bar?) as having :activate-code but in the
> example code you show you use tab:activate instead: does one somehow
>

ya, in my code I called the symbols tab:activate, and in messages I wrote
:activate. Sorry.



> morph into the other, or are the two completely independent and if so
> how/where/when does the other appear in code?
>

The same


>
> > But if I want to be able to re-initialize a tab, then a function to
> operate
> > on tab's environment is required.
>
> I'm beginning to think that the init-code should return a value (the
> tab's private data), which is then passed to the
> (de)activate functions.
>

This is a good idea.


> The tabbar code doesn't need to care about what that value is, it just
> needs to store it and pass it along; the init-code and (de)activate
> functions will decide what to do with it.
> It can be a window-config or anything else.  That should make your
> environment business unnecessary.
>

Yes, if it is only 1 value, we know that it is on the first position of
private-data list, and can access it via cadr.



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

Yes, tabs must be separate from frames, and keep indepedent of every other
thing.

A frame/window can subscribe to tabs, and show them when it is
activated/etc.



>
> > Imagine that emacs had lexical binding.
>
> Elisp offers plenty of ways to do what one would do with lexical
> bindings.  So please, just assume that lexical binding is available and
> don't add weird things to try to work around its absence.  E.g. You can
> simulate it with `(lambda () ... ,foo ...) or with `lexical-let' or with
> `apply-partially', plus many many other ways (plus Emacs-24 will offer
> true lexical binding, if all goes as planned).
>

OK. I will try to use it



>
> > Then we woud not need a tab environment,
>
> Then, please throw it away.
>
> > Note that inside my implementation of make-tab, the variable 'winconfig
> has
> > a different value for every tab. When :activatecode is called ,
>
> That's really nasty for the programmer: there is no variable `winconfig'
> in your code.  There's only a symbol `winconfig' whose value cell you
> use as a place holder.  You could just as well replace
>

true. I did not write look-for-variable function; I did not insert it within
an obarray, as Alyssa Hacker, Ben Bitdiddle or Louis Reasoner would have
done.



>
>   (setq sym (make-symbol "winconfig"))
>    (set sym (current-window-configuration))
>    ...
>   ...(eval (cdr (assoc 'tab:env (frame-parameters))))
>
> with
>
>   (let ((dataholder (list nil)))
>     (setcar dataholder (current-window-configuration))
>     ...
>     ...(car (cdr (assoc 'tab:env (frame-parameters))))
>
> and that would work just as well: `winconfig' is not a variable, but
> a "box" data structure.
>

true.


> At least, if I've understood your code correctly.
>
>
It would be very well to agree, before I start completing the code.



Alin.

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

  reply	other threads:[~2010-12-08  8:14 UTC|newest]

Thread overview: 32+ 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
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 [this message]
     [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

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=AANLkTinX9jJ6K5KCncFx+G9+uQYbswzVs7tb4o-2c3Do@mail.gmail.com \
    --to=as1789@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /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).