Skip to content

Add map argument autocomplete - #229

Open
dheeraj12347 wants to merge 3 commits into
apache:mainfrom
dheeraj12347:feature/map-autocomplete
Open

dheeraj12347 wants to merge 3 commits into
apache:mainfrom
dheeraj12347:feature/map-autocomplete

Conversation

@dheeraj12347

Copy link
Copy Markdown
Contributor

Summary

Add autocomplete support for map API arguments in CloudMonkey.

Changes

  • Add support for map argument autocomplete.
  • Extract indexed map fields from API argument descriptions.
  • Support generic key/value map descriptions.
  • Suggest indexed fields such as:
    • tags[0].key=
    • tags[0].value=
  • Avoid assuming that every map argument follows the key/value structure.
  • Add regression tests covering:
    • Indexed map fields
    • Multiple map fields
    • Multiple indexes
    • Generic key/value maps
    • Non-key/value map arguments
    • Autocomplete option generation

Testing

  • gofmt -w cli/completer_test.go
  • go test ./...
  • git diff --check

All tests are passing.

@dheeraj12347

Copy link
Copy Markdown
Contributor Author

Hi @Pearl1594 and @DaanHoogland , I’ve raised the map argument autocomplete work as a separate PR: #229.

It adds autocomplete support for map API arguments, including indexed fields like tags[0].key= and tags[0].value=, while avoiding assumptions about maps that don’t follow the key/value structure. I’ve also added regression tests covering the different cases.

go test ./... and git diff --check are passing.

Whenever you’re available, could you please have a look and let me know if the approach looks good or if anything should be changed?

PR: #229

@DaanHoogland
DaanHoogland requested review from Pearl1594 and a balanced review from Copilot October 5, 2026 08:08
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

✅ Build complete for PR #229.

📦 Binary artifacts are available in the workflow run (expires on October 23, 2026).

Note: Download artifacts by clicking on the workflow run link above, then scroll to the "Artifacts" section.
Artifacts from PR builds are for testing only and may contain unreviewed, malicious code.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Argument routing prevents indexed map suggestions from appearing with real cached argument names.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds description-based autocomplete for CloudMonkey map arguments without assuming every map uses key/value fields.

Changes:

  • Extracts indexed fields from argument descriptions.
  • Adds generic key/value suggestions.
  • Adds regression tests for field extraction and suggestion generation.
File Description
cli/​completer.go Adds map-field extraction and completion handling.
cli/​completer_test.go Tests indexed, generic, and non-key/value maps.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cli/completer.go Outdated
Comment on lines +460 to +461
if arg.Type == "map" {
suggestions := mapFieldSuggestions(arg)
@Damans227

Copy link
Copy Markdown

the new map suggestions never show up when you press tab. typing tags gives only "=", and tags= or tags[0].k give nothing, because the new part only runs after the full tags= is typed and none of its suggestions start with tags=. copilot's comment above is right. can we add a test that goes through the normal tab completion with tags= so this gets caught?

@dheeraj12347

Copy link
Copy Markdown
Contributor Author

the new map suggestions never show up when you press tab. typing tags gives only "=", and tags= or tags[0].k give nothing, because the new part only runs after the full tags= is typed and none of its suggestions start with tags=. copilot's comment above is right. can we add a test that goes through the normal tab completion with tags= so this gets caught?

Thanks for the feedback! I've pushed a follow-up commit, c79972f, that moves map-field matching before the argument-prefix check and adds a regression test through the normal autoCompleter.Do path using tags=. The focused test and full go test ./... suite pass locally. Could you please review the updated implementation when you get a chance?

@Damans227

Copy link
Copy Markdown

I've pushed a follow-up commit, c79972f, that moves map-field matching before the argument-prefix check

@dheeraj12347 tags and tags[0].k work now, but tags= still breaks in the real shell. pressing tab there gives tags=[0]. because the shell adds the text after the = instead of replacing it. can the test check the full line after tab, not just the suggestions?

@dheeraj12347

Copy link
Copy Markdown
Contributor Author

I've pushed a follow-up commit, c79972f, that moves map-field matching before the argument-prefix check

@dheeraj12347 tags and tags[0].k work now, but tags= still breaks in the real shell. pressing tab there gives tags=[0]. because the shell adds the text after the = instead of replacing it. can the test check the full line after tab, not just the suggestions?

@Damans227 , I traced the tags= issue to readline's completion behavior. AutoCompleter.Do() returns candidate suffixes, and readline appends them to the existing buffer, so the trailing = cannot be removed by the CloudMonkey completer alone. A proper fix appears to require changing readline's replacement behavior. Would you be comfortable with a narrowly scoped change to the vendored readline code, or would you prefer an approach that avoids modifying the dependency?

@Damans227

Copy link
Copy Markdown

Would you be comfortable with a narrowly scoped change to the vendored readline code, or would you prefer an approach that avoids modifying the dependency?

@dheeraj12347 the vendored readline already has cloudmonkey changes from #199 that rewrite the text after the last =, so a small change there looks fine to me. can it build on that instead of adding a separate path?

@dheeraj12347

Copy link
Copy Markdown
Contributor Author

Thanks @Damans227 for the suggestion!

I've pushed bc7d4b0, which extends the existing vendored readline completion helper to handle the trailing = case while preserving its previous behavior.

I've also added a regression test that exercises OnComplete() and verifies the full command line after completion. The focused readline test, go test ./..., and git diff --check all pass locally. I also verified the behavior manually in the interactive shell.

Could you please take another look when you get a chance?

@Damans227

Copy link
Copy Markdown

I've pushed bc7d4b0, which extends the existing vendored readline completion helper to handle the trailing = case

@dheeraj12347 that covers it. tags, tags= and tags[0].k all complete right in the shell now.

@DaanHoogland
DaanHoogland requested a balanced review from Copilot October 13, 2026 11:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

3 open findings

🧠 Review effort: Lite

Comment thread cli/completer.go
Comment on lines +228 to +232
func mapFieldsFromDescription(description string) []string {
fields := []string{}
seen := make(map[string]bool)

re := regexp.MustCompile(`([A-Za-z0-9_-]+\[\d+\]\.[A-Za-z0-9_.:-]+)=`)
Comment thread cli/completer.go

func mapFieldsFromDescription(description string) []string {
fields := []string{}
seen := make(map[string]bool)
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.

3 participants