Showing posts with label programação. Show all posts
Showing posts with label programação. Show all posts

23 January 2009

Emacs

Já faz um tempo que eu estou ciente da guerra sagrada dos editores de texto. Como o primeiro deles que eu vi sendo usado foi o vi (trocadilho não intencional) foi ele o primeiro a ganhar minha atenção também. No entanto nunca me motivei o suficiente para me adaptar à interface. Como minha história de programador foi marcada por editores bem normais (para os padrões de hoje) eu acabava sempre caindo para uma alternativa simples e confortável quando eu realmente tinha que fazer algo sério, ou então para um ambiente especializado caso precisasse trabalhar com uma linguagem específica.

No entanto, eu sempre me senti atraído pelas lendas de poder infinito prometido àqueles que dominam um desses editores lendários. Um pouco frustrado pela falta de flexibilidade da minha opção atual, resolvi voltar a investir no aprendizado de uma dessas ferramentas. Baixei e instalei os dois, mas apesar da minha maior simpatia com o Vim, resolvi que deveria experimentar o GNU Emacs dessa vez.

Bom, os comentários sarcásticos sobre o Emacs dizendo que ele é “um grande sistema operacional, faltando apenas um editor decente” estão perto de ser verdade: o Emacs é um sistema bem complexo. Ele vem com diversos modos de edição diferente que são divididos em dois tipos: major-modes e minor-modes. Os major-modes governam o comportamento geral do editor para um determinado buffer (o que você chamaria de "arquivo" em um editor comum, mas que não necessariamente está associado a um arquivo no disco), enquanto os minor-modes adicionam comandos e comportamentos que podem complementar um major-mode. Para um determinado buffer apenas um major-mode pode estar ativo, mas minor-modes podem ser vários. Um exemplo: o major-mode Text serve para editar arquivos de texto normais e o minor-mode Autofill pode ser usado para que as linhas sejam quebradas automaticamente para formar parágrafos uniformes. Existem também major-modes para linguagens de programação e marcação como o c-mode, o python-mode e o html-mode. Além de comandos adicionais, aparecem menus para executar alguns dos comandos mais comuns.

Bom, até agora parece que tudo isso é só uma nomenclatura rebuscada pra coisas comuns que todos os editores tem, mas a diferença é o grau de customização que é possível no emacs. Cada um desses modos são implementados como programas em um dialeto específico de Lisp chamado Emacs Lisp ou ELisp. O que acontece é que cada tecla (ou combinação de teclas) pressionada pode estar associada com uma função ELisp, inclusive as teclas alfanuméricas, o que quer dizer que quando você digita a letra A no seu teclado, existe uma função Lisp que insere o caractere A na posição atual do cursor. Porém, não precisa ser assim! Nada impede você de associar qualquer tecla ou combinação com qualquer outro comando fazendo seu próprio programa Lisp. E é graças a essa flexibilidade que o Emacs vem com uma míriade de modos que não tem nada a ver com editar texto, por exemplo, um psicoterapeuta virtual, um jogo de tetris, um navegador de arquivos, leitor de notícias online e MUITOS outros, tanto já incluídos no GNU Emacs como disponíveis na internet. Fora minor-modes adicionais que acrescentam ferramentas muito legais como essa aqui:



Vale também mencionar que um dos major-modes chamado org-mode tem uma palestra de mais de 40 minutos do Google Tech Talks para explicar o seu funcionamento.

Apesar de todas essas maravilhas, existem razões pelas quais é difícil começar a usar o Emacs.
  • A pletora de funcionalidade pode ser um tanto desgastante. São tantos comandos e opções que é enlouquecedor no início.
  • Os atalhos de teclado costumam envolver malabarismos não tão comuns em outros editores. Existem atalhos como Ctrl+x, b significando que você precisa primeiro apertar Ctrl+x e depois apertar b, até porque Ctrl+x, Ctrl+b é outro atalho que ativa outro comando.
  • O programa foi criado bem antes de algumas convenções que muitos de nós estamos acostumados (Ctrl+C, Ctrl+V, Ctrl+Z, alguém?). Para se ter uma idéia, o comando padrão de desfazer é Ctrl+_ e como o caractere é um underscore, isso significa que você precisa apertar Shift junto em um teclado QWERTY convencional. Felizmente isso tem uma solução simples: existe o modo CUA que é fácil de ativar e que faz com que muitas coisas passem a funcionar do jeito que é convencional nos editores atuais.
  • O programa é um tanto feio para padrões estéticos atuais e tem cara de antigo.
  • Customizar o comportamento do programa significa editar um arquivo Lisp ou usar uma interface um tanto poluída chamada Custom (que, adivinhem, é implementada em Lisp dentro do próprio Emacs)
Apesar dessas desvantagens eu estou gostando de aprender a usá-lo. Já fiz minhas primeiras funções em Lisp para adicionar uns comandos que eu sentia falta de outros editores e foi bem fácil. A impressão que eu tenho é que é um tipo de ferramenta que tem uma interface nem um pouco convencional, mas que compensa aprender. É mais ou menos a impressão que eu tenho do Blender também.

Meu principal objetivo é usá-lo como a IDE perfeita para Python e ele tem umas features bastante impressionantes para isso:



O Rope é usado para uma parte da funcionalidade mostrada nesse vídeo. É uma biblioteca com recursos de refatoração e funções de introspecção úteis para IDE's. No Emacs ele é usado através do Ropemacs.

Uma dica para quem estiver iniciando: aprenda os comandos por nome. Todo comando tem um nome que está relacionado com a função que ele desempenha. Aperte Esc e depois x (ou segure a tecla Meta - Alt normalmente - e pressione x) que você irá para o minibuffer e poderá executar um comando digitando seu nome. Além disso, você não precisa saber todo o nome do comando, basta apertar tab para mostrar uma lista de opções de autocompletar. Se o comando que você executar tiver um atalho de teclado, uma mensagem aparecerá no minibuffer dizendo qual é o atalho, logo após a execução. Assim você pode ir memorizando os atalhos dos comandos que você usa com mais frequência, enquanto os comandos novos que você aprender dá pra memorizar pelo nome que é muito mais fácil.

20 November 2008

FazerJogos.org

Eu e o Andrews Medina, um amigo que conheci através da lista do Python, acabamos de iniciar um blog: o Fazer Jogos. A idéia do blog é compartilhar tutoriais baseados em nossas experiências como entusiastas de programação de jogos e também notícias relevantes ao assunto.

Como somos pessoas do Python vai haver um certo viés a favor da linguagem, mas não necessariamente todos os posts envolverão Python. O importante é que tudo tenha a ver com fazer jogos.

14 October 2008

Uma dura verdade

Writer's Block: acontece na programação também.

05 June 2008

Python: pseudo-código executável

Depois de várias noites mal dormidas tentando fazer funcionar minha função de rasterizar triângulos, finalmente consegui! O jeito que eu encontrei foi escrever ela em Python, debugar até funcionar e só depois traduzir ela pra C++.

Mais uma vez Python me serviu como pseudo-código executável e testável. É a única linguagem em que eu consigo pensar e escrever código quase diretamente.

29 May 2008

Minha Primeira Experiência como Professor

Hoje pela manhã, junto com o Leonardo Santagada, ministrei a aula do Minicurso Python na Semana Acadêmica do Instituto de Informática da UFRGS. O curso surgiu expontâneamente por demanda de alguns alunos da graduação na nossa lista de discussão. O Santagada e eu então nos propusemos a ministrar uma aula para passar adiante a nossa experiência com a linguagem Python.

A experiência foi muito legal pra mim e me diverti bastante dando essa aula. O interessante foi ver 2 professores acadêmicos que me deram aula na universidade - e inclusive estão me dando aula nesse semestre também - inscritos como alunos do curso. Acho que isso serve como exemplo de que a troca de conhecimento é algo independente de hierarquia ou posição acadêmica. Todos nós temos conhecimento para compartilhar e é legal se dispor a fazer isso.

O material usado no curso está publicado no Google Documents aqui e pode ser conferido abaixo também:



Obrigado a todos que assistiram!

16 February 2008

Ânimo para Modelar

A descoberta do Google SketchUp me deu um ânimo muito maior para começar a criação de novos cenários para o MoonBunny.

Para quem não sabe tínhamos um plano para suportar um cenário por nível (sim, no momento o cenário dos níveis é fixo) e enquanto implementar o suporte para os cenários diversos é muito fácil, modelar os cenários não era uma tarefa muito grata. As horas que eu perdi fazendo um simples mapeamento de textura em casinhas que eram praticamente cubos com pontas dão uma sensação de tempo perdido. As ferramentas fantásticas para mapear texturas do SketchUp fazem tudo ficar muito mais fácil!

Aguardem em breve o suporte para cenários diferentes no MoonBunny!

23 January 2008

gtk.EntryCompletion

Esse é um tutorial que exige algum conhecimento de programação, da linguagem Python e do módulo PyGTK. Programadores experientes em outras linguagens provavelmente conseguirão entender e adaptar às suas necessidades. Caso queira aprender, existem tutoriais introdutórios de Python e PyGTK.

Para quem programa interfaces em PyGTK (ou GTK+ em outra linguagem, eu uso Python) aí vai uma dica de usabilidade:

Caso você tenha um campo de texto no seu programa, considere se não existe uma lista de valores comuns de preenchimento e dê uma ajudinha ao usuário a lembrar desses valores usando um gtk.EntryCompletion. Usá-lo é muito simples:
# Aqui eu pego uma gtk.Entry. Nesse caso peguei ela do
# meu xml que eu criei no glade

entry = xml.get_widget('entry_verbo')

# Depois crio os dois objetos necessários: um gtk.EntryCompletion,
# que vai desenhar a lista de sugestões e um gtk.ListStore que
# vai armazenar os valores.

completion = gtk.EntryCompletion()
list_store = gtk.ListStore(gobject.TYPE_STRING)

# Inserir uns valores. Note que são tuplas de um elemento só
# (por isso a vírgula sem nada depois). As tuplas inseridas
# seguem o modelo inicializado no construtor do ListStore.
# Nesse caso eu usei apenas um gobject.TYPE_STRING para dizer
# que minha lista guarda apenas uma string por registro

list_store.append(('aqui',))
list_store.append(('botamos',))
list_store.append(('umas',))
list_store.append(('palavras',))
list_store.append(('para',))
list_store.append(('testar',))

# Aqui eu associo a list_store ao meu completion criado anteriormente

completion.set_model(list_store)
completion.set_match_func(match_func)

# O método abaixo escolhe qual coluna do modelo vai conter o texto a
# ser mostrado no completion. Como só tem uma coluna no gtk.ListStore,
# vai ser essa que vamos usar.

completion.set_text_column(0)

entry.set_completion(completion)
Bom, a única coisa que falta no código acima é definir match_func que é uma função para buscar os valores de acordo com o que é digitado no gtk.Entry. Ela deve ser uma função com a seguinte assinatura
def match_func(completion, key_string, iter, func_data):
onde completion é o próprio objeto gtk.EntryCompletion usado pela função, key_string é a palavra que está no entry no momento da verificação, iter é um gtk.TreeIter que aponta para um item da lista de dados da gtk.EntryCompletion (uma gtk.ListStore, no caso do exemplo acima) e func_data é um argumento adicional que pode ser passado no método set_match_func do gtk.EntryCompletion.

Essa função será executada para cada item do gtk.ListStore e deve retornar True caso o item deva ser mostrado como opção de sugestão e False caso não deva. Na documentação da PyGTK a seguinte função está disponível como exemplo:
# Assumes that the func_data is set to the number of the text column in the
# model.

def match_func(completion, key, iter, column):
model = completion.get_model()
text = model.get_value(iter, column)
if text.startswith(key):
return True
return False
Ela cobre um dos usos mais comuns de um completion, que é mostrar as palavras na lista cujo início seja igual à palavra digitada. Um exemplo é mostrado na imagem abaixo: