Skip to content

feat: complete custom Qiq helper names in templates#19

Open
jingu wants to merge 2 commits into
developfrom
feat/helper-completion
Open

feat: complete custom Qiq helper names in templates#19
jingu wants to merge 2 commits into
developfrom
feat/helper-completion

Conversation

@jingu
Copy link
Copy Markdown
Owner

@jingu jingu commented May 29, 2026

Summary

Adds code completion for custom Qiq helper names at call positions inside templates — the natural companion to the helper Go to Declaration shipped in 0.7.0.

  • New QiqHelperCompletionContributor (PHP completion.contributor): at a call-name position in a Qiq template ({{ helperName| }} or {{ $this->helperName| }}), offers custom helper names and inserts () with the caret inside on selection.
  • Names come from the same sources as navigation: QiqHelperRegistry.allHelperNames() (1.x HelperLocator::set) + QiqHelpersClassResolver.allHelperNames() (2.x/3.x Qiq\Helpers subclass methods).
  • Built-in helpers are global functions in qiq_runtime.php, so PhpStorm already completes them; only custom names are added (no duplicates for built-ins).

Adjacent cleanup (from the post-0.7.0 tech-debt list)

  • Centralize Qiq-file detection: QiqReferenceContributor now delegates to QiqInjectionSupport.isInQiqFile instead of carrying its own copy.
  • Narrow 1.x registration methods to set / setFactory (drop the broad register, which could match unrelated $x->register('name', fn) calls). Test updated to assert register(...) is ignored.

Test plan

  • ./gradlew test — all suites green (registry/resolver/injector unit tests, incl. updated acceptsSetFactoryAliasButNotUnrelatedRegister)
  • ./gradlew buildPlugin
  • Manual: in a Qiq template, type a custom helper prefix inside {{ }} and {{ $this-> }} → name is offered and inserts ()

Notes

  • The completion firing/insertion path isn't covered by an automated test here — that needs an indexed CodeInsightTestFixture (heavy test), which also trips the light-project leak detector under the vintage engine. The name-source logic is covered by existing unit tests. A follow-up will add HeavyPlatformTestCase-based integration tests covering the 2.x/3.x resolver, Go to Declaration, and completion together (the remaining "test debt" item).

🤖 Generated with Claude Code

Add a PHP CompletionContributor that offers custom helper names at call
positions inside Qiq templates (`{{ helperName| }}` / `{{ $this->name| }}`).
Names come from the same sources the navigation uses: 1.x HelperLocator
registrations (QiqHelperRegistry) and 2.x/3.x Qiq\Helpers subclass methods
(QiqHelpersClassResolver). Built-in helpers are already completed via the
qiq_runtime.php stub, so only custom names are added; selecting one inserts
`()` with the caret inside.

Also fold in adjacent cleanup:
- Centralize the "is this in a Qiq file" check: QiqReferenceContributor now
  delegates to QiqInjectionSupport instead of keeping its own copy.
- Narrow the 1.x registration method names to `set`/`setFactory` (drop the
  broad `register`, which could match unrelated calls); update tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 29, 2026 08:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds custom Qiq helper-name completion inside PHP injections in Qiq templates, complementing existing helper navigation and inspection suppression.

Changes:

  • Registers a new PHP completion contributor for custom Qiq helpers.
  • Exposes 2.x/3.x helper names from QiqHelpersClassResolver.
  • Centralizes Qiq-file detection and narrows 1.x registration scanning to set / setFactory.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/main/kotlin/io/github/jingu/idea_qiq_plugin/completion/QiqHelperCompletionContributor.kt Adds helper-name completion and call insertion handling.
src/main/kotlin/io/github/jingu/idea_qiq_plugin/helper/QiqHelpersClassResolver.kt Exposes discovered helper method names for completion.
src/main/kotlin/io/github/jingu/idea_qiq_plugin/helper/QiqHelperRegistry.kt Narrows recognized registration methods.
src/main/kotlin/io/github/jingu/idea_qiq_plugin/navigation/QiqReferenceContributor.kt Delegates Qiq-file detection to shared support.
src/main/resources/META-INF/plugin.xml Registers the new completion contributor.
src/test/kotlin/io/github/jingu/idea_qiq_plugin/helper/QiqHelperRegistryTest.kt Updates registry expectations for setFactory and ignored register.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +53 to +57
// Only at a function/method call *name* position. The dummy
// identifier inserted by completion keeps the enclosing reference,
// so the leaf's parent is the (incomplete) FunctionReference /
// MethodReference (the latter extends FunctionReference).
if (position.parent !is FunctionReference) return
Comment on lines +68 to +70
LookupElementBuilder.create(name)
.withTypeText("Qiq helper", true)
.withInsertHandler(CALL_INSERT_HANDLER),
Self-review found the position gate only accepted FunctionReference, so
completion did not fire at the most common moment: a bare `{{ helper| }}`
parses as a ConstantReference (and `{{ $this->helper| }}` as a member
reference) until `(` is typed.

Widen the gate to bare references (ConstantReference / unqualified
FunctionReference) and to member references qualified by `$this`, while
still excluding members on other objects (e.g. `$article->title`) to avoid
noise. The gate is extracted to a testable companion function with unit
tests over in-memory PSI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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