3a927e756a
Using the :local-repo to test local repositories of my .. this doesn't seem right.
128 lines
4.5 KiB
Org Mode
128 lines
4.5 KiB
Org Mode
#+TITLE: Configuring Python in Emacs
|
|
#+AUTHOR: Howard X. Abrams
|
|
#+DATE: 2021-11-16
|
|
#+FILETAGS: :emacs:
|
|
|
|
A literate programming file for configuring Python.
|
|
|
|
#+BEGIN_SRC emacs-lisp :exports none
|
|
;;; ha-programming-python.el --- A literate programming file for configuring Python. -*- lexical-binding: t; -*-
|
|
;;
|
|
;; Copyright (C) 2021 Howard X. Abrams
|
|
;;
|
|
;; Author: Howard X. Abrams <http://gitlab.com/howardabrams>
|
|
;; Maintainer: Howard X. Abrams
|
|
;; Created: November 16, 2021
|
|
;;
|
|
;; This file is not part of GNU Emacs.
|
|
;;
|
|
;; *NB:* Do not edit this file. Instead, edit the original literate file at:
|
|
;; ~/other/hamacs/ha-programming-python.org
|
|
;; And tangle the file to recreate this one.
|
|
;;
|
|
;;; Code:
|
|
#+END_SRC
|
|
* Introduction
|
|
The critical part of Python integration with Emacs is running LSP in Python using [[file:ha-programming.org::*direnv][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:
|
|
#+begin_src conf
|
|
layout_python3
|
|
#+end_src
|
|
That is pretty slick and simple.
|
|
|
|
The old way, that we still use if you need a particular version of Python, is to install [[https://github.com/pyenv/pyenv][pyenv]] globally:
|
|
#+BEGIN_SRC sh
|
|
pip install pyenv
|
|
#+END_SRC
|
|
|
|
And have this in your =.envrc= file:
|
|
#+begin_src conf
|
|
use python 3.7.1
|
|
#+end_src
|
|
|
|
Also, you need the following in your =~/.config/direnv/direnvrc= file (which I have):
|
|
#+begin_src shell
|
|
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
|
|
}
|
|
#+end_src
|
|
** 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 [[https://github.com/snbuback/container-env][container-env]].
|
|
|
|
Your project's =.envrc= file would contain something like:
|
|
#+begin_src shell
|
|
CONTAINER_NAME=my-docker-container
|
|
CONTAINER_WRAPPERS=(python3 pip3 yamllint)
|
|
CONTAINER_EXTRA_ARGS="--env SOME_ENV_VAR=${SOME_ENV_VAR}"
|
|
|
|
container_layout
|
|
#+end_src
|
|
** Python Dependencies
|
|
Whew. Each Python project's =requirements-dev.txt= file would reference the [[https://pypi.org/project/python-lsp-server/][python-lsp-server]] (not the /unmaintained/ =python-language-server=):
|
|
#+begin_src conf
|
|
python-lsp-server[all]
|
|
#+end_src
|
|
|
|
*Note:* This does mean, you would have a =tox.ini= with this line:
|
|
#+BEGIN_SRC conf
|
|
[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
|
|
# ...
|
|
#+END_SRC
|
|
*** Using Jedi Instead
|
|
Do we want to use the Jedi version of LSP? Not sure what it buys us.
|
|
#+BEGIN_SRC emacs-lisp :tangle no
|
|
(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)))
|
|
#+END_SRC
|
|
* LSP Integration of Python
|
|
Now that the [[file:ha-programming.org::*Language Server Protocol (LSP) Integration][LSP Integration]] is complete, we can stitch the two projects together:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package lsp-mode
|
|
:hook ((python-mode . lsp)))
|
|
#+END_SRC
|
|
And we're done.
|
|
* Technical Artifacts :noexport:
|
|
Let's =provide= a name so we can =require= this file:
|
|
|
|
#+BEGIN_SRC emacs-lisp :exports none
|
|
(provide 'ha-programming-python)
|
|
;;; ha-programming-python.el ends here
|
|
#+END_SRC
|
|
|
|
#+DESCRIPTION: A literate programming file for configuring Python.
|
|
|
|
#+PROPERTY: header-args:sh :tangle no
|
|
#+PROPERTY: header-args:emacs-lisp :tangle yes
|
|
#+PROPERTY: header-args :results none :eval no-export :comments no mkdirp yes
|
|
|
|
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil
|
|
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil
|
|
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|