copilot-emacs / copilot.el

An unofficial Copilot plugin for Emacs.
MIT License
1.79k stars 126 forks source link

global-copilot-mode uses entire system memory #226

Open simi48 opened 9 months ago

simi48 commented 9 months ago

When I M-x global-copilot-mode, I run out of system memory.

It essentially spawns .../copilot//dist/agent.js processes until the OOM starts killing off programs.

Annoyingly, for some reason I cannot exit emacs once too many processes are started.

I get error messages like the following: Lisp nesting exceeds 'max-lisp-eval-depth' and error in process sentinel: Lisp nesting exceeds 'maxlisp-eval-depth'.


I am running

Linux Mint 21.1 Vera
$ node --version
v20.10.0
$ doom --version
GNU Emacs     v27.1            nil
Doom core     v3.0.0-pre       grafted, HEAD -> master, origin/master,
origin/HEAD 03d692f1 2023-12-08 15:11:45 -0500
Doom modules  v23.12.0-pre     grafted, HEAD -> master, origin/master,
origin/HEAD 03d692f1 2023-12-08 15:11:45 -0500

Currently on master branch 1542d76909636bf8804dd9c770f28818a897cfdc, installed with straight. (For the installation I just followed what was written in the README)

To reproduce error

  1. start emacs
  2. M-x global-copilot-mode

Also, no strange behavior when M-x copilot-mode is run before M-x global-copilot-mode


Using M-x copilot-mode works just fine. So it's really not an inconvenience and generally copilot works great. Just thought I'd let you guys know.

Cheers

lroolle commented 8 months ago

Has there been any progress on this issue? I'm currently using Doom Emacs. My workaround is as follows:

(use-package! copilot
  :after company
  :hook ((prog-mode . copilot-mode)
         (org-mode . copilot-mode)
         (markdown-mode . copilot-mode))
  :bind (("C-TAB" . 'copilot-accept-completion-by-word)
         ("C-<tab>" . 'copilot-accept-completion-by-word)
         ("C-!" . 'copilot-next-completion)
         :map copilot-completion-map
         ("<tab>" . 'copilot-accept-completion)
         ("TAB" . 'copilot-accept-completion)
         :map company-active-map
         ("<tab>" . 'my/copilot-tab)
         ("TAB" . 'my/copilot-tab)
         :map company-mode-map
         ("<tab>" . 'my/copilot-tab)
         ("TAB" . 'my/copilot-tab))
  :config
  ;; https://github.com/copilot-emacs/copilot.el/issues/226
  ;; (global-copilot-mode)
  (setq! copilot-idle-delay 0.12)
  (setq! copilot-max-char -1)
  (setq! copilot-log-max 10000))
rakete commented 8 months ago

Same problem here, solved it with this change:

(defun copilot-turn-on-unless-buffer-read-only ()
  "Turn on `copilot-mode' if the buffer is writable."
  (unless (or buffer-read-only (not (buffer-file-name (current-buffer))))
    (copilot-mode 1)))

I think the problem is that global-copilot-mode enables copilot-mode in *Messages*, and then starts running on every change in there.

emil-vdw commented 8 months ago

I don't like the idea of an unrestricted global mode for copilot in Emacs. It is too unpredictable. I would vote for users to set up hooks for copilot mode in whatever buffers they would actually want it in.

Supporting global-copilot-mode will be more effort than it's worth IMO. What do you think @zerolfx ?

zerolfx commented 8 months ago

@emil-vdw Making breaking changes could be a last resort. Global mode is useful in my view, because it is the default behavior of Copilot in other IDEs. I know the problem could be complex in Emacs, but how about trying the suggested fix from @rakete?

emil-vdw commented 6 months ago

@zerolfx The problem with @rakete's approach is that the mode won't be active for buffers without a saved file corresponding to the buffer. This includes buffers just created (like temp.py) but not saved yet.

Another approach would be to not activate when the major mode is special-mode derived or just ban certain modes (like messages-buffer-mode).

In my opinion though, Emacs it would be better to hand craft a set of modes for which global-copilot-mode should activate:

(derived-mode-p
 prog-mode
 Info-mode
 ;; Other modes
 )

But at that point we might as well advise the user to use these hooks in their config for copilot-mode?

The concept of global copilot mode works very well in other editors because they are only text editors. Not including process buffers, web browsers, PDF viewers, etc.

zerolfx commented 6 months ago

@emil-vdw Thanks for your explanation. It seems having global-copilot-mode could cause many potential problems, and deprecating it is reasonable.

ncaq commented 1 month ago

It worked on the peripheral version when I wrote my copilot-turn-on-unless-buffer-read-only, but I encounter the same problem on other machines. It works on the machine that I have stopped updating elpa. I wonder how it works. At any rate, it seems like the right decision to discontinue it before it doesn't work.

ncaq commented 3 weeks ago

I set copilot-mode to text-mode-hook and prog-mode-hook. I have tried it for about a week and it is good.