1. Objetivos

O objetivo desse processo é chegarmos a um ambiente para estudar e programar em Common Lisp utilizando o Emacs e sendo capaz de ler a documentação localmente, preferencialmente a partir do próprio editor, ao invés de termos de ficar fazendo buscas online.

NOTA: Neste tutorial, vamos rodar o emacs pelo terminal, sem a GUI. Se você preferir rodar pela GUI, basta não usar as opções -nw.

2. Instalando SBCL e Emacs

Vamos iniciar instalando o compilador Steel Bank Common Lisp e o Emacs.

$ sudo pacman -S sbcl emacs --needed

A opção --needed é útil pois ela evita reinstalar um pacote que já tenha sido instalado anteriormente.

3. Testando o REPL SBCL

REPL é um acrônimo para “Read, Eval, Print, Loop”, algo como, ler, processar, mostrar, e repetir tudo novamente.

Para testar o repl do sbcl, faça:

$ sbcl
(+ 1 3)
(- 4 5)

Se você conseguir ver a versão do sbcl e outras informações a seu respeito, e rodar aquelas expressões Lisp sem problemas, então, está tudo certo. Essa etapa é simples e não há muitas chances de que algo saia errado.

Digite Ctrl-D para sair.

4. Quicklisp, Slime

Para facilitar o trabalho com Lisp, podemos instalar o Quicklisp, que é um “Library Manager” para Common Lisp, e o SLIME: The Superior Lisp Interaction Mode for Emacs.

Vamos instalar o quicklisp in $HOME/bin/quicklisp/, portanto, vamos criar esse diretório e baixar o arquivo ‘quicklisp.lisp’.

mkdir --parents ~/bin/quicklisp
cd !$
wget https://beta.quicklisp.org/quicklisp.lisp

DICA: !$, no bash, significa o último argumento do último comando executado. Portanto, no exemplo, cd !$ é o mesmo que cd ~/bin/quicklisp pois ~/bin/quicklisp foi o último argumento do comando anterior (mkdir).

Iniciamos o console sbcl novamente e executamos alguns comandos para instalar o SLIME. Certifique-se de estar no diretório ~/bin/quicklisp antes de executar os próximos passos.

Carregar o quickslisp.lisp para o repl sbcl.

sbcl
(load "quicklisp.lisp")

Instalar bibliotecas básicas em ~/bin/quicklisp.

(quicklisp-quickstart:install :path "/home/seuuser/bin/quicklisp/")

Adicionar algumas configurações em ~/.sbclrc.

(ql:add-to-init-file)

Instalar o slime. Essa é a parte que faz a integração com o Emacs.

(ql:quickload "quicklisp-slime-helper")

Este último comando nos avisa para colocar algumas linhas de configuração no arquivo ~/.emacs. No meu caso foi:

To use, add this to your ~/.emacs:

  (load (expand-file-name "~/bin/quicklisp/slime-helper.el"))
  ;; Replace "sbcl" with the path to your implementation
  (setq inferior-lisp-program "sbcl")

("quicklisp-slime-helper")

5. Executando o SLIME pela primeira vez!

Que emoção!

Abra o Emacs e digite M-x slime RET. No Emacs, RET é “Enter”, C é “CTRL”, e M é “Alt”. Então, C-b é “CTRL+b”, e M-x é “Alt+x”.

SLIME funcionando

6. Commandos Úteis

Vejamos agora alguns exemplos de situações comuns quando estamos dando os primeiros passos.

1 — Fechar o slime.

Com o prompt sem nenhum comando pendente (esperando por um "RET"), pressione ‘vírgula’ e então digite sayoonara ou quit, seguido de RET.

2 — Executar um arquivo .lisp.

`(load "/path/to/programa.lisp")

3 — Executar o código lisp a partir do arquivo em vez de executar interativamente pelo REPL no SLIME.

C-x C-f ~/Projs/cl/prog1.lisp. Digite o código, salve com C-x C-s e então C-c C-k para compilar e rodar o programa. É importante notar que se você estiver visualizando apenas buffer com o arquivo .lisp, será necessário mudar para o buffer slime repl scbl. Para isso, faça C-x b TAB e digite parte do nome, seguido de TAB novamente.

4 — Manter o Emacs com uma window para o programa lisp, e outra para o slime repl, de modo que ao compilar e executar o programa, já possamos ver o resultado imediatamente, sem necessitar ficar mudando de buffers.

Nesse caso, um entendimento de como gerenciar buffers e windows se faz necessário, mas basicamente:

  • C-x 1 → fecha outras windows, mantendo apenas a window do buffer atual.

  • C-x 2 → abre uma window nova com o mesmo buffer.

  • C-x o → muda o foco para a outra (other) window.

Se estiver com mais de uma window, certifique-se de ficar com apenas uma, pressionando C-x 1. Em seguida, pressione C-x 2. Usando C-x o, foque na window superior abra um arquivo lisp (ou crie um) com C-x C-f ~/Projs/cl/prog1.lisp.

C-x o novamente para alternar o foco para a window inferior. Agora pressione C-x b slime-repl TAB para visualizar o repl.

Finalmente, volte para a window superior e pressione C-c C-k. Isso compila e executa o código do arquivo, e mostra o resultado na window inferior.

5 — Fechar tudo.

Mude para o buffer to slime repl sbcl, digite , quit. Feche o emacs com C-x C-c. Talvez ele fale algo sobre arquivos não salvos. Você decide se salva ou não.

7. Documentação Local

Abra o Emacs e execute o SLIME novamente.

emacs -nw
M-x slime RET

Vamos instalar uma cópia local do CLHS (Common Lisp HyperSpec)

Execute a seguinte expressão lisp:

(ql:quickload "clhs")
CL-USER> (ql:quickload "clhs")
To load "clhs":
  Install 1 Quicklisp release:
    clhs
; Fetching #<URL "http://beta.quicklisp.org/archive/clhs/2015-04-07/clhs-0.6.3.tgz">
; 2186.27KB

2,238,743 bytes in 2.06 seconds (1060.78KB/sec)
; Loading "clhs"
[package clhs]...

clhs-use-local.el doesn't seem to have been installed.
(Assuming "/home/poster/bin/quicklisp/" is the correct quicklisp directory location.)

Please run (clhs:print-emacs-setup-form) for details
on how to setup Emacs/Slime to perform lookups/browsing
with your local copy of the CLHS provided by this wrapper.

(That command will also tell you how to set
another quicklisp directory location, if necessary.)


("clhs")
CL-USER>

Basicamente, é só seguir as instruções, mas em todo caso, aqui vai um passo a passo.

CL-USER> (clhs:print-emacs-setup-form)

[ Quicklisp directory: "/home/poster/bin/quicklisp/" (exists)
  If the above location is not correct, do:
  (setf clhs:*quicklisp-directory* "/path/to/quicklisp/") ]

clhs-use-local.el was not found in your quicklisp directory.
This means you're at step 1 of 2 for configuring Emacs/Slime
to perform lookups/browsing with your local copy of the CLHS.

Please run (clhs:install-clhs-use-local) in the (Common Lisp) REPL.
This will install clhs-use-local.el in your quicklisp directory.

Then, run (clhs:print-emacs-setup-form) again for instructions for step 2.

; No value
CL-USER>

Okay, vamos lá.

CL-USER> (clhs:install-clhs-use-local)
T
CL-USER>

T é o retorno da operação (True). Podemos prosseguir, rodando novamente a expressão (clhs:print-emacs-setup-form).

CL-USER> (clhs:print-emacs-setup-form)

[ Quicklisp directory: "/home/poster/bin/quicklisp/" (exists)
  If the above location is not correct, do:
  (setf clhs:*quicklisp-directory* "/path/to/quicklisp/") ]

(clhs-use-local.el was found in your quicklisp directory.
Moreover, its version matches the one bundled with this CLHS ASDF wrapper.
You may proceed with step 2 of 2 below.)


Make Emacs evaluate this form to browse the CLHS locally:

(load "/home/poster/bin/quicklisp/clhs-use-local.el" t)


Use C-c C-d h make-instance RET to test if the change was successful.
If it was, then this will open your browser and the URL will begin with "file:///".

Put the form in your ~/.emacs to persist the change for future sessions.


The README file has some further information,
including a list of 3 useful Slime CLHS lookup commands
and how to get Emacs to open CLHS pages in a different browser.
(Location: /home/poster/bin/quicklisp/dists/quicklisp/software/clhs-0.6.3/README)

; No value
CL-USER>

Note bem o que diz:

Make Emacs evaluate this form to browse the CLHS locally:

(load "/home/poster/bin/quicklisp/clhs-use-local.el" t)

Para tal, pressione M-x seguido de eval-expression.

M-x eval-expression RET
(load "/home/poster/bin/quicklisp/clhs-use-local.el" t) RET

Nesse ponto, é possível digitar C-c C-d h (rapidinho, senão não funciona) seguido de alguma função, como make-instance e o Emacs deverá abrir o navegador, usando o protocolo file:// para mostrar a documentação local.

Se funcionou, basta colocar a mesma linha em ~/.emacs para persistir as alterações.

8. Documentação Dentro do Emacs

A partir do Emacs 24, temos o navegador eww, escrito em elisp. Podemos utilizá-lo para ler a documentação sem ter que ficar mudando de programa. Isso não é melhor nem pior. Depende do gosto de cada um.

Do Emacs,

M-x
customize-variable RET
browse-url-browser-function RET

Navegue até Value Menu e pressione RET. Vai aparecer uma lista de opções. Aqui, o browser eww estava na opção 2. Agora, basta salvar com C-x C-s.

Abra o arquivo ~/.emacs novamente, e certifique-se de que ele possui as seguintes linhas.

(load "/home/fernando/bin/quicklisp/clhs-use-local.el" t)
(require 'eww)

A linha com (load …​) já havia sido adicionada anteriormente. Apenas adicione (require 'eww).

Para testar, execute C-c C-d h list RET. Se tudo deu certo, basta navegar até a entrada desejada, como "Function" e pressionar RET para ler as docs.

Veja um exemplo:

eww clhs docs

9. Set Midori as the browser

M-x customize-variable RET browser-url-browser-function — click in 'value' — specified by 'browse url generic program'

salve e feche o emacs, então adicione isso ao ~/.emacs:

(setq browse-url-browser-function 'browse-url-generic
      browse-url-generic-program "midori")

C-c C-d h cons RET deve abrir as docs da função cons no midori, a partir de uma cópia local das docs.