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