Feature Description
Today staticStrings (with strings / dataFile / stringsWithLocation) can suggest values for a single parameter position, always from the same list regardless of what the user typed elsewhere in the call. This works great when the valid values are global — controller identifiers, view names, config keys.
It falls short as soon as the valid values at position N depend on the literal value the user already wrote at position M. The prototypical case is Stimulus helpers, where the same signature is used across many frameworks (Symfony UX, Rails, and multiple Laravel packages ship identical Twig/Blade helpers):
// Laravel
stimulus_action('modal', 'open', 'click');
stimulus_target('modal', 'panel');
{# Symfony UX StimulusBundle — same shape #}
{{ stimulus_action('modal', 'open', 'click') }}
{{ stimulus_target('modal', 'panel') }}
Once the user has typed 'modal', the valid methods (open, close, toggle, …) and targets (panel, overlay, …) are entirely determined by that controller. But staticStrings has no way to express "the list of strings at parameter 2 depends on the literal at parameter 1".
Package authors can compute the full (controller → methods/targets/values) map at build time and ship it in ide.json. What's missing is a completion mode on the plugin side that indexes into that map based on a sibling parameter.
Proposal
A new completion type, conditionalStrings, that reads a literal from another parameter of the same call and picks a sub-map of values (with locations, exactly like stringsWithLocation).
{
"$schema": "https://laravel-ide.com/schema/laravel-ide-v2.json",
"completions": [
{
"complete": "conditionalStrings",
"condition": [
{ "functionNames": ["stimulus_action"], "parameters": [2] }
],
"options": {
"keyedBy": { "parameter": 1 },
"map": {
"modal": {
"open": "vendor/.../js/controllers/modal_controller.js:34",
"close": "vendor/.../js/controllers/modal_controller.js:41",
"toggle": "vendor/.../js/controllers/modal_controller.js:48"
},
"tooltip": {
"show": "vendor/.../js/controllers/tooltip_controller.js:22",
"hide": "vendor/.../js/controllers/tooltip_controller.js:29"
}
}
}
},
{
"complete": "conditionalStrings",
"condition": [
{ "functionNames": ["stimulus_target"], "parameters": [2] }
],
"options": {
"keyedBy": { "parameter": 1 },
"map": {
"modal": { "panel": "…/modal_controller.js:11", "overlay": "…/modal_controller.js:12" },
"tooltip": { "trigger": "…/tooltip_controller.js:9", "content": "…/tooltip_controller.js:10" }
}
}
}
]
}
Semantics:
- keyedBy.parameter names which parameter of the same call is inspected. Its literal value is looked up in map. If it's a non-literal (variable, method call), completion falls back silently (empty list) — same graceful degradation staticStrings already has.
- The inner values reuse the stringsWithLocation shape shipped in 13.2 (path or path:line), so declaration/usages already jumps to the exact method or target line.
Why this generalises beyond Stimulus
The same shape appears any time an API takes a (namespace, member) pair as separate string arguments:
- Cache tags / event names — Cache::tags('users')->flush('by-role') where valid tags-per-namespace live in a manifest.
- Broadcasting channels — broadcast()->on('orders')->as('created').
- Feature flags — Features::for('billing')->flag('invoicing-v2').
- Test doubles / spies where a class name in one position determines the valid method list in the next.
Package authors can already compute these maps; only the plugin-side lookup is missing.
I'm happy to prototype the Laravel-side generator against a snapshot plugin build if that helps validate the schema.
Feature Description
Today staticStrings (with strings / dataFile / stringsWithLocation) can suggest values for a single parameter position, always from the same list regardless of what the user typed elsewhere in the call. This works great when the valid values are global — controller identifiers, view names, config keys.
It falls short as soon as the valid values at position N depend on the literal value the user already wrote at position M. The prototypical case is Stimulus helpers, where the same signature is used across many frameworks (Symfony UX, Rails, and multiple Laravel packages ship identical Twig/Blade helpers):
Once the user has typed 'modal', the valid methods (open, close, toggle, …) and targets (panel, overlay, …) are entirely determined by that controller. But staticStrings has no way to express "the list of strings at parameter 2 depends on the literal at parameter 1".
Package authors can compute the full (controller → methods/targets/values) map at build time and ship it in ide.json. What's missing is a completion mode on the plugin side that indexes into that map based on a sibling parameter.
Proposal
A new completion type, conditionalStrings, that reads a literal from another parameter of the same call and picks a sub-map of values (with locations, exactly like stringsWithLocation).
{ "$schema": "https://laravel-ide.com/schema/laravel-ide-v2.json", "completions": [ { "complete": "conditionalStrings", "condition": [ { "functionNames": ["stimulus_action"], "parameters": [2] } ], "options": { "keyedBy": { "parameter": 1 }, "map": { "modal": { "open": "vendor/.../js/controllers/modal_controller.js:34", "close": "vendor/.../js/controllers/modal_controller.js:41", "toggle": "vendor/.../js/controllers/modal_controller.js:48" }, "tooltip": { "show": "vendor/.../js/controllers/tooltip_controller.js:22", "hide": "vendor/.../js/controllers/tooltip_controller.js:29" } } } }, { "complete": "conditionalStrings", "condition": [ { "functionNames": ["stimulus_target"], "parameters": [2] } ], "options": { "keyedBy": { "parameter": 1 }, "map": { "modal": { "panel": "…/modal_controller.js:11", "overlay": "…/modal_controller.js:12" }, "tooltip": { "trigger": "…/tooltip_controller.js:9", "content": "…/tooltip_controller.js:10" } } } } ] }Semantics:
Why this generalises beyond Stimulus
The same shape appears any time an API takes a (namespace, member) pair as separate string arguments:
Package authors can already compute these maps; only the plugin-side lookup is missing.
I'm happy to prototype the Laravel-side generator against a snapshot plugin build if that helps validate the schema.