mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
Update _beet to use zsh caching
Caching is now done with zsh builtin completion caching functions.
This commit is contained in:
parent
965640859c
commit
209d281871
1 changed files with 95 additions and 88 deletions
181
extra/_beet
181
extra/_beet
|
|
@ -2,28 +2,29 @@
|
||||||
|
|
||||||
# zsh completion for beets music library manager and MusicBrainz tagger: http://beets.radbox.org/
|
# zsh completion for beets music library manager and MusicBrainz tagger: http://beets.radbox.org/
|
||||||
|
|
||||||
# NOTE: it will be very slow the first time you try to complete in a zsh shell (especially if you've enable many plugins)
|
# Cache will be updated if it is older than the beets database or binary.
|
||||||
# You can make it faster in future by creating a cached version:
|
# Need to set BEETS_LIBRARY to some preliminary value since it is used by the cache checking function.
|
||||||
# 1) perform a query completion with this file (_beet), e.g. do: beet list artist:"<TAB>
|
typeset -g BEETS_LIBRARY=~/.config/beets/library.db
|
||||||
# to create the completion function (takes a few seconds)
|
zstyle ":completion:${curcontext}:" cache-policy _beet_check_cache
|
||||||
# 2) save a copy of the completion function: which _beet > _beet_cached
|
_beet_check_cache () {
|
||||||
# 3) save a copy of the query completion function: which _beet_query > _beet_query_cached
|
[[ ! -a "${1}" ]] || [[ ! -a ${~BEETS_LIBRARY} ]] || [[ "${1}" -ot ${~BEETS_LIBRARY} ]] || [[ "${1}" -ot =beet ]]
|
||||||
# 4) copy the contents of _beet_query_cached to the top of _beet_cached
|
}
|
||||||
# 5) copy and paste the _beet_field_values function from _beet to the top of _beet_cached
|
# Try to retrieve the cache, and find out if it needs to be updated
|
||||||
# 6) add the following line to the top of _beet_cached: #compdef beet
|
if ! _retrieve_cache beets || _cache_invalid beets; then
|
||||||
# 7) add the following line to the bottom of _beet_cached: _beet "$@"
|
local updatecache=1
|
||||||
# 8) save _beet_cached to your completions directory (e.g. /usr/share/zsh/functions/Completion)
|
# Location of database
|
||||||
# 9) add the following line to your .zshrc file: compdef _beet_cached beet
|
typeset -g BEETS_LIBRARY="$(beet config|grep library|cut -f 2 -d ' ')"
|
||||||
# You will need to repeat this proceedure each time you enable new plugins if you want them to complete properly.
|
# List of all fields
|
||||||
|
local -a fields
|
||||||
|
fields=(`beet fields | grep -G '^ ' | sort -u | colrm 1 2`)
|
||||||
|
fi
|
||||||
|
|
||||||
# useful: argument to _regex_arguments for matching any word
|
# useful: argument to _regex_arguments for matching any word
|
||||||
local matchany=/$'[^\0]##\0'/
|
local matchany=/$'[^\0]##\0'/
|
||||||
|
|
||||||
# Deal with completions for querying and modifying fields..
|
# Deal with completions for querying and modifying fields..
|
||||||
local fieldargs matchquery matchmodify
|
local fieldargs matchquery matchmodify
|
||||||
local -a fields
|
|
||||||
# get list of all fields
|
|
||||||
fields=(`beet fields | grep -G '^ ' | sort -u | colrm 1 2`)
|
|
||||||
# regexps for matching query and modify terms on the command line
|
# regexps for matching query and modify terms on the command line
|
||||||
matchquery=/"(${(j/|/)fields[@]})"$':[^\0]##\0'/
|
matchquery=/"(${(j/|/)fields[@]})"$':[^\0]##\0'/
|
||||||
matchmodify=/"(${(j/|/)fields[@]})"$'(=[^\0]##|!)\0'/
|
matchmodify=/"(${(j/|/)fields[@]})"$'(=[^\0]##|!)\0'/
|
||||||
|
|
@ -43,14 +44,17 @@ function _join_lines() {
|
||||||
function _beet_field_values()
|
function _beet_field_values()
|
||||||
{
|
{
|
||||||
local -a output fieldvals
|
local -a output fieldvals
|
||||||
local library="$(beet config|grep library|cut -f 2 -d ' ')"
|
local sqlcmd="select distinct $1 from items;"
|
||||||
output=$(sqlite3 ${~library} "select distinct $1 from items;")
|
|
||||||
case $1
|
case $1
|
||||||
in
|
in
|
||||||
lyrics)
|
lyrics)
|
||||||
fieldvals=
|
fieldvals=
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
if [[ "$(sqlite3 ${~BEETS_LIBRARY} ${sqlcmd} 2>&1)" =~ "no such column" ]]; then
|
||||||
|
sqlcmd="select distinct value from item_attributes where key=='$1' and value!='';"
|
||||||
|
fi
|
||||||
|
output="$(sqlite3 ${~BEETS_LIBRARY} ${sqlcmd} 2>/dev/null | sed -rn '/^-+$/,${{/^[- ]+$/n};p}')"
|
||||||
fieldvals=("${(f)output[@]}")
|
fieldvals=("${(f)output[@]}")
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
@ -68,8 +72,7 @@ queryelem="_values -S : 'query field (add an extra : to match by regexp)' '::' $
|
||||||
# store call to _values function for completing modify terms (no need to complete field values)
|
# store call to _values function for completing modify terms (no need to complete field values)
|
||||||
modifyelem="_values -S = 'modify field (replace = with ! to remove field)' $(echo "'${^fields[@]}:: '")"
|
modifyelem="_values -S = 'modify field (replace = with ! to remove field)' $(echo "'${^fields[@]}:: '")"
|
||||||
# Create completion function for queries
|
# Create completion function for queries
|
||||||
_regex_arguments _beet_query "$matchany" \# \( "$matchquery" ":query:query string:$queryelem" \) \
|
_regex_arguments _beet_query "$matchany" \# \( "$matchquery" ":query:query string:$queryelem" \) \( "$matchquery" ":query:query string:$queryelem" \) \#
|
||||||
\( "$matchquery" ":query:query string:$queryelem" \) \#
|
|
||||||
# store regexps for completing lists of queries and modifications
|
# store regexps for completing lists of queries and modifications
|
||||||
local -a query modify
|
local -a query modify
|
||||||
query=( \( "$matchquery" ":query:query string:{_beet_query}" \) \( "$matchquery" ":query:query string:{_beet_query}" \) \# )
|
query=( \( "$matchquery" ":query:query string:{_beet_query}" \) \( "$matchquery" ":query:query string:{_beet_query}" \) \# )
|
||||||
|
|
@ -174,73 +177,76 @@ function _beet_subcmd_options()
|
||||||
}
|
}
|
||||||
|
|
||||||
# Now build the arguments to _regex_arguments for each subcommand.
|
# Now build the arguments to _regex_arguments for each subcommand.
|
||||||
local -a options regex_words_subcmds regex_words_help
|
if [[ -n $updatecache ]]; then
|
||||||
local subcmd cmddesc
|
local -a options regex_words_subcmds regex_words_help
|
||||||
for i in ${${(f)"$(beet help | _join_lines ' ' 3 'Commands:')"[@]}[@]}
|
local subcmd cmddesc
|
||||||
do
|
for i in ${${(f)"$(beet help | _join_lines ' ' 3 'Commands:')"[@]}[@]}
|
||||||
subcmd="${i[(w)1]}"
|
do
|
||||||
# remove first word and parenthesised alias, replace : with -, [ with (, ] with ), and remove single quotes
|
subcmd="${i[(w)1]}"
|
||||||
cmddesc="${${${${${i[(w)2,-1]##\(*\) #}//:/-}//\[/(}//\]/)}//\'/}"
|
# remove first word and parenthesised alias, replace : with -, [ with (, ] with ), and remove single quotes
|
||||||
case $subcmd
|
cmddesc="${${${${${i[(w)2,-1]##\(*\) #}//:/-}//\[/(}//\]/)}//\'/}"
|
||||||
|
case $subcmd
|
||||||
in
|
in
|
||||||
(config)
|
(config)
|
||||||
_regex_words options "config options" "$helpopt" "$pathopt" "$editopt" "$defaultopt"
|
_regex_words options "config options" "$helpopt" "$pathopt" "$editopt" "$defaultopt"
|
||||||
options=("${reply[@]}")
|
options=("${reply[@]}")
|
||||||
;;
|
;;
|
||||||
(import)
|
(import)
|
||||||
_regex_words options "import options" "$helpopt" "$writeopt" "$nowriteopt" "$copyopt" "$nocopyopt"\
|
_regex_words options "import options" "$helpopt" "$writeopt" "$nowriteopt" "$copyopt" "$nocopyopt"\
|
||||||
"$inferopt" "$noinferopt" "$resumeopt" "$noresumeopt" "$nopromptopt" "$logopt" "$individualopt" "$confirmopt"\
|
"$inferopt" "$noinferopt" "$resumeopt" "$noresumeopt" "$nopromptopt" "$logopt" "$individualopt" "$confirmopt"\
|
||||||
"$retagopt" "$skipopt" "$noskipopt" "$flatopt" "$groupopt"
|
"$retagopt" "$skipopt" "$noskipopt" "$flatopt" "$groupopt"
|
||||||
options=( "${reply[@]}" \# "${files[@]}" \# )
|
options=( "${reply[@]}" \# "${files[@]}" \# )
|
||||||
;;
|
;;
|
||||||
(list)
|
(list)
|
||||||
_regex_words options "list options" "$helpopt" "$pathopt" "$albumopt" "$formatopt"
|
_regex_words options "list options" "$helpopt" "$pathopt" "$albumopt" "$formatopt"
|
||||||
options=( "$reply[@]" \# "${query[@]}" )
|
options=( "$reply[@]" \# "${query[@]}" )
|
||||||
;;
|
;;
|
||||||
(modify)
|
(modify)
|
||||||
_regex_words options "modify options" "$helpopt" "$dontmoveopt" "$writeopt" "$nowriteopt" "$albumopt" \
|
_regex_words options "modify options" "$helpopt" "$dontmoveopt" "$writeopt" "$nowriteopt" "$albumopt" \
|
||||||
"$noconfirmopt" "$formatopt"
|
"$noconfirmopt" "$formatopt"
|
||||||
options=( "${reply[@]}" \# "${query[@]}" "${modify[@]}" )
|
options=( "${reply[@]}" \# "${query[@]}" "${modify[@]}" )
|
||||||
;;
|
;;
|
||||||
(move)
|
(move)
|
||||||
_regex_words options "move options" "$helpopt" "$albumopt" "$destopt" "$copynomoveopt"
|
_regex_words options "move options" "$helpopt" "$albumopt" "$destopt" "$copynomoveopt"
|
||||||
options=( "${reply[@]}" \# "${query[@]}")
|
options=( "${reply[@]}" \# "${query[@]}")
|
||||||
;;
|
;;
|
||||||
(remove)
|
(remove)
|
||||||
_regex_words options "remove options" "$helpopt" "$albumopt" "$removeopt"
|
_regex_words options "remove options" "$helpopt" "$albumopt" "$removeopt"
|
||||||
options=( "${reply[@]}" \# "${query[@]}" )
|
options=( "${reply[@]}" \# "${query[@]}" )
|
||||||
;;
|
;;
|
||||||
(stats)
|
(stats)
|
||||||
_regex_words options "stats options" "$helpopt" "$exactopt"
|
_regex_words options "stats options" "$helpopt" "$exactopt"
|
||||||
options=( "${reply[@]}" \# "${query[@]}" )
|
options=( "${reply[@]}" \# "${query[@]}" )
|
||||||
;;
|
;;
|
||||||
(update)
|
(update)
|
||||||
_regex_words options "update options" "$helpopt" "$albumopt" "$dontmoveopt" "$pretendopt" "$formatopt"
|
_regex_words options "update options" "$helpopt" "$albumopt" "$dontmoveopt" "$pretendopt" "$formatopt"
|
||||||
options=( "${reply[@]}" \# "${query[@]}" )
|
options=( "${reply[@]}" \# "${query[@]}" )
|
||||||
;;
|
;;
|
||||||
(write)
|
(write)
|
||||||
_regex_words options "write options" "$helpopt" "$pretendopt"
|
_regex_words options "write options" "$helpopt" "$pretendopt"
|
||||||
options=( "${reply[@]}" \# "${query[@]}" )
|
options=( "${reply[@]}" \# "${query[@]}" )
|
||||||
;;
|
;;
|
||||||
(fields|migrate|version)
|
(fields|migrate|version)
|
||||||
options=()
|
options=()
|
||||||
;;
|
;;
|
||||||
(help)
|
(help)
|
||||||
# The help subcommand is treated separately
|
# The help subcommand is treated separately
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
(*) # completions for plugin commands are generated using _beet_subcmd_options
|
(*) # completions for plugin commands are generated using _beet_subcmd_options
|
||||||
_beet_subcmd_options "$subcmd"
|
_beet_subcmd_options "$subcmd"
|
||||||
options=( \( "${reply[@]}" \# "${query[@]}" \) )
|
options=( \( "${reply[@]}" \# "${query[@]}" \) )
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
# Create variable for holding option for this subcommand, and assign to it (needs to have a unique name).
|
# Create variable for holding option for this subcommand, and assign to it (needs to have a unique name).
|
||||||
typeset -a opts_for_$subcmd
|
typeset -a opts_for_$subcmd
|
||||||
set -A opts_for_$subcmd ${options[@]} # Assignment MUST be done using set (other methods fail).
|
set -A opts_for_$subcmd ${options[@]} # Assignment MUST be done using set (other methods fail).
|
||||||
regex_words_subcmds+=("$subcmd:$cmddesc:\${(@)opts_for_$subcmd}")
|
regex_words_subcmds+=("$subcmd:$cmddesc:\${(@)opts_for_$subcmd}")
|
||||||
# Add to regex_words args for help subcommand
|
# Add to regex_words args for help subcommand
|
||||||
regex_words_help+=("$subcmd:$cmddesc")
|
regex_words_help+=("$subcmd:$cmddesc")
|
||||||
done
|
done
|
||||||
|
_store_cache beets regex_words_subcmds regex_words_help BEETS_LIBRARY fields
|
||||||
|
fi
|
||||||
|
|
||||||
local -a opts_for_help
|
local -a opts_for_help
|
||||||
_regex_words subcmds "subcommands" "${regex_words_help[@]}"
|
_regex_words subcmds "subcommands" "${regex_words_help[@]}"
|
||||||
|
|
@ -253,7 +259,7 @@ _regex_words options "global options" "$configopt" "$debugopt" "$libopt" "$helpo
|
||||||
globalopts=("${reply[@]}")
|
globalopts=("${reply[@]}")
|
||||||
|
|
||||||
# Create main completion function
|
# Create main completion function
|
||||||
#local -a subcmds
|
local -a subcmds
|
||||||
_regex_words subcmds "subcommands" "${regex_words_subcmds[@]}"
|
_regex_words subcmds "subcommands" "${regex_words_subcmds[@]}"
|
||||||
subcmds=("${reply[@]}")
|
subcmds=("${reply[@]}")
|
||||||
_regex_arguments _beet "$matchany" \( "${globalopts[@]}" \# \) "${subcmds[@]}"
|
_regex_arguments _beet "$matchany" \( "${globalopts[@]}" \# \) "${subcmds[@]}"
|
||||||
|
|
@ -267,3 +273,4 @@ _beet "$@"
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# mode:shell-script
|
# mode:shell-script
|
||||||
# End:
|
# End:
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue