Usando scripts Python no Emacs

No início de Janeiro de 2018 iniciamos um grupo de estudos sobre o uso do Python para estatística. O objetivo era tentarmos descobrir como fazer em Python aquilo que fazemos rotineiramente em R. O resultado foi muito interessante e vimos que existe muita similaridade entre as duas linguagens. Abaixo está a divulgação que fizemos do grupo de estudos.

Uma das primeiras coisas que analisamos, logo no início do curso, foram as IDEs (Integrated Development Environment ou Ambiente de Desenvolvimento Integrado) mais utilizadas para se escrever e executar códigos em Python. No mundo do R, sabemos que o RStudio é o editor preferido da maioria dos usuários. No entanto, no mundo do Python não parece haver um único preferencial.

Na categoria de uma IDE específica para a linguagem (como é o RStudio para o R), vimos primeiro o Spyder, por ser o editor distribuído junto com a plataforma Anaconda. Naturalmente, existe também o Jupyter notebook que permite misturar código e texto em um único documento, mas por enquanto estávamos apenas interessados em editores para scripts “puros” de Python (arquivos .py). Fora o Spyder, sabemos que existem diversos bons editores de uso geral, que permitem a edição e possuem ferramentas comuns para várias linguagens. Entre estes editores estão o Atom e o Sublime, que tem suporte para a edição de scripts em Python.

No entanto, como a ideia do grupo de estudos era se familiarizar com o Python, então nada melhor do que utilizarmos o mesmo editor que já utilizamos para códigos R. E esse editor é o Emacs, utilizado por muitos aqui no LEG. O Emacs é um editor altamente customizável e de múltiplos propósitos. Seu alto índice de uso aqui no laboratório remonta aos tempos de uma era pré-RStudio, quando a edição de scripts R no Linux só era possível de duas formas: copiando código de um editor qualquer e colando no terminal ou usando o módulo ESS (Emacs Speaks Statistics) para o Emacs. Claro que existiam opções intermediárias, como os plugins do R para o Vim e para o Gedit, por exemplo, mas nenhuma se compara aos recursos do Emacs+ESS. A preferência pelo Emacs vai além dos recursos qye ele dispõe apenas para a linguagem R. O Emacs pode ser utilizado para editar diversas outras linguagens, como LaTeX, Markdown, HTML, CSS, Shell, C, C++, JSON, etc.

Dito isso, naturalmente fomos em busca da solução para usar o Python de uma forma similar ao ESS no Emacs. O Emacs já possui um “modo” Python por padrão, ou seja, ao abrir um script .py já existem as ferramentas mais comuns de um editor (syntax highlighting, identação automática, etc). No entanto, pode-se ganhar muito mais funcionalidades ao se instalar e habilitar um modo mais elaborado para Python. De acordo com a Emacs Wiki, existem três grandes modos do Python para o Emacs:

Entre estes modos, o que mais chamou nossa atenção foi o Elpy, por ser o mais próximo (em utilização) ao ESS que já estamos acostumados. Por isso, vamos mostrar como instalar e habilitar o Elpy no Emacs padrão e também no Spacemacs. O Spacemacs nada mais é do que um Emacs que já vem com uma série de pacotes pré-instalados e habilitados, mas possui um sistema de instalação de pacotes um pouco diferente, baseado em layers.

Instalando Elpy no Emacs

De acordo com a documentação do Elpy, para instalar no Emacs padrão, antes é necessário instalar os seguintes pacotes para o Python (aqui utilizando o pip como instalador):

A instalação do Elpy deve ser feita através do MELPA (que é o procedimento padrão para se instalar qualquer pacote no Emacs). Para habilitar o MELPA (se ainda não estiver habilitado) veja esse link. Feito isso, digite:

para abrir a lista de pacotes disponíveis do MELPA. Procure pelo Elpy com

e aperte Enter para instalar automaticamente. Feito isso, abra seu ~/.emacs e insira essas linhas para habilitar o pacote:

Reinicie o Emacs e abra um arquivo .py. O modo Elpy já deverá estar habilitado (veremos alguns comandos básicos logo abaixo).

Um detalhe importante (mas não estritamente necessário) é que você pode alterar a versão do Python que será utilizada quando você abrir o terminal do Python no Emacs. Por exemplo, esse comando:

indica que o python3 deverá ser utilizado em todas as sessões. Da mesma forma, esse caminho pode ser alterado para outras versões do Python, como o Python 2 ou a versão do Python disponibilizada pelo Anaconda.

Um exemplo dessa configuração (e algumas coisas a mais) pode ser visto no arquivo ~/.emacs do Walmes no Github.

Instalando Elpy no Spacemacs

O Spacemacs possui uma forma diferente de instalar pacotes, que funciona com a habilitação de layers no arquivo ~/.spacemacs. Uma layer nada mais é do que uma coleção de pacotes úteis para determinada tarefa. Na verdade o processo de instalação é o mesmo, baixando e instalando pacotes através do MELPA, mas ao habilitar uma layer e reiniciar o Emacs, a instalação dos pacotes já é feita automaticamente.

A layer “oficial” do Python para o Spacemacs é a python. No entanto, essa layer instala o anaconda-mode, que não é o que estamos procurando. O Elpy não possui uma layer “oficial” para o Spacemacs, pois possuir duas layers para o mesmo propósito poderia causar uma série de conflitos, e a escolha dos desenvolvedores do Spacemacs foi pelo anaconda-mode.

No entanto, é possível instalar o Elpy no Spacemacs utilizando uma layer alternativa, disponibilizada nesse repositório. Basta baixar o diretório elpy e copiá-lo para ~/.emacs.d/private/. Depois disso, habilite a layer elpy no seu ~/.spacemacs (na seção dotspacemacs/layers ()). Ao reiniciar o Emacs, o Elpy será instalado e já estará habilitado para arquivos .py.

A versão do Python que será executada no terminal também pode ser alterada da mesma forma como mencionado acima para o Emacs. Basta incluir o comando acima na seção dotspacemacs/user-config () do seu ~/.spacemacs.

Como um exemplo de configuração, veja o meu arquivo ~/.spacemacs no Github.

Usando Elpy no Emacs/Spacemacs

Para usar o Elpy basta abrir ou criar um arquivo com a extensão .py. Depois abra um terminal Python com C-c C-p. Esse terminal estará rodando a versão padrão do Python do seu sistema ou aquela que você configurou se modificou a versão como mencionado acima.

Ao digitar comandos do Python, basta apertar a tecla Tab para autocompletar ou para abrir uma lista de possíveis conplementações para o que está digitando.

Para enviar o código de uma linha para o console aperte C-RET. P

Alguns comandos úteis para enviar comandos do script para o console:

  • C-RET para enviar a linha atual
  • C-c C-c para enviar linhas selecionadas ou todo o script se não houverem linhas selecionadas
  • C-c C-d para abrir a página de ajuda de uma função especificada

Muitos outros comandos existem para diversas finalidades, e eles podem ser consultados na página de documentação do Elpy. Uma seção interessante é a Evaluating code fragments que mostra vários comandos para interação do código com o console Python. A maioria dos comandos é prefixada por C-c C-y. Por exemplo, C-c C-y e envia a linha atual (e tem o mesmo efeito que C-RET).

Nos próximos posts, serão mostrados como fazer para rodar o Jupyter notebook dentro do Emacs (e utilizar todos os benefícios disso), e como usar o Rmarkdown com blocos de código em Python (e misturando códigos Python e R no mesmo arquivo).

Share

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">