1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/bin/sh
# anki-cli - dmenu-integrated Anki flashcard manager
# Usage: anki-cli [add|list|review|decks|info|tags|-h]
# Default (no args): dmenu action picker
cmd_add() {
# Pick deck
deck=$(apy info 2>/dev/null | awk '/^[A-Za-z]/ && !/^(Model|Sum|Sched|Coll|Conf|─)/{print $1}' | head -1)
decks=$(apy list-cards "deck:*" 2>/dev/null | awk '{print $1}' | sort -u)
if [ -n "$decks" ]; then
deck=$(printf '%s\nNew deck...' "$decks" | dmenu -i -l 20 -p "Deck:" || exit 0)
else
deck=$(printf 'Default\nNew deck...' | dmenu -i -l 20 -p "Deck:" || exit 0)
fi
[ -z "$deck" ] && exit 0
if [ "$deck" = "New deck..." ]; then
deck=$(printf '' | dmenu -l 1 -p "Deck name:" || exit 0)
[ -z "$deck" ] && exit 0
fi
# Pick model
model=$(apy list-models 2>/dev/null | dmenu -i -l 10 -p "Model:" || exit 0)
[ -z "$model" ] && exit 0
# Get front
front=$(printf '' | dmenu -c -l 1 -h 40 -p "Front:" || exit 0)
[ -z "$front" ] && exit 0
# Get back
back=$(printf '' | dmenu -c -l 1 -h 40 -p "Back:" || exit 0)
[ -z "$back" ] && exit 0
# Optional tags
tags=$(printf '' | dmenu -l 1 -p "Tags (space-separated):" || true)
if [ -n "$tags" ]; then
apy add-single -d "$deck" -m "$model" -t "$tags" "$front" "$back" 2>&1
else
apy add-single -d "$deck" -m "$model" "$front" "$back" 2>&1
fi
notify-send "Card added" "$front → $deck"
}
cmd_quick() {
# Quick add: front and back only, defaults for everything else
front=$(printf '' | dmenu -c -l 1 -h 40 -p "Front:" || exit 0)
[ -z "$front" ] && exit 0
back=$(printf '' | dmenu -c -l 1 -h 40 -p "Back:" || exit 0)
[ -z "$back" ] && exit 0
apy add-single "$front" "$back" 2>&1
notify-send "Card added" "$front"
}
cmd_list() {
apy list-cards-table "${1:-*}" 2>&1
}
cmd_review() {
apy review "${1:-is:due}" 2>&1
}
cmd_decks() {
apy info 2>&1
}
cmd_tags() {
apy tag 2>&1
}
cmd_dmenu() {
action=$(printf 'Quick add\nAdd (full)\nReview due\nList cards\nDecks & info\nTags' | dmenu -i -l 10 -p "Anki:" || exit 0)
[ -z "$action" ] && exit 0
case "$action" in
"Quick add") cmd_quick ;;
"Add (full)") cmd_add ;;
"Review due") cmd_review ;;
"List cards") cmd_list ;;
"Decks & info") cmd_decks ;;
"Tags") cmd_tags ;;
esac
}
case "$1" in
add) cmd_add ;;
quick) cmd_quick ;;
list) shift; cmd_list "$@" ;;
review) shift; cmd_review "$@" ;;
decks) cmd_decks ;;
info) apy info ;;
tags) cmd_tags ;;
-h|help)
printf 'anki-cli dmenu action picker\n'
printf 'anki-cli quick Quick add (front/back only)\n'
printf 'anki-cli add Add card (deck/model/tags)\n'
printf 'anki-cli list [Q] List cards (optional query)\n'
printf 'anki-cli review Review due cards in terminal\n'
printf 'anki-cli decks Show decks and stats\n'
printf 'anki-cli tags List all tags\n'
printf 'anki-cli info Collection info\n'
;;
"") cmd_dmenu ;;
*) printf 'Unknown command: %s (try anki-cli -h)\n' "$1" ;;
esac