Skip to content
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

Synergy with company *during* yasnippet expansion #781

Closed
jojojames opened this issue Feb 23, 2017 · 11 comments
Closed

Synergy with company *during* yasnippet expansion #781

jojojames opened this issue Feb 23, 2017 · 11 comments

Comments

@jojojames
Copy link
Contributor

I'm trying to get company and yasnippet to behave properly together when a snippet expansion is already happening.

For example

	for ([auto] [i] = 0; i < [MAXIMUM]; ++i) {
		[]
	}

I have something like this to hopefully prioritize company.

  (defun jojo/yas-company-expand ()
    "If `company-mode' is active, try to use complete using `company-mode',
otherwise expand with `yasnippet'."
    (interactive)
    (if (or
         (company-tooltip-visible-p)
         company-prefix)
        (company-complete-common-or-cycle)
      (yas-next-field-or-maybe-expand)))

  (define-key yas-keymap [(tab)] 'jojo/yas-company-expand)
  (define-key yas-keymap (kbd "TAB") 'jojo/yas-company-expand)

This seems to work, company expands the snippet or cycles through the completion list. At this point, I'd expect yasnippet's snippet expansion to continue working. It seems to continue working half the time afterward company 'completes', I'm able to get to the next field/expansion. The other half of the time, it seems to backfill to my previous? tab command.

I took a quick look at the code and possibly, the overlay is going away?

Setting a breakpoint on

(defun yas-exit-snippet (snippet)
  "Goto exit-marker of SNIPPET."
  (interactive (list (cl-first (yas-active-snippets))))
  (when snippet
    (setf (yas--snippet-force-exit snippet) t)
    (goto-char (if (yas--snippet-exit snippet)
                   (yas--exit-marker (yas--snippet-exit snippet))
                 (overlay-end (yas--snippet-control-overlay snippet))))))

This actually gets called in the good case but never gets called in the bad case, so I'm a little lost on how to figure this out.

Any help would be appreciated.

Thanks!

@npostavs
Copy link
Collaborator

Try setting a breakpoint on yas--commit-snippet, I'm guessing company might be doing some modification that causes yasnippet to cancel the snippet. Also set yas-verbosity to 4.

@jojojames
Copy link
Contributor Author

Hmnn,

It looks like sometimes company-active-map's tab is the one that gets called over yasnippet's tab.

When that happens, I see this breakage.

this command company-select-next-if-tooltip-visible-or-complete-selection ;; <-- yas--check-commit-snippet not called yet
this command indent-for-tab-command ;; pressing TAB again prints these two messages out
yas--check-commit-snippet called
;; Added this log statement to yas--post-command-handler
  (message (concat "this command " (symbol-name this-command)))

So clashing mode maps,, I would've thought yasnippet would have the highest priority with its keymap being in the overlay vs company which pushes its keymap to emulation-mode-map-alists.

Then again, this bug only shows 5-10% of the time so it seems like in the good case, yasnippet does have priority.

@npostavs
Copy link
Collaborator

Then again, this bug only shows 5-10% of the time so it seems like in the good case, yasnippet does have priority.

Do you have a reproducible recipe for the bad case?

@npostavs
Copy link
Collaborator

I'm closing, as there is no bug that I can see. Don't hesitate to post if you have more info.

@npostavs
Copy link
Collaborator

Possibly this is the same as #982.

@muirdm
Copy link

muirdm commented Apr 17, 2019

I had the same problem where pressing <tab> during company completion during tabstop jumping breaks out of the completion. My desired behavior is <tab> delegates to company mode if company selection is active. I'm not sure if this would entail a change in yassnippet or company-mode.

The details of my use case are (using company-lsp with lsp-mode):

  1. Use company-mode to get completion Foo(a int, b string)
  2. Selecting that completion jumps me to first placeholder Foo(*a int*, b string)
  3. I use company mode again to complete my argument to myInt and want to press company mode <tab> (in my case I use tab to complete selection rather than complete prefix).
  4. Instead, yassnippet gets the <tab> and jumps me to Foo(myIn, *b string*) without performing the completion on myInt.

I assume keymaps are last-one-wins, so maybe the second use of company-mode doesn't reinstate the company-mode keymap?

I am currently using this yassnippet <tab> binding to get the behavior I want:

(defun muir-yas-company ()
  (interactive)
  (if company-candidates
      (company-complete-selection)
    (yas-next-field-or-maybe-expand)))

@muirdm
Copy link

muirdm commented Apr 17, 2019

Edit: nevermind about this, I don't actually want this behavior.

While I'm on this topic, I tried updating my tab to be:

(defun muir-yas-company ()
  (interactive)
  (when company-candidates
    (company-complete-selection))
  (yas-next-field-or-maybe-expand))

So after it company completes it automatically jumps to the next snippet, but the snippet jumping doesn't seem to happen. I see [yas] snippet 129 expanded.\n[yas] Snippet 129 exited., but I have to press tab again to actually jump/exit snippet. Do you know off the top of your head why it doesn't work?

@npostavs
Copy link
Collaborator

I had the same problem where pressing <tab> during company completion during tabstop jumping breaks out of the completion. My desired behavior is <tab> delegates to company mode if company selection is active. I'm not sure if this would entail a change in yassnippet or company-mode.

Actually this is #987. It requires minor changes to both yasnippet (to add a hook) and company-mode (to use the hook).

Edit: nevermind about this, I don't actually want this behavior.
[...]
Do you know off the top of your head why it doesn't work?

I'll make a quick guess that company-complete-selection moves point or inserts text in a way that confuses yas-next-field-or-maybe-expand

@dgutov
Copy link
Contributor

dgutov commented Apr 30, 2019

My desired behavior is delegates to company mode if company selection is active

@muirrn With the latest snapshot builds of company and yasnippet, you now get this behavior.

I can imagine a couple of reasons why you might not want it after all, but the second option doesn't seem universal either. I'm open to new ideas in this area, though.

@muirdm
Copy link

muirdm commented May 1, 2019

Thanks. I can confirm it works. I was using yas-keymap-disable-hook myself but this is much better!

@jojojames
Copy link
Contributor Author

Nice, working so far for me too.

Do you have a reproducible recipe for the bad case?
I'm closing, as there is no bug that I can see. Don't hesitate to post if you have more info.

Welp, sorry about that. Slipped my mind on the order of about 2 years. :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants