Jot a CLI note taker in rust
Author
qgriffithDate Published
I started to learn the rust programming language as a fun thing to do while the weather was not to great. I've taught myself Python, PHP and even Perl back in the day and I wanted to finally try a compiled language. I have created a few crates in the past, but this is my first binary program. I wanted to create something easy to take notes with out having the leave the command line. I use Obsidian as my daily note taker, but found myself often in the CLI wanting to jot something down, with out leaving the CLI to launch another app. So I created Jot. I can quickly create a new note, or append to a long running note. For things I want to keep, I move them into my Obsidian Vault. By default Jot treats everything as a markdown file. So it is quite easy to have Obsidian pick those up! I used this as an opportunity to learn about clap, a rust command line parser. With very little actual code, one can create a pretty verbose argument parser with built in help
1A ClI for jotting down notes23Usage: jot [OPTIONS] <COMMAND>45Commands:6 new jot something new down7 open Running jot doc that appends text to the same file8 scratch Used as a scratch pad9 search Search documents for a string of text. query can be passed several times10 list List all files in your jot dir11 help Print this message or the help of the given subcommand(s)1213Options:14 -p, --jot-path <JOT_PATH> [env: JOT_PATH=]15 -h, --help Print help16 -V, --version Print version17
The code to create that is pretty simple:
1#[derive(Parser, Debug)]2#[clap(version)]3struct Args {4 #[clap(short = 'p', long, env)]5 jot_path: Option<PathBuf>,67 #[command(subcommand)]8 cmd: Commands,9}1011#[derive(Subcommand, Debug)]12enum Commands {13 /// jot something new down14 ///15 /// This command will open your $EDITOR, wait for you16 /// to write something, and then save the file to your17 /// jot. This is to create a new file and save it18 New {19 /// Optionally set a title for what you are going to write about20 #[clap(short, long)]21 title: Option<String>,22 },23 /// Running jot doc that appends text to the same file.24 Open {25 /// Open an existing file to write26 #[clap(short, long)]27 title: String,28 },29 /// Used as a scratch pad30 ///31 /// To get thoughts into quickly. Perfect to use as a reminder for something32 /// to work out later. File name is _scratch.md33 Scratch {34 #[clap(short, long)]35 message: String,36 },37 /// Search documents for a string of text. query can be passed several times38 Search {39 #[clap(short, long)]40 query: Vec<String>,41 },42 /// List all files in your jot dir43 List {},44}
Clap takes in enum and allows you to set comments about what the option will do. It displays those comments to the user. The help and version flags are baked in. No need to add code for those options. It even takes the version right out of the Cargo.toml file. So anytime the crate is updated to a new version it will display that. I hope to piggy back off this learning to advance another project I have been working on, to expert fitness data out of various services so users can have access to their data.
Using Jot
To create a new note you can simply run
1jot new
This will launch what ever your EDITOR value is set to in your env. The file will automatically get # at the top. This is a header in markdown. When you save the file Jot will prompt you for a file name to save as. It will first attempt to save it as the string entered after the # in the first line, or offer you a chance to type in a name. Alternatively passing a flag to Jot will set the title and the name for you.
1jot new -t cool_file
To see all the files you have created Jot has a list feature
1jot list
If you want to open an exiting file, you only need to pass the name of the file and not the path or extension.
1jot open -t cool_file
Jot even comes with a basic string search that can search several strings at once
1jot search -q "test" -q "me"2