Specify default capture file
This commit is contained in:
parent
039b7b73ee
commit
0b4f614af6
7 changed files with 70 additions and 6 deletions
33
src/files.rs
33
src/files.rs
|
|
@ -85,6 +85,7 @@ pub struct Files {
|
|||
/// Codespan-reporting file database.
|
||||
cs_files: SimpleFiles<String, String>,
|
||||
timezone: Option<Tz>,
|
||||
capture: Option<usize>,
|
||||
logs: HashMap<NaiveDate, Source>,
|
||||
}
|
||||
|
||||
|
|
@ -132,6 +133,7 @@ impl Files {
|
|||
files: vec![],
|
||||
cs_files: SimpleFiles::new(),
|
||||
timezone: None,
|
||||
capture: None,
|
||||
logs: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
|
@ -155,6 +157,7 @@ impl Files {
|
|||
|
||||
self.load_file(&mut loaded, path)?;
|
||||
self.determine_timezone()?;
|
||||
self.determine_capture()?;
|
||||
self.collect_logs()?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -257,6 +260,32 @@ impl Files {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn determine_capture(&mut self) -> Result<()> {
|
||||
assert_eq!(self.capture, None);
|
||||
|
||||
let mut found: Option<Source> = None;
|
||||
|
||||
for command in self.commands() {
|
||||
if let Command::Capture = &command.value.value {
|
||||
if let Some(found) = &found {
|
||||
let found_cmd = self.command(*found);
|
||||
return Err(Error::MultipleCapture {
|
||||
file1: found.file(),
|
||||
span1: found_cmd.value.span,
|
||||
file2: command.source.file(),
|
||||
span2: command.value.span,
|
||||
});
|
||||
} else {
|
||||
found = Some(command.source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.capture = found.map(|s| s.file);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn collect_logs(&mut self) -> Result<()> {
|
||||
for command in Self::commands_of_files(&self.files) {
|
||||
if let Command::Log(log) = &command.value.value {
|
||||
|
|
@ -369,6 +398,10 @@ impl Files {
|
|||
.max_by_key(|(d, _)| *d)
|
||||
}
|
||||
|
||||
pub fn capture(&self) -> Option<FileSource> {
|
||||
self.capture.map(FileSource)
|
||||
}
|
||||
|
||||
pub fn now(&self) -> DateTime<&Tz> {
|
||||
if let Some(tz) = &self.timezone {
|
||||
Utc::now().with_timezone(&tz)
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ pub enum Statement {
|
|||
Remind(Option<Spanned<Delta>>),
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DoneDate {
|
||||
Date {
|
||||
|
|
@ -374,6 +375,7 @@ pub struct Log {
|
|||
pub enum Command {
|
||||
Include(Spanned<String>),
|
||||
Timezone(Spanned<String>),
|
||||
Capture, // TODO Set capture file by template?
|
||||
Task(Task),
|
||||
Note(Note),
|
||||
Log(Log),
|
||||
|
|
|
|||
|
|
@ -114,6 +114,13 @@ pub enum Error {
|
|||
span2: Span,
|
||||
tz2: String,
|
||||
},
|
||||
#[error("Multiple capture commands")]
|
||||
MultipleCapture {
|
||||
file1: FileSource,
|
||||
span1: Span,
|
||||
file2: FileSource,
|
||||
span2: Span,
|
||||
},
|
||||
#[error("Duplicate logs for {date}")]
|
||||
LogConflict {
|
||||
file1: FileSource,
|
||||
|
|
@ -179,6 +186,23 @@ impl<'a> Eprint<'a, Files> for Error {
|
|||
]);
|
||||
Self::eprint_diagnostic(files, config, &diagnostic);
|
||||
}
|
||||
Error::MultipleCapture {
|
||||
file1,
|
||||
span1,
|
||||
file2,
|
||||
span2,
|
||||
} => {
|
||||
let diagnostic = Diagnostic::error()
|
||||
.with_message("Multiple capture commands")
|
||||
.with_labels(vec![
|
||||
Label::primary(*file1, span1),
|
||||
Label::primary(*file2, span2),
|
||||
])
|
||||
.with_notes(vec![
|
||||
"There must be at most one CAPTURE command.".to_string()
|
||||
]);
|
||||
Self::eprint_diagnostic(files, config, &diagnostic);
|
||||
}
|
||||
Error::LogConflict {
|
||||
file1,
|
||||
span1,
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ impl fmt::Display for Command {
|
|||
match self {
|
||||
Command::Include(name) => writeln!(f, "INCLUDE {}", name),
|
||||
Command::Timezone(name) => writeln!(f, "TIMEZONE {}", name),
|
||||
Command::Capture => writeln!(f, "CAPTURE"),
|
||||
Command::Task(task) => write!(f, "{}", task),
|
||||
Command::Note(note) => write!(f, "{}", note),
|
||||
Command::Log(log) => write!(f, "{}", log),
|
||||
|
|
@ -322,8 +323,9 @@ impl File {
|
|||
// Order of commands in a file:
|
||||
// 1. Imports, sorted alphabetically
|
||||
// 2. Time zone(s)
|
||||
// 3. Log entries, sorted by date (ascending)
|
||||
// 4. Tasks and notes, in original order
|
||||
// 3. Captures
|
||||
// 4. Log entries, sorted by date (ascending)
|
||||
// 5. Tasks and notes, in original order
|
||||
|
||||
// There should always be at most one time zone, so we don't care about
|
||||
// their order.
|
||||
|
|
@ -347,8 +349,9 @@ impl File {
|
|||
commands.sort_by_key(|c| match c {
|
||||
Command::Include(_) => 0,
|
||||
Command::Timezone(_) => 1,
|
||||
Command::Log(_) => 2,
|
||||
Command::Task(_) | Command::Note(_) => 3,
|
||||
Command::Capture => 2,
|
||||
Command::Log(_) => 3,
|
||||
Command::Task(_) | Command::Note(_) => 4,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ rest_any = { (!eol ~ ANY)* }
|
|||
|
||||
include = { "INCLUDE" ~ WHITESPACE ~ rest_some ~ eol }
|
||||
timezone = { "TIMEZONE" ~ WHITESPACE ~ rest_some ~ eol }
|
||||
capture = { "CAPTURE" ~ eol }
|
||||
|
||||
number = @{ ASCII_DIGIT{1,9} } // Fits into an i32
|
||||
|
||||
|
|
@ -144,7 +145,7 @@ log_head = !{ "LOG" ~ datum ~ eol }
|
|||
log = { log_head ~ description }
|
||||
|
||||
empty_line = _{ WHITESPACE* ~ NEWLINE }
|
||||
command = { include | timezone | task | note | log }
|
||||
command = { include | timezone | capture | task | note | log }
|
||||
|
||||
file = ${ SOI ~ (empty_line* ~ command)* ~ empty_line* ~ WHITESPACE* ~ EOI }
|
||||
|
||||
|
|
|
|||
|
|
@ -826,6 +826,7 @@ fn parse_command(p: Pair<'_, Rule>) -> Result<Spanned<Command>> {
|
|||
let command = match p.as_rule() {
|
||||
Rule::include => Command::Include(parse_include(p)),
|
||||
Rule::timezone => Command::Timezone(parse_timezone(p)),
|
||||
Rule::capture => Command::Capture,
|
||||
Rule::task => Command::Task(parse_task(p)?),
|
||||
Rule::note => Command::Note(parse_note(p)?),
|
||||
Rule::log => Command::Log(parse_log(p)?),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue