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`.
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
-----
@@ -88,7 +88,7 @@ In addition, there are the following keybindings:
| Key | Action |
| --- | ------ |
| `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-r` | Refresh the view |
| `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-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
-----------
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);
}
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; }
/^# / && !summary { summary = "S" escape(substr($0, 3)); next; }
/^> / && !categories { categories = "C" escape_but_commas(substr($0, 3)); next; }
@@ -27,6 +28,14 @@ END {
categories = categories "," a[i]
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) {
# Use command line `date` for parsing
cmd = "date -d \"" due "\" +\"%Y%m%d\"";
+12 -1
View File
@@ -19,6 +19,14 @@ ENDFILE {
categories = categories "," a[i]
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) {
# Use command line `date` for parsing
cmd = "date -d \"" due "\" +\"%Y%m%d\"";
@@ -31,6 +39,7 @@ ENDFILE {
}
NR == FNR && desc { desc = desc "\\n" escape($0); 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 && /^> / && !categories { categories = "C" escape_but_commas(substr($0, 3)); next; }
@@ -41,13 +50,15 @@ due && type == "VJOURNAL" { print "Notes and journal entries do not have
/^BEGIN:(VJOURNAL|VTODO)/ { type = $2; print; next; }
/^ / && drop { next; } # drop this folded line
/^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
/^SEQUENCE/ && type { seq = $2; next; } # store sequence number and skip
/^END:/ && type == $2 {
seq = seq ? seq + 1 : 1;
print_cr("SEQUENCE:" seq);
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);
print_fold("SUMMARY:", summary);
print_fold("CATEGORIES:", categories);
+2 -2
View File
@@ -66,8 +66,8 @@ if [ "${1:-}" = "--help" ]; then
specified summary
--add-task <summary> [<due>] Read task from stdin and add it with the
specified summary and optional due date
--add-jour <summary> Read journal from stdin and add it with the
specified summary
--add-jour <summary> [<date>] Read journal from stdin and add it with the
specified summary and optional date
--collection <nr> Select collection to which the note, task, or
journal entry is added non-interactively. The
argument <nr> is the ordinal describing the
+13 -11
View File
@@ -37,7 +37,7 @@ esac
if [ -z "${next_filter:-}" ]; then
# 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
"--add-note" | "--add-task" | "--add-jour" | "--collection")
noninteractive=1
@@ -53,26 +53,28 @@ if [ -z "${next_filter:-}" ]; then
fi
add_option="$1"
shift
summary=${1-}
summary=${1:-}
if [ -z "$summary" ]; then
err "You did not give a summary"
exit 1
fi
shift
if [ "$add_option" = "--add-task" ] && [ -n "${1:-}" ]; then
if [ -n "${1:-}" ]; then
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
if [ -z "$due" ] || ! date -d "$due" >/dev/null 2>&1; then
err "Invalid due date"
if [ -z "$dueorstartdate" ] || ! date -d "$dueorstartdate" >/dev/null 2>&1; then
err "Invalid date"
exit 1
fi
;;
esac
;;
esac
fi
;;
"--collection")
@@ -112,10 +114,10 @@ if [ -n "${noninteractive:-}" ]; then
__add_note "$collection" "$summary"
;;
"--add-task")
__add_task "$collection" "$summary" "${due:-}"
__add_task "$collection" "$summary" "${dueorstartdate:-}"
;;
"--add-jour")
__add_jour "$collection" "$summary"
__add_jour "$collection" "$summary" "${dueorstartdate:-}"
;;
esac
exit 0
+10 -4
View File
@@ -74,18 +74,20 @@ __add_task() {
__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 $2: Summary
# @input $3: start date (optional, defaults to "today")
__add_jour() {
collection="$1"
shift
summary="$1"
shift
[ "${1:-}" ] && start=$1 || start="today"
tmpmd=$(mktemp --suffix='.md')
{
echo "::: |> <!-- keep this line to associate the entry to _today_ -->"
echo "::: |> $start"
echo "# $summary"
echo ""
} >"$tmpmd"
@@ -137,9 +139,13 @@ __edit() {
file="$1"
shift
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")
if [ -n "$due" ]; then
echo "::: <| $due" >"$tmpmd"
echo "::: <| $due" >>"$tmpmd"
fi
{
echo "# $(awk -v field="SUMMARY" -v oneline=1 "$AWK_GET" "$file")"
@@ -228,7 +234,7 @@ __new() {
done
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 "# <!-- write summary here -->"
echo "> <!-- comma-separated list of categories -->"