back

by jotaen·4y ago·view on hn ↗
For reference, this is the discussion around subitems / nesting: https://github.com/jotaen/xit/discussions/2

As mentioned in that ticket, I’m still reluctant to add this to the [x]it! file specification. On the one hand it seems like an obvious and useful feature, but on the other hand it’s unfortunately pretty difficult to implement in tooling. For example, I tried to add experimental support for nested subitems in the Sublime Text plugin, but I eventually had to give up, just because the syntax highlighting engine is so limited in regards to recursion. It’s the same – or much worse – for other editors.

At the end of the day, I feel that it doesn’t help to add such a feature to the file format, if tools then cannot deal with it properly. Right now, the spec is so simple that it can be implemented in maybe a day or so. I see a great deal of value in keeping the hurdle for tool creators small. But it’s a pretty tricky balancing act in the end.

4 comments
I came up with this format 10 years ago to document running our regression test. It was a complicated process (for reasons) and I had four major sections---one outlining items to do once, such as:

    [ ] Check you can log into Jenkins
    [ ] Check you have an account on lab1
    [ ] SSH into account on lab1
        [ ] "mkdir bin"
        [ ] "mkdir conf"
        [ ] "mkdir var"
        [ ] In shell configuration file, export following
            [ ] export FOOBAR=...
            [ ] export PATH=$PATH:$FOOBAR/bin:$FOOBAR/install
            [ ] export LD_LIBRARY_PATH=$FOOBAR/lib64b:$LD_LIBRARY_PATH
        [ ] Ensure you can run "sudo -u root foo"
        [ ] Ensure you can run "sudo -u nobody bar"
    [ ] Check you have an account on lab 2
    [ ] SSH into account on lab2
        [ ] ...
A second section outlining the steps needed to prepare to run the regression test. The third section was actually running the regression test, and the final section about shutting down the regression test. This list was then checked into our repository and any new hires were given this check list to do (and update it for any steps not clear or not specified---such updates happened a few times).

When I came up with this system, I didn't know about ORG mode. Nor did I expect anyone to use a tool other than a text editor with this. Heck, a person could print this out and use a pen to mark items off the list.

It's mostly the lack of nesting that convinced me not to use xit and to make my own format: http://richardmavis.info/does-the-world-really-need-another-...

And I'm curious about nesting being "pretty difficult to implement in tooling"---how do you mean? At least with emacs I found it no more difficult than counting whitespace characters: https://git.sr.ht/~rfm/tdtd-mode/tree/master/item/readme.md

I’ve tried to implement the item nesting in the [x]it! Sublime Text plugin. The problem there was that I didn’t manage to implement strict rules for subitems. If you consider the following example:

    [x] Example item
        [ ] Subitem
                [ ] Another Sub-Sub Item
    Continuation of the first item’s description
Some problems I encountered:

- The “Another Sub-Sub Item” should not be allowed, because it skips one level (from the first to the third, instead of to the second).

- The “Continuation of the first item’s description” should not be allowed, because it only makes sense for sub-items to appear after an item’s description, but not in between.

- It also doesn’t seem to be possible for sub-items to inherit their parent’s status, e.g. if the parent is checked, to also colour the sub-item as if it was checked.

Oh, interesting. When you put it that way---"Example item" and "Continuation ..." being the same semantic unit---I see the problem. And why nesting is easier to implement when the semantics are based on lines.

I think it's also interesting the way you say "The “Another Sub-Sub Item” should not be allowed". Seems to me the format and tooling should do what the user wants and expects, or at least try to. Why not allow it if the user wants it that way?

I realised that I made a small mistake in my code sample above, but I can’t edit the post anymore. It should have been:

    [x] Example item
        [ ] Subitem
                [ ] Another Sub-Sub Item
        Continuation of the first item’s description
(Last line is indented, because continuations of descriptions have to be indented.)

The “Another Sub-Sub Item” wouldn’t make sense in my mind, because the idea is that the text maps to well-defined data structures, in this case a tree structure. So an item can have child items, which each can have child items, and so on. However, “Subitem” doesn’t have direct child items.

I find this restriction important, because it would allow to parse the text into relatively simple programmatic models.

> The “Another Sub-Sub Item” wouldn’t make sense in my mind, because the idea is that the text maps to well-defined data structures, in this case a tree structure. So an item can have child items, which each can have child items, and so on.

I get it :) and that's how I implemented mine too: https://git.sr.ht/~rfm/tdtd-parser/tree/master/item/tdtd.jan...

> However, “Subitem” doesn’t have direct child items.

I'm not sure if the difference in our approaches is philosophical or practical. Why shouldn't "Another Sub-Sub Item" be considered a direct child? What if the user added the extra spaces unintentionally? What if, just for fun, they wanted to indent their list like:

    [x] Example item
        [ ] Subitem
                    [ ] A Sub-Sub Item
                [ ] A Sub-Sub Item
            [ ] A Sub-Sub Item
        Continuation of the first item’s description
If that was my list, and my list's parser couldn't handle that, I wouldn't be very happy. But what would/could/should I expect the behavior to be? I'd hope, given the rule that a child has more leading whitespace than its parent, that all three Sub-Sub Items would be treated as peers.
> There can be conflicting state, for example: what happens if the parent item is checked, but the children are still open? Or the other way around? If all children are checked, shouldn’t that “automatically” resolve the parent? What if the parent has a closer due date than the children? And so on. While decision could be made for any of these corner cases, it might still feel strange in practice.

To me, the convention to go with seems easy.

1) If the parent is explicitly checked, leave the children as they are, and ask the user through tooling if they want to check each unchecked subtask, delete it, or move it up a level.

2) If all of the children are checked, the parent stays unchecked, but tooling should ask the user if the parent is complete, or if another subtask should be added.

3) If the parent has a closer due date than the children, don't do anything unless you feel like warning the user i.e. hold the subtasks to their due dates, and hold the parent task to its due date.

The issue about descriptions I see as a non-issue: dictate that descriptions marry to the task above them. It would be nicer to be freer with mixing descriptions and tasks, but you'd have to introduce more tokens.

One thing in the thread that I don't find necessary is marking partial completion.

I don't have any experience with Sublime, but this seems like a very basic tree.

When reading the subtasks, all you have to hold is the stack of the checkbox states and due dates of higher task levels for tooling to answer any of the above questions. A tool could seek backwards in order to check a parent if the children were checked, the user was warned, and the user said they wanted the parent checked. But if instead you really only wanted to read a line at a time, you could add a dummy item called "[ ] Complete parent task" at the end of the subtask list in order to keep an unchecked parent with checked children consistent.

The problem for me is that a tree is what I have trouble organizing. If it's just a linear list of things, I'm not sure how useful it could be for me other than by setting alarms that I could set directly. There is never a time when one of my tasks isn't to break down another task into simpler steps; all but the simplest tasks I have really have "break this down" that as the default first subtask.

So one workflow datapoint for useful with subtasks, useless without subtasks.

I'd suggest creating a new version of the spec that requires more advanced parsing and let people add spec version to the top or bottom of the file via a comment. (adding comments would be really useful too)