as per gh c65d8ae5fe6bafefe8182613f7f9f79983e12a78

This commit is contained in:
2026-03-19 12:10:46 +01:00
parent b356b557c2
commit 439b661cb8
6 changed files with 92 additions and 30 deletions
+36 -2
View File
@@ -79,7 +79,7 @@ item_types = ["VJOURNAL", "VTODO"]
You may also specify the location of the configuration file with the environment `CONFIGFILE`. You may also specify the location of the configuration file with the environment `CONFIGFILE`.
By default, `fzf-vjour` sets a descriptive terminal title. By default, `fzf-vjour` sets a descriptive terminal title.
This can be bypassed by specyfing `SET_TERMINAL_TITLE="no"` in the configuration file. This can be bypassed by specifying `SET_TERMINAL_TITLE="no"` in the configuration file.
Usage Usage
----- -----
@@ -88,7 +88,7 @@ In addition, there are the following keybindings:
| Key | Action | | Key | Action |
| --- | ------ | | --- | ------ |
| `enter` | Open note/journal/task in your `$EDITOR` | | `enter` | Open note/journal/task in your `$EDITOR` |
| `ctrl-alt-d` | Delete the seleted entry | | `ctrl-alt-d` | Delete the selected entry |
| `ctrl-n` | Make a new entry | | `ctrl-n` | Make a new entry |
| `ctrl-r` | Refresh the view | | `ctrl-r` | Refresh the view |
| `ctrl-s` | Run the synchronization command | | `ctrl-s` | Run the synchronization command |
@@ -117,6 +117,40 @@ In the attachment view, you may use the following keys:
| `ctrl-a` | Add attachment | | `ctrl-a` | Add attachment |
| `ctrl-alt-d` | Delete attachment | | `ctrl-alt-d` | Delete attachment |
Entry types
-----------
This applications, as well as [jtx Board](https://jtx.techbee.at/), distinguishes among three entry types.
**Notes** are VJOURNAL entries without dates. Here is an example of a note:
```md
# Related research
> research
Lorem ipsum
```
**Journal** entries are notes associated to a date (typically to _today_). An example of a journal entry is:
```md
::: |> today <!-- specify the date for journal entries -->
# Alignment for Bell experiment
> lab
Lorem ipsum
```
**Tasks** are VTODO entries with an optional due date. An example of a task _with_ a due date is:
```md
::: <| next Sunday
# Finish manuscript
> research
```
Another example of a task _without_ due date is
```md
::: <|
# Acquire Epist. Lett
> research
```
Git support Git support
----------- -----------
You can track your entries with `git` by simply running `fzf-vjour --git-init`. You can track your entries with `git` by simply running `fzf-vjour --git-init`.
+10 -1
View File
@@ -5,7 +5,8 @@ BEGIN {
zulu = strftime("%Y%m%dT%H%M%SZ", systime(), 1); zulu = strftime("%Y%m%dT%H%M%SZ", systime(), 1);
} }
desc { desc = desc "\\n" escape($0); next; } desc { desc = desc "\\n" escape($0); next; }
/^::: \|>/ && !start { gsub("\"", ""); start = substr(zulu, 1, 8); next; } /^::: \|>/ && !start { gsub("\"", ""); i = index($0, "<");
start = i ? substr($0, 8, 8-i) : substr($0, 8); next; }
/^::: <\|/ && !due { gsub("\"", ""); due = "D" substr($0, 8); next; } /^::: <\|/ && !due { gsub("\"", ""); due = "D" substr($0, 8); next; }
/^# / && !summary { summary = "S" escape(substr($0, 3)); next; } /^# / && !summary { summary = "S" escape(substr($0, 3)); next; }
/^> / && !categories { categories = "C" escape_but_commas(substr($0, 3)); next; } /^> / && !categories { categories = "C" escape_but_commas(substr($0, 3)); next; }
@@ -27,6 +28,14 @@ END {
categories = categories "," a[i] categories = categories "," a[i]
categories = substr(categories, 2) categories = substr(categories, 2)
} }
if (start) {
# Use command line `date` for parsing
cmd = "date -d \"" start "\" +\"%Y%m%d\"";
suc = cmd | getline start
close(cmd)
if (suc != 1)
exit 1
}
if (due) { if (due) {
# Use command line `date` for parsing # Use command line `date` for parsing
cmd = "date -d \"" due "\" +\"%Y%m%d\""; cmd = "date -d \"" due "\" +\"%Y%m%d\"";
+13 -2
View File
@@ -19,6 +19,14 @@ ENDFILE {
categories = categories "," a[i] categories = categories "," a[i]
categories = substr(categories, 2) categories = substr(categories, 2)
} }
if (start) {
# Use command line `date` for parsing
cmd = "date -d \"" start "\" +\"%Y%m%d\"";
suc = cmd | getline start
close(cmd)
if (suc != 1)
exit 1
}
if (due) { if (due) {
# Use command line `date` for parsing # Use command line `date` for parsing
cmd = "date -d \"" due "\" +\"%Y%m%d\""; cmd = "date -d \"" due "\" +\"%Y%m%d\"";
@@ -31,7 +39,8 @@ ENDFILE {
} }
NR == FNR && desc { desc = desc "\\n" escape($0); next; } NR == FNR && desc { desc = desc "\\n" escape($0); next; }
NR == FNR && /^::: <\|/ && !due { gsub("\"",""); due = "D" substr($0, 8); next; } NR == FNR && /^::: \|>/ && !start { gsub("\"", ""); start = substr($0, 8); next; }
NR == FNR && /^::: <\|/ && !due { gsub("\"", ""); due = "D" substr($0, 8); next; }
NR == FNR && /^# / && !summary { summary = "S" escape(substr($0, 3)); next; } NR == FNR && /^# / && !summary { summary = "S" escape(substr($0, 3)); next; }
NR == FNR && /^> / && !categories { categories = "C" escape_but_commas(substr($0, 3)); next; } NR == FNR && /^> / && !categories { categories = "C" escape_but_commas(substr($0, 3)); next; }
NR == FNR && !$0 && !el { el = 1; next; } NR == FNR && !$0 && !el { el = 1; next; }
@@ -41,13 +50,15 @@ due && type == "VJOURNAL" { print "Notes and journal entries do not have
/^BEGIN:(VJOURNAL|VTODO)/ { type = $2; print; next; } /^BEGIN:(VJOURNAL|VTODO)/ { type = $2; print; next; }
/^ / && drop { next; } # drop this folded line /^ / && drop { next; } # drop this folded line
/^X-ALT-DESC/ && type { drop = 1; next; } # drop this alternative description /^X-ALT-DESC/ && type { drop = 1; next; } # drop this alternative description
/^(DUE|SUMMARY|CATEGORIES|DESCRIPTION|LAST-MODIFIED)/ && type { drop = 1; next; } # skip for now, we will write updated fields at the end /^(DTSTART|DUE|SUMMARY|CATEGORIES|DESCRIPTION|LAST-MODIFIED)/ && type { drop = 1; next; } # skip for now, we will write updated fields at the end
{ drop = 0 } # keep everything else { drop = 0 } # keep everything else
/^SEQUENCE/ && type { seq = $2; next; } # store sequence number and skip /^SEQUENCE/ && type { seq = $2; next; } # store sequence number and skip
/^END:/ && type == $2 { /^END:/ && type == $2 {
seq = seq ? seq + 1 : 1; seq = seq ? seq + 1 : 1;
print_cr("SEQUENCE:" seq); print_cr("SEQUENCE:" seq);
print_cr("LAST-MODIFIED:" zulu); print_cr("LAST-MODIFIED:" zulu);
if (start && due && due < start) {print "Due date cannot be earlier than the start date." > "/dev/stderr"; exit 1;}
if (start) print_cr("DTSTART;VALUE=DATE:" start);
if (due) print_cr("DUE;VALUE=DATE:" due); if (due) print_cr("DUE;VALUE=DATE:" due);
print_fold("SUMMARY:", summary); print_fold("SUMMARY:", summary);
print_fold("CATEGORIES:", categories); print_fold("CATEGORIES:", categories);
+2 -2
View File
@@ -66,8 +66,8 @@ if [ "${1:-}" = "--help" ]; then
specified summary specified summary
--add-task <summary> [<due>] Read task from stdin and add it with the --add-task <summary> [<due>] Read task from stdin and add it with the
specified summary and optional due date specified summary and optional due date
--add-jour <summary> Read journal from stdin and add it with the --add-jour <summary> [<date>] Read journal from stdin and add it with the
specified summary specified summary and optional date
--collection <nr> Select collection to which the note, task, or --collection <nr> Select collection to which the note, task, or
journal entry is added non-interactively. The journal entry is added non-interactively. The
argument <nr> is the ordinal describing the argument <nr> is the ordinal describing the
+13 -11
View File
@@ -37,7 +37,7 @@ esac
if [ -z "${next_filter:-}" ]; then if [ -z "${next_filter:-}" ]; then
# else [FILTER] are the next options # else [FILTER] are the next options
# Here, we have --add-xyz with --collection or nothign # Here, we have --add-xyz with --collection or nothing
case "${1:-}" in case "${1:-}" in
"--add-note" | "--add-task" | "--add-jour" | "--collection") "--add-note" | "--add-task" | "--add-jour" | "--collection")
noninteractive=1 noninteractive=1
@@ -53,26 +53,28 @@ if [ -z "${next_filter:-}" ]; then
fi fi
add_option="$1" add_option="$1"
shift shift
summary=${1-} summary=${1:-}
if [ -z "$summary" ]; then if [ -z "$summary" ]; then
err "You did not give a summary" err "You did not give a summary"
exit 1 exit 1
fi fi
shift shift
if [ "$add_option" = "--add-task" ] && [ -n "${1:-}" ]; then if [ -n "${1:-}" ]; then
case "$1" in case "$1" in
"--"*) "--"*) continue ;;
continue
;;
*) *)
due=$(printf "%s" "$1" | tr -dc "[:alnum:][:blank:]") case "$add_option" in
"--add-task" | "--add-jour")
dueorstartdate=$(printf "%s" "$1" | tr -dc "[:alnum:][:blank:]")
shift shift
if [ -z "$due" ] || ! date -d "$due" >/dev/null 2>&1; then if [ -z "$dueorstartdate" ] || ! date -d "$dueorstartdate" >/dev/null 2>&1; then
err "Invalid due date" err "Invalid date"
exit 1 exit 1
fi fi
;; ;;
esac esac
;;
esac
fi fi
;; ;;
"--collection") "--collection")
@@ -112,10 +114,10 @@ if [ -n "${noninteractive:-}" ]; then
__add_note "$collection" "$summary" __add_note "$collection" "$summary"
;; ;;
"--add-task") "--add-task")
__add_task "$collection" "$summary" "${due:-}" __add_task "$collection" "$summary" "${dueorstartdate:-}"
;; ;;
"--add-jour") "--add-jour")
__add_jour "$collection" "$summary" __add_jour "$collection" "$summary" "${dueorstartdate:-}"
;; ;;
esac esac
exit 0 exit 0
+10 -4
View File
@@ -74,18 +74,20 @@ __add_task() {
__add_from_md "$tmpmd" "$collection" __add_from_md "$tmpmd" "$collection"
} }
# Noninteractively add jounral, and fill description from stdin # Noninteractively add journal, and fill description from stdin
# #
# @input $1: Collection # @input $1: Collection
# @input $2: Summary # @input $2: Summary
# @input $3: start date (optional, defaults to "today")
__add_jour() { __add_jour() {
collection="$1" collection="$1"
shift shift
summary="$1" summary="$1"
shift shift
[ "${1:-}" ] && start=$1 || start="today"
tmpmd=$(mktemp --suffix='.md') tmpmd=$(mktemp --suffix='.md')
{ {
echo "::: |> <!-- keep this line to associate the entry to _today_ -->" echo "::: |> $start"
echo "# $summary" echo "# $summary"
echo "" echo ""
} >"$tmpmd" } >"$tmpmd"
@@ -137,9 +139,13 @@ __edit() {
file="$1" file="$1"
shift shift
tmpmd=$(mktemp --suffix='.md') tmpmd=$(mktemp --suffix='.md')
start=$(awk -v field="DTSTART" -v format="date" "$AWK_GET" "$file")
if [ -n "$start" ]; then
echo "::: |> $start" >>"$tmpmd"
fi
due=$(awk -v field="DUE" -v format="date" "$AWK_GET" "$file") due=$(awk -v field="DUE" -v format="date" "$AWK_GET" "$file")
if [ -n "$due" ]; then if [ -n "$due" ]; then
echo "::: <| $due" >"$tmpmd" echo "::: <| $due" >>"$tmpmd"
fi fi
{ {
echo "# $(awk -v field="SUMMARY" -v oneline=1 "$AWK_GET" "$file")" echo "# $(awk -v field="SUMMARY" -v oneline=1 "$AWK_GET" "$file")"
@@ -228,7 +234,7 @@ __new() {
done done
tmpmd=$(mktemp --suffix='.md') tmpmd=$(mktemp --suffix='.md')
{ {
echo "::: |> <!-- keep this line to associate the entry to _today_ -->" echo "::: |> today <!-- specify the date for journal entries -->"
echo "::: <| <!-- specify the due date for to-dos, can be empty, a date string, or even \"next Sunday\" -->" echo "::: <| <!-- specify the due date for to-dos, can be empty, a date string, or even \"next Sunday\" -->"
echo "# <!-- write summary here -->" echo "# <!-- write summary here -->"
echo "> <!-- comma-separated list of categories -->" echo "> <!-- comma-separated list of categories -->"