From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Fwd: Tabs for console. Date: Tue, 07 Dec 2010 12:06:29 -0500 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1291741763 27087 80.91.229.12 (7 Dec 2010 17:09:23 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 7 Dec 2010 17:09:23 +0000 (UTC) Cc: Emacs Dev To: Alin Soare Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Dec 07 18:09:19 2010 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PQ12L-0006oK-5r for ged-emacs-devel@m.gmane.org; Tue, 07 Dec 2010 18:09:14 +0100 Original-Received: from localhost ([127.0.0.1]:46065 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PQ12K-0000rF-HB for ged-emacs-devel@m.gmane.org; Tue, 07 Dec 2010 12:09:08 -0500 Original-Received: from [140.186.70.92] (port=43306 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PQ0zp-000826-Gi for emacs-devel@gnu.org; Tue, 07 Dec 2010 12:06:34 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PQ0zn-0001Rp-DD for emacs-devel@gnu.org; Tue, 07 Dec 2010 12:06:33 -0500 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.183]:30051 helo=ironport2-out.pppoe.ca) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PQ0zn-0001RW-7K for emacs-devel@gnu.org; Tue, 07 Dec 2010 12:06:31 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjoIAIP4/UxMCosK/2dsb2JhbACiPYEGcsFdhUkEhGKNfg X-IronPort-AV: E=Sophos;i="4.59,311,1288584000"; d="scan'208";a="84755082" Original-Received: from 76-10-139-10.dsl.teksavvy.com (HELO ceviche.home) ([76.10.139.10]) by ironport2-out.pppoe.ca with ESMTP/TLS/ADH-AES256-SHA; 07 Dec 2010 12:06:29 -0500 Original-Received: by ceviche.home (Postfix, from userid 20848) id AB8E36616B; Tue, 7 Dec 2010 12:06:29 -0500 (EST) In-Reply-To: (Alin Soare's message of "Tue, 7 Dec 2010 06:47:33 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:133504 Archived-At: >> > 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? >> > 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? >> 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. > 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. >> > 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. >> > ;; 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. >> 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 morph into the other, or are the two completely independent and if so how/where/when does the other appear in code? > 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. 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. >> 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. > 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). > 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 (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. At least, if I've understood your code correctly. Stefan