Porão do Juca

Emacs é o editor mais legal¶

Eu uso emacs desde o terceiro dia do meu primeiro emprego. Sempre pensei em escrever algo sobre aqui, mas aí sempe ficava naquelas: «Põ, é só um editor de texto, besteira escrever sobre isso». Mas esses dias no trampo fiz um esqueminha que na minha opnião é a melhor coisa do emacs: Elisp e poder fazer qualquer coisa com seu editor

É só executar uma query, caralho¶

Se sempre que vão contar a história do software livre metem uma história com impressora no meio, não tem problema nenhum minha história ser sobre só executar umas query, né?

A coisa começa com um serviço que temos lá no trampo e eu tinha feito umas apis pra consulta, o normal, tipo:

GET /api?fields=a,sum(1)&filter=b__gt=2|c=3&group=a HTTP/1.1

O problema com isso que é quando isso começa a crescer a coisa fica feia pra cacete e muito disso era feita na mão, alguém fazia uma query, mandava via curl ou postman e pegava o json da resposta. Então era muito ruim pro pessoal escrever isso. Um dia um colega me mostrou a api do salesforce que você basicamente manda um query sql na api. Aí implementei um sql parser (não sou doido de deixar umas query aberta na minha api) e começaram a uma api com um sql direto.

Isso acabou sendo bem mais prático de usar, de explicar pros outros, então a mesma coisa começou a ir pra outros serviços e em pouco tempo eu tinha uma meia dúzia de serviços com apis sql e aí acabou ficando um saco fazer as queries todas via postman ou curl.

Minha primeira solução foi fazer um cliente em python + readline que ficou melhor de usar do que a maneira que eu usava antes, mas ainda faltava coisa. Eu basicamente queria highlight syntax pro sql e pro json do retorno. O CodePrettifier faz highlight systax, mas só gera html e eu teria que mudar um monte de coisa. Trabalho demais pra uma coisa bem pouco útil.

Lá vem o Emacs¶

Nesse ponto eu me liguei: o emacs já tem o que eu quero, usemo-lo! E com isso eu precisava fazer bem menos coisa, só alterar o cliente em python que tinha feito para só aceitar uma query como parâmetro, fazer o request e cuspir o retorno (eu poderia fazer o request pra api de dentro do emacs, mas o outro já estava pronto, com o esquema de autenticação e talz, entõa assim seria mais fácil). Do lado do emacs seria só pegar uma query do buffer que eu estou usando, chamar o cliente com a query como param e pegar o retorno.

Explicando melhor o que foi a minha ideia aqui: eu escrevo as queries em um buffer em sql-mode no emacs pra poder ter o realce de sintaxe e quando eu usasse um atalho essa query seria executada, a janela dividia em duas e o retorno seria exibido ao lado do do buffer onde eu digito a query.

O código pra fazer isso ficou assim:

(defun sequela-exec ()

  (interactive)

  ;; aqui a gente pega o texto do buffer atual
  (setq sql (buffer-substring-no-properties (point-min) (point-max)))

  ;; aqui a gente pega uma linha do tipo
  ;; env: SomeWhere
  ;; onde SomeWhere é o serviço que a gente quer executar aquery
  (string-match "^env: (.*)" sql)
  (setq sequela-env (match-string 1 sql))
  (unless sequela-env
    (user-error "missing env"))

  ;; deixando só a query que vamos excutar, tirando comentários, env
  ;; e new lines.
  (setq query (replace-regexp-in-string "--.*$\\|^env:.*$\\|\n" "" sql))

  (setq buffname "sequela-idle")
  (setq proc-buffname "sequela")

  ;; aqui divide a janela em duas e vai para a janela onde será exibido
  ;; o resultado
  (pop-to-buffer buffname)
  (erase-buffer)
  (insert "sequelando...")

  (with-current-buffer (get-buffer-create proc-buffname)
    (erase-buffer))

  ;; executa o script que faz o acesso à api
  (start-process proc-buffname proc-buffname "query.py" sequela-env query)

  ;; o sentinela do processo é chamado quando o estado do processo muda
  (set-process-sentinel
   (get-process proc-buffname)
   (lambda (process event)
     (when (string= event "finished\n")
       ;; aqui quando o processo terminar a gente formata o
       ;; resultado e copia para o buffer onde é exibido o resultado
       (with-current-buffer proc-buffname
         (json-pretty-print-buffer)
         (copy-to-buffer (get-buffer-create buffname) (point-min) (point-max)))
       (pop-to-buffer buffname)
       (json-ts-mode)))))

Legal, né? Agora é só eu abrir um arquivo .sql, escrever a query que eu quiser, executar essa função e pronto! Um hackzinho vagabundo no emacs é mais fácil e fica melhor do que fazendo um programa separado!

A beleza do Common Gateway Interface Uma passada de olhos em websockets

© Copyright 2009-2025, Juca Crispim.

Feito com Sphinx usando um tema fornecido por Porão do Juca.
Porão do Juca
Início
  • Blog
  • Fotos
  • Sobre
  • 🛜 Atom feed