Autocomplete for JavaScript
The Stimulus LSP currently only supports completion for HTML and (HTML+ERB). There's also an opportunity to provide autocomplete for JavaScript files, especially within Stimulus controllers themselves.
For example, a controller like this should provide autocomplete for targets and all other Stimulus APIs:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["name"]
connect() {
this.|
+----------------+
| nameTarget |
| nameTargets |
| hasNameTarget |
+----------------+
}
}
🤔 It might be easier to build this as a TS-Server LSP plugin so it's gonna work with almost all editors out of the box (without building custom extensions on top)
Good point @Zeko369. I honestly haven't really dug deep into how we could properly implement that.
Any chance you know of an example doing this already?
My initial thinking here is to leverage codelens together with code actions to make this capability a reality but the TS-Server LSP plugin is likely a far more fluid route opposed to employing custom logic (though I am yet to explore the available API and implementation requirements).
The capability needs to cater to both TS and JS projects, JS projects will be an easier undertaking but I see TS projects being a tad extraneous. I know for my use cases, I rely heavily on JSDoc annotations to describe static defined targets, values and classes and I'd be concerned that underlying declarations applied via TS-Server could conflict or complicate things.
For example, take the below sample wherein I've annotated nameTarget:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["name"]
connect() {
this.nameTarget
}
/**
* This annotation describing this target
*/
nameTarget: HTMLElement;
}
The base reference of nameTarget is the only annotation which one would realistically require. The nameTargets[] and hasNameTarget do not necessarily need annotation reference because it is assumptive, but this is where considerations need to be had and maybe it could look something like this:
- Check for the presence/existence of typed occurrences
- When occurrences exist, inherit them
- Determine which static definitions are un-typed and apply
JSDoc Annotations may also be able to play a bigger role overall, specifically in the markup completions. Though some additional thought needs to be had on that front.
Yeah, I'm all-in on supporting multiple scenarios. I think that the parser can/should detect what kind of approach the project, or even a single controller file is using, either by looking at the AST or by looking at whatever packages are included in the package.json.
There is also the stimulus-decorators approach for TypeScript projects, which we opened an issue for in stimulus-parser: https://github.com/marcoroth/stimulus-parser/issues/10.
I think as long as the stimulus-parser is capable enough for supporting multiple approaches, we could unify it into a common ControllerDefinition object, which Stimulus LSP then can rely on, without having to know anything about the implementation/parsing details.