feat: complete custom Qiq helper names in templates#19
Open
jingu wants to merge 2 commits into
Open
Conversation
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>
Contributor
There was a problem hiding this comment.
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), |
3 tasks
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
QiqHelperCompletionContributor(PHPcompletion.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.QiqHelperRegistry.allHelperNames()(1.xHelperLocator::set) +QiqHelpersClassResolver.allHelperNames()(2.x/3.xQiq\Helperssubclass methods).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)
QiqReferenceContributornow delegates toQiqInjectionSupport.isInQiqFileinstead of carrying its own copy.set/setFactory(drop the broadregister, which could match unrelated$x->register('name', fn)calls). Test updated to assertregister(...)is ignored.Test plan
./gradlew test— all suites green (registry/resolver/injector unit tests, incl. updatedacceptsSetFactoryAliasButNotUnrelatedRegister)./gradlew buildPlugin{{ }}and{{ $this-> }}→ name is offered and inserts()Notes
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 addHeavyPlatformTestCase-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