Skip to main content

Config-driven parser for keybindings with fzf interface

Project description

confhelp

PyPI Python CI License: MIT

Find and edit your keybindings instantly.

demo

The Problem

Over time you accumulate tmux bindings, zsh aliases, vim mappings, custom functions - scattered across dozens of files. You know you set something up, but where?

Two pain points:

  1. Finding bindings - "What key did I bind for git status?" "Do I have an alias for docker compose?"
  2. Editing bindings - You remember it exists, now you need to change it. Which file? What line? grep → open → scroll → find → edit. Every. Single. Time.

The Solution

confhelp -b ~/dotfiles --edit

Fuzzy search all your bindings → select one → opens $EDITOR at exact file:line.

Install

pip install confhelp

Usage

# Output all bindings (uses base_dirs from config)
confhelp

# Interactive fzf selection
confhelp --select

# Select and open in $EDITOR at line
confhelp --edit

# JSON output
confhelp -f json

# Override base directory
confhelp -b ~/other-dotfiles

# Show keys defined more than once
confhelp --conflicts

# Report lines that look like bindings but failed to parse
confhelp --check

Example output:

[tmux]   prefix+g   display-popup -w 80%...   .tmux.conf:42
[alias]  gs         git status                .zsh_aliases:15
[bind]   ^[e        edit-command-line         .zshrc:89

The --edit flag drops you directly into the file at the exact line. Change the binding, save, done.

Binding Sources

confhelp supports two ways to extract bindings:

1. Regex Parsing (data-driven)

Define patterns in TOML to extract bindings from config files. Works for any text-based config format - tmux, zsh, aliases, etc. You specify paths, regex, and capture groups.

2. Query Engines (code-driven)

Some tools (like nvim) store bindings in ways that can't be reliably parsed with regex - runtime keymaps, plugin-generated bindings, multi-line table formats. Query engines run the tool itself to extract bindings.

Currently available: nvim (runs nvim headlessly to query keymaps)

Architecture note: Query engines are currently hardcoded. Future versions may support registering custom extractors - any code that returns (type, key, desc, file, line) tuples could become a binding source. This would allow community-contributed engines for tools like vim, emacs, i3, sway, etc.

Config Format

Define parsers in TOML. Each section describes how to extract bindings from a set of files:

# Default directories to search (no -b needed)
base_dirs = ["~/dotfiles", "~/work-dotfiles"]

# Query engines - run external tools to get bindings
# Available: "nvim" (queries nvim headlessly for keymaps)
query_engines = ["nvim"]

# tmux: bind [-n] <key> <command>
# Example: bind r source-file ~/.tmux.conf
#          bind-key -n M-l popup -E lazygit
# Captures: (1) key=r or M-l, (2) command
[tmux]
paths = [".tmux.conf"]
match_line = "^bind"
regex = 'bind(?:-key)?\s+(?:-n\s+)?(\S+)(.*)'
key_group = 1
desc_group = 2
type = "tmux"
truncate = 100

# zsh alias: alias [-gs] <name>=<command>
# Example: alias gs='git status'
#          alias -g C='| xsel --clipboard'
# Captures: (1) name=gs or C, (2) command
[alias]
paths = [".zsh_aliases", ".zsh_claude"]
regex = "alias\\s+(?:-[gs]\\s+)?([^=]+)=(.*)"
key_group = 1
desc_group = 2
type = "alias"
strip_quotes = true

# zsh-abbr: "abbrev" 'expansion'
# Example: "ga" 'git add'
# Captures: (1) abbrev=ga, (2) expansion=git add
[abbrev]
paths = [".zsh_abbreviations"]
match_line = '".*"'
regex = '''"([^"]+)"\s+'([^']+)''''
key_group = 1
desc_group = 2
type = "abbrev"

# nvim query engine options (enabled via query_engines above)
[nvim]
truncate = 60

# nvim regex fallback (if nvim binary unavailable, use this instead of query_engines)
[nvim-regex]
paths = [".config/nvim/lua/**/*.lua"]
match_line = "vim.keymap.set"
regex = 'vim\.keymap\.set\([^,]+,\s*"([^"]+)".*desc\s*=\s*"([^"]+)"'
key_group = 1
desc_group = 2
type = "nvim"

Config Options

Top-level options:

Option Description
base_dirs Default directories to search
query_engines List of query engines to enable (e.g., ["nvim"])

Section options:

Option Description
paths List of files or glob patterns (e.g., **/*.lua)
regex Pattern with capture groups for key/desc (Python re syntax)
key_group Capture group number for the key
desc_group Capture group number for description
match_line Only process lines matching this pattern
skip_comment Skip lines starting with #
truncate Max length for description
strip_quotes Remove surrounding quotes from desc
desc_literal Use fixed string as description
desc_from_comment Extract desc from trailing # comment

Regex Tips

Patterns use Python's re module. Test patterns at regex101.com (select Python flavor).

Quick CLI test:

echo "bind r reload" | python -c "import re,sys; m=re.search(r'bind\s+(\S+)\s+(.*)', sys.stdin.read()); print(m.groups() if m else 'no match')"

Output Formats

  • pipe (default): pipe-delimited [type]|key|desc|file:line
  • tsv: Tab-separated
  • json: JSON array

The pipe format works well with column -t -s'|' for aligned display.

Integration Examples

confhelp outputs text. How you display it is up to you.

Alacritty Popup

Spawn a centered popup window showing bindings. Enter jumps to the file:

selection=$(confhelp -b ~/dotfiles | column -t -s'|' | fzf)
# parse selection, open in editor

See examples/alacritty-popup.sh for a complete implementation.

tmux Popup

tmux display-popup -w 80% -h 80% -E 'confhelp -b ~/dotfiles --select'

See examples/tmux-popup.sh for a complete implementation.

Rofi/dmenu

confhelp -b ~/dotfiles | rofi -dmenu

Acknowledgments

Inspired by Extracto.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

confhelp-0.6.0.tar.gz (270.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

confhelp-0.6.0-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

File details

Details for the file confhelp-0.6.0.tar.gz.

File metadata

  • Download URL: confhelp-0.6.0.tar.gz
  • Upload date:
  • Size: 270.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for confhelp-0.6.0.tar.gz
Algorithm Hash digest
SHA256 81c98bbba179fa54ba1b120759c6480a6c09a4191ed9c2d01159498a9f71d1c1
MD5 09a8a016c6d8386bbf700f26e5dc95af
BLAKE2b-256 b85e35624bfcb4b12602d0f648498658b056fd250bbbaacab2b6af47b6f662bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for confhelp-0.6.0.tar.gz:

Publisher: publish.yml on Piotr1215/confhelp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file confhelp-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: confhelp-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 11.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for confhelp-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e767a14fd62f2e69cf2ca6f8c38d6aa4292f6d386363582d413f568c75fab276
MD5 d14885a0d5b99fbf9ca119b704ee75bc
BLAKE2b-256 c3378421f901770730e008233946e7b9fa3ca90c22b6d350237a47748ea84300

See more details on using hashes here.

Provenance

The following attestation bundles were made for confhelp-0.6.0-py3-none-any.whl:

Publisher: publish.yml on Piotr1215/confhelp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page