Coder Social home page Coder Social logo

copilot.el's Introduction

Copilot.el

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.

Installation

  1. Install Node.js (only support 12.x to 17.x, limited by upstream). Workaround for node.js v18+ users: install an old version of node.js via nvm and set copilot-node-executable to it.

  2. Setup copilot.el as described in the next section.

  3. Login to Copilot by M-x copilot-login. You can also check the status by M-x copilot-diagnose.

  4. Enjoy!

Configurations

Example for Doom Emacs

Add package definition to ~/.doom.d/packages.el:

(package! copilot
  :recipe (:host github :repo "zerolfx/copilot.el" :files ("*.el" "dist")))

Configure copilot in ~/.doom.d/config.el:

;; accept completion from copilot and fallback to company
(defun my-tab ()
  (interactive)
  (or (copilot-accept-completion)
      (company-indent-or-complete-common nil)))

(use-package! copilot
  :hook (prog-mode . copilot-mode)
  :bind (("C-TAB" . 'copilot-accept-completion-by-word)
         ("C-<tab>" . 'copilot-accept-completion-by-word)
         :map company-active-map
         ("<tab>" . 'my-tab)
         ("TAB" . 'my-tab)
         :map company-mode-map
         ("<tab>" . 'my-tab)
         ("TAB" . 'my-tab)))

Strongly recommend to enable childframe option in company module ((company +childframe)) to prevent overlay conflict.

Example for Spacemacs

Edit your ~/.spacemacs:

;; ===================
;; dotspacemacs/layers
;; ===================

;; add copilot.el to additional packages
dotspacemacs-additional-packages
 '((copilot :location (recipe
                       :fetcher github
                       :repo "zerolfx/copilot.el"
                       :files ("*.el" "dist"))))

;; ========================
;; dotspacemacs/user-config
;; ========================

;; accept completion from copilot and fallback to company
(defun my-tab ()
  (interactive)
  (or (copilot-accept-completion)
      (company-indent-or-complete-common nil)))

(with-eval-after-load 'company
  ;; disable inline previews
  (delq 'company-preview-if-just-one-frontend company-frontends)
  ;; enable tab completion
  (define-key company-mode-map (kbd "<tab>") 'my-tab)
  (define-key company-mode-map (kbd "TAB") 'my-tab)
  (define-key company-active-map (kbd "<tab>") 'my-tab)
  (define-key company-active-map (kbd "TAB") 'my-tab))


(add-hook 'prog-mode-hook 'copilot-mode)

(define-key evil-insert-state-map (kbd "C-<tab>") 'copilot-accept-completion-by-word)
(define-key evil-insert-state-map (kbd "C-TAB") 'copilot-accept-completion-by-word)

General Configurations

1. Load copilot.el

Option 1: Load via straight.el (recommended)
(use-package copilot
  :straight (:host github :repo "zerolfx/copilot.el" :files ("dist" "*.el"))
  :ensure t)
;; you can utilize :map :hook and :config to customize copilot
Option 2: Load manually

Please make sure you have these dependencies installed, and use load-file or load-path + require to load it.

  • dash
  • s
  • editorconfig

2. Configure completion

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.

Option 2: Manually provide completions

You need to bind copilot-complete to some key and call copilot-clear-overlay inside post-command-hook.

3. Configure completion acceptation

In general, you need to bind copilot-accept-completion to some key in order to accept the completion. Also, you may find copilot-accept-completion-by-word is useful.

Example of using tab with company-mode

; complete by copilot first, then company-mode
(defun my-tab ()
  (interactive)
  (or (copilot-accept-completion)
      (company-indent-or-complete-common nil)))

; modify company-mode behaviors
(with-eval-after-load 'company
  ;; disable inline previews
  (delq 'company-preview-if-just-one-frontend company-frontends)

  (define-key company-mode-map (kbd "<tab>") 'my-tab)
  (define-key company-mode-map (kbd "TAB") 'my-tab)
  (define-key company-active-map (kbd "<tab>") 'my-tab)
  (define-key company-active-map (kbd "TAB") 'my-tab))

Example of using tab with auto-complete

; complete by copilot first, then auto-complete
(defun my-tab ()
  (interactive)
  (or (copilot-accept-completion)
      (ac-expand nil)))

(with-eval-after-load 'auto-complete
  ; disable inline preview
  (setq ac-disable-inline t)
  ; show menu if have only one candidate
  (setq ac-candidate-menu-min 0)

  (define-key ac-completing-map (kbd "TAB") 'my-tab)
  (define-key ac-completing-map (kbd "<tab>") 'my-tab))

(define-key global-map [remap indent-for-tab-command] '(lambda ()
                                                         (interactive)
                                                         (or (copilot-accept-completion)
                                                             (indent-for-tab-command))))

Example of defining tab in copilot-mode

This is useful if you don't want to depend on a particular completion framework.

(defun my/copilot-tab ()
  (interactive)
  (or (copilot-accept-completion)
      (indent-for-tab-command)))

(with-eval-after-load 'copilot
  (define-key copilot-mode-map (kbd "<tab>") #'my/copilot-tab))

Or with evil-mode:

(with-eval-after-load 'copilot
  (evil-define-key 'insert copilot-mode-map
    (kbd "<tab>") #'my/copilot-tab))

Commands

copilot-diagnose

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.

copilot-login

Login to GitHub, required for using the plugin.

copilot-mode

Enable/disable copilot mode.

copilot-complete

Try to complete at the current point.

copilot-accept-completion

Accept the current completion.

copilot-clear-overlay

Clear copilot overlay in the current buffer.

copilot-accept-completion-by-line / copilot-accept-completion-by-word

Similar 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.

copilot-next-completion / copilot-previous-completion

Cycle through the completion list.

copilot-logout

Logout from GitHub.

Customization

copilot-node-executable

The executable path of Node.js.

copilot-idle-delay

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

A list of predicate functions with no argument to enable Copilot in copilot-mode. Copilot will be enabled only if all predicates return t.

copilot-disable-predicates

A list of predicate functions with no argument to disable Copilot in copilot-mode. Copilot will be disabled if any predicate returns t.

Known Issues

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.

Cursor Jump to End of Line When Typing

  • If you are using whitespace-mode, make sure to remove newline-mark from whitespace-style.

Reporting Bugs

  • Make sure you have restarted your Emacs (and rebuild the plugin if necessary) after updating the plugin.
  • Please paste related logs in the *copilot events* and *copilot stderr* buffer.
  • If an exception is thrown, please also paste the stack trace (use M-x toggle-debug-on-error to enable stack trace).

Roadmap

  • Setup Copilot without Neovim
  • Cycle through suggestions
  • Add Copilot minor-mode
  • Add package to MELPA

Thanks

These projects helped me a lot:

copilot.el's People

Contributors

zerolfx avatar ethan-leba avatar lululau avatar thefool32 avatar sqrtminusone avatar mpontus avatar syohex avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.