Forked from copilot-emacs/copilot.el with my own customizations.
Copilot.el is an Emacs plugin for GitHub Copilot.
Warning: This plugin is unofficial and based on binaries provided by copilot.vim.
Note: You need access to GitHub Copilot to use this plugin.
Current maintainer: @emil-vdw, @jcs090218, @rakotomandimby.
Retired maintainer: @zerolfx.
Ensure your Emacs version is at least 27, the dependency package editorconfig
(melpa) and jsonrpc
(elpa, >= 1.0.14) are both installed.
Install Node.js v18+. (You can specify the path to node
executable by setting copilot-node-executable
.)
Setup copilot.el
as described in the next section.
Install the copilot server by M-x copilot-install-server
.
Login to Copilot by M-x copilot-login
. You can also check the status by M-x copilot-diagnose
(NotAuthorized
means you don't have a valid subscription).
Enjoy!
Add package definition to ~/.doom.d/packages.el
:
(package! copilot :recipe (:host github :repo "copilot-emacs/copilot.el" :files ("*.el")))
Configure copilot in ~/.doom.d/config.el
:
;; accept completion from copilot and fallback to company (use-package! copilot :hook (prog-mode . copilot-mode) :bind (:map copilot-completion-map ("<tab>" . 'copilot-accept-completion) ("TAB" . 'copilot-accept-completion) ("C-TAB" . 'copilot-accept-completion-by-word) ("C-<tab>" . 'copilot-accept-completion-by-word)))
Strongly recommend to enable childframe
option in company
module ((company +childframe)
) to prevent overlay conflict.
If pressing tab to complete sometimes doesn't work you might want to bind completion to another key or try:
(after! (evil copilot) ;; Define the custom function that either accepts the completion or does the default behavior (defun my/copilot-tab-or-default () (interactive) (if (and (bound-and-true-p copilot-mode) ;; Add any other conditions to check for active copilot suggestions if necessary ) (copilot-accept-completion) (evil-insert 1))) ; Default action to insert a tab. Adjust as needed. ;; Bind the custom function to <tab> in Evil's insert state (evil-define-key 'insert 'global (kbd "<tab>") 'my/copilot-tab-or-default))
If you would love to configure indentation here, this is an example config that may work for you:
(use-package! copilot
:hook (prog-mode . copilot-mode)
:bind (:map copilot-completion-map
("<tab>" . 'copilot-accept-completion)
("TAB" . 'copilot-accept-completion)
("C-TAB" . 'copilot-accept-completion-by-word)
("C-<tab>" . 'copilot-accept-completion-by-word)
("C-n" . 'copilot-next-completion)
("C-p" . 'copilot-previous-completion))
:config
(add-to-list 'copilot-indentation-alist '(prog-mode . 2))
(add-to-list 'copilot-indentation-alist '(org-mode . 2))
(add-to-list 'copilot-indentation-alist '(text-mode . 2))
(add-to-list 'copilot-indentation-alist '(closure-mode . 2))
(add-to-list 'copilot-indentation-alist '(emacs-lisp-mode . 2)))
Edit your ~/.spacemacs
:
;; =================== ;; dotspacemacs/layers ;; =================== ;; add or uncomment the auto-completion layer dotspacemacs-configuration-layers '( ... auto-completion ... ) ;; add copilot.el to additional packages dotspacemacs-additional-packages '((copilot :location (recipe :fetcher github :repo "copilot-emacs/copilot.el" :files ("*.el")))) ;; ======================== ;; dotspacemacs/user-config ;; ======================== ;; accept completion from copilot and fallback to company (with-eval-after-load 'company ;; disable inline previews (delq 'company-preview-if-just-one-frontend company-frontends)) (with-eval-after-load 'copilot (define-key copilot-completion-map (kbd "<tab>") 'copilot-accept-completion) (define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion) (define-key copilot-completion-map (kbd "C-TAB") 'copilot-accept-completion-by-word) (define-key copilot-completion-map (kbd "C-<tab>") 'copilot-accept-completion-by-word)) (add-hook 'prog-mode-hook 'copilot-mode)Option 1: Load via
straight.el
or quelpa
(recommended)
(use-package copilot :straight (:host github :repo "copilot-emacs/copilot.el" :files ("*.el")) :ensure t) ;; you can utilize :map :hook and :config to customize copilot
quelpa
+ quelpa-use-package
:
(use-package copilot :quelpa (copilot :fetcher github :repo "copilot-emacs/copilot.el" :branch "main" :files ("*.el"))) ;; you can utilize :map :hook and :config to customize copilot
Please make sure you have these dependencies installed (available in ELPA/MELPA):
dash
s
editorconfig
f
After installing those, clone this repository then insert the below snippet into your config file.
(add-to-list 'load-path "/path/to/copilot.el") (require 'copilot)Option 1: Use
copilot-mode
to automatically provide completions
(add-hook 'prog-mode-hook 'copilot-mode)
To customize the behavior of copilot-mode
, please check copilot-enable-predicates
and copilot-disable-predicates
.
You need to bind copilot-complete
to some key and call copilot-clear-overlay
inside post-command-hook
.
Use tab to accept completions (you may also want to bind copilot-accept-completion-by-word
to some key):
(define-key copilot-completion-map (kbd "<tab>") 'copilot-accept-completion) (define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion)Programming language detection
Copilot.el detects the programming language of a buffer based on the major-mode name, stripping the -mode
part. Resulting languageId should match table here. You can add unusual major-mode mappings to copilot-major-mode-alist
. Without the proper language set suggestions may be of poorer quality.
(add-to-list 'copilot-major-mode-alist '("enh-ruby" . "ruby"))
Check the current status of the plugin. Also you can check logs in the *copilot events*
buffer and stderr output in the *copilot stderr*
buffer.
Login to GitHub, required for using the plugin.
Enable/disable copilot mode.
Try to complete at the current point.
copilot-accept-completionAccept the current completion.
Clear copilot overlay in the current buffer.
copilot-accept-completion-by-line / copilot-accept-completion-by-wordSimilar to copilot-accept-completion
, but accept the completion by line or word. You can use prefix argument to specify the number of lines or words to accept.
Cycle through the completion list.
Log out from GitHub.
The executable path of Node.js.
Time in seconds to wait before starting completion (default to 0). Note Copilot itself has a ~100ms delay because of network communication.
copilot-enable-predicates / copilot-disable-predicatesA list of predicate functions with no argument to enable/disable triggering Copilot in copilot-mode
.
A list of predicate functions with no argument to enable/disable showing Copilot's completions in copilot-mode
.
A list of commands that won't cause the overlay to be cleared.
Format: '(:host "127.0.0.1" :port 7890 :username: "user" :password: "password")
, where :username
and :password
are optional.
For example:
(setq copilot-network-proxy '(:host "127.0.0.1" :port 7890))Wrong Position of Other Completion Popups
This is an example of using together with default frontend of company-mode
. Because both company-mode
and copilot.el
use overlay to show completion, so the conflict is inevitable. To solve the problem, I recommend you to use company-box
(only available on GUI), which is based on child frame rather than overlay.
After using company-box
, you have:
In other editors (e.g. VS Code
, PyCharm
), completions from copilot and other sources can not show at the same time. But I decided to allow them to coexist, allowing you to choose a better one at any time.
whitespace-mode
, make sure to remove newline-mark
from whitespace-style
.copilot-log-max
(to e.g. 1000), then paste related logs in the *copilot events*
and *copilot stderr*
buffer.M-x toggle-debug-on-error
to enable stack trace).These projects helped me a lot:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4