
Leo Editor - type0
https://www.leoeditor.com/
======
jacquesm
I've used Leo extensively for one large project, several smaller ones and all
the DD work for 8 years until 1/1/2017.

It's a _very_ good and well thought out program, it's a bit like a cross
between emacs org mode and python programming environment (rather than lisp)
geared towards literate programming but very useful for other kinds of
applications.

I'd love to see a 'Google docs' style multi-user version of it, that would be
an awesome tool, especially if it would be self hosted.

~~~
dlbucci
What happened on 1/1/17 to make you stop using it?

~~~
jacquesm
We badly needed a multi-user capable tool so I hacked something that
replicates the 2% of Leo's functionality that we need to get our work done.
It's far from ideal but two years on there are a few tens of thousands of
nodes in the system and it has already far outlived it's expected life-span
(as always...).

We really will do that rewrite one of these days though, especially with more
than one job on the go at once the system will start to show its limitations.

Even so, for a three day hack it has done remarkably well.

~~~
jv22222
Please write a blog post about it! That would be a great read :)

~~~
jacquesm
It's a one page PHP app that any HN'er could probably throw together in a day
or two, and it would likely look better and work better than what I built so
there isn't much honor in there, I needed a solution, not something that would
serve as the basis for a nice write-up.

~~~
lucideer
> _two years on there are a few tens of thousands of nodes in the system and
> it has already far outlived it 's expected life-span_

This sounds like something that would be more than interesting enough for me
to want to read, quite apart from the quality or complexity or ingenuity of
the code itself. A nice write up isn't necessarily one that was planned as
such at inception.

~~~
jacquesm
It's a few hundred lines of _very_ ugly PHP, at a minimum I would have to do
some housecleaning before posting the code and there is no upside for me, it
was - and is - throwaway code and I can't wait until we have a viable
replacement so I can kill it.

Side note: it uses a bunch of keyboard short-cuts to rearrange the tree by
moving nodes around and JS absolutely sucks are reliably capturing ctrl-key
combinations. Highly frustrating.

Long story short (and without the code):

The application presents a tree to the user, parts of which can be copied,
each node in the tree is internally referenced by an ID which allows for
multiple nodes having the same name attribute. Besides the name attribute
there are tags, source (handy to keep track of where you found stuff), an
answer to the question associated with that node, an advisory and a bunch of
flags and priorities.

The layout is three panes, a top one with some links for commonly used
functions and a search bar, the left hand side gives the tree and the present
location in the tree and the right hand side shows all the attributes of the
current node.

It features import and export in XML format of the whole tree or parts of it,
the ability to attach pdfs and images to nodes (the images are shown inline in
the parent node), to attach notes to nodes and to export to a different editor
for report writing purposes (usually open office).

~~~
erikpukinskis
The web is amazing. That you can throw that together in a single small file of
“throwaway” PHP and use it in production speaks to why the web has been such a
successful platform.

------
fspeech
I have been using it forever (over 10 years) to organize financial data and do
taxes. While I should credit Python because these are Python programs after
all, it is really Leo that enables me to easily keep data organized. Queries
can be ran by easily running Python scripts inside of Leo with results
directed to the log panel, turning Leo into a light-weight IDE.

For example the top node for accounting is like this:

    
    
      #@killcolor
      # accounting
    
      from datetime import date
      import pprint
      import math
    
      <<defs>>
    
      year = 2006
    
      <<2006>>
    
      inc_year()
      <<2007>>
    
      inc_year()
      <<2008>>
    
      ... more data
    
      inc_year()
      <<2018>>
    
      inc_year(0) #update certain yearly balance records without 
      advancing
    
      def runacct(argv):
          if len(argv) > 1:
            if argv[1] == 'q':
                transquery(argv[2].upper())
            elif argv[1] == 'g':
                groupquery(argv[2].upper())
            elif argv[1] == 'h':
                holdingquery(argv[2].upper())
            elif argv[1] == 'm':
                if len(argv) == 3:
                    monthquery(int(argv[2]))
                else:
                    monthquery(int(argv[2]), int(argv[3]))
            elif ... many other query options
          else:
            balancequery()
    
      if __name__ == '__main__':
          from sys import argv
          runacct(argv)

~~~
jtoledo
Interesting! How do you keep transaction records?

~~~
fspeech
I use two classes to track accounts and transactions:

    
    
      class acct(object):
        # bank and brokerage account
        allacct = []
    
        def __init__(self, name, balance, holdings=None):
            self.name = name
            self.balance = balance
            self.holdings = holdings
            self.xferamt = 0
            self.accum = 0 # used to track cumulation ad hoc values
            acct.allacct.append(self)
    
        def buy(self, sec, amt, cost, day):
            rec = trans(('buy', sec, amt), -cost, day, self)
            self.balance -= cost
            if not self.holdings.has_key(sec):
                self.holdings[sec] = [0]
            self.holdings[sec][0] += amt
            self.holdings[sec].append(rec)
      ......
    
      class trans(object):
        # transaction record object track cash invovled in each transaction
    
        allrec = []
    
        def __init__(self, t, amt, day, where):
            try:
                self.type = t
                self.amt = amt
                self.date = date(year, month, day)
                self.where = where
    
                trans.allrec.append(self)
            except Exception as err:
                print t, amt, year, month, day, where
                raise err            
    

Then for each data line I just do any of the following:

    
    
      SOMEACCT.buy(...)
      SOMEACCT.sell(...)
      SOMEACCT.credit(...)
      SOMEACCT.debit(...)
      SOMEACCT.xfer(...)
      # classified by tax categories:
      SOMEACCT.int(...)
      SOMEACCT.div(...)
      SOMEACCT.fdiv(...)
      SOMEACCT.mint(...)
      SOMEACCT.mdiv(...)
    

Then it is easy to query and do computations in any way one cares to write a
function to do.

~~~
jtoledo
Thanks! Today I use Excel to track my accounts, but I've been looking for
alternatives... Now I'll evaluate your idea.

~~~
fspeech
You are welcome. This approach has worked well for me with over 10 thousand
transactions tracked so far. It is very flexible as you can write your own IIR
computation or match capital gains etc.

------
BeetleB
I've wanted to use this for a few years, and finally dived in this year.

The good: If you can wrap your head around it and spend a fair amount of time
learning it, it is quite useful, and the claims on the web site no longer seem
crazy. It's not my primary editor, but I can see I'll use this a lot
(primarily an Emacs guy).

The bad: Very poor documentation. A lot of the stuff on the site is outdated
(so examples won't work). In my experience, people on the mailing list will
help, so it makes up for the poor docs - but it is kind of off-putting.
There's a ton of stuff it supports that are mentioned nowhere in the docs.

Some hints: Learn how settings work, and dive into all the settings - you can
do this from within Leo. You'll learn a lot more about Leo's capabilities that
way (as well as make small tweaks to the pretty ugly UI). Changing a setting
doesn't go into effect immediately - for that I think you can do:

M-x reload-settings (honestly forgot the command).

Some settings, though, involve quitting and restarting.

Also, it's not really a great _editor_. Its power comes from nodes and
scripting. So become very comfortable with nodes, and try to learn scripting
immediately. I'm still a beginner at the latter, and sadly the docs just suck.
So I slowly try, ask, learn more, make my own notes, etc.

If I keep it enough to become much more knowledgeable, I'll probably end up
writing a _proper_ guide on using it.

It very much is similar to Emacs in the sense that everything is a
command/function. So you can reprogram it to do whatever you want.

------
stevesimmons
People use Leo in different ways...

I used to use Leo for notes on everything I was working on. The killer feature
for me was the tree outline pane could clone nodes. So I could have one
subtree of say Projects, another of say my Jira tickets, a third on Talks and
Blog Posts. And then have clones of the current ones all together in a subtree
called Current. I would adjust their order each morning as my prioritised To
Do list for the day.

More recently, I have tried switching to orgmode. Some aspects are great. But
I really miss Leo's tree pane 'table of contents' and its clonable nodes.

~~~
jadbox
So you still use Leo or managed to switch to orgmode? I haven't used either,
but have contemplating it. Currently, I'm using CherryTree, which is just
okay.

~~~
stevesimmons
I switched to orgmode. Mainly because I wanted to run the same core tools at
work and at home.

At work we are not allowed to run random software; every package needs to be
registered, source security-tested, compiled from source in house, put in an
internal repo, and then installed from there. So while at home I could do 'pip
install leo', at work it was a mess of tracing dependencies (Qt), getting them
registered, etc, etc.

Plus at work, someone else had gone through this pain for Emacs and orgmode.

------
PurpleRamen
Ah yeah, Leo Editor. The Lotus Notes of the outliner-world. That thing is as
powerful as horrible. So full of good ideas, and such a garbage in
implementation.

On the good side stands the ability to have an programmable outline, paired
with a good enough editor to handle the content of nodes. Then there also
directives, which are basically special commands for inline-usage. Things like
@wrap to wrap lines, or @language <value> to define activate language-specific
handling for the following code. @language is especially useful because you
can combine several in one node. Finally there is also the relativ open
ability to customize things with python. All of this combined a regular
workflow I still use with Leo is to create a node with several @language-
blocks on a node. One for code, one for data, one for Documentation. Then call
a selfmade-function which extracts the code and data and executes it and save
the result in a new node in the outline. Very useful to transform or generate
data on the fly. There are also directives to load/save external files, with
support for some fileformats to automagically handle the outline.

But then again, on the bad side, as a dev I must say the whole projects has a
horrible stench of foul code and ugly design. There is a huge amount of
features which either work bad, don't work at all or even work in harmful ways
(dataloss). The codebase is just a ragtag-compilation of random ideas from
people which seems to have no clue about proper software development, and who
are even proud to have come up with some shit they consider as smart. For
anyone who wanna try out this software: don't except to much, and prepare for
many hateful corners and a steep unnesseccary learning-curve. And save your
data! Often.

~~~
Tloewald
Upvoted based on your selection of Lotus Notes as the apotheosis of good ideas
wrapped in awful implementation. I've never used Leo but just looking at the
installation process turned me off the entire idea.

------
juancampa
I'm watching the videos and the nodes look like a powerful abstraction. I'm
not a fan of some of the terminology, for example, "clones" are not really
clones but the opposite: references

~~~
algorias
I think the conceptual difference between a clone and a reference is that
clones have no hierarchy. If I have two clones, then removing either one will
cause the other one to become the "original".

~~~
ptman
aliases?

------
Herodotus38
In case the author is reading this there is a broken link for "screen-shots",
looks like a simple mistake of not including the root.

~~~
wumms
Working link to the screenshots-page: [https://www.leoeditor.com/screen-
shots.html](https://www.leoeditor.com/screen-shots.html)

------
msla
First, something which amused me:

> “Word outlines are very useful. But Leo makes Word look like a clunky
> toy.”—Joe Orr

Well, yes. Any text editor would make Word look like a clunky toy, because
Word is a word processor. They don't do the same things, they aren't aimed at
the same audiences, and they evolved different UI conventions because of that.

That nitpick aside: It being written in Python is nice, and the fact outlines
give your document something like a DOM which is accessible in a Python object
tree is nice. It might be possible to massage this into something almost as
nice as macros for languages like C# or Java.

------
diminish
past

[https://hn.algolia.com/?query=Leo%20Editor&sort=byDate&dateR...](https://hn.algolia.com/?query=Leo%20Editor&sort=byDate&dateRange=all&type=story&storyText=false&prefix&page=0)

~~~
gouggoug
I missed every single one of those past posts, so I'm glad OP posted it once
again.

There are many reposts that I'm also glad happen. They're often a reminder of
something I've forgotten about and that I'm glad to see again, or sometimes
they're just something I missed.

~~~
kiliankoe
Reposts are great, but I also enjoy comments linking to previous discussions.
It's nice to have a look at what was said before.

------
tbolt
UI looks ugly as sin

~~~
jacquesm
So does a chainsaw. But it gets the job done quickly and with a minimum of
fuss. Eye candy is fine of you put form over function, personally I prefer
fast and effective. Pretty is optional.

~~~
dsies
I don’t think it has to be quite that black and white. It doesn’t have to have
“eye candy” and it also doesn’t have to look like a 1998 Delphi project.
Strive for the gray area and if that is not achievable... then yes, function
over form.

~~~
fiddlerwoaroof
If more things looked like a 1998 Delphi project, desktop UIs would be much
nicer to deal with.

------
jskulski
Has anyone used this, org-mode or other literate programming tools for a full
team project _at scale_ (whatever that means, non-trivial multiple months,
lots of code)? Did the team have to buy in or were they already users? How did
it go- did it improve.

I've used org-mode for about a year and a half and have found it helpful to to
my productivity and feeling put together. I can see the potential for benefits
to a team, but not many people want to learn emacs for a job if they don't
already use it.

~~~
thyrsus
We use Leo to organize about 1000 puppet modules managing about 500 linux
systems (50/50 real/virtual), of which 60% are "unique", a.k.a., pets, not
cattle. Geppetto in Eclipse is the closest thing, but Geppetto only helps with
puppet modules, not puppet nodes (hosts).

The good: Leo provides rapid access to understanding the complexity.

The bad: Leo XML file format is collaboration hostile, since resolving git
conflicts in its multi-megabyte XML file is out of the question.

The ugly: I've got perl code to translate the XML file to and from a directory
of several thousand small files, one per Leo node, and far more git-conflict
friendly.

The worst: the version of Leo on which we're stuck used "sentinels" \-
specially formatted comments - to keep Leo's structure of the file in sync
with external changes to the file. Never use that: use a new version of Leo
and use its @clean format, which doesn't use sentinels. Not only are sentinels
offensive to look at in the managed file, this version of Leo occasionally
gets confused and tries to use "//" for puppet comments instead of "#". (Yes,
some of what puppet (and thus Leo) is managing is php.) But we're stuck with
this version of Leo, because when newer versions of Leo read our Leo XML file,
many of the nodes lose their content, namely, a catastrophic lack of backward
compatibility. It would take me at least a month of getting nothing else done
to re-ingest our puppet configuration into a newer Leo.

~~~
marci
@thyrsus (slightly off-topic)

I stumbled upon an old comment* you made about dealing with orgmode and noweb
when editing an erlang file (bit syntax). If you didn't find it yet, at the
end of the file, insert:

    
    
      Local Variables:
      org-babel-noweb-wrap-start: "{{{"
      org-babel-noweb-wrap-end: "}}}"
    

then you'll use {{{chunk-name}}} instead of <<chunk-name>>.

*[https://news.ycombinator.com/item?id=8185442](https://news.ycombinator.com/item?id=8185442)

------
X6S1x6Okd1st
What do they mean by outline?

~~~
sien
Outliner - like emacs org mode or what Scrivener will do.

[https://en.wikipedia.org/wiki/Outliner](https://en.wikipedia.org/wiki/Outliner)

------
Timothycquinn
I love outliners but I am firmly in the single pane outlines camp like Ecco
Pro and Omni Outliner (org mode also?). For some reason, I just can't swallow
the two pane UI.

I wonder if there has been any usability research on which model (single or
two pane) is least obtrusive to flow of information to and from the user.

------
PythonicAlpha
If here are some Leo people reading here:

The "Screen Shots" link is broken.

It should be: [https://www.leoeditor.com/screen-
shots.html](https://www.leoeditor.com/screen-shots.html)

But currently it points to nowhere.

------
porker
Wish JetBrains would add these features to their IDEs. We need more literate
programming today, not less.

I've tried Leo a couple of times and like the concept _a lot_, but never got
on with the implementation.

~~~
elviejo
I agree with the need for more literate programming. Have you tried emacs with
org-mode instead of Leo?

~~~
porker
I'm a Windows user and so I've never really got into emacs. It's one of those
pieces of software that like vim (beyond the ultra-basics) seems too daunting
to get started with.

------
koliber
I heard about Leo about half a year ago. I got really excited, as from the way
it was described, it mirrors the way I think. Unfortunately, I could not get
it to run on MacOS.

~~~
mikestew
Just installed it tonight.

High Sierra

Python 3 installed via Homebrew

pip3 install leo

Ran fine right out of the box.

~~~
koliber
I'll have to give it another go. I really wanted to try it out but was bummed
that I could not get it running.

------
craftyguy
Since the title gives absolutely no information about what this is, here's the
description on the site:

> Leo is a PIM, IDE and outliner that accelerates the work flow of
> programmers, authors and web designers. Outline nodes may appear in more
> than one place, allowing multiple organizations of data within a single
> outline.

I still have no idea what this is after reading the front page other than
being yet another IDE.

~~~
grok2
I used it a while back in a previous incarnation of the editor. It is a
"Outline Editor" for use in what is called "Literate Programming". My view of
it was that you write documentation and embed code in the documentation and
then you can use a mechanism the editor provides to output just the code (when
you want to compile it or execute it). The editor made it easy to
hierarchically organize and rearrange code the way you wanted it and had a way
to output just the code for use in compilation etc.

The current iteration seems to have added more features while basically being
a outline editor -- imagine keeping code in Emacs's Org mode and being able to
compile it.

I liked it, but it felt like it didn't have all the bells-and-whistles of
modern IDEs and required a different way of dealing with code.

~~~
zokier
> imagine keeping code in Emacs's Org mode and being able to compile it.

Something like this

[https://github.com/nakkaya/ferret](https://github.com/nakkaya/ferret)

The whole source code is in literate form in one org file.

~~~
grok2
Nice. Someone actually used Literate programming to write something useful
:-). The ferret org-mode info is very readable.

~~~
sparkie
Perhaps the most insane example of literate programming is Axiom
[[https://en.wikipedia.org/wiki/Axiom_(computer_algebra_system...](https://en.wikipedia.org/wiki/Axiom_\(computer_algebra_system\))],
which is several books worth.

It wasn't originally written in literate style, but it was a very large
codebase which almost nobody understood. Tim Daly put an enormous amount of
effort into making it literate, so that anybody can be introduced to it.

------
gcbw2
(because there is no toplevel comment saying this):

it is emacs' org mode on steroids. If you don't like org mode, move along.

...And some of the side effects of the steroids are already showing (e.g. "you
can embed html in markdown". Really? So it is now an html renderer with
markdown 'shortcuts'?)

~~~
j88439h84
What does Leo have that org doesn't? I use org a lot.

~~~
BeetleB
Mostly the clones feature. The most common use case: If you get a bug report,
you can put the bug report, portions of the code related to the bug report
(which could be spread over several source code files), any tests and test
collateral related to it, all in one tree. When you make changes to the code
in that tree, the corresponding source file will get touch.

Also, things like "Find all functions that contain some string and put them in
a tree" is trivial, and used a lot.

These are out of the box. You can then script more advanced stuff in Python.

Even though it's all Python, it seems to handle heavy loads well. I once
opened all the source code of my project at work (0.5M lines of code). It took
a long time to load them the first time (initial conversion into nodes). But
once I had them loaded, I could save it as a project and reopen easily. Then
searching the whole code base for a string was pretty fast as well. I don't
know how well Emacs can handle thousands of files...

The literate capability is really trivial as well. If you're coding with Leo,
you likely _will_ start using basic literate constructs. It's just natural.

But don't read too much into the comparison with org mode. I use org mode and
Leo for very different things.

~~~
madmulita
EDIT: never mind, I see the clones are references that can appear in multiple
places.

Wouldn't narrowed views in org-mode accomplish the same?

~~~
BeetleB
>Wouldn't narrowed views in org-mode accomplish the same?

No. Narrowed views only let you see a subtree. This is about gathering nodes
from different parts of the tree and putting views into them under another
node.

Let me give some detailed examples - starting from some basics.

In Leo, if I open a .cpp file, it will make a node out of each function. If I
edit any node and hit "Save", it will update the cpp file with the change. In
Org mode, you can copy/paste code from an existing .cpp file into an org
document, but the two are now distinct. A change in the org file doesn't
affect the .cpp file. The best you can do is use tangle/weave - but that would
involve a fair amount of work to convert your whole project/file. And probably
won't play as well with the rest of your coworkers as Leo will.

A trivial example: I've cleaned up many of our .cpp files where we had
multiple classes in one file, and the methods were all over the place. Since
each method was a node, it was easy for me to group together all methods of
each class so they are not scattered around the file. It was absolutely
trivial.

Now to the bug example. You have a bug you need to explore. You have a Leo
project that has all your source code. At the top level, you'll have a node
called "Code". Under that, each file will be another node. Under each "file"
node you'll have a node for each function. Back at the top level, you have
another node called "Tests" \- also hierarchically structured by type of test.

So now you create another top level node and call it "Bug". You can put in
notes (e.g. Bugzilla ID, or copy/paste relevant portion from the bug text
here). So now what you do is find all parts of the code that you think are
involved in the bug. Make a "clone" of their nodes, and put them under your
Bug node. So now those functions appear in two places - under the "Code" node,
and under your "Bug" node. A clone is basically a "view". If you edit the text
of a cloned node, all of its clones get updated. So you can now happily edit
code under the Bug node, knowing that your files are getting updated. You can
also clone relevant tests and again put them under the Bug node, and fix your
tests. When you're done fixing the bug, just delete the "Bug" node.

A simpler example: My work involves some rather large classes that are
essentially singletons (i.e. a hack to use global variables without calling
them that). This causes headaches. So sometimes I need to know all the
possible places in my code base where one of its members is updated. In Leo,
with one command, I can tell it to search all the nodes for that string, make
clones of them, and put them under a top level node. So now under that node I
have all the places the variable is touched. Easy to quickly examine. This
really sped up the rate at which I would understand unfamiliar parts of the
code.

BTW, you can get deeper than the function level. I've often taking a long
function and split it up into nodes. So some of my code explorations involve
nodes that are parts of functions. It is quite easy to break up a function
this way in Leo.

------
patrickg_zill
Some years ago I tried to use Leo but could never really get in the "groove"
of it. Now that I have more experience with outlining and have bumped into the
limitations of what I use now, it deserves a second look.

------
onion-soup
Is this how internet looked in 60s?

