Skip to content

feat: correctly include hosts from nested SSH Include - #47

Merged
sunlei merged 4 commits into
sunlei:masterfrom
ergoz:master
Apr 23, 2026
Merged

feat: correctly include hosts from nested SSH Include#47
sunlei merged 4 commits into
sunlei:masterfrom
ergoz:master

Conversation

@ergoz

@ergoz ergoz commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR improves SSH host completion so entries from Include-d config files are reliably included in suggestions, not just hosts from the main config file.

What changed

  • Updated zsh-ssh.zsh parser to handle Include directives more robustly:
    • Supports leading whitespace before Include
    • Uses case-insensitive matching for the directive
    • Keeps support for ~, relative paths, absolute paths, and glob expansion
  • Added cycle protection for recursive include parsing:
    • Tracks already-visited config files (by normalized path)
    • Skips re-parsing files to prevent infinite recursion in cyclic include graphs
  • Hardened multi-line config processing in completion pipeline:
    • Replaced unsafe echo $var usage with printf "%s\n" "$var" in key places
    • Preserves line breaks and block boundaries for AWK parsing
  • Updated README.md with a concrete multi-file Include example (~/.ssh/config.d/*.ssh_config style)

Why this change

In some real-world setups, host definitions live in multiple files included from ~/.ssh/config. Completion was expected to include those hosts but could miss them in edge cases (or fail on recursive include loops). This PR aligns completion behavior with typical OpenSSH multi-file config layouts.

Validation

  • Syntax check passed: zsh -n zsh-ssh.zsh
  • Manual verification against a real user config with:
    • Multiple direct Include lines
    • Files under ~/.ssh/config.d/*.ssh_config
  • Confirmed that sampled host aliases from each included file are present in _ssh_host_list output

Example include layout validated

Include ~/.ssh/config.d/work.ssh_config
Include ~/.ssh/config.d/home.ssh_config
Include ~/.ssh/config.d/company.ssh_config
Include ~/.ssh/config.d/amazon.ssh_config

# alsow works with

Include ~/.ssh/config.d/*.ssh_config

Notes

  • No behavior changes were made to host extraction semantics beyond include handling robustness and safer line-preserving text flow.
  • Existing markdown lint warnings in README.md are pre-existing and unrelated to this PR.

Also maybe fixes:

ergoz added 4 commits April 22, 2026 15:55
…files

Normalize Include parsing and preserve multiline config flow when building completion candidates.
Add visited-file tracking to avoid infinite recursion on cyclic includes.
Use an actual newline when combining the fzf header and host list so aliases no longer get a literal "\\n" prefix in completion output.
…ssions

Reset parser globals when state is inconsistent and always clean up recursion tracking.
This prevents empty completion output after interrupted include parsing.
Normalize literal `~` prefixes before resolving relative include paths so hosts from configs like `~/.ssh/config.d/*.ssh_config` are included in fzf completion.

Made-with: Cursor
@sunlei

sunlei commented Apr 23, 2026

Copy link
Copy Markdown
Owner

@ergoz Thank you.
However, there are some issues in it, and I will make adjustments after merging.

@sunlei
sunlei merged commit 74f1622 into sunlei:master Apr 23, 2026
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