LSP and DAP for Python, Golang, Rust and Typescript/Javascript.

Emacs LSP and DAP

Overview

In previous article I developed a configuration for Emacs beginner. In this article let’s continue to set up LSP (Language Server Protocol) and DAP (Debug Adapter Protocol). Particularly the languages that I will focus on are Python, Golang, Rust and Typescript.

Language Servers Installation

I am going to use the same language servers in my earlier article on setting up Neovim LSP using Lua.

Python

For Python, let’s install pyright.

$ npm install -g pyright

Golang

For Golang, let’s install gopls.

$ GO111MODULE=on go get golang.org/x/tools/gopls@latest

Rust

For Rust, let’s use rust_analyzer. The easiest way to install is to download the binary, copy to a folder, and add the folder to environment PATH.

Typescript

For Typescript, let’s install typescript-language-server.

$ npm install -g typescript-language-server$ npm install -g typescript

lsp-mode and dap-mode

I am going to use lsp-mode and dap-mode for Emacs.

Create a file called lang.el under the elisp folder with the following content.

Besides lsp-mode, I installed dap-mode, dap-node, dap-gdb-lldb, and dap-go in this package.

lang.el

In init.el, require this package.

(require 'lang)   ;; base extensions

Python LSP and DAP

Create a file called lang-python.el under elisp folder and require it from init.el.

dap-mode uses debugpy. Make sure you install it.

# pip install debugpy
lang-python.el

Restart Emacs and LSP and DAP should work now.

Python — LSP
Python — DAP

Golang LSP and DAP

Create a file called lang-go.el under elisp folder and require it from init.el.

dap-mode uses delve. Make sure you install it.

$ go install github.com/go-delve/delve/cmd/dlv@latest
lang-go.el

Restart Emacs and LSP and DAP should work now.

Golang — LSP
Golang — DAP

Make sure you select “Go Launch Unoptimized Debug Package Configuration” from dap-debug menu.

Debug Options

Rust LSP and DAP

Create a file called lang-rust.el under elisp folder and require it from init.el.

dap-mode uses gdb or lldb. Make sure you install them.

lang-rust.el

Restart Emacs and LSP and DAP should work now.

Rust — LSP

For debugging, create a launch template by selecting dap-debug-edit-template.

dap-debug-edit-template
Rust DAP Debug Template

Refer to the DAP mode documentation for more details.

Typescript LSP and DAP

Create a file called lang-typescript.el under elisp folder and require it from init.el.

lang-typescript.el

Restart Emacs and LSP and DAP should work now.

Typescript — LSP

For debugging, create a launch template by selecting dap-debug-edit-template.

Typescript DAP Debug Template

A sample template that I used.

(dap-register-debug-template
"hello"
(list :type "node"
:cwd "/Users/alpha2phi/workspace/development/alpha2phi/python-apps/debugging"
:request "launch"
:program "/Users/apha2phi/workspace/development/alpha2phi/python-apps/debugging/hello.js"
:name "hello"))
Typescript — DAP

ivy-posframe

As personal preference, I use ivy-posframe to show menu at the center of the frame.

In completion.el, I added these lines

(use-package ivy-posframe
:config
(setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-center)))
(ivy-posframe-mode 1))
ivy-posframe

Key Mappings using general.el

I also use general.el to map some common functions to Space-XX

In keymappings.el.

(use-package general
:after evil
:config
(general-create-definer alpha2phi/leader-keys
:keymaps '(normal insert visual emacs)
:prefix "SPC"
:global-prefix "C-SPC")
(alpha2phi/leader-keys
"t" '(:ignore t :which-key "theme")
"tt" '(counsel-load-theme :which-key "choose theme")
"p" '(:ignore t :which-key "project")
"pp" '(counsel-projectile-switch-project :which-key "choose project")
"pc" '(projectile-command-map :which-key "choose action")
"f" '(:ignore t :which-key "find")
"ff" '(counsel-fzf :which-key "fuzzy find")
"fx" '(counsel-M-x :which-key "M-x")
"g" '(:ignore t :which-key "git")
"gs" '(magit-status :which-key "git status")
"d" '(:ignore t :which-key "debug")
"dd" '(dap-debug :which-key "start debugging")
"dba" '(dap-breakpoint-add :which-key "add breakpoint")
"dbd" '(dap-breakpoint-delete :which-key "delete breakpoint")
"dr" '(dap-ui-repl :which-key "repl")
"du" '(dap-ui-mode :which-key "ui")
))
(provide 'keymappings)

This makes it easy for me to switch among different projects using projectile (SPC-p-p), perform fuzzy file searching (SPC-f-f), and debugging (SPC-d-d).

Switch Project using Projectile

Summary

Learning and hacking Emacs is not so straight forward but it is fun once you get it working the way you want.

The dotfiles I used can be found at this repository.

Other articles that could be of interest to you.

References

Programmer and occasional blogger.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store