It seems the thing to do these days is to write "a better todo list". Probably there is at least one (maybe dozens) implemented in each programming language in existence. Factor even has its own todo web application.
When it comes to development, most developers keep lists of changes that need to be made or features that need to be implemented. Factor has its own todo list on the concatenative.org wiki. I know you are thinking what I'm thinking: wouldn't it be great if we could keep the todo list alongside the code? In any event, it would make a nice demonstration of the vocabulary and help browser system.
metadata
First, some background. Every vocabulary supports various metadata associated with the code, including:
summary.txt
a single line description of the vocabulary authors.txt
a list of vocabulary authors resources.txt
a list of files to include when deploying tags.txt
a list of vocabulary tags used for organization platforms.txt
a list of supported platforms if not cross-platform
todo.txt
We are going to add to this a todo.txt
file containing a todo list of improvements or additions that could be made to the vocabulary. The format of the todo.txt
file will be a list of text, each on its own line.
USING: arrays assocs formatting io io.pathnames kernel sequences vocabs vocabs.loader vocabs.metadata ; IN: todos
The path to the todo.txt
file is relative to the directory containing the specified vocabulary:
: vocab-todo-path ( vocab -- string ) vocab-dir "todo.txt" append-path ;
We can get and set the list of todo items using vocab-file-contents and set-vocab-file-contents, respectively.
: vocab-todo ( vocab -- todos ) dup vocab-todo-path vocab-file-contents ; : set-vocab-todo ( todos vocab -- ) dup vocab-todo-path set-vocab-file-contents ;
We could add new todo items at runtime:
: add-vocab-todo ( todo vocab -- ) [ vocab-todo swap suffix ] keep set-vocab-todo ;
Printing out the todo list for a specified vocabulary is pretty easy:
: todos. ( vocab -- ) vocab-todo [ print ] each ;
Using the child-vocabs word, we can look through a vocabulary hierarchy for all todo files, returning a map of vocabulary to non-empty list of todo items.
: all-todos ( vocab -- assoc ) child-vocabs [ dup vocab-todo 2array ] map [ second empty? not ] filter ;
And then print them out from the Listener:
: all-todos. ( vocab -- ) all-todos [ [ "%s:\n" printf ] [ [ "- %s\n" printf ] each ] bi* ] assoc-each ;
Try it
Although we could make the todo.txt
files by hand, why not try using Factor?
( scratchpad ) USE: tools.scaffold ( scratchpad ) "foo" scaffold-work Creating scaffolding for P" resource:work/foo/foo.factor" ( scratchpad ) "foo.bar" scaffold-work Creating scaffolding for P" resource:work/foo/bar/bar.factor" Loading resource:work/foo/bar/bar.factor ( scratchpad ) "The first thing" "foo" add-vocab-todo ( scratchpad ) "The second thing" "foo" add-vocab-todo ( scratchpad ) "Another thing" "foo.bar" add-vocab-todo ( scratchpad ) "foo" todos. The first thing The second thing ( scratchpad ) "foo" all-todos. foo: - The first thing - The second thing foo.bar: - Another thing
If you look in $FACTOR/work
, you will now find the foo/todo.txt
and foo/bar/todo.txt
files that we just created.
help
We can use these words to make a dynamic help article containing all of the todo entries for loaded vocabularies:
USING: assocs help.markup help.syntax kernel todos ; : $all-todos ( element -- ) drop "" all-todos [ [ $heading ] [ $list ] bi* ] assoc-each ; ARTICLE: "vocab-todos" "Vocabulary todos" { $all-todos } ;
Once loaded, just run this to see the help article created by the previous example:
( scratchpad ) "vocab-todos" help
The code for this is on my Github.
No comments:
Post a Comment