Dicen que con emacs, a parte de hablar por irc, mandar correos y ver los cómics de xkcd se puede editar texto! Hasta se puede convertir emacs en un ide! Una locura. Hoy vamos a ver como programar en python y tener soporte para todo lo que suelen tener los IDE de programación.
Empecemos por el principio. Qué es elpy? Viene a ser un envoltorio de varios módulos. Por defecto viene con soporte de identación automática, auto-completado, documentación de los módulos, corrector de errores, virtualenv, inserción de snippets y más. Todo esto lo envuelve en un proceso que corre en segundo plano. Iremos viendo poco a poco como se usa todo.
Pero antes que nada, instalemos lo necesario. Primero algunas dependencias en pip. Por si se programa en python 2 y en python 3, mejor instalar las dependencias de ambas versiones:
Para que elpy funcione hay que instalar las siguientes dependencias:
sudo pip3 install rope importmagic autopep8 yapf
sudo pip2 install rope importmagic autopep8 yapf
Además, es conveniente que estas dependencias se instalen en cada virtualenv que se cree. Para hacerlo, hay que añadir lo siguiente al archivo ~/.virtualenvs/postmkvirtualenv
:
pip install rope importmagic autopep8 yapf
La configuración de elpy:
(defun elpy-goto-definition-or-rgrep ()
"Go to the definition of the symbol at point, if found. Otherwise, run `elpy-rgrep-symbol'."
(interactive)
(ring-insert find-tag-marker-ring (point-marker))
(condition-case nil (elpy-goto-definition)
(error (elpy-rgrep-symbol
(concat "\\(def\\|class\\)\s" (thing-at-point 'symbol) "(")))))
(use-package elpy
:ensure t
:init
(use-package pyvenv :ensure t)
(setq elpy-modules '(elpy-module-sane-defaults elpy-module-company elpy-module-eldoc elpy-module-pyvenv))
(setq elpy-rpc-backend "jedi")
:config
(add-to-list 'ivy-completing-read-handlers-alist '(elpy-doc . completing-read-default)) ;; véase https://github.com/abo-abo/swiper/issues/892
;; Use pytest
(setq elpy-test-runner 'elpy-test-pytest-runner)
(setq elpy-test-pytest-runner-command '("tox"))
(add-to-list 'elpy-project-ignored-directories "__pycache__")
(add-to-list 'elpy-project-ignored-directories ".cache")
(setq compilation-scroll-output 'first-error)
(add-to-list 'auto-mode-alist '("\\.py" . python-mode))
(add-to-list 'auto-mode-alist '("\\.py" . elpy-mode))
(elpy-enable)
(evil-define-key 'normal elpy-mode-map
"gd" 'elpy-goto-definition-or-rgrep))
Hay que recordar que evaluando la configuración de use-package
se instalan los paquetes automáticamente, gracias al :ensure t
, como vimos en el articulo para instalar automáticamente la configuración de emacs.
Es posible que tarde un rato en instalarse todo, ya que elpy tiene varias dependencias. Estas son company, find-file-in-project, highlight-indentation, pyvenv y yasnippet. En la configuración anterior se puede ver que he re-definido la variable elpy-modules
. Por defecto trae un par de módulos más, como yasnippet o highlight-indentation, pero como no los uso, pues fuera. También he quitado flymake, por que prefiero flycheck que tiene soporte para otros lenguajes, aunque de momento solo tengo agregado el lenguaje python.
Este paquete muestra una ralla que marca los 79 carácteres, para cumplir con el pep8.
(use-package fill-column-indicator
:init
(setq fci-rule-color "purple")
(setq fill-column 79)
(setq fci-rule-column 79)
(add-hook 'python-mode-hook 'fci-mode)
(add-hook 'emacs-lisp-mode-hook 'fci-mode)
(add-hook 'sh-mode-hook 'fci-mode)
:ensure t)
Y aquí configuramos flycheck, en vez de flake8:
(use-package flycheck
:config
;; (setq flycheck-global-modes '(python-mode))
;; (global-flycheck-mode)
(add-hook 'after-init-hook #'global-flycheck-mode)
(spc-map
"i" '(nil :which-key "flycheck prefix")
"in" 'flycheck-next-error
"ip" 'flycheck-previous-error
"il" 'flycheck-list-errors)
:diminish flycheck-mode
:ensure t)
De tema de configuración ya estamos. Veamos ahora como se utiliza esto. Solo mencionaré los que uso o los que tengo intención de usar más.
Atajo de teclado | Función | Explicación |
---|---|---|
S/N | elpy-config | Muestra la configuración actual de elpy |
S/N | pyvenv-workon | Equivalente al workon del virtualenvwrapper. Permite escoger entre todos los virtualenv existentes. |
S/N | pyvenv-deactivate | Desactiva el virtualenv. |
M-TAB | elpy-company-backend | Auto completado. Para moverse entre las opciones, presionar M-n y M-p. |
M-. | elpy-goto-definition | Va a la localización de la definición del elemento en el que está el cursor. |
M-* | pop-tag-mark | Vuelve al punto en el que estaba el cursor antes de ejecutar elpy-goto-definition. |
C-c C-o | elpy-occur-definitions | Abre un minibuffer con las definiciones de todas las clases y funciones del buffer. |
C-c C-z | elpy-shell-switch-to-shell | Abre un buffer con un intérprete de python. Usará el entorno virtual si está activo. |
C-c C-c | elpy-shell-send-region-or-buffer | Envia la región o el buffer al intérprete de python. |
C-c C-v | elpy-check | Ejecutará el corrector de sintaxis. |
C-c C-d | elpy-doc | Abrirá la documentación para el elemento del cursor. |
C-c C-e | elpy-multiedit-python-symbol-at-point | Edita todas las ocurrencias en el cursor. Para cambiar solo las de la función, C-x n d y C-x n w. |
C-c C-r f | elpy-format-code | Formatea automáticamente. |
C-c C-r i | elpy-importmagic-fixup | Auto importar módulos que se estén usando. |
A continuación unas cuantas imágenes de algunas funciones:
Fuentes:
- https://elpy.readthedocs.io/en/latest/introduction.html
- https://realpython.com/blog/python/emacs-the-best-python-editor/