This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Do not try to use $0 as a placeholder in completion snippets
ClosedPublic

Authored by nridge on Jun 26 2022, 7:42 PM.

Details

Summary

$0 can only be used as a tab stop, not as a placeholder (e.g.
${0:expression} is not valid)

Fixes https://github.com/clangd/clangd/issues/1190

Diff Detail

Event Timeline

nridge created this revision.Jun 26 2022, 7:42 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 26 2022, 7:42 PM
nridge requested review of this revision.Jun 26 2022, 7:42 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 26 2022, 7:42 PM
kadircet added inline comments.Jun 27 2022, 1:17 AM
clang-tools-extra/clangd/CodeCompletionStrings.cpp
197

as you've mentioned in the vscode issue, i think it'd be better to append a $0 when we reach CursorSnippetArg. it's annoying that we require an extra tab, but IMO it's still better than just requiring user to move around a bunch.

also i think it makes sense to wait for a little while until we hear back from vscode folks about a workaround. Despite them saying $0 is not a placeholder, LSP doesn't clearly state that. hence clangd might not be the only language server that's affected from this.

My 2 cents here. We should probably try hard to keep the cursor inside braces/parentheses for those patterns.
Having

namespace foo {
  decls
}^ <- cursor here

hurts UX. It would be nice to get the old behavior back somehow.
I still have hopes for the VSCode discussion, maybe they can provide a workaround/willing to change their behavior.
@kadircet also suggested trying something like ${2:decls}$0. Could you check if that works in VSCode?

Another alternative that I think should give the best UX is to replace ${0:named} with $0.
The items will look different, but will behave identically to the old behavior before VSCode change, i.e. won't "eat" an extra tab press at the end of completion session.
I feel that's the trade-off we should pick.

What do others think?

Another alternative that I think should give the best UX is to replace ${0:named} with $0.
The items will look different, but will behave identically to the old behavior before VSCode change, i.e. won't "eat" an extra tab press at the end of completion session.
I feel that's the trade-off we should pick.

What do others think?

Put some thoughts in https://github.com/clangd/clangd/issues/1190
TL;DR:

  • I think fixing this only in the server for future releases (and not touching vscode-clangd) is OK
  • Of the ideas we've heard, I like ${0:named} => $0 best, but can certainly live with the one in this patch
  • (I think we could refine behavior further, but let's not block on it)
nridge updated this revision to Diff 445407.Jul 18 2022, 12:49 AM

Revise patch to use $0 (no placeholder text) rather than ${n:placeholder}

  • Of the ideas we've heard, I like ${0:named} => $0 best, but can certainly live with the one in this patch

I like this approach as well. Revised the patch to do this.

kadircet accepted this revision.Jul 18 2022, 6:12 AM

thanks, LG, just some extra precautions.

clang-tools-extra/clangd/CodeCompletionStrings.cpp
194–195

i think we shouldn't even have braces for $0 (just to be safe). so what about:

if (SnippetArg == CursorSnippetArg) {
  *Snippet = "$0";
} else {
  *Snippet = "${" + std::to_string(SnippetArg) + ":";
  appendEscapeSnippet(Chunk.Text, Snippet);
  *Snippet += "}";
}
This revision is now accepted and ready to land.Jul 18 2022, 6:12 AM
sammccall accepted this revision.Jul 18 2022, 6:12 AM

Thank you!

clang-tools-extra/clangd/CodeCompletionStrings.cpp
194–195

nit: at this point it might be clearer to unfold the two cases (not longer or shorter)
up to you which is more readable

if (SnippetArg == CursorSnippetArg) {
  // we'd like to make...
  *Snippet += "${0}";
} else {
  *Snippet += "${" + to_string(SnippetArg) + ":";
  appendEscapeSnippet(...);
  *Snippet += "}";
}
nridge updated this revision to Diff 447112.Jul 24 2022, 12:00 AM

Address final review comments

This revision was landed with ongoing or failed builds.Jul 24 2022, 12:01 AM
This revision was automatically updated to reflect the committed changes.