-
Notifications
You must be signed in to change notification settings - Fork 18k
x/tools/gopls: no completion for function literal in parameter #38416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
That func literal requires placeholders to be enabled since the function signature doesn't give a name for the parameter. gopls gives a placeholder for If we change the placeholder option to only apply to function invocations, then this problem would go away. |
I've hit this a lot too, and didn't realize I'd need to have placeholders to do it (I don't like them, so have them disabled) so had been assuming it was a weird bug that only affected some code. Would it be reasonable to insert with the parameter names as |
Would you dislike placeholders in this case as well, or do you mainly not want the function call placeholders? The reason not to include "_" was because it is inconvenient/annoying to go back and update them. In general I feel like having to go "backwards" to change something is quite annoying, even vs having to type out the entire signature. |
I gave it a shot, re-enabling placeholders and checking this. Given it's a declaration, I don't mind the placeholders so much. A small part (but definitely not all) of my issue with placeholders for normal calls is that it inserts "incorrect" code by inserting the type names (which then need to be replaced with values of that type). For decls, that's not the case, as it inserts say This doesn't solve my other personal usability issues with placeholders, but I think it's fine in this case and better than inserting |
Change https://golang.org/cl/228104 mentions this issue: |
What else don't you like about placeholders? |
I'll try to explain it, but this is of course personal preference and years of workflow gained from previous Go tooling.
So in comparison to your (100% reasonable) statement of "having to go backwards to change something is quite annoying", I find it annoying to have to undo what completion's done that I didn't like or "ask for", and the only benefit is not having to type a few commas. Now, I know a lot of people like placeholders, and wouldn't want my workflow to break someone else's. I appreciate having the toggle so I can work happily. I see that the above CL disables placeholders in other contexts as well. I'm not sure if I'm into that, for similar reasons as 1/2 above. I get things like: Which end up distracting me in a similar fashion. The code isn't real, I have to clean it up, I'm just going to re-type it anyway, etc. For function literals I think "forcing placeholders" (or a least filling things out automatically) makes sense as there is no way to end up with a usable function when the signature doesn't have names. It's certainly much better than not giving literal completion at all and leaving people confused as to why the (very cool) feature didn't work this time around. But I'd be sad if the placeholders option stopped working for the other placeholders. It's much more likely that I'd just live with some function literals being mysteriously "broken" so I can save myself the trouble in the other contexts where I know it's going to slow me down. (EDIT: though now that I think about it, there just wouldn't be any way at all to disable those placeholders now, so I'd just be frustrated and leave my Can this change only be made for the specific "function literal without parameter names" case? Or, with placeholders disabled, just leave the auto-generated names? |
@zikaeroh very much agree. We've covered this topic a few times, most recently in #37656 (comment). This issue seems to add weight to the idea that there needs to be different configuration options for the various types of placeholders that people might want:
(In #37656 (comment) and elsewhere I've argued that option 2 could be implemented using multiple text edits as opposed to snippets, but that's an orthogonal concern). |
One extra thing I thought up after my comment (and numerous edits, sorry) is that I also view the "label" of the completion to signify the intent. If the completion says However, when I'm in a struct literal and the completion is I'd even go so far as to say that completions for function calls where the label is |
Thanks! It's really helpful to know other people's thoughts. I sympathize with the placeholder text being invalid Go - that bugs me too. For function call placeholders, my editor does not present signature help very well, so I rely more on the placeholders. Other than that, I don't like them either. The struct field placeholder in particular may not be that useful. Perhaps the solution there is to just remove the placeholder altogether. I agree it is strange to just jam in some informational message as source code. That being said, I don't understand the "have to clean it up" or "have to undo" sentiment (for struct field placeholders at least). Normally I just start typing what I want to complete and it overwrites the placeholder, so there are no wasted keystrokes. Your scenario in 2) of course causes extra work, and that has bugged me for function call placeholders.
I agree. The label should be clearer.
Are you still running into issues using functions as values? Maybe it is due to an expected type of I don't have any good ideas for how to proceed with this change. Long term I would love it if we could eliminate all the controversial use of placeholders and just get rid of the usePlaceholders option, but that might not be possible. |
A lot of the time, I probably don't know what I'm about to type as parameters, or I get distracted. As stated in my issue, if I "leave", that stuff gets leftover and I have to fix it. The only keystrokes I'm saving are the commas, and I have no trouble typing those myself. I get that your editor doesn't display signature help too well, but mine does and I don't like the rest of the implications of the placeholders. Also note that at least in VS Code (I think you use emacs?), typing a comma does not advance the placeholders, only tab does. This is frustrating as in every other language (and in Go previously), I have to type the commas. For example: I'd rather just type it out.
Simple case, I've also seen It's extremely irritating. With placeholders off, it's less frustrating (just deleting
I don't see this ever being possible. I'd much rather things continue to be configurable. For this specific issue, I think leaving the auto-generated names is the most "correct" thing to do for I think it's possible to come up with a range of options that would make this more customizable as @myitcv said above, though it may take a little defining. I haven't personally found a case (besides this bug) where I'd actually want the placeholders to warrant extra levels, however. @myitcv has a technical motivation from the standpoint of not wanting to handle snippets at all (I think), which is more than I need given I'm a VS Code user. |
I entirely skipped over your "for struct field placeholders at least" when writing my first paragraph, my mistake. I thought I hadn't expressed my original thought well enough but you were just narrowing it to the struct stuff. Oops... Generally I view all of the placeholders as "the same", at least from the "annoys me" POV where I have to undo. This is probably due to my first bullet thing before where I'm not used to it, and I feel weirded out by the extra text I didn't request (my follow-up label point). |
I agree with most of @zikaeroh's comments above. I like the simplicity of Regarding structs, I think the struct field placeholder could just be empty - I've seen that done before, and I find it helpful even though I don't like parameter placeholders. |
It sounds like the options are:
|
I wouldn't pick 1, as it leaves this bug unresolved (literal completion sometimes not working). For me, 2/3 are equivalent as I would plan to keep placeholders disabled anyway; I have no opinion between them. As for If I can offer a fourth option: If placeholders are disabled and the completion item requires generated parameter names (i.e., this bug), offer the function literal without placeholders and place the cursor inside the function body, leaving the generated names.
Then, leave everything else as-is (or proceed with removing struct field placeholders in a different CL?). |
This options sounds good to me, if it's ok with you, @muirdm. |
It's fine with me. You will end up with unusable "_" parameters in some cases, but probably less annoying than having to type out the entire signature. |
Under what conditions would you not be able to make a "fresh" name? Is it due to the current code picking out the first letter of the typename? |
You will get "_" for unnamed types or if the abbreviation has been used by a previous param.
|
Ah, I see, the camelCase conversion is clever. I would have been lazy and just made them p0, p1, p2, p3, etc... 🙂 If possible it'd be nice to have names for those even if they're "bad" so I can have gopls rename them after the fact; I can't trigger a rename on |
In any case, any function literal will be better than none and I can hand-name the parameters in lieu of any changes there. I don't mean to make this more complicated than it needs to be. |
@stamblerre with placeholders disabled, what should we do for unnamed params we can't guess a good name for?
If we make them generic as 2), then perhaps we should make all the generated param names generic to simplify things? For reference my main example of annoying unnamed params was:
It was annoying to get "p1", "p2" or "r1", "r2", so I added the acronym logic. Maybe instead we should just add names to the signatures instead of trying to guess good names. |
I agree with your suggestion - either 2 or 3 seem fine to me. 2 seems like a good starting point that we can improve off of - I agree that unnamed params are not as helpful. |
Change https://golang.org/cl/246262 mentions this issue: |
Triggering completion here should offer a suggestion for a function literal.
The function call pictured below is https://pkg.go.dev/golang.org/x/build/maintner?tab=doc#Gerrit.ForeachProjectUnsorted, which takes a function as a parameter.
/cc @muirdm
The text was updated successfully, but these errors were encountered: