Eglot for Better Programming Experience in Emacs


LSP, or Language Server Protocol, makes programming easier by introducing features like more precise auto-completion and definition lookup. It may have scratched your itches, and you are wondering what the experience is like in Emacs.

Emacs has mainly two LSP clients out there, eglot and lsp-mode. Eglot is lightweight, and it could almost run out of the box. So in this post I will briefly show you how to use eglot.

As a user, we only need to know these commands to get started:

  1. M-x eglot connects to an LSP server for the current project

  2. M-x flymake-goto-next-error goes to previous error

  3. M-x flymake-goto-prev-error goes to next error

  4. M-. or M-x xref-find-definitions finds the definition and opens it in the current window

  5. M-. or M-x xref-pop-marker-stack jumps back

  6. M-? or M-x xref-find-references finds the references

Occasionally, we may need:

  1. M-x company-complete to trigger completions manually

  2. M-x eldoc-doc-buffer

I've also made a video to demonstrate the workflow as below:

And, the emacs-showcase.el is following for the video:

;;;; basics
;; don't auto-save and back up files
(setq auto-save-default nil
      make-backup-files nil)

;;; look and feel
(load-theme 'leuven 'no-confirm)

(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)

;; font & font size
(add-to-list 'default-frame-alist
             '(font . "DejaVu Sans Mono-16"))

;;;; install & customize packages
(require 'package)
(setq package-user-dir "~/tmp/elpa/")
(setq package-archives '(
                         ("gnu" . "https://elpa.gnu.org/packages/")
                         ("melpa" . "https://melpa.org/packages/")
                         ("melpa-stable" . "http://stable.melpa.org/packages/")
                         ))
;;(package-refresh-contents)
(package-initialize)

;;; keycast
;; use the newest keycast
(load-file "~/workspace/elisp/keycast/keycast.el")
;;(package-install 'keycast)
(keycast-mode)
;; (keycast-log-mode)
(setq keycast-log-format "%-18K%C%R\n"
      keycast-remove-tail-elements nil
      keycast-log-frame-alist '((inhibit-switch-frame . t)
                                (pop-up-frame-parameters . ((font . "DejaVu Sans Mono-12")
                                                            (minibuffer . nil)))))
(push '(self-insert-command nil nil) keycast-substitute-alist)

;;; org
(setq org-agenda-files '("~/test/video-agenda.org"))
(global-set-key (kbd "C-c o a") #'org-agenda)

;;;; eglot
;; it needs to install `jsonrpc' from elpa
(package-install 'eglot)

(package-install 'company)
(global-company-mode)

(setq eldoc-echo-area-use-multiline-p nil)

(require 'eglot)
(define-key eglot-mode-map (kbd "C-c <tab>") #'company-complete) ; initiate the completion manually
(define-key eglot-mode-map (kbd "C-c e f n") #'flymake-goto-next-error)
(define-key eglot-mode-map (kbd "C-c e f p") #'flymake-goto-prev-error)
(define-key eglot-mode-map (kbd "C-c e r") #'eglot-rename)

;;; python venv for LSP
;;; python -m venv ~/workspace/virtualenv/devel
;;; pip install 'python-language-server[all]' scrapy
(package-install 'pyvenv)
(pyvenv-activate "~/workspace/virtualenv/devel/")

;;;; Show the topic
(defun w/topic-butterfly (topic)
  "Show a TOPIC in a buffer, based on M-x butterfly."
  (interactive "Mtopic: ")
  (progn
	(switch-to-buffer (get-buffer-create "*video-topic*"))
	(erase-buffer)
	(sit-for 0)
	(animate-string topic
			        (- (/ (window-height) 2)
                       5)
                    (- (/ (window-width) 2)
                       (/ (length topic) 2)))
	(sit-for (* 5 (/ (abs (random)) (float most-positive-fixnum))))))

(global-set-key (kbd "<f6>")
                (lambda ()
                  (interactive)
                  (w/topic-butterfly "eglot for better programming experience")))
The minimal config for the demo video

See also

comments powered by Disqus