copilot.el 0.4
Good news, everyone – copilot.el 0.4 is out! But that’s just the start of it. This is the most important release for me since I assumed the project’s leadership and I hope this article will manage to make you agree with my reasoning. Enough empty words – let me now walk you through the highlights. A Proper Copilot Client The single biggest change in this release is the migration from the legacy getCompletions API (reverse-engineered from copilot.vim) to the standard textDocument/inlineCompletion LSP method provided by the official @github/copilot-language-server. This might sound like a dry and boring internal change, but it’s actually a big deal. copilot.el started its life as a port of copilot.vim – we were essentially reverse-engineering how that plugin talked to the Copilot server and replicating it in Elisp. That worked, but it was fragile and meant we were always playing catch-up with undocumented protocol changes. Now we speak the official LSP protocol. We send proper textDocument/didOpen, textDocument/didChange, and textDocument/didFocus notifications. We manage workspace folders. We handle server-to-client requests like window/showMessageRequest and window/showDocument. We perform a clean shutdown/exit sequence instead of just killing the process. In short, copilot.el is now a proper Copilot LSP client, not a reverse-engineered hack. This release, in a way, completes the cycle – from a package born out of reverse engineering copilot.vim to a legitimate Copilot client built on the official API.1 But wait, there’s (a lot) more! AI Model Selection You can now choose which AI model powers your completions via M-x copilot-select-completion-model. The command queries the server for available models on your subscription and lets you pick one interactively. The selection is persisted in copilot-completion-model. Parentheses Balancer 2.0 The parentheses balancer – the component that post-processes completions in Lisp modes to fix unbalanced delimiters – got a complete rewrite. The old implementation counted parentheses as raw characters, which meant it would “balance” parens inside comments and strings where they shouldn’t be touched. The new implementation uses parse-partial-sexp to understand the actual syntactic structure, so it only fixes genuinely unbalanced delimiters. Whether the balancer will remain necessary in the long run is an open question – as Copilot’s models get smarter, they produce fewer unbalanced completions. But for now it still catches enough edge cases to earn its keep. You can disable it with (setopt copilot-enable-parentheses-balancer nil) if you want to see how well the raw completions work for you. Improved Server Communication Beyond the core API migration, we’ve improved the server communication in several ways: Status reporting: didChangeStatus notifications show Copilot’s state (Normal, Warning, Error, Inactive) in the mode-line. Progress tracking: $/progress notifications display progress for long-running operations like indexing. Request cancellation: stale completion requests are cancelled with $/cancelRequest so the server doesn’t waste cycles on abandoned work. User-defined handlers: copilot-on-request and copilot-on-notification let you hook into any server message. UTF-16 positions: position offsets now correctly use UTF-16 code units, so emoji and other supplementary-plane characters no longer confuse the server. Tests and Documentation This release adds a proper test suite using buttercup. We went from zero tests to over 120, covering everything from URI generation and position calculation to the balancer, overlay management, and server lifecycle. CI now runs across multiple Emacs versions (27.2 through snapshot) and on macOS and Windows in addition to Linux. The README got a (almost) complete rewrite – it now covers installation for every popular package manager, documents all commands and customization options, includes a protocol coverage table, and has a new FAQ section addressing the most common issues people run into. Plenty of good stuff in it! This might sound like a lot of effort for not much user-visible payoff, but when I started hacking on the project: I really struggled to understand how to make the best use of the package The lack of tests made it hard to make significant changes, as every change felt quite risky Anyways, I hope you’ll enjoy the improved documentation and you’ll have easier time setting up copilot.el. Bug Fixes Too many to list individually, but here are some highlights: copilot-complete now works without copilot-mode enabled (#450) Partial accept-by-word no longer loses trailing text when the server uses a replacement range (#448) JSON-RPC requests send an empty object instead of omitting params, fixing authentication on newer server versions (#445) The company-mode dependency is gone – no more void-function company--active-p errors (#243) The completion overlay plays nice with Emacs 30’s completion-preview-mode (#377) See the full changelog for the complete list. What’s Next There’s still plenty of work ahead. We have three big feature branches in the pipeline, all open as PRs and ready for adventurous testers: Next Edit Suggestions (NES) – proactive edit suggestions that appear at your cursor based on your recent editing patterns, similar to the NES feature in VS Code. Copilot Chat – interactive chat with Copilot, right inside Emacs. Native installation without Node.js – use the pre-built Copilot language server binary instead of requiring a Node.js installation. If any of these sound interesting to you, please give them a spin and report back. Your feedback is what shapes the next release. Thanks A big thanks to Paul Nelson for contributing several partial acceptance commands and the overlay clearing improvements – those are some of the most user-visible quality-of-life changes in this release. Thanks also to everyone who filed detailed bug reports and tested fixes – you know who you are, and this release wouldn’t be the same without you. That’s all I have for you today. Keep hacking! That’s why I dropped the word “unofficial” from the package’s description. ↩
metaredux.com · Meta Redux