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/
|
||||
|
||||
# NOTE: it will be very slow the first time you try to complete in a zsh shell (especially if you've enable many plugins)
|
||||
# You can make it faster in future by creating a cached version:
|
||||
# 1) perform a query completion with this file (_beet), e.g. do: beet list artist:"<TAB>
|
||||
# to create the completion function (takes a few seconds)
|
||||
# 2) save a copy of the completion function: which _beet > _beet_cached
|
||||
# 3) save a copy of the query completion function: which _beet_query > _beet_query_cached
|
||||
# 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
|
||||
# 6) add the following line to the top of _beet_cached: #compdef beet
|
||||
# 7) add the following line to the bottom of _beet_cached: _beet "$@"
|
||||
# 8) save _beet_cached to your completions directory (e.g. /usr/share/zsh/functions/Completion)
|
||||
# 9) add the following line to your .zshrc file: compdef _beet_cached beet
|
||||
# You will need to repeat this proceedure each time you enable new plugins if you want them to complete properly.
|
||||
# Cache will be updated if it is older than the beets database or binary.
|
||||
# Need to set BEETS_LIBRARY to some preliminary value since it is used by the cache checking function.
|
||||
typeset -g BEETS_LIBRARY=~/.config/beets/library.db
|
||||
zstyle ":completion:${curcontext}:" cache-policy _beet_check_cache
|
||||
_beet_check_cache () {
|
||||
[[ ! -a "${1}" ]] || [[ ! -a ${~BEETS_LIBRARY} ]] || [[ "${1}" -ot ${~BEETS_LIBRARY} ]] || [[ "${1}" -ot =beet ]]
|
||||
}
|
||||
# Try to retrieve the cache, and find out if it needs to be updated
|
||||
if ! _retrieve_cache beets || _cache_invalid beets; then
|
||||
local updatecache=1
|
||||
# Location of database
|
||||
typeset -g BEETS_LIBRARY="$(beet config|grep library|cut -f 2 -d ' ')"
|
||||
# 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
|
||||
local matchany=/$'[^\0]##\0'/
|
||||
|
||||
# Deal with completions for querying and modifying fields..
|
||||
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
|
||||
matchquery=/"(${(j/|/)fields[@]})"$':[^\0]##\0'/
|
||||
matchmodify=/"(${(j/|/)fields[@]})"$'(=[^\0]##|!)\0'/
|
||||
|
|
@ -43,14 +44,17 @@ function _join_lines() {
|
|||
function _beet_field_values()
|
||||
{
|
||||
local -a output fieldvals
|
||||
local library="$(beet config|grep library|cut -f 2 -d ' ')"
|
||||
output=$(sqlite3 ${~library} "select distinct $1 from items;")
|
||||
local sqlcmd="select distinct $1 from items;"
|
||||
case $1
|
||||
in
|
||||
lyrics)
|
||||
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[@]}")
|
||||
;;
|
||||
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)
|
||||
modifyelem="_values -S = 'modify field (replace = with ! to remove field)' $(echo "'${^fields[@]}:: '")"
|
||||
# Create completion function for queries
|
||||
_regex_arguments _beet_query "$matchany" \# \( "$matchquery" ":query:query string:$queryelem" \) \
|
||||
\( "$matchquery" ":query:query string:$queryelem" \) \#
|
||||
_regex_arguments _beet_query "$matchany" \# \( "$matchquery" ":query:query string:$queryelem" \) \( "$matchquery" ":query:query string:$queryelem" \) \#
|
||||
# store regexps for completing lists of queries and modifications
|
||||
local -a query modify
|
||||
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.
|
||||
local -a options regex_words_subcmds regex_words_help
|
||||
local subcmd cmddesc
|
||||
for i in ${${(f)"$(beet help | _join_lines ' ' 3 'Commands:')"[@]}[@]}
|
||||
do
|
||||
subcmd="${i[(w)1]}"
|
||||
# remove first word and parenthesised alias, replace : with -, [ with (, ] with ), and remove single quotes
|
||||
cmddesc="${${${${${i[(w)2,-1]##\(*\) #}//:/-}//\[/(}//\]/)}//\'/}"
|
||||
case $subcmd
|
||||
if [[ -n $updatecache ]]; then
|
||||
local -a options regex_words_subcmds regex_words_help
|
||||
local subcmd cmddesc
|
||||
for i in ${${(f)"$(beet help | _join_lines ' ' 3 'Commands:')"[@]}[@]}
|
||||
do
|
||||
subcmd="${i[(w)1]}"
|
||||
# remove first word and parenthesised alias, replace : with -, [ with (, ] with ), and remove single quotes
|
||||
cmddesc="${${${${${i[(w)2,-1]##\(*\) #}//:/-}//\[/(}//\]/)}//\'/}"
|
||||
case $subcmd
|
||||
in
|
||||
(config)
|
||||
_regex_words options "config options" "$helpopt" "$pathopt" "$editopt" "$defaultopt"
|
||||
options=("${reply[@]}")
|
||||
;;
|
||||
(import)
|
||||
_regex_words options "import options" "$helpopt" "$writeopt" "$nowriteopt" "$copyopt" "$nocopyopt"\
|
||||
"$inferopt" "$noinferopt" "$resumeopt" "$noresumeopt" "$nopromptopt" "$logopt" "$individualopt" "$confirmopt"\
|
||||
"$retagopt" "$skipopt" "$noskipopt" "$flatopt" "$groupopt"
|
||||
options=( "${reply[@]}" \# "${files[@]}" \# )
|
||||
;;
|
||||
(list)
|
||||
_regex_words options "list options" "$helpopt" "$pathopt" "$albumopt" "$formatopt"
|
||||
options=( "$reply[@]" \# "${query[@]}" )
|
||||
;;
|
||||
(modify)
|
||||
_regex_words options "modify options" "$helpopt" "$dontmoveopt" "$writeopt" "$nowriteopt" "$albumopt" \
|
||||
"$noconfirmopt" "$formatopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" "${modify[@]}" )
|
||||
;;
|
||||
(move)
|
||||
_regex_words options "move options" "$helpopt" "$albumopt" "$destopt" "$copynomoveopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}")
|
||||
;;
|
||||
(remove)
|
||||
_regex_words options "remove options" "$helpopt" "$albumopt" "$removeopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(stats)
|
||||
_regex_words options "stats options" "$helpopt" "$exactopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(update)
|
||||
_regex_words options "update options" "$helpopt" "$albumopt" "$dontmoveopt" "$pretendopt" "$formatopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(write)
|
||||
_regex_words options "write options" "$helpopt" "$pretendopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(fields|migrate|version)
|
||||
options=()
|
||||
;;
|
||||
(help)
|
||||
# The help subcommand is treated separately
|
||||
continue
|
||||
;;
|
||||
(*) # completions for plugin commands are generated using _beet_subcmd_options
|
||||
_beet_subcmd_options "$subcmd"
|
||||
options=( \( "${reply[@]}" \# "${query[@]}" \) )
|
||||
;;
|
||||
esac
|
||||
# Create variable for holding option for this subcommand, and assign to it (needs to have a unique name).
|
||||
typeset -a opts_for_$subcmd
|
||||
set -A opts_for_$subcmd ${options[@]} # Assignment MUST be done using set (other methods fail).
|
||||
regex_words_subcmds+=("$subcmd:$cmddesc:\${(@)opts_for_$subcmd}")
|
||||
# Add to regex_words args for help subcommand
|
||||
regex_words_help+=("$subcmd:$cmddesc")
|
||||
done
|
||||
(config)
|
||||
_regex_words options "config options" "$helpopt" "$pathopt" "$editopt" "$defaultopt"
|
||||
options=("${reply[@]}")
|
||||
;;
|
||||
(import)
|
||||
_regex_words options "import options" "$helpopt" "$writeopt" "$nowriteopt" "$copyopt" "$nocopyopt"\
|
||||
"$inferopt" "$noinferopt" "$resumeopt" "$noresumeopt" "$nopromptopt" "$logopt" "$individualopt" "$confirmopt"\
|
||||
"$retagopt" "$skipopt" "$noskipopt" "$flatopt" "$groupopt"
|
||||
options=( "${reply[@]}" \# "${files[@]}" \# )
|
||||
;;
|
||||
(list)
|
||||
_regex_words options "list options" "$helpopt" "$pathopt" "$albumopt" "$formatopt"
|
||||
options=( "$reply[@]" \# "${query[@]}" )
|
||||
;;
|
||||
(modify)
|
||||
_regex_words options "modify options" "$helpopt" "$dontmoveopt" "$writeopt" "$nowriteopt" "$albumopt" \
|
||||
"$noconfirmopt" "$formatopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" "${modify[@]}" )
|
||||
;;
|
||||
(move)
|
||||
_regex_words options "move options" "$helpopt" "$albumopt" "$destopt" "$copynomoveopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}")
|
||||
;;
|
||||
(remove)
|
||||
_regex_words options "remove options" "$helpopt" "$albumopt" "$removeopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(stats)
|
||||
_regex_words options "stats options" "$helpopt" "$exactopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(update)
|
||||
_regex_words options "update options" "$helpopt" "$albumopt" "$dontmoveopt" "$pretendopt" "$formatopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(write)
|
||||
_regex_words options "write options" "$helpopt" "$pretendopt"
|
||||
options=( "${reply[@]}" \# "${query[@]}" )
|
||||
;;
|
||||
(fields|migrate|version)
|
||||
options=()
|
||||
;;
|
||||
(help)
|
||||
# The help subcommand is treated separately
|
||||
continue
|
||||
;;
|
||||
(*) # completions for plugin commands are generated using _beet_subcmd_options
|
||||
_beet_subcmd_options "$subcmd"
|
||||
options=( \( "${reply[@]}" \# "${query[@]}" \) )
|
||||
;;
|
||||
esac
|
||||
# Create variable for holding option for this subcommand, and assign to it (needs to have a unique name).
|
||||
typeset -a opts_for_$subcmd
|
||||
set -A opts_for_$subcmd ${options[@]} # Assignment MUST be done using set (other methods fail).
|
||||
regex_words_subcmds+=("$subcmd:$cmddesc:\${(@)opts_for_$subcmd}")
|
||||
# Add to regex_words args for help subcommand
|
||||
regex_words_help+=("$subcmd:$cmddesc")
|
||||
done
|
||||
_store_cache beets regex_words_subcmds regex_words_help BEETS_LIBRARY fields
|
||||
fi
|
||||
|
||||
local -a opts_for_help
|
||||
_regex_words subcmds "subcommands" "${regex_words_help[@]}"
|
||||
|
|
@ -253,7 +259,7 @@ _regex_words options "global options" "$configopt" "$debugopt" "$libopt" "$helpo
|
|||
globalopts=("${reply[@]}")
|
||||
|
||||
# Create main completion function
|
||||
#local -a subcmds
|
||||
local -a subcmds
|
||||
_regex_words subcmds "subcommands" "${regex_words_subcmds[@]}"
|
||||
subcmds=("${reply[@]}")
|
||||
_regex_arguments _beet "$matchany" \( "${globalopts[@]}" \# \) "${subcmds[@]}"
|
||||
|
|
@ -267,3 +273,4 @@ _beet "$@"
|
|||
# Local Variables:
|
||||
# mode:shell-script
|
||||
# End:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue