diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a452e8a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,680 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "clap" +version = "4.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "cliclack" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "178885eafa17af5b359629e9a4d278940ae790c0bff75843985dc65574c3ac42" +dependencies = [ + "console", + "indicatif", + "once_cell", + "strsim", + "textwrap", + "zeroize", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "ctrlc" +version = "3.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" +dependencies = [ + "nix", + "windows-sys", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "grom" +version = "0.1.0" +dependencies = [ + "chrono", + "clap", + "cliclack", + "console", + "ctrlc", + "serde", + "toml", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "toml" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +dependencies = [ + "memchr", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..010769b --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "grom" +version = "0.1.0" +edition = "2021" + +[dependencies] +chrono = "0.4.38" +clap = { version = "4.5.8", features = ["derive"]} +cliclack = "0.3.2" +console = "0.15.8" +ctrlc = "3.4.4" +serde = { version = "1.0.204", features = ["derive"]} +toml = "0.8.14" diff --git a/src/commands.rs b/src/commands.rs new file mode 100644 index 0000000..3f97854 --- /dev/null +++ b/src/commands.rs @@ -0,0 +1,4 @@ +pub mod diary; +pub mod project; +pub mod quick_note; +mod utils; diff --git a/src/commands/diary.rs b/src/commands/diary.rs new file mode 100644 index 0000000..42d7d67 --- /dev/null +++ b/src/commands/diary.rs @@ -0,0 +1,51 @@ +use super::utils::{self, path_exists}; +use crate::core::config::Config; +use chrono::{Datelike, Local}; + +pub fn create_or_open_daily_diary(config: Config) { + let today = Local::now(); + let file = format!( + "{}/diary/{}/{}/week{}/{}.md", + config.core.note_dir, + today.year(), + today.format("%B"), + today.iso_week().week(), + today.format("%m-%d-%Y") + ); + if path_exists(file.clone()) { + utils::open_file(config.core.open_cmd.clone(), file.clone()); + } + utils::ensure_all_dirs(file.clone()); + utils::save_and_open_file(file, config); +} + +pub fn create_or_open_weekly_diary(config: Config) { + let today = Local::now(); + let file = format!( + "{}/diary/{}/{}/week{}/week.md", + config.core.note_dir, + today.year(), + today.format("%B"), + today.iso_week().week(), + ); + if path_exists(file.clone()) { + utils::open_file(config.core.open_cmd.clone(), file.clone()); + } + utils::ensure_all_dirs(file.clone()); + utils::save_and_open_file(file, config) +} + +pub fn create_or_open_monthly_diary(config: Config) { + let today = Local::now(); + let file = format!( + "{}/diary/{}/{}/month.md", + config.core.note_dir, + today.year(), + today.format("%B"), + ); + if path_exists(file.clone()) { + utils::open_file(config.core.open_cmd.clone(), file.clone()); + } + utils::ensure_all_dirs(file.clone()); + utils::save_and_open_file(file, config) +} diff --git a/src/commands/project.rs b/src/commands/project.rs new file mode 100644 index 0000000..6226988 --- /dev/null +++ b/src/commands/project.rs @@ -0,0 +1,39 @@ +use super::utils; +use crate::core::config::Config; +use std::process; + +pub fn create_project(project_name: String, config: Config) { + let path = config.core.note_dir.clone() + "/projects/" + project_name.as_str() + "/start.md"; + + if utils::path_exists(path.clone()) { + cliclack::note("-_-", "Project already exists.").unwrap(); + process::exit(1); + } else { + utils::ensure_all_dirs(path.clone()); + utils::save_file(path); + cliclack::note("^_^", "Project created.").unwrap(); + process::exit(0); + } +} + +pub fn open_project(project_name: String, config: Config) { + let project_base: String = + config.core.note_dir.clone() + "/projects/" + project_name.as_str() + "/start.md"; + if utils::path_exists(project_base.clone()) { + utils::open_file(config.core.open_cmd.clone(), project_base.clone()); + } else { + cliclack::note(":(", "Project does not exist.").unwrap(); + } +} + +pub fn interative_project_selecion(config: Config) { + let open_cmd = config.core.open_cmd.clone(); + let project = match utils::select_project(config) { + Ok(p) => p, + Err(_e) => { + cliclack::note(":(", "No Projects found.").unwrap(); + process::exit(1); + } + }; + utils::open_file(open_cmd, project); +} diff --git a/src/commands/quick_note.rs b/src/commands/quick_note.rs new file mode 100644 index 0000000..e1b3227 --- /dev/null +++ b/src/commands/quick_note.rs @@ -0,0 +1,25 @@ +use super::utils::{self, path_exists}; +use crate::core::config::Config; +use std::process; + +pub fn create_and_open_quick_note(config: Config) { + let note_name: String = cliclack::input("What do you want to name your new Quick-Note?") + .validate(|input: &String| { + if input.is_empty() { + Err("Please enter a name.") + } else { + Ok(()) + } + }) + .interact() + .unwrap(); + + let filepath = config.core.note_dir.clone() + "/quick-notes/" + note_name.as_str() + ".md"; + if path_exists(filepath.clone()) { + cliclack::note("-_-", "Name is taken.").unwrap(); + process::exit(0); + } + + utils::ensure_all_dirs(filepath.clone()); + utils::save_and_open_file(filepath, config); +} diff --git a/src/commands/utils.rs b/src/commands/utils.rs new file mode 100644 index 0000000..d621bbd --- /dev/null +++ b/src/commands/utils.rs @@ -0,0 +1,132 @@ +use crate::core::config::Config; +use std::{ + fs::{self, OpenOptions}, + io::{self}, + path::Path, + process::{self, Command}, +}; + +pub fn save_file(file: String) { + match OpenOptions::new() + .write(true) + .create_new(true) + .open(file.clone()) + { + Ok(_) => { + #[cfg(debug_assertions)] + println!("Note created successfully!"); + } + Err(e) => match e.kind() { + _ => { + #[cfg(debug_assertions)] + println!("Error creating Note : {:?}", e); + process::exit(1); + } + }, + }; +} + +pub fn open_file(cmd: String, file: String) { + let status = Command::new(cmd).arg(file).status(); + match status { + Ok(s) if s.success() => { + #[cfg(debug_assertions)] + println!("Note opened successfully!"); + process::exit(0); + } + Ok(_s) => { + #[cfg(debug_assertions)] + eprintln!("Command couldn't open File"); + process::exit(1); + } + Err(_e) => { + #[cfg(debug_assertions)] + eprintln!("Error executing open_cmd!"); + process::exit(1); + } + } +} + +pub fn ensure_all_dirs(path: String) { + let path = Path::new(path.as_str()); + if let Some(parent) = path.parent() { + if let Err(_e) = fs::create_dir_all(parent) { + #[cfg(debug_assertions)] + eprintln!("Unable to create Parent-Directories!"); + process::exit(1); + } + } +} + +pub fn save_and_open_file(file: String, config: Config) { + match OpenOptions::new() + .write(true) + .create_new(true) + .open(file.clone()) + { + Ok(_) => { + #[cfg(debug_assertions)] + println!("Note created successfully!"); + } + Err(e) => match e.kind() { + _ => { + #[cfg(debug_assertions)] + println!("Error creating Note : {:?}", e); + process::exit(1); + } + }, + }; + open_file(config.core.open_cmd, file); + process::exit(0); +} + +pub fn path_exists>(path: P) -> bool { + let path = path.as_ref(); + path.exists() +} + +pub fn find_projects(dir: String) -> Option> { + let mut projects = Vec::new(); + let dir = Path::new(&dir); + + if let Ok(entries) = fs::read_dir(dir) { + for entry in entries.filter_map(Result::ok) { + let path = entry.path(); + if path.is_dir() { + let start_md_path = path.join("start.md"); + if start_md_path.exists() { + if let Some(parent) = path.file_name().and_then(|n| n.to_str()) { + projects.push(( + String::from(start_md_path.to_str().unwrap()), + parent.to_string(), + )) + } + } + } + } + Some(projects) + } else { + None + } +} + +pub fn select_project(config: Config) -> Result { + let projects_dir = config.core.note_dir + "/projects"; + let projects = find_projects(projects_dir).unwrap(); + if projects.is_empty() { + return Err(io::Error::new( + io::ErrorKind::NotFound, + "No Projects found.", + )); + } + cliclack::intro(console::style(" NoJo ").on_cyan().black()).unwrap(); + + let mut items: Vec<(String, String, String)> = Vec::new(); + for (_index, (name, path)) in projects.iter().enumerate() { + items.push((name.clone(), path.clone(), String::from(""))); + } + return Ok(cliclack::select(format!("Select a Project")) + .items(&items) + .interact() + .unwrap()); +} diff --git a/src/core.rs b/src/core.rs new file mode 100644 index 0000000..ef68c36 --- /dev/null +++ b/src/core.rs @@ -0,0 +1 @@ +pub mod config; diff --git a/src/core/config.rs b/src/core/config.rs new file mode 100644 index 0000000..4cf65f8 --- /dev/null +++ b/src/core/config.rs @@ -0,0 +1,45 @@ +use serde::Deserialize; +use std::env; +use std::fs; +use std::process::exit; +use toml; + +#[derive(Deserialize)] +pub struct Core { + pub note_dir: String, + pub open_cmd: String, + pub always_open: bool, +} + +#[derive(Deserialize)] +pub struct Config { + pub core: Core, +} + +pub fn load_config() -> Config { + let home_path = match env::var("HOME") { + Ok(p) => p, + Err(e) => { + eprintln!("Could not get home path: {}", e); + exit(1); + } + }; + let filename = home_path + "/.config/nojo/nojo.toml"; + + let contents = match fs::read_to_string(filename.clone()) { + Ok(c) => c, + Err(e) => { + eprintln!("Could not read config file: {}", e); + exit(1); + } + }; + + let data: Config = match toml::from_str(&contents) { + Ok(d) => d, + Err(_) => { + eprintln!("Unable to load data from '{}", filename); + exit(1) + } + }; + data +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..04b2f03 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +pub mod commands; +pub mod core; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..6dc0a52 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,47 @@ +use clap::{Parser, Subcommand}; + +use grom::commands::{diary, project, quick_note}; +use grom::core::config; + +#[derive(Parser)] +#[command(name = "grom")] +#[command(author = "alwaysamer")] +#[command(version = "1.0")] +#[command(about = "Note-Taking")] +struct Cli { + #[command(subcommand)] + command: Option, + project: Option, +} + +#[derive(Subcommand)] +enum Command { + Quick {}, + New { + #[arg(value_name = "PROJECT_NAME")] + project_name: String, + }, + Today {}, + Week {}, + Month {}, +} + +fn main() { + ctrlc::set_handler(move || {}).expect("settings ctrl-c handler"); + let cli = Cli::parse(); + let config = config::load_config(); + + if let Some(command) = &cli.command { + match &command { + Command::Quick {} => quick_note::create_and_open_quick_note(config), + Command::Today {} => diary::create_or_open_daily_diary(config), + Command::Week {} => diary::create_or_open_weekly_diary(config), + Command::Month {} => diary::create_or_open_monthly_diary(config), + Command::New { project_name } => project::create_project(project_name.clone(), config), + } + } else if let Some(project) = &cli.project { + project::open_project(project.clone(), config); + } else { + project::interative_project_selecion(config); + } +}