copilot-emacs / copilot.el

An unofficial Copilot plugin for Emacs.
MIT License
1.72k stars 122 forks source link

`copilot-complete` does not do anything outside of `copilot-mode` #210

Closed stasvlasov closed 4 months ago

stasvlasov commented 6 months ago

I had a binding just for completion of thing at point (with copilot-complete) and it used to work regardless the state of copilot-mode (sometimes I like it switched off). Since some time ago the copilot-complete only works for me when copilot-mode is on and do nothing otherwise.

Could this be a bug (feature) or it is just something with my setup? Can someone maybe check on their machine if it is really an issue?

(For now I just set copilot-idle-delay to a high value to turn off auto completion.)

rakotomandimby commented 6 months ago

IMO, copilot-complete is about to ask Copilot for its proposals, I cannot see how to ask it that while it's off.

zerolfx commented 6 months ago

It may caused by #164.

In previous versions, copilot.el would send the entire buffer to agent.js for completion. Now, it requires hooks from copilot-mode to sync the most recent buffer content.

emil-vdw commented 6 months ago

That would explain it. It seems to me reasonable to expect copilot-complete to work only when the mode is active in principle.

Is the reason you (used) to keep the mode disabled that you do not want the overlay to show on an idle timer? If so I think that the appropriate course of action is to create a ticket to support explicitly disabling completion on idle (when set to nil for example instead of just setting it to some large number).

stasvlasov commented 6 months ago

That would explain it. It seems to me reasonable to expect copilot-complete to work only when the mode is active in principle.

Yes, it is reasonable but logically the user would naturally expect the command to work as it is since it is autoloaded and available to the user everywhere. Maybe add a message that tells it will not work unless copilot-mode is on. I was really thinking I broke something with my setup.

Also having copilot-mode always on might be overkill for many cases (browse the buffers or editing small things that does not really require AI assistance). As I understand with the copilot-mode on even if I switch off completions by setting copilot-idle-delay high it syncs the buffer on every change.

Is the reason you (used) to keep the mode disabled that you do not want the overlay to show on an idle timer? If so I think that the appropriate course of action is to create a ticket to support explicitly disabling completion on idle (when set to nil for example instead of just setting it to some large number).

That would be very useful indeed (more like a separate feature/issue not as a full solution this one:). And if it were implemented it might be also logical that the 0 value of copilot-idle-delay would mean infinite delay whereas nil would mean immediate completion.

emil-vdw commented 6 months ago

Yes, it is reasonable but logically the user would naturally expect the command to work as it is since it is autoloaded and available to the user everywhere. Maybe add a message that tells it will not work unless copilot-mode is on. I was really thinking I broke something with my setup.

Good point. It should not be autoloaded.

Unfortunately it's just not possible to provide completions without the mode being active (and tracking buffer changes) within the current scheme. Copilot mode is buffer local so it doesn't have to be that overkill at all.

emil-vdw commented 4 months ago

What you could do to accommodate your use case is:

(advice-add 'copilot-complete :before
            (lambda (&rest _)
              (unless (bound-and-true-p copilot-mode)
                (copilot-mode 1))))
NightMachinery commented 3 months ago

Here is what I use:

;;;
  (defun night/copilot-overlay-disable ()
    (interactive)
    (setq copilot-idle-delay nil)
    ;; Complete immediately if set to 0.
    ;; Disable idle completion if set to nil.
    (message "Copilot overlays disabled.")
    )

  (defun night/copilot-overlay-enable ()
    (interactive)
    (setq copilot-idle-delay 0)
    (message "Copilot overlays enabled!"))

  (defun night/copilot-overlay-toggle ()
    (interactive)
    (cond
     ((null copilot-idle-delay)
      (night/copilot-overlay-enable))
     (t
      (night/copilot-overlay-disable))))
;;;
  (defun night/h-copilot-clear-overlay ()
    "Like `copilot-clear-overlay', but returns `t' if the overlay was visible."
    (when (copilot--overlay-visible)
      (copilot-clear-overlay) t))
  (add-hook 'doom-escape-hook #'night/h-copilot-clear-overlay)
;;;
  (defun night/copilot-ensure (&rest _)
    (interactive)
    (unless (bound-and-true-p copilot-mode)
      (copilot-mode 1)
      (night/copilot-overlay-disable)))

  (advice-add 'copilot-complete :before #'night/copilot-ensure)
;;;