swift-mode icon indicating copy to clipboard operation
swift-mode copied to clipboard

Better support for lsp-sourcekit placeholders?

Open dabrahams opened this issue 8 months ago • 6 comments

(c.f. https://github.com/emacs-lsp/lsp-sourcekit/issues/31)

When I use completion with sourcekit-lsp I often get things of the form ${1:SomeType} in my emacs buffer where Xcode would show a placeholder to be filled in. It would be awesome if that worked better. I imagine supporting this might need some cooperation with lsp-sourcekit. If you look at rust-mode for emacs with LSP, it inserts gray text, that isn't in the file, showing types of things (and other information) everywhere in the buffer. I find that somewhat annoying but it would be perfect for placeholders.

dabrahams avatar Apr 01 '25 17:04 dabrahams

When I use completion with sourcekit-lsp I often get things of the form ${1:SomeType} in my emacs buffer where Xcode would show a placeholder to be filled in. It would be awesome if that worked better. I imagine supporting this might need some cooperation with lsp-sourcekit.

Could you provide us more info? Something like screenshots of Xcode and current swift-mode would help.

If you look at rust-mode for emacs with LSP, it inserts gray text, that isn't in the file, showing types of things (and other information) everywhere in the buffer.

Are you talking about this? https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/#inlay-hints

taku0 avatar Apr 02 '25 10:04 taku0

Are you talking about this? https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/#inlay-hints

Yep, that's it exactly.

Xcode as I'm choosing a completion:

Image

After hitting return (Because it looks a little confusing, I'll explain that I am inserting this precondition call just before another one):

Image

After TAB:

Image

When I type in any field it becomes inactive. When there are any fields active in the buffer TAB will go to one of them and cycle between them.

Emacs LSP choosing a completion:

Image

After hitting return:

Image

dabrahams avatar Apr 02 '25 20:04 dabrahams

Implementation plan:

  • When propertizing the buffer, recognize placeholders and add overlays.
  • Set keymap property of the overlays for <tab> and <backtab>.
  • Set modification-hooks, insert-in-front-hooks, and insert-behind-hooks properties to delete the placeholder before editing.

taku0 avatar Apr 12 '25 06:04 taku0

@dabrahams

Should the TAB key be overridden whenever placeholders are present?

  • Override TAB throughout the entire file - The cursor should move to the next placeholder from the current position, regardless of where it is in the file. What if we want to indent lines before filling all fields?

  • Override TAB only on placeholder fields - TAB should indent the line when the cursor is not positioned on any placeholder. A placeholder is removed when the user start filling it. How long should we remember the fact that the field once exists there?

  • Override TAB only on lines containing placeholder fields - TAB should perform normal indentation when used elsewhere. What if the template spans multiple lines?

taku0 avatar Jun 15 '25 13:06 taku0

Absolutely the first bullet. There are other means of indenting lines: M-x indent-for-tab-command and C-M-\ runs the command indent-region. There should be a means of canceling the placeholders. Actually, this seems like a good idea: C-g cancels the effect of the placeholders until point enters a placeholder.

dabrahams avatar Jun 18 '25 17:06 dabrahams

@dabrahams

lsp-sourcekit is based on lsp-mode, which supports placeholders in snippets via yasnippet. Please ensure lsp-enable-snippet is non-nil (default) and yas-minor-mode is initialized before lsp. Please close the issue if it works.

taku0 avatar Jun 23 '25 12:06 taku0

@dabrahams Please close the issue if it works.

taku0 avatar Jul 07 '25 06:07 taku0

It works, thanks!

dabrahams avatar Jul 13 '25 22:07 dabrahams