Configuración de Emacs paso a paso (04)

Nota
Este artículo se actualizó por última vez el 2022-04-22, es posible que el contenido no esté actualizado.

Seguimos revisando la configuración de nuestro editor Emacs esta vez vamos a ver las configuraciones para programar en Python.

No he conseguido automatizar completamente la instalación de los paquetes para programación en Python, así que es aconsejable añadir las nuevas secciones a mano a nuestro fichero de configuración y seguir los pasos descritos.

He probado dos configuraciones diferentes para programar en Python. La primera usando jedi (un motor de autocompletado en Python) y company-jedi un paquete Emacs que integra jedi con company. La segunda configuración se implementa usando el paquete elpy, un paquete para Emacs que pretende implementar un IDE completo para Python.

Solo necesitamos tener una de las dos configuraciones activa. Son redundantes por qué elpy va a instalar también su propio jedi y usarlo para el autocompletado.

Paquetes instalados en el sistema

Yo uso Linux Mint 18.04. y tengo instalados tres versiones de Python:

  • Python 2.7.17, instalado por defecto en Linux Mint. Comando: python. Ruta: /usr/bin/python
  • Python 3.6.9, instalado por defecto en Linux Mint. Comando: python3. Ruta: /usr/bin/python3
  • Python 3.8.0, instalado desde repos via apt. Comando: python3.8. Ruta: /usr/bin/python3.8

En principio quiero evitar tener que instalar paquetes en ninguno de estos tres python y montar todo lo que Emacs necesite en un entorno virtual aislado.

jedi y company-jedi

El primer paquete emacs que vamos a instalar es company-jedi.el. company-jedi necesita que el paquete python jedi esté instalado para funcionar correctamente. Afortunadamente el paquete Emacs se encargará de crear un entorno virtual con las dependecias instaladas, si le damos suficiente información.

Añadimos la nueva sección a nuestro fichero ~/.emacs.d/myinit.org:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
* Use the latest python
   #+begin_src emacs-lisp
     (setq python-shell-interpreter "/usr/bin/python3.8")
     (setq py-python-command "/usr/bin/python3.8")        ; maybe not needed
     (setq python-python-command "/usr/bin/python3.8")    ; maybe not needed
   #+end_src

** company-jedi
   Autocompletion for python
   - Run M-x jedi:install-server
   - M-x jedi:show-setup

   #+begin_src emacs-lisp
     (use-package company-jedi             ;;; company-mode completion back-end for Python JEDI
       :ensure t
       :config
       (setq jedi:environment-virtualenv
             (append python-environment-virtualenv
                     '("--no-site-packages" "--python" "/usr/bin/python3.8")))
       (setq jedi:environment-virtualenv (list (expand-file-name "~/.emacs.d/.python-environments/")))
       (add-hook 'python-mode-hook 'jedi:setup)
       (setq jedi:complete-on-dot t)
       (setq jedi:use-shortcuts t)
       (defun config/enable-company-jedi ()
         (add-to-list 'company-backends 'company-jedi))
       (add-hook 'python-mode-hook 'config/enable-company-jedi)
       )
   #+end_src

Lo más importante al añadir esta sección es establecer los parámetros necesarios para que se cree el virtualenv para jedi. Yo no he cambiado el nombre del virtualenv que será default y tampoco he cambiado su localización (~/.emacs.d/.python-environments). Solo he especificado que quiero que Emacs use python3.8 para todo y que el entorno virtual se debe crear con la opción --no-site-packages.

Este último detalle es muy importante. Resulta que el paquete emacs-python-environment que se invoca para crear el entorno virtual, por defecto usa la opción --system-site-packages Esto rompe el aislamiento del entorno virtual creado y a mi me ha causado problemas de todo tipo. Como yo quiero mantener mis python de sistema tan limpios como sea posible añado la opción --no-site-packages a la creación del entorno virtual.

Más información acerca de parámetros para el entorno virtual aquí. Y una aclaración de la opción --system-site-packages aquí

Con la nueva sección añadida tenemos que cerrar completamente nuestro editor y abrir una nueva sesión. Con esto forzaremos a que se descargue el paquete company-jedi.el. Al hacer esto puede que recibamos algunos Warnings sobre todo del paquete company-jedi pero podemos ignorarlos.

Una vez completada la instalación, desde el editor invocamos M-x jedi:install-server con esta orden se creará un entorno virtual para python en ~/.emacs.d/.python-environments/default y dentro de ese entorno default se instalará el paquete jedi de python.

Con el comando M-x jedi:show-setup-info podremos comprobar si todo queda instalado correctamente en nuestro sistema.

elpy

No he conseguido que el entorno virtual que crea elpy utilice el python3.8 de mi Linux. Al final me he rendido y he creado yo el entorno virtual, yo uso virtualenvwrapper pero en realidad puedes crear el entorno virtual como quieras y basado en el python que prefieras. Ni siquiera tendrías que instalar las dependencias de elpy, lo puede hacer el mismo si invocas Mx-elpy-config (una vez instalado, claro está)

1
2
mkvirtualenv -p /usr/bin/python3.8 elpy-rpc
pip install jedi rope autopep8 yapf black

Una vez creado el virtualenv añadimos la sección de configuración a nuestro fichero myinit.org

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
** elpy
   See the docs
   #+begin_src emacs-lisp
     (use-package elpy
       :ensure t
       :defer t
       :init
       (advice-add 'python-mode :before 'elpy-enable)
       :config
       (setq elpy-rpc-python-command (expand-file-name "~/.virtualenvs/elpy-rpc/bin/python"))
       (setq elpy-rpc-virtualenv-path (expand-file-name "~/.virtualenvs/elpy-rpc"))
       (elpy-enable)
       (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
       (add-hook 'elpy-mode-hook 'flycheck-mode)            ;; flycheck for syntax check
       (setq elpy-rpc-backend "jedi")                       ;; jedi for completions
       (add-hook 'elpy-mode-hook (lambda ()
                                   (add-hook 'before-save-hook
                                             'elpy-format-code nil t))) ;; format code before saving
       )
   #+end_src

No está de más invocar M-x elpy-config para comprobar que la instalación está bien.

Conclusión

Tengo la sensación, sin haber hecho pruebas objetivas, de que company-jedi es más rápido completando que la opción elpy. Por otro lado elpy es mucho más potente, hay que leer la documentación para ver todas las posibilidades que ofrece.

He añadido la instalación de company-quickhelp en la sección de company del fichero myinit.org para ver la documentación de python como pop-up mientras programas. Si no te gusta basta con no añadir ese paquete a la configuración.

Recuerda que solo necesitas tener una de las dos configuraciones activa, no tiene sentido activar las dos.

Ficheros para descargar

Los ficheros descritos: init.el y myinit.org puedes descargarlos desde este enlace

Los ficheros están almacenados en https://gitlab.com/comacero/emacs_conf_step e irán ampliándose a medida que publiquemos esta serie. En realidad el único fichero que tienes que actualizar es el myinit.org. El init.el debería cambiar automaticamente sin intervención de nadie.

Referencias