summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-07-15 17:34:08 +0300
committerLars Wirzenius <liw@liw.fi>2021-07-15 17:34:08 +0300
commit80bd48f44c1ba6c5010f7d50fd9387b1c4424464 (patch)
tree94381a10bea6990ca5d017bb9067749f17ce614c
parent0f3eeccc4403ddf27ad4e7cdffb8033dcab5f9cf (diff)
downloadjt2-80bd48f44c1ba6c5010f7d50fd9387b1c4424464.tar.gz
feat: add command to list current drafts
Sponsored-by: author
-rw-r--r--Cargo.lock25
-rw-r--r--Cargo.toml3
-rw-r--r--jt.md3
-rw-r--r--src/bin/jt2.rs1
-rw-r--r--src/cmd.rs11
-rw-r--r--src/error.rs8
-rw-r--r--src/journal.rs30
-rw-r--r--src/opt.rs3
8 files changed, 75 insertions, 9 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e6a7e11..9ea5edc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,10 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "aho-corasick"
-version = "0.7.15"
+version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
@@ -216,6 +218,12 @@ dependencies = [
]
[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
name = "globset"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -297,6 +305,7 @@ dependencies = [
"anyhow",
"chrono",
"directories-next",
+ "glob",
"log",
"pretty_env_logger",
"regex",
@@ -342,9 +351,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "memchr"
-version = "2.3.4"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "num-integer"
@@ -499,9 +508,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.4.5"
+version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
@@ -510,9 +519,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.6.23"
+version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "ryu"
diff --git a/Cargo.toml b/Cargo.toml
index 6bbe649..98ec949 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,9 +8,10 @@ edition = "2018"
anyhow = "1"
chrono = "0.4"
directories-next = "2.0.0"
+glob = "0.3.0"
log = "0.4"
pretty_env_logger = "0.4"
-regex = "1"
+regex = "1.5.4"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8"
structopt = "0.3"
diff --git a/jt.md b/jt.md
index 0a945ea..f2729ff 100644
--- a/jt.md
+++ b/jt.md
@@ -158,6 +158,9 @@ and there is one draft in jrnl
and draft 0 in jrnl contains "Abracadabra"
and draft 0 in jrnl contains "!meta date="
+when I run jt2 --dirname=jrnl list
+then stdout matches regex ^0 Abracadabra$
+
given an executable script append.sh
when I run jt2 --editor=./append.sh --dirname=jrnl edit 0
then command is successful
diff --git a/src/bin/jt2.rs b/src/bin/jt2.rs
index c37b799..1574f2e 100644
--- a/src/bin/jt2.rs
+++ b/src/bin/jt2.rs
@@ -20,6 +20,7 @@ fn do_work() -> anyhow::Result<()> {
SubCommand::IsJournal(x) => x.run(&config)?,
SubCommand::New(x) => x.run(&config)?,
SubCommand::NewTopic(x) => x.run(&config)?,
+ SubCommand::List(x) => x.run(&config)?,
SubCommand::Edit(x) => x.run(&config)?,
SubCommand::Finish(x) => x.run(&config)?,
}
diff --git a/src/cmd.rs b/src/cmd.rs
index da917ee..2f2f626 100644
--- a/src/cmd.rs
+++ b/src/cmd.rs
@@ -62,6 +62,17 @@ impl New {
}
#[derive(Debug, StructOpt)]
+pub struct List {}
+
+impl List {
+ pub fn run(&self, config: &Configuration) -> Result<(), JournalError> {
+ let journal = Journal::new(&config.dirname, &config.entries)?;
+ journal.list_drafts()?;
+ Ok(())
+ }
+}
+
+#[derive(Debug, StructOpt)]
pub struct NewTopic {
#[structopt(help = "Path to topic page in journal")]
path: PathBuf,
diff --git a/src/error.rs b/src/error.rs
index 8db0991..36d8f07 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -97,4 +97,12 @@ pub enum JournalError {
/// Failed to make a path relative to a directory.
#[error("failed to make {0} relative to {1}: {2}")]
RelativePath(PathBuf, PathBuf, std::path::StripPrefixError),
+
+ /// Problem with glob pattern.
+ #[error("Error in glob pattern {0}: {1}")]
+ PatternError(String, #[source] glob::PatternError),
+
+ /// Problem when matching glob pattern on actual files.
+ #[error("Failed to match glob pattern {0}: {1}")]
+ GlobError(String, #[source] glob::GlobError),
}
diff --git a/src/journal.rs b/src/journal.rs
index 8042f83..ad8b4af 100644
--- a/src/journal.rs
+++ b/src/journal.rs
@@ -2,6 +2,8 @@ use crate::error::JournalError;
use crate::git;
use crate::template::Templates;
use chrono::{DateTime, Local};
+use glob::glob;
+use regex::Regex;
use std::path::{Path, PathBuf};
use std::process::Command;
use tera::Context;
@@ -121,6 +123,21 @@ impl Journal {
}
}
+ pub fn list_drafts(&self) -> Result<(), JournalError> {
+ let prefix = format!("{}/", self.drafts().display());
+ let pattern = format!("{}*.md", prefix);
+ let entries =
+ glob(&pattern).map_err(|err| JournalError::PatternError(pattern.to_string(), err))?;
+ for entry in entries {
+ let entry = entry.map_err(|err| JournalError::GlobError(pattern.to_string(), err))?;
+ let title = get_title(&entry)?;
+ let entry = entry.file_stem().unwrap().to_string_lossy();
+ let entry = entry.strip_prefix(&prefix).unwrap_or(&entry);
+ println!("{} {}", entry, title);
+ }
+ Ok(())
+ }
+
fn edit(&self, editor: &str, filename: &Path) -> Result<(), JournalError> {
if editor == "none" {
return Ok(());
@@ -209,3 +226,16 @@ fn current_timestamp() -> String {
let now: DateTime<Local> = Local::now();
now.to_rfc2822()
}
+
+fn get_title(filename: &Path) -> Result<String, JournalError> {
+ let text = std::fs::read(filename)
+ .map_err(|err| JournalError::ReadDraft(filename.to_path_buf(), err))?;
+ let text = String::from_utf8_lossy(&text);
+ let pat = Regex::new(r#"^\[\[!meta title="(?P<title>.*)"\]\]"#).unwrap();
+ if let Some(caps) = pat.captures(&text) {
+ if let Some(m) = caps.name("title") {
+ return Ok(m.as_str().to_string());
+ }
+ }
+ Ok("(untitled)".to_string())
+}
diff --git a/src/opt.rs b/src/opt.rs
index 7d3dcda..7530f54 100644
--- a/src/opt.rs
+++ b/src/opt.rs
@@ -58,6 +58,9 @@ pub enum SubCommand {
/// Create draft for a new journal entry.
New(cmd::New),
+ /// List current drafts.
+ List(cmd::List),
+
/// Create topic page.
NewTopic(cmd::NewTopic),