Save tabs button.

7 views
Skip to first unread message

Terry Brown

unread,
Oct 14, 2011, 1:22:04 PM10/14/11
to leo-e...@googlegroups.com
Here's code that can be placed in a @button to save the current tabs.

tablist = g.findNodeAnywhere(c, '@script load tabs')
if not tablist:
from leo.core.leoNodes import vnode
v = vnode(c)
v.h = '@script load tabs'
v._linkAsNthChild(c.hiddenRootNode,
len(c.hiddenRootNode.children))
tablist = g.findNodeAnywhere(c, '@script load tabs')
assert tablist
import time
b = ["# Generated %s\n"%time.strftime('%c')]
for oc in g.app.commanders():
b.append("g.openWithFileName('%s', c)" % oc.fileName())
b.append("c.frame.bringToFront()")
tablist.b = '\n'.join(b)

The button creates a @script node which will load the current tabs on
future openings of this file.

If I was Kent, I might put this in an @rclick node to it's a submenu
item of some general button collecting scripts like this. If I was
anyone else, I'd have forgotten about the @rclick option and have to
take up valuable button bar space for it ;-)

If the node "@script load tabs" doesn't exist it's created at the
bottom of the file, but it can be moved anywhere.

For the first version I used g.handleUrlInUrlNode
instead of g.openWithFileName. That just opened 3 instances of Google
Earth, so I prefer this version :-)

Edward - if the node "@script load tabs" doesn't exist in the outline,
I want to create it, at the *bottom*, and I'm sure there's a cleaner
way than I'm using here, but my attempts to iterate to the end of
c.rootPosition()'s siblings failed, probably just oversight on my part.

Cheers -Terry

Edward K. Ream

unread,
Oct 14, 2011, 1:56:23 PM10/14/11
to leo-e...@googlegroups.com
On Fri, Oct 14, 2011 at 12:22 PM, Terry Brown <terry_...@yahoo.com> wrote:

> Edward - if the node "@script load tabs" doesn't exist in the outline,
> I want to create it, at the *bottom*, and I'm sure there's a cleaner

> way than I'm using here.

v._linkAsNthChild(c.hiddenRootNode,
len(c.hiddenRootNode.children))

This seems like the simplest code possible.

> my attempts to iterate to the end of
> c.rootPosition()'s siblings failed, probably just oversight on my part.

This works::

p = c.rootPosition()
while p.hasNext():
p.moveToNext()
p = p.insertAfter()
p.h = 'success'
c.redraw()

But your vnode way still seems simplest.

Edward

Terry Brown

unread,
Oct 14, 2011, 2:09:01 PM10/14/11
to leo-e...@googlegroups.com
On Fri, 14 Oct 2011 12:56:23 -0500
"Edward K. Ream" <edre...@gmail.com> wrote:

> This works::
>
> p = c.rootPosition()
> while p.hasNext():
> p.moveToNext()
> p = p.insertAfter()
> p.h = 'success'
> c.redraw()
>
> But your vnode way still seems simplest.

But wouldn't the p approach be preferred? Whenever something starts
with '_' it feels like there's a risk of getting your fingers mangled in
moving parts... particularly seeing my approach needed
`from leo.core.leoNodes import vnode`, I think. Perhaps there are some
rough edges on the API there. It would be helpful if there was a fake
position available, `r`, such the r.v == c.hiddenRootNode, or something
functionally equivalent to that.

Cheers -Terry

SegundoBob

unread,
Oct 14, 2011, 4:52:48 PM10/14/11
to leo-editor
Great idea. I played with the "save tabs" button you suggest, and I
noticed that the start up messages to the Log Pane get messed up.
When I open several tabs by hand, only the first tab gets the full set
of start up messages. The other tabs gets shorter start up message
sets. When your @scripts node creates the tabs, the full start up
message set does not go to the Log Pane for the first tab. It is
split in the middle and some goes to the second tab. This is
confusing and not sensible.

Terry Brown

unread,
Oct 14, 2011, 5:06:11 PM10/14/11
to leo-e...@googlegroups.com

I think it's a major thing to fix though. Basically Leo has no concept
of the "current" commander. The user thinks it's the currently
focused window or tab, but there isn't really a context in Leo where
you can work out what which commander is selected - they're all equal.

Well, I suppose a simple fix would be calling something in
c.frame.bringToFront() which nominates this commander as the recipient
of g.es() messages. Not sure of the implications, Edward would know
better.

Cheers -Terry

Kent Tenney

unread,
Oct 15, 2011, 7:45:30 AM10/15/11
to leo-e...@googlegroups.com
On Fri, Oct 14, 2011 at 4:06 PM, Terry Brown <terry_...@yahoo.com> wrote:
> On Fri, 14 Oct 2011 13:52:48 -0700 (PDT)
> SegundoBob <bhos...@ieee.org> wrote:
>
>> Great idea.  I played with the "save tabs" button you suggest, and I
>> noticed that the start up messages to the Log Pane get messed up.
>> When I open several tabs by hand, only the first tab gets the full set
>> of start up messages. The other tabs gets shorter start up message
>> sets.  When your @scripts node creates the tabs, the full start up
>> message set does not go to the Log Pane for the first tab.  It is
>> split in the middle and some goes to the second tab.  This is
>> confusing and not sensible.
>
> I think it's a major thing to fix though.  Basically Leo has no concept
> of the "current" commander.

Dang. That also makes it hard to save the current position, an important aspect.
Sounds like Leo needs a commander container.

instead of
g.openWithFileName('/home/ktenney/work/explanans.leo', c)

c = g.openWithFileName('/home/ktenney/work/explanans.leo')

then one could do c.setCurrentPosition(saved_position)

 The user thinks it's the currently
> focused window or tab, but there isn't really a context in Leo where
> you can work out what which commander is selected - they're all equal.
>
> Well, I suppose a simple fix would be calling something in
> c.frame.bringToFront() which nominates this commander as the recipient
> of g.es() messages.  Not sure of the implications, Edward would know
> better.
>
> Cheers -Terry
>

> --
> You received this message because you are subscribed to the Google Groups "leo-editor" group.
> To post to this group, send email to leo-e...@googlegroups.com.
> To unsubscribe from this group, send email to leo-editor+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/leo-editor?hl=en.
>
>

Terry Brown

unread,
Oct 15, 2011, 1:30:07 PM10/15/11
to leo-e...@googlegroups.com
On Sat, 15 Oct 2011 06:45:30 -0500
Kent Tenney <kte...@gmail.com> wrote:

> Dang. That also makes it hard to save the current position, an important aspect.
> Sounds like Leo needs a commander container.
>
> instead of
> g.openWithFileName('/home/ktenney/work/explanans.leo', c)

I think, off the top of my head, it's

ok, new_c = g.openWithFileName('/home/ktenney/work/explanans.leo',
old_c)

so you can do what you want to do already.

Cheers -Terry

Edward K. Ream

unread,
Oct 15, 2011, 4:46:56 PM10/15/11
to leo-e...@googlegroups.com
On Fri, Oct 14, 2011 at 4:06 PM, Terry Brown <terry_...@yahoo.com> wrote:

> I think it's a major thing to fix though.  Basically Leo has no concept
> of the "current" commander.

There are at least two separate issues here.

1. g.app.setLog and c.setLog.

As usual when switching between contexts, getting the switch just
exactly correct is dicey. The log problems you mention may be tricky
to get right, but they have no fundamental significance.

2. The "current" commander and related issues.

g.app.windowList is a list of open frames. For any frame f, f.c is
its commander. You can always find exactly what commander you want by
finding it in g.app.windowList.

Conversely, you can specify any commander by giving the full path to
its file, or simply by giving id(c). This is, I think, all that is
needed to save any per-commander info you like.

In particular, extending quicksearch to show global matches can save
id(c) for each match.

Edward

SegundoBob

unread,
Oct 16, 2011, 1:35:36 PM10/16/11
to leo-editor
I think there is another problem that is probably unrelated to the Log
Pane problems.

I think openWithFileName() is not quite correct. The symptom is as
follows.

When opening an outline executes this @script node:

# 2011-10-14 14:14:05

g.openWithFileName('/home/bob/.leo/workbook.leo', c)
g.openWithFileName('/media/sda1/BobH/1/Leo/Snippets.leo', c)
g.openWithFileName('/media/sda1/BobH/1/Leo/Groceries.leo', c)
c.frame.bringToFront()
---------- End @script contents ----------

The console ends up containing these messages:


10:14:39 ~$ leomy
10:14:48 ~$ *** isPython3: False
Leo 4.9 final, build 4411, June 21, 2011
Python 2.7.1, qt version 4.7.2
linux2
reading settings in /home/bob/bzrWork/pluginPath/leo/config/
leoSettings.leo
reading settings in /home/bob/.leo/myLeoSettings.leo
reading settings in /home/bob/.leo/workbook.leo
createRecentFilesMenuItems Recent Files Menu does not exist
<module>,openWithFileName,createMenu,updateRecentFiles
createRecentFilesMenuItems Recent Files Menu does not exist
<module>,openWithFileName,createMenu,updateRecentFiles
------ End Console Contents -------------------

I think this is the output of a trace statement in
createRecentFilesMenuItems() and the list at the end is the call stack.

SegundoBob

unread,
Oct 16, 2011, 3:20:36 PM10/16/11
to leo-editor
On Oct 14, 2:06 pm, Terry Brown <terry_n_br...@yahoo.com> wrote:
> On Fri, 14 Oct 2011 13:52:48 -0700 (PDT)
> I think it's a major thing to fix though.

Hmm?

When you specify K outlines on Leo-Editor's command line, Leo-Editor
opens them all and all the appropriate Log Pane messages go to all the
appropriate tabs. Doesn't this show that somebody at some previous
time know how to do it?

Terry Brown

unread,
Oct 16, 2011, 7:33:29 PM10/16/11
to leo-e...@googlegroups.com
On Sun, 16 Oct 2011 12:20:36 -0700 (PDT)
SegundoBob <bhos...@ieee.org> wrote:

[Re getting output into the right log]

> When you specify K outlines on Leo-Editor's command line, Leo-Editor
> opens them all and all the appropriate Log Pane messages go to all the
> appropriate tabs. Doesn't this show that somebody at some previous
> time know how to do it?

Sure, I was thinking that it was hard to fix because it required being
able to define the 'current' commander, which Leo doesn't really do.
The user feels as if a particular commander is current, because you can
only have one raised tab or focused window, but to Leo they're all
equally current.

However, the logging problem doesn't require addressing that issue, the
'current' commander in that context is the one running the @script, so
it's just a matter of c.setLog() or whatever.

Cheers -Terry

Edward K. Ream

unread,
Oct 18, 2011, 8:36:13 AM10/18/11
to leo-e...@googlegroups.com
On Sun, Oct 16, 2011 at 12:35 PM, SegundoBob <bhos...@ieee.org> wrote:
> I think there is another problem that is probably unrelated to the Log
> Pane problems.
>
> I think openWithFileName() is not quite correct.  The symptom is as
> follows.
>
> When opening an outline executes this @script node:
>
> # 2011-10-14 14:14:05
>
> g.openWithFileName('/home/bob/.leo/workbook.leo', c)
> g.openWithFileName('/media/sda1/BobH/1/Leo/Snippets.leo', c)
> g.openWithFileName('/media/sda1/BobH/1/Leo/Groceries.leo', c)
> c.frame.bringToFront()

g.openWithFileName is the heart of Leo's code that opens files and
switches from one commander to another.

Executing g.openWithFileName from an @script node, that is, while
*another* .leo file is in the process of being loaded, is an abuse of
an internal method. Don't do it.

There are plenty of ways to open various files. But not this way.

Edward

Terry Brown

unread,
Oct 18, 2011, 10:43:48 AM10/18/11
to leo-e...@googlegroups.com
On Tue, 18 Oct 2011 07:36:13 -0500

"Edward K. Ream" <edre...@gmail.com> wrote:

> There are plenty of ways to open various files. But not this way.

So the sanctioned method for loading a file from a @script node in a
loading file is...?

The g.openWithFileName() approach seems to be working fine to me, but
if there's an alternative that's good.

Cheers -Terry

Edward K. Ream

unread,
Oct 18, 2011, 11:38:14 AM10/18/11
to leo-e...@googlegroups.com
On Tue, Oct 18, 2011 at 9:43 AM, Terry Brown <terry_...@yahoo.com> wrote:

> So the sanctioned method for loading a file from a @script node in a
> loading file is...?

Try an 'after-create-leo-frame' event handler. This executes near the
end of g.openWithFileName. Here are the last statements from
g.openWithFileName::

c.setLog()
g.createMenu(c,fn)
g.finishOpen(c)

It is the call (or rather, calls, plural) to c.setLog that must be
done in the right order, whatever that could be, when opening multiple
files. Don't ask me to create a stack of logs: I'm not going there.

g.createMenu invokes the 'after-create-leo-frame' handler.
g.finishOpen sets the focus, so there is potential for focus problems.
If so, your 'after-create-leo-frame' handler can deal with it.

To repeat, this is an edge case that I don't feel compelled to support.

Edward

Edward K. Ream

unread,
Oct 18, 2011, 11:40:50 AM10/18/11
to leo-e...@googlegroups.com
On Tue, Oct 18, 2011 at 10:38 AM, Edward K. Ream <edre...@gmail.com> wrote:
> On Tue, Oct 18, 2011 at 9:43 AM, Terry Brown <terry_...@yahoo.com> wrote:
>
>> So the sanctioned method for loading a file from a @script node in a
>> loading file is...?

The real answer is that there is no "sanctioned" method: open files
from the command line, or find some other automatic or semi-automatic
way.

EKR

Terry Brown

unread,
Oct 18, 2011, 12:56:07 PM10/18/11
to leo-e...@googlegroups.com
On Tue, 18 Oct 2011 10:38:14 -0500

"Edward K. Ream" <edre...@gmail.com> wrote:

> Try an 'after-create-leo-frame' event handler. This executes near the
> end of g.openWithFileName. Here are the last statements from
> g.openWithFileName::
>
> c.setLog()
> g.createMenu(c,fn)
> g.finishOpen(c)

[snip]


> To repeat, this is an edge case that I don't feel compelled to support.

I guess I'm not sure what the problem with g.openWithFileName() is,
unless it's just the spreading of log messages across several log
windows. Doesn't bother me, but I think it could be fixed by having
the @button save tabs write the @script so that it calls c.setLog()
after it's done loading the other files.

Hmm, tried that and not sure if it fixes the problem, because I wasn't
seeing the problem myself anyway.

Cheers -Terry

Edward K. Ream

unread,
Oct 18, 2011, 1:00:17 PM10/18/11
to leo-e...@googlegroups.com
On Tue, Oct 18, 2011 at 11:56 AM, Terry Brown <terry_...@yahoo.com> wrote:

> I guess I'm not sure what the problem with g.openWithFileName() is,
> unless it's just the spreading of log messages across several log
> windows.

I'm guessing myself, but surely the log will be disrupted by what are,
in essence, recursive calls to g.openWithFileName.

I think we have discussed this in enough detail. The adventurous may
take their chances, but I will not welcome bug reports on this topic.

Edward

Kent Tenney

unread,
Oct 19, 2011, 10:19:11 AM10/19/11
to leo-e...@googlegroups.com

Ok. I wasn't doing that, I had the session list in a @session node.
@session doesn't mean anything, it's just a description of editor state.
When I want to load a session I <ctrl-b> on the node.

Presumably that's ok.

>
> There are plenty of ways to open various files.  But not this way.
>
> Edward
>

Edward K. Ream

unread,
Oct 27, 2011, 3:50:46 PM10/27/11
to leo-e...@googlegroups.com
On Tue, Oct 18, 2011 at 7:36 AM, Edward K. Ream <edre...@gmail.com> wrote:

> g.openWithFileName is the heart of Leo's code that opens files and
> switches from one commander to another.
>
> Executing g.openWithFileName from an @script node, that is, while
> *another* .leo file is in the process of being loaded, is an abuse of
> an internal method.  Don't do it.

In light of my new-found realization that the desire to save the
present "session" (open .leo files) makes sense, I am more open to
improving g.openWithFileName with an eye to making it "reentrant",
that is, callable from within itself.

Various people have suggested code snippets. I would welcome one or
more more-or-less-standard ways of saving and restoring sessions.
Perhaps save/restore session commands. Or something like that.

Anyone have code that they would like to propose?

Edward

Reply all
Reply to author
Forward
0 new messages