Skip to content

Instantly share code, notes, and snippets.

@nonrice
Last active September 1, 2022 02:35
Show Gist options
  • Save nonrice/b0367394995b3492fa1efe2036502bc6 to your computer and use it in GitHub Desktop.
Save nonrice/b0367394995b3492fa1efe2036502bc6 to your computer and use it in GitHub Desktop.
Very simple and minimal todo list CLI.
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
/* Installation:
* Compile from source: g++ todo.cpp -o todo -O3
* Put it into path: sudo mv ./todo /usr/local/bin
*
* Usage:
* todo add <some task> (Multiple word tasks supported, no quotes needed)
* todo list (List the tasks)
* todo done <num> (Complete the task number shown in "todo list")
*
* Tasks are stored in a plaintext file at $HOME/.todo
*
*/
const string HOME = getenv("HOME");
void ensure_file_exists(){
std::ifstream file(HOME + "/.todo");
if (!file){
file.close();
std::ofstream file(HOME + "/.todo");
file.close();
}
}
void list_tasks(){
std::ifstream file(HOME + "/.todo");
std::string task;
int num = 1;
while (std::getline(file, task)){
std::cout << '[' << num << "] " << task << '\n';
++num;
}
file.close();
}
void add_task(int argc, char** argv){
std::ofstream file(HOME + "/.todo", std::ios::app);
for (int i=2; i<argc; ++i){
file.write(argv[i], strlen(argv[i]));
file << ' ';
}
file << '\n';
file.close();
}
bool remove_task(int task){
if (task < 1)
return false;
std::ifstream file(HOME + "/.todo");
std::ofstream tmp(HOME + "/.todotmp");
int i = 0;
std::string line;
while (std::getline(file, line)){
++i;
if (i != task)
tmp << line << '\n';
}
file.close();
tmp.close();
std::remove((HOME + "/.todo").c_str());
std::rename((HOME + "/.todotmp").c_str(), (HOME + "/.todo").c_str());
return i >= task;
}
int main(int argc, char** argv){
ensure_file_exists();
if (argc==1){
std::cout << "todo: Command requires an action\n";
} else {
if (!strcmp(argv[1], "add")){
add_task(argc, argv);
std::cout << "todo: Add successful\n";
} else if (!strcmp(argv[1], "list")){
std::cout << "todo:\n";
list_tasks();
} else if (!strcmp(argv[1], "done")){
if (remove_task(atoi(argv[2]))){
std::cout << "todo: Task completion successful\n";
} else {
std::cout << "todo: Task completion failed (Task # does not exist)\n";
}
} else {
std::cout << "todo: Invalid action\n";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment