Try also to install the patch from Saturday and execute the code, to see how the tab-local variables are used to communicate between :initcode, and :activationcode. I deactivated the :deactivationcode, because it is not useful for me, and I wanted to keep the code minimal. Alin 2010/12/7 Alin Soare > > > 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; > ... > } > > > >> In any case, how difficult would it be to generalize your code so the >> tabs can be attached to a window rather than a frame, or even to an >> internal window (i.e. internal windows are those that are somewhere >> along the window tree and hold various actual windows: currently your >> tabs are at the root internal window). >> >> > I did not think about. Not too difficult. > > > >> > 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. > > >> 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. 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. > > No other tab needs to see its own windows 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. > > > >> > ;; 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. > > > >> > (set sym (current-window-configuration)) >> > ;; make a tab that keeps a window configuration. When it is created, >> > ;; it memorizes 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) ) ) ) ) ) ) >> >> `eval' is bad. Stay very far away from it. >> >> > ;; save the current win config into the tab environment >> > (cons 'tab:env sym) ) ) ) >> >> How do "tab:activate" and friends relate to the >> previous :activate-code thingies? >> > > > Via tab-local variables. > > In this moment I added code to modify the environment of a tab only via the > initialization of the tab with make-terminal-frame, but I can add a function > to operate on tab-local variables even after the creation of a tab. > > For example, I did not add the tab:init code to tab's alist, because it is > runned only to creation, in make-tab, before calling make-terminal-frame. > > But if I want to be able to re-initialize a tab, then a function to operate > on tab's environment is required. > > >> >> 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. > > Imagine that emacs had lexical binding. Then we woud not need a tab > environment, because that environment would be included insode the > evaluation process, when the closure that represents the tab is initialized. > But because emacs is not able of closures, I need a tab environment, to be > able to communicate between the > > > (:init-code (lambda () ... code) ) > (:activate-code (lambda() ... code) ) > (:deactivate-code ... ) > > of the same tab, > > Note that inside my implementation of make-tab, the variable 'winconfig has > a different value for every tab. When :activatecode is called , > > > (lambda () > > (set-window-configuration > > (eval (cdr (assoc 'tab:env (frame-parameters) ) > > (cdr (assoc 'tab:env (frame-parameters) ) returns the variable 'winconfig, > id est sym. > > > > > > >