tide icon indicating copy to clipboard operation
tide copied to clipboard

Make the completion functionality independent of company-mode

Open avli opened this issue 7 years ago • 6 comments

Not everyone uses company-mode for code completion. Another popular approach, I believe, is using C-M-i combination for getting a list of possible completions in another buffer. This approach works for me pretty good in combination with helm. Could you consider changing the plugin behavior the way to support different completion front-ends?

avli avatar Sep 27 '16 08:09 avli

I would be happy to accept a PR, as long as it keeps the current async behavior.

ananthakumaran avatar Oct 10 '16 04:10 ananthakumaran

I got this working (more or less, not deeply tested) like this:

(defun tide-completion-at-point ()
  (let ((prefix (progn (looking-back "[a-zA-Z_$]\*" 50 t) (match-string 0))))
    (tide-command:completions prefix
      (lambda (response)
        (completion-in-region (- (point) (length prefix)) (point)
                              (loop for completion in response
                                    if (string-prefix-p prefix completion)
                                    collect completion))))))

;; And then in setup-tide-mode, bind this as a local completion function
(make-local-variable 'completion-at-point-functions)
(push (lambda () 'tide-completion-at-point) completion-at-point-functions)

marijnh avatar Apr 06 '18 16:04 marijnh

I had looked into this issue a bit more since my initial comment. The interface expected by completion-at-point-functions doesn't support async, async here means the UI won't block the user from typing or doing anything else when tide waits for the results from tsserver. Company provides a clean interface to handle the async scenarios. So building company backend on top of completion-at-point function is not possible. That said, I am still open to a PR which adds support for completion-at-point and leaves the company backend implementation as it is.

ananthakumaran avatar Apr 08 '18 02:04 ananthakumaran

completion-at-point-functions doesn't properly support asynchronicity, but it allows you to return a function that will imperatively do the completions by calling completion-in-region, which I do in the snippet I pasted. It's all a bit shaky, but does make the default bindings for completion work.

marijnh avatar Apr 10 '18 10:04 marijnh

@marijnh: It seems like you're the ones who are best suited to deliver this. I think the best option is you package this as a PR.

To me it sounds like @avli will be happy to test it and ensure everything works as intended.

When you two are done maybe me and @ananthakumaran can do some code-review too to ensure we're happy about how things are done before merging.

I'm on overall positive to such a change, as long as we can get it working, with reasonably clean & decoupled code.

josteink avatar Apr 23 '18 09:04 josteink

I got this work from @marijnh 's code, with a little modification, since I didn't enable Lexical Binding in my el files:

(defun tide-completion-at-point ()
  (let ((prefix (progn (looking-back "[a-zA-Z_$]\*" 50 t) (match-string 0))))
    (tide-command:completions
     prefix
     `(lambda (response)
        (completion-in-region (- (point) (length ',prefix)) (point)
                              (loop for completion in response
                                    if (string-prefix-p ',prefix completion)
                                    collect completion))))))

and in setup-tide-mode

(defun setup-tide-mode ()
  (interactive)
  ; ... ...
  ; your configurations here
  ; ... ...
  ;; And then in setup-tide-mode, bind this as a local completion function
  (make-local-variable 'completion-at-point-functions)
  (push (lambda () 'tide-completion-at-point) completion-at-point-functions))

I'm interested in bring a PR, but for now I'm wondering how to write a test for this? or do we need a test for this?

VitoVan avatar Jan 04 '20 03:01 VitoVan