Using the typical `lsp` project, but am not sure if I should switch over to `eglot`. It will be interesting to mess with this.
4.6 KiB
Configuring Python in Emacs
A literate programming file for configuring Python.
Introduction
The critical part of Python integration with Emacs is running LSP in Python using direnv. And the only question to ask is if the Python we run it in Docker or in a virtual environment.
Virtual Environment
For a local virtual machine, simply put the following in your .envrc
file:
layout_python3
That is pretty slick and simple.
The old way, that we still use if you need a particular version of Python, is to install pyenv globally:
pip install pyenv
And have this in your .envrc
file:
use python 3.7.1
Also, you need the following in your ~/.config/direnv/direnvrc
file (which I have):
use_python() {
local python_root=$(pyenv root)/versions/$1
load_prefix "$python_root"
if [[ -x "$python_root/bin/python" ]]; then
layout python "$python_root/bin/python"
else
echo "Error: $python_root/bin/python can't be executed."
exit
fi
}
Docker Environment
Docker really allows you to isolate your project's environment. The downside is that you are using Docker and probably a bloated container. On my work laptop, a Mac, this creates a behemoth virtual machine that immediately spins the fans like a wind tunnel.
But, but… think of the dependencies!
Enough of the rant (I go back and forth), after getting Docker installed and running (ooo Podman … shiny), and you've created a Dockerfile
for your project, let's install container-env.
Your project's .envrc
file would contain something like:
CONTAINER_NAME=my-docker-container
CONTAINER_WRAPPERS=(python3 pip3 yamllint)
CONTAINER_EXTRA_ARGS="--env SOME_ENV_VAR=${SOME_ENV_VAR}"
container_layout
Python Dependencies
Whew. Each Python project's requirements-dev.txt
file would reference the python-lsp-server (not the unmaintained python-language-server
):
python-lsp-server[all]
Note: This does mean, you would have a tox.ini
with this line:
[tox]
minversion = 1.6
skipsdist = True
envlist = linters
ignore_basepython_conflict = True
[testenv]
basepython = python3
install_command = pip install {opts} {packages}
deps = -r{toxinidir}/test-requirements.txt
commands = stestr run {posargs}
stestr slowest
# ...
Using Jedi Instead
Do we want to use the Jedi version of LSP? Not sure what it buys us.
(use-package lsp-jedi
:config
(with-eval-after-load "lsp-mode"
(add-to-list 'lsp-disabled-clients 'pyls)
(add-to-list 'lsp-enabled-clients 'jedi)))
LSP Integration of Python
Now that the LSP Integration is complete, we can stitch the two projects together:
(use-package lsp-mode
:hook ((python-mode . lsp)))
And we're done.