termwiki is a personal knowledge management tool for the terminal, with a focus on zero-thought, zero-wait when getting to the bit you're interested in.
It also:
- Does pretty syntax highlighting and formatting with
rich - Supports
[[including]]bits and files within one another - Allows for high modularity for organizing your knowledge
- Supports dynamic pages by executing Python code
Alternative phrasing: Information management for the terminal, focusing on zero-wait, zero-think when you're getting to the information you need.
This also has a ring to it: Access the information you need with zero wait time and no thinking.
Tools like Notion come with a big context switch. Navigating through the pages and waiting through loading times is awkward and slow.
When I don't remember how bash arrays work, I want to be able to type bash array and get whatever I wrote there, without having to leave the terminal.
I also want to edit my notes as easily as editing a local file with my editor of choice.
tw PATH [TO NESTED PAGE...]
termwiki parses the given page, then prints it.
By default, pages are looked for in ~/termwiki, or in TERMWIKI_PATH if set (multiple colon-separated paths are supported).
Let's say you have a:
📂 ~/termwiki/
├── bash.md
Typing tw bash pretty-prints the contents of bash.md:
# Array
numbers=(1 2 3)For high modularity, tw treats each of these as a page:
- Plain files (
.mdor otherwise) - Whole directories
- Python files
- Variables, functions and classes within Python files
- ...as well as within other variables / functions / classes
Pages can be arbirarily nested in other pages, with no depth limit.
Together with the [[including]] syntax, and the ability to run Python code, this allows for a very flexible way to organize your knowledge.
Take this example:
📂 ~/termwiki/ ├── 📂 bash/ │ ├── array.md # numbers=(1 2 3) │ ├── variable.md # hello="world"
tw bashprints the contents of botharray.mdandvariable.md, one after the other.tw bash arrayprintsnumbers=(1 2 3).tw bash variableprintshello="world".
You can control what tw renders when specifying a page, by nesting same-named pages under it. So with a directory, we would add a file inside that shares the directory's name.
termwiki will render only this nested page, instead of rendering all the others one by one.
In our case, we would add a bash.md file alongside array.md and variable.md:
📂 ~/termwiki/ ├── 📂 bash/ │ ├── array.md # numbers=(1 2 3) │ ├── variable.md # hello="world" │ ├── bash.md
Typing just tw bash now renders only bash/bash.md, not the other files.
If the content of bash.md was:
# Array
[[bash.array]]
# For
[[bash.for]]tw bash would print the contents of both array.md and variable.md, plus a couple of titles.
This holds true for any type of page, including Python objects.
Replace bash/bash.md with a bash/bash.py:
array = '[[bash.array]]'
variable = 'hello="world"'
def bash():
guide = "www.etalabs.net/sh_tricks.html"
return f"""# Bash
{guide}
{array}
{variable}
"""tw bash renders the return value of the bash() function, even though the bash() function is in a bash.py file which is in a bash/ directory.
Two things to note here:
- How
[[bash.array]]can be used across different page types - The
guidevariable inside thebash()function can be accessed viatw bash guide.
Click here for more information about page hierarchy.
If you give tw a path that doesn't exist, it tries hard to get what you wanted anyway, and if it's too ambiguous, it will prompt you to choose among its best guesses.
This is done in several ways:
- When it's not really ambiguous:
- In our example above,
tw arraywould render thearraypage, even though we omittedbash, since it's the onlyarraypage in the whole tree. - Even if an additional
arraypage existed somewhere else, but the wholebash/directory would be nested under a newlanguages/directory,tw bash arraywould similarily render the correctarraypage, because there's only onebash > arraypage.
- In our example above,
- File extensions are ignored, as well as letter casing, including non-alphanumeric characters (
_,-, whitespace etc.) in page names. - Fuzzy matching (Levenstein distance), so
bash arayworks. - If all fails, a "Did you mean: [1] ..., [2] ..." prompt is shown.
Sorted by importance:
- Instant retrieval of knowledge; must be about as quick as recalling a memory
- Easy organization of potentially complex, nested information
- Flexibility and modularity of information bits
- No editing learning curve; Just edit local files like you've been doing for years
[[path.to.page]]to include other pages, reglardless of page type- Inline images and gifs
- Embedding links
- Proper syntax highlighting for
```langblocks - Markdown
# Headlinesare pages - Comments that are # grey
richformatting, or ascii color codes, are rendered even inside markdown. So this would actually[bright_blue]work[/].
- Knowledge graph
termwiki might not be for you, in which case I would recommend either Notion, Dendron or Dnote.
Notion is the fanciest out there, and it's really good for heavy-duty, "this is my life's work" kind of usage. It's web-based, rather slow, and has an editing learning curve.
Dendron is local-first and lets you edit the files with your favorite editor, but it isn't a terminal tool (a VSCodium window), and doesn't support dynamic code execution; only static markdown files.
Dnote has a CLI, but doesn't support page nesting nor markdown, and has a paid Pro plan.