Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ option(BUILD_FUZZ_BINARY "Build fuzz binary." OFF)
option(BUILD_FOR_FUZZING "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF)

option(INSTALL_MAN "Install man pages." ON)
if(WIN32)
option(INSTALL_ZSH_COMPLETION "Install zsh completion files." OFF)
else()
option(INSTALL_ZSH_COMPLETION "Install zsh completion files." ON)
endif()

set(APPEND_CPPFLAGS "" CACHE STRING "Preprocessor flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
set(APPEND_CFLAGS "" CACHE STRING "C compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
Expand Down
16 changes: 12 additions & 4 deletions cmake/module/InstallBinaryComponent.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ include(GNUInstallDirs)

function(install_binary_component component)
cmake_parse_arguments(PARSE_ARGV 1
IC # prefix
"HAS_MANPAGE" # options
"" # one_value_keywords
"" # multi_value_keywords
IC # prefix
"HAS_MANPAGE;HAS_ZSH_COMPLETION" # options
"" # one_value_keywords
"" # multi_value_keywords
)
set(target_name ${component})
install(TARGETS ${target_name}
Expand All @@ -23,4 +23,12 @@ function(install_binary_component component)
COMPONENT ${component}
)
endif()
if(INSTALL_ZSH_COMPLETION AND IC_HAS_ZSH_COMPLETION)
# Zsh completion files must be prefixed with underscore
install(FILES ${PROJECT_SOURCE_DIR}/contrib/completions/zsh/${target_name}.zsh
DESTINATION ${CMAKE_INSTALL_DATADIR}/zsh/site-functions
RENAME _${target_name}
COMPONENT ${component}
)
endif()
endfunction()
25 changes: 24 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,30 @@ if(BUILD_CLI)
libevent::core
libevent::extra
)
install_binary_component(bitcoin-cli HAS_MANPAGE)

# Generate zsh completion file
if(INSTALL_ZSH_COMPLETION)
set(ZSH_COMPLETION_FILE ${PROJECT_SOURCE_DIR}/contrib/completions/zsh/bitcoin-cli.zsh)
add_custom_command(
OUTPUT ${ZSH_COMPLETION_FILE}
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/contrib/completions/zsh
COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/functional/tool_cli_completion.py
--configfile=${PROJECT_BINARY_DIR}/test/config.ini
--zsh-completion=${ZSH_COMPLETION_FILE}
--overwrite
--cachedir=${PROJECT_BINARY_DIR}/test/cache
--tmpdir=${PROJECT_BINARY_DIR}/test/tmp_zsh_completion
DEPENDS bitcoin-cli bitcoind
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src
COMMENT "Generating zsh completion for bitcoin-cli"
VERBATIM
)
add_custom_target(generate_zsh_completion ALL
DEPENDS ${ZSH_COMPLETION_FILE}
)
endif()

install_binary_component(bitcoin-cli HAS_MANPAGE HAS_ZSH_COMPLETION)
endif()


Expand Down
48 changes: 48 additions & 0 deletions test/functional/data/completion/bitcoin-cli.footer.zsh-completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Handle current word completions
case "$words[CURRENT]" in
-conf=*)
local conf_path=${words[CURRENT]#-conf=}
_files -W ${conf_path:h} -g "*"
return 0
;;
-datadir=*)
local datadir_path=${words[CURRENT]#-datadir=}
_files -/ -W ${datadir_path:h}
return 0
;;
-*=*)
# prevent nonsense completions
return 0
;;
*)
local helpopts commands
local -a opts

# only parse -help if sensible (empty or starts with -)
if [[ -z "$words[CURRENT]" || "$words[CURRENT]" == -* ]]; then
helpopts="$($bitcoin_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }')"
opts+=(${(f)helpopts})
fi

# only parse help if sensible (empty or starts with letter)
if [[ -z "$words[CURRENT]" || "$words[CURRENT]" == [a-z]* ]]; then
commands="$(_bitcoin_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }')"
opts+=(${(f)commands})
fi

_describe 'bitcoin-cli options and commands' opts

return 0
;;
esac
}

# Function is now defined and will be called by zsh completion system

# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
# ex: ts=4 sw=4 et filetype=sh
25 changes: 25 additions & 0 deletions test/functional/data/completion/bitcoin-cli.header.zsh-completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (c) 2012-2024 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

# call bitcoin-cli for RPC
_bitcoin_rpc() {
# determine already specified args necessary for RPC
local rpcargs=()
local -a words_array
words_array=(${(z)BUFFER})

for i in $words_array; do
case "$i" in
-conf=*|-datadir=*|-regtest|-rpc*|-testnet|-testnet4)
rpcargs+=("$i")
;;
esac
done

$bitcoin_cli "${rpcargs[@]}" "$@"
}

_bitcoin-cli() {
local context state line
local bitcoin_cli="$words[1]"
2 changes: 1 addition & 1 deletion test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@
'mempool_resurrect.py',
'wallet_sweepprivkeys.py',
'wallet_txn_doublespend.py --mineblock',
'tool_cli_bash_completion.py',
'tool_cli_completion.py',
'tool_wallet.py --legacy-wallet',
'tool_wallet.py --legacy-wallet --bdbro',
'tool_wallet.py --legacy-wallet --bdbro --swap-bdb-endian',
Expand Down
Loading