Skip to content

Conversation

mstampfer
Copy link

This PR integrates zsh completion script generation and installation into the CMake build system, providing automated shell completion for bitcoin-cli commands on both macOS and Linux.

Changes

  1. CMake build integration (ce1c7f7, ba04c1a, 996da6a, b01cb59)
    - Added INSTALL_ZSH_COMPLETION CMake option (defaults to ON when BUILD_CLI is enabled)
    - Automatically generates contrib/completions/zsh/bitcoin-cli.zsh during build
    - Installs completion file to system zsh completions directory (compatible with both macOS and Linux paths)
    - Fixed build issues in CI environments by properly configuring paths and dependencies

Features

  • Automatic generation: Completion script is regenerated during build to stay in sync with available RPC commands
  • CMake integration: Respects standard CMake installation paths and can be disabled via -DINSTALL_ZSH_COMPLETION=OFF
  • Cross-platform: Works on both macOS and Linux systems

Testing

The completion generation is tested as part of the functional test suite via tool_cli_completion.py, which validates the zsh completion script.

Testing Zsh Completion Installation

Prerequisites

  • CMake 3.22 or higher
  • Python 3.10 or higher
  • Build tools (make/ninja)
  • Zsh shell (for testing the completion)

Building with Zsh Completion

1. Configure with Zsh Completion Enabled (Default)

cmake -B build -DBUILD_DAEMON=ON -DBUILD_CLI=ON

2. Configure with Zsh Completion Explicitly Enabled

cmake -B build -DINSTALL_ZSH_COMPLETION=ON -DBUILD_DAEMON=ON -DBUILD_CLI=ON

3. Build the Project

cmake --build build -j$(nproc)

This will automatically generate the zsh completion file at:
contrib/completions/zsh/bitcoin-cli.zsh

Installation Options

Option 1: System-Wide Installation (Requires sudo)

sudo cmake --install build --component bitcoin-cli
Files will be installed to:
- Binary: /usr/local/bin/bitcoin-cli
- Completion: /usr/local/share/zsh/site-functions/_bitcoin-cli

Option 2: User Directory Installation (No sudo required)

cmake --install build --prefix ~/.local --component bitcoin-cli
Files will be installed to:
- Binary: ~/.local/bin/bitcoin-cli
- Completion: ~/.local/share/zsh/site-functions/_bitcoin-cli

Note: Add to your ~/.zshrc:
fpath=(~/.local/share/zsh/site-functions $fpath)
export PATH="$HOME/.local/bin:$PATH"

Option 3: Custom Installation Directory

cmake --install build --prefix ~/bitcoin-install --component bitcoin-cli
Files will be installed to:
- Binary: ~/bitcoin-install/bin/bitcoin-cli
- Completion: ~/bitcoin-install/share/zsh/site-functions/_bitcoin-cli

Testing the Completion

1. Reload Zsh Configuration

# Reload completions
autoload -U compinit && compinit

# Or restart your shell
exec zsh

2. Test Completion

# Type and press TAB
bitcoin-cli <TAB>

# Should show available commands like:
# getblockcount getblockchaininfo getbestblockhash ...

# Test with partial command
bitcoin-cli get<TAB>

# Test option completion
bitcoin-cli -<TAB>

Disabling Zsh Completion

Build without Zsh Completion Generation

cmake -B build_no_zsh -DINSTALL_ZSH_COMPLETION=OFF -DBUILD_DAEMON=ON -DBUILD_CLI=ON
cmake --build build_no_zsh
cmake --install build_no_zsh --prefix ~/test_no_zsh --component bitcoin-cli

Verify only the binary and man page are installed (no zsh directory):
ls -la ~/test_no_zsh/share/
# Should NOT contain a 'zsh' directory

Verification Steps

1. Check Generated Completion File

# Verify the file exists and has content
head -20 contrib/completions/zsh/bitcoin-cli.zsh

# Check file starts with zsh completion header
grep "^#compdef bitcoin-cli" contrib/completions/zsh/bitcoin-cli.zsh

2. Verify Installation

# After installation, check the completion file
ls -la $(cmake --install build --prefix /tmp/test --component bitcoin-cli 2>&1 | grep "zsh" | awk '{print $NF}')

3. Test Completion Functionality

# In a new zsh shell
which _bitcoin-cli  # Should show the completion function is loaded
bitcoin-cli <TAB>   # Should show completions

Troubleshooting

Completion Not Working?


1. Check fpath:
echo $fpath | tr ' ' '\n' | grep zsh
2. Manually source the completion:
source /path/to/share/zsh/site-functions/_bitcoin-cli
3. Rebuild completion database:
rm -f ~/.zcompdump
autoload -U compinit && compinit

Build Errors?

1. Check Python is found:
cmake -B build -DBUILD_CLI=ON 2>&1 | grep -i python
2. Verify test script exists:
ls -la test/functional/tool_cli_completion.py
3. Check build log for generation:
cmake --build build --target generate_zsh_completion --verbose

Cross-Platform Testing

macOS (with Homebrew)

cmake --install build --prefix /usr/local --component bitcoin-cli
# Completion will be at: /usr/local/share/zsh/site-functions/_bitcoin-cli

Linux

cmake --install build --prefix /usr --component bitcoin-cli
# Completion will be at: /usr/share/zsh/site-functions/_bitcoin-cli

Both platforms use the same zsh completion structure and paths relative to the installation prefix.

Tested as above on MacOS Darwin 25.0 (Tahoe). I'm Happy to test on Ubuntu Linux on request!

Marcel Stampfer added 3 commits September 24, 2025 10:09
- Add tool_cli_completion.py test script supporting both bash and zsh completions
- Add --bash-completion and --zsh-completion parameters for bitcoin-cli
- Include zsh-specific completion header and footer templates
- Make completion file comparison optional in tests
- Refactor completion test for better efficiency and maintainability
This commit integrates zsh completion script generation and installation
into the CMake build system:

- Add INSTALL_ZSH_COMPLETION option to CMakeLists.txt (defaults to ON)
- Extend InstallBinaryComponent.cmake to support HAS_ZSH_COMPLETION parameter
- Add custom CMake target to generate bitcoin-cli.zsh using tool_cli_completion.py
- Install zsh completion to ${CMAKE_INSTALL_DATADIR}/zsh/site-functions/_bitcoin-cli
- Ensure zsh directory is created before generation
- Use correct config.ini path from build directory
- Set proper working directory and paths for the generation script

The zsh completion file is automatically generated during build when
INSTALL_ZSH_COMPLETION=ON and installed to the appropriate system or
user directory based on CMAKE_INSTALL_PREFIX.

Note: This requires the tool_cli_completion.py script from the
add-zsh-completion-generation branch to function properly.
@mstampfer
Copy link
Author

@luke-jr @Retropex
Questions on cmake integration of zsh completions script generation:

  1. Should cmake INSTALL_ZSH_COMPLETION default to ON when -DBUILD_CLI=ON
  2. Should the completions script script be installed in the user directory in ~/.local/bin/bitcoin-cli (no sudo) or system wide (with sudo) or in a custom install dircetory e.g. ~/bitcoin-install/share/zsh/site-functions/_bitcoin-cli
    (no sudo)
  3. Should I integrate tests in the cmake build to test the completions are working properly?
  4. Are there any other requirements to get this PR merged?

@luke-jr
Copy link
Collaborator

luke-jr commented Sep 29, 2025

Should cmake INSTALL_ZSH_COMPLETION default to ON when -DBUILD_CLI=ON

I think so. Maybe not if the target is Windows?

Should the completions script script be installed in the user directory in ~/.local/bin/bitcoin-cli (no sudo) or system wide (with sudo) or in a custom install dircetory e.g. ~/bitcoin-install/share/zsh/site-functions/_bitcoin-cli

Probably should treat the prefix as if it is a system-wide installation.

Should I integrate tests in the cmake build to test the completions are working properly?

Maybe in a subsequent PR? But need to be careful not to break if zsh isn't installed.

Are there any other requirements to get this PR merged?

Cross-compile support :|

Replace the simple option for INSTALL_ZSH_COMPLETION with
cmake_dependent_option that automatically disables zsh completion
when targeting Windows (WIN32=true). This prevents build errors
on Windows where zsh is not available, while maintaining the
feature for Unix-like systems.

The change is safe for cross-compilation as the WIN32 variable
correctly reflects the target platform, not the host platform.
@luke-jr
Copy link
Collaborator

luke-jr commented Sep 30, 2025

AFAIK zsh can be used on Windows, and building the completion file doesn't require zsh itself - so I would only change the default for Windows, not make the option entirely unavailable. (It might even make sense to include it with the Windows ZIP/installer)

Marcel Stampfer added 2 commits October 1, 2025 13:54
Change the zsh completion installation option to use conditional
defaults rather than completely disabling it on Windows. This allows
Windows users to explicitly enable zsh completion if needed (e.g.,
for WSL environments) while defaulting to OFF for Windows and ON
for Unix-like systems.

This provides better flexibility for users with non-standard setups
while maintaining sensible platform-specific defaults.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants