Introdução

O Emacs é um IDE (Integrated Development Environment), na verdade ele foi o primeiro a existir. Datando de 1976 como um simples editor de macros (Editor MACroS) criado por Richard Stallman, foi convertido em um poderoso editor em 1984 que vinha a ser o primeiro ambiente de desenvolvimento integrado, o qual auxiliava o programador a fazer tarefas relacionadas ao desenvolvimento, como compilar, depurar, testar e outras coisas inerentes ao processo de desenvolvimento.

Emacs pode ser extendido usando a linguagem LISP ou seu próprio dialeto E-Lisp (Emacs Lisp). Hoje existem diversas extensões para o Emacs, sendo possível fazer quase tudo dentro dele. Ler email, conversar no IRC, ver páginas Web e até um servidor HTTP são módulos implementados para este IDE. Pessoas como alguns professores do IC e mesmo o Richard Stallman são conhecidas por usar seu computador totalmente via o Emacs.

A Interface

A interface padrão do Emacs conta com 3 componentes principais:

Mais componentes podem ser adicionados, seja por meio de divisão de janelas ou por módulos extras os quais podem adicionar funcionalidade. Também podem existir barras de rolagem e menu, os quais podem ser desabilitados posteriormente.

Teclas de Atalho do Emacs

Neste texto usaremos a notação do Emacs para teclas de atalho, na qual C-c diz que devemos manter pressionada a tecla Control enquanto pressionamos a tecla c. Já M-c diz que devemos manter pressionada a tecla Meta (a qual é traduzida para Alt nos PCs) enquanto pressionamos a tecla c. Note que o Emacs é famoso por usar teclas de atalho encadeadas, isto é descrito como C-c M-x significa que devemos pressionar Control enquanto pressionamos c, soltamos todas as teclas e então pressionamos Meta enquanto pressionamos x.

Além de ser acessível via teclas de atalho e menus, o Emacs ainda entende comandos os quais devem ser digitados no mini-buffer que ficará ativo após a combinação M-x.

Para cada atalho descrito, segue o comando que este executa.

O Emacs possui algumas teclas de atalho globais, as mais úteis são:

Geral

C-x C-c
save-buffers-kill-emacs Sai do emacs e pergunta se quer salvar os arquivos.
M-x
execute-extended-command Executa comando que será digitado no mini-buffer.
C-g
Aborta o comando que está ocupando o mini-buffer.
C-_
undo Desfaz ação.
C-k
kill-line Apaga a linha da posição atual para frente. Este comando não apaga o símbolo de nova linha quando esta contém texto. Se você deseja apagar este símbolo, repita a combinação. Este comando também copia a linha para o buffer temporário, podendo ser colada depois. Este atalho também funciona em terminais shell e outros!
C-SPACE
set-mark-command Inicia seleção de região. A região se extende até a posição atual do cursor. C-@ é um atalho alternativo.
M-h
mark-paragraph Seleciona parágrafo.
C-x h
mark-whole-buffer Seleciona todo o buffer.
C-M-\
indent-region Indenta a região.
C-w
kill-region Apaga a região selecionada (vide C-SPACE). O conteúdo apagado vai para o buffer temporário, podendo ser colado depois.
M-w
copy-region-as-kill Copia o conteúdo para o buffer temporário, podendo ser colado depois.
C-y
yank Cola região que está no buffer temporário. Vem do inglês jogar.
C-a
beginning-of-line Vai para o começo da linha. Alguns terminais antigos não possuem o botão HOME. Este atalho também funciona em terminais shell e outros!
C-e
end-of-line Vai para o fim da linha. Alguns terminais antigos não possuem o botão END. Este atalho também funciona em terminais shell e outros!
C-b
backward-char Volta um caractere. Alguns terminais antigos não possuem o botão SETA PARA TRÁS. Este atalho também funciona em terminais shell e outros!
C-f
forward-char Avança um caractere. Alguns terminais antigos não possuem o botão SETA PARA FRENTE. Este atalho também funciona em terminais shell e outros!
M-b
backward-word Volta uma palavra. Este atalho também funciona em terminais shell e outros!
M-f
forward-word Avança uma palavra. Este atalho também funciona em terminais shell e outros!
M-<
beginning-of-buffer Vai para o começo do arquivo.
M->
end-of-buffer Vai para o fim do arquivo.
C-n
next-line Vai para a próxima linha. Alguns terminais antigos não possuem o botão SETA PARA BAIXO. Este atalho também funciona em terminais shell e outros!
C-p
previous-line Vai para a linha anterior. Alguns terminais antigos não possuem o botão SETA PARA CIMA. Este atalho também funciona em terminais shell e outros!
C-l
recenter Centraliza verticalmente o buffer na linha atual.
C-t
transpose-chars Troca caractere atual com o anterior.
C-u
universal-argument Seguido de um número e depois de uma ação, ele executa tal ação o dado número de vez.
C-z
suspend-emacs Suspende o emacs para o fundo (se no terminal, use fg para voltar) ou senão minimiza se estiver em ambiente gráfico.
M-!
shell-command Executa comando shell.
M-$
spell-word Confere se a palavra é válida no dicionário escolhido. Vide comando ispell-change-dictionary.
F10
tmm-menubar Mostra o menu no mini-buffer.
F10
eval-expression Avalia (executa) comando lisp.
C-x (
start-kbd-macro Inicia gravação de um macro de teclado.
C-x )
end-kbd-macro Termina gravação de um macro de teclado.
C-x e
call-last-kbd-macro Executa último macro de teclado.

Arquivos

C-x C-f
find-file Procura e abre um arquivo.
C-x C-s
save-buffer Salva o arquivo.
C-x C-w
write-file Salva buffer para novo arquivo. "Salvar como".
C-x C-q
toggle-read-only Muda o estado do buffer para somente leitura.

Diretórios

C-x C-d
list-directory Lista conteúdo de um diretório.
C-x d
dired Entra em um diretório de forma interativa. Neste modo podemos selecionar arquivos, movê-los, apagá-los, ... Vide comando help dired.

Procuras e Substituições

C-s
isearch-forward Procura incremental para frente.
C-r
isearch-backward Procura incremental para trás.
C-M-s
isearch-forward-regexp Procura incremental para frente usando expressão regular.
M-%
replace-string Procura por um texto e substitui por outro.

Trabalhando com Buffers

C-x 0
delete-window Fecha vista do buffer atual.
C-x 1
delete-other-widnows Fecha todas as vistas de buffers exceto o atual.
C-x 2
split-window-vertically Divide a janela verticalmente em duas vistas do buffer.
C-x 3
split-window-horizontally Divide a janela horizontalmente em duas vistas do buffer.
C-x o
other-window Troca entre as vistas abertas.
C-x k
kill-buffer Fecha o buffer atual (fecha o arquivo).
C-x C-b
list-buffers Lista buffers existentes.
C-x b
switch-to-buffer Troca o buffer por outro.

Abreviações

O Emacs suporta dois tipos de abreviação: dinâmica e estática. Na abreviação dinâmica ele tenta inferir o que você quer digitar a partir do texto que você digitou. Na estática você define sequências de caracteres que serão automaticamente substituidas pelo dado texto.

Abreviações Estáticas

Vide o manual do emacs para saber como salvar suas abreviações.

C-x a g
add-global-abbrev Adiciona uma abreviação global (pode ser usada em qualquer modo). A abreviação vai se expandir para a ultima palavra digitada e o símbolo que representará a abreviação será perguntado no mini-buffer. Se desejar que a abreviação se aplique para mais palavras pode-se usar o comando de repetição C-u numero_de_palavras C-x a g.
C-x a l
add-global-abbrev Similar ao anterior, porém adiciona uma abreviação local (só pode ser usada no modo atual).

Abreviações Dinâmicas

M-/
dabbrev-expand Expande a abreviação dinâmica baseada em busca para trás por palavras que começem com o mesmo prefixo digitado.
C-M-/
dabbrev-completion Completa abreviação dinâmica.

Personalização

O Emacs pode ser personalizado configurando os valores das variáveis que ele usa internamente, valores tais devem ser salvos em um arquivo ~/.emacs.

Como saber todos os nomes e opções é difícil, o emacs provê uma interface a qual pode ser acessada com os comandos:

Modos de Edição

O Emacs provê vários modos de edição, algum deles são modos principais, voltados à programação de C ou Python, outros são genéricos, também conhecidos como minor modes e pode ser utilizados junto com os principais, como o caso do Auto-Fill, que quebra linhas de texto.

Python

Ao ler um arquivo Python (arquivos terminados em .py) ou qualquer outro nome a definir com a variável lisp auto-mode-alist o modo de edição especialmente preparado para Python. Neste modo, além do destaque de sintaxe, ele provê funcionalidades extras, tais como:

Teclas de Atalho

C-c TAB
py-indent-region Indenta a região de acordo com o contexto. Útil para os casos em que tinha-se um código e deseja-se colocá-lo dentro de um bloco (while, if, for, ...) sem que ele perca a coerência. O comando C-M-\ indent-region funciona de modo equivalente, sendo uma tecla de atalho constante em todas as linguagens.
C-c #
py-comment-region Comenta região selecionada.
C-c C-c
py-execute-buffer Executa o buffer atual.
C-M-x
py-execute-def-or-class Executa função ou classe.
C-c |
py-execute-region Executa região selecionada.
C-c !
py-shell Inicia interpretador.
C-c C-s
py-execute-string Executa string.
C-M-a
py-beginning-of-def-or-class Vai para começo da função ou classe.
C-M-e
py-end-of-def-or-class Vai para o fim da função o classe.
C-M-h
py-mark-def-or-class Seleciona a função ou da classe.
C-c C-u
py-goto-block-up Vai para o início do bloco.
C-c <
py-shift-region-left Desloca a região de 1 tabulação a esquerda.
C-c >
py-shift-region-right Desloca a região de 1 tabulação a direita.
C-c ?
py-describe-mode Ajuda sobre como o modo funciona.

Emacs Code Browser

ECB http://ecb.sourceforge.net é um projeto que implementa melhores funcionalidades para navegação no código fonte pelo Emacs. Ele adiciona três componentes à janela, sendo eles um navegador de arquivos, um navegador de classes e funções e um histórico de arquivos abertos. Isso facilita o acesso a várias partes do projeto.

O modo ECB define varias teclas de atalho, dentre elas:

C-c . g l
ecb-goto-window-edit-last vai para o último buffer de edição arquivo.
C-c . g m
ecb-goto-window-methods vai para a janela de métodos.
C-c . g s
ecb-goto-window-source vai para a janela de arquivos fonte.
C-c . g d
ecb-goto-window-directories vai para a janela de diretórios.
C-c . g h
ecb-goto-window-history vai para a janela de histórico.

Epílogo

Se você decorou todas os atalhos que foram mencionados aqui, você usará o Emacs de maneira muito mais rápida ou ao menos poderá impressionar sua mãe...Meu filho mexe no computador que eu nem consigo ver! ou senão pode virar pianista, pois como dizem O Emacs não tem teclas de atalho, tem acordes e entenda isto como uma partitura ;)

Apêndice

Meu ~/.emacs


;; Custom Variables
(custom-set-variables
 '(add-log-current-defun-function nil)
 '(add-log-mailing-address "my@emai.com" t)
 '(auto-compression-mode t nil (jka-compr))
 '(browse-url-generic-program "w3m")
 '(calculator-remove-zeros (quote leave-decimal))
 '(case-fold-search t)
 '(column-number-mode t)
 '(ecb-layout-window-sizes (quote (("left8" (0.2753623188405797
					     . 0.16666666666666666)
				    (0.2753623188405797
				     . 0.16666666666666666)
				    (0.2753623188405797 . 0.5)
				    (0.2753623188405797
				     . 0.14814814814814814)))))
 '(ecb-options-version "2.21")
 '(ecb-source-path (quote ("/home/gustavo/Development/svn/pytvgrab"
			   "/home/gustavo/Development/cvs/freevo"
			   "/home/gustavo/Development/cvs/kde"
			   "/home/gustavo/Development/cvs/libvisual"
			   "/home/gustavo/Development/cvs/libvisual-plugins" "/home/gustavo")))

 '(ecb-tag-display-function (quote ((default
				      . ecb-format-tag-uml-prototype))))

 '(global-font-lock-mode t nil (font-lock))
 '(ispell-dictionary-alist
   (quote
    (
     (nil "[A-Za-z]" "[^A-Za-z]" "[']"
	  nil ("-B") nil iso-8859-1)
     ("american" "[A-Za-z]" "[^A-Za-z]"
      "[']" nil ("-B") nil iso-8859-1)
     ("brasileiro"
      "[A-ZÁÉÍÓÚÀÈÌÒÙÃÕÇÜÂÊÔa-záéíóúàèìòùãõçüâêô]"
      "[^A-ZÁÉÍÓÚÀÈÌÒÙÃÕÇÜÂÊÔa-záéíóúàèìòùãõçüâêô]"
      "[']"
      nil
      ("-d" "pt_BR")
      nil iso-8859-1)
     ("british"
      "[A-Za-z]"
      "[^A-Za-z]"
      "[']"
      nil
      ("-B" "-d" "british")
      nil iso-8859-1)
     ("english"
      "[A-Za-z]"
      "[^A-Za-z]"
      "[']"
      nil
      ("-B") nil iso-8859-1)
     ("portugues"
      "[a-zA-ZÁÂÉÓàáâéêíóãú]"
      "[^a-zA-ZÁÂÉÓàáâéêíóãú]"
      "[']"
      t
      ("-C" "-d" "portugues")
      "~latin1" iso-8859-1)
     )
    )
   )

 '(ispell-program-name "aspell")
 '(menu-bar-mode nil)
 '(mouse-wheel-mode t nil (mwheel))
 '(save-abbrevs (quote silently))
 '(save-place t nil (saveplace))
 '(scroll-bar-mode nil)
 '(show-paren-mode t nil (paren))
 '(show-trailing-whitespace t)
 '(spell-command "aspell")
 '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify)))
 '(tool-bar-mode nil nil (tool-bar))
 '(tooltip-gud-tips-p t)
 '(transient-mark-mode t)
 '(uniquify-buffer-name-style (quote forward) nil (uniquify))
 '(which-func-modes (quote (emacs-lisp-mode c-mode c++-mode perl-mode
					    cperl-mode makefile-mode
					    sh-mode fortran-mode
					    python-mode)))

 '(which-function-mode nil nil (which-func))
 '(x-select-enable-clipboard t))



;; Colors and Fonts:
(custom-set-faces
 '(default ((t (:stipple nil :background "#000000" :foreground
			 "#d9d9d9" :inverse-video nil :box nil
			 :strike-through nil :overline nil :underline
			 nil :slant normal :weight normal :height 94
			 :width normal :family "adobe-courier"))))
 '(cursor ((t (:background "#ff00ff" :foreground "black"))))
 '(ecb-bucket-node-face ((((class color) (background dark)) (:inherit
							     ecb-default-general-face :weight bold))))
 '(ecb-default-highlight-face ((((class color) (background dark))
				(:background "#226622"))))
 '(ecb-directories-general-face ((((class color) (background dark))
				  (:inherit ecb-default-general-face
					    :foreground "#3333ff"
					    :height 1.0))))
 '(ecb-directory-face ((((class color) (background dark)) (:inherit
							   ecb-default-highlight-face :background "#222222" :foreground "#4444ff"))))
 '(ecb-tag-header-face ((((class color) (background dark))
			 (:background "#003300"))))
 '(ecb-tree-guide-line-face ((((class color) (background dark))
			      (:inherit ecb-default-general-face
					:foreground "gray35" :height
					1.0))))
 '(mode-line ((((type x w32 mac) (class color)) (:background "gray15"
							     :foreground "wheat" :box (:line-width -1 :style released-button)))))
 '(scroll-bar ((t (:background "gray75" :foreground "#000000"))))
 '(tool-bar ((((type x w32 mac) (class color)) (:background "gray75"
							    :foreground "black" :box (:line-width 1 :style released-button))))))



;; Abbreviations file
(quietly-read-abbrev-file "~/.abbrev_defs")

;; Meta-g is now goto-line
(global-set-key "\M-g" 'goto-line)

;; Shift+F3 search for manual page
(global-set-key [S-f3] 'man)


;;;;;;;;;;;;;;;;;;;;;;;;;;;; w3m ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(global-set-key [f11] 'w3m-browse-url)
(global-set-key [S-f11] 'w3m-search)
(unless (fboundp 'w3m)
  (add-site-lisp-load-path "w3m/")
  (autoload 'w3m "w3m" "Interface for w3m on Emacs." t)
  (autoload 'w3m-find-file "w3m" "w3m interface function for local file." t)
  (autoload 'w3m-browse-url "w3m" "Ask a WWW browser to show a URL." t)
  ;(autoload 'w3m-search "w3m-search" "Search QUERY using SEARCH-ENGINE." t)
  (autoload 'w3m-antenna "w3m-antenna" "Report change of WEB sites." t)
  (autoload 'w3m-bookmark-view "w3m-bookmark" "List w3m bookmarks" t))

(setq w3m-key-binding 'info)
(setq w3m-search-default-engine "google")
(setq w3m-fill-column 100)
(add-hook 'w3m-mode-hook
          '(lambda()
             (define-key w3m-mode-map [(meta ?c)] 'w3m-print-current-url)))

;;;;;;;;;;;;;;;;;;;;;;;;; Web Jump ;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'webjump)
;; Keys
(global-set-key [f12] 'webjump)
;(global-set-key [(super meta j)] 'webjump-w3)
(global-set-key [S-f12] 'webjump-w3)
;; Sites
(setq webjump-sites
      '(
        ("google" . [simple-query "www.google.com"
				  "www.google.com/search?q=" ""])
        ("Google Groups" . [simple-query "groups.google.com"
					 "groups.google.com/groups?q="
					 ""])
        ("Debian GNU/Linux" . [simple-query "www.debian.org"
					    "search.debian.org/?q="
					    ""])
        ("Python Documentation" . [simple-query "starship.python.net"
						"http://starship.python.net/crew/theller/pyhelp.cgi?keyword=" "&version=current"])
        ("Dictionary.com" . [simple-query "www.dictionary.com"
					  "www.dictionary.com/cgi-bin/dict.pl?term=" "&db=*"])
        ("latex online help"
	 . "http://www.giss.nasa.gov/latex/ltx-2.html")
        ("latex online index"
	 . "http://www.weinelt.de/latex/index.html")
))
;; Browser
(if (eq window-system 'x)
    ;;; Browser for X mode:
    ;; Netscape
    ;(setq browse-url-browser-function 'browse-url-netscape
    ;browse-url-new-window-p t)

    ;; KDE
    (setq browse-url-browser-function 'browse-url-kde)
  (setq browse-url-browser-function 'w3m-browse-url)
  )

;; New XML
(add-to-list 'auto-mode-alist
	     (cons (concat "\\." (regexp-opt '("xml" "xsd" "sch" "rng"
					       "xslt" "svg" "rss") t)
			   "\\'")
		   'nxml-mode))
;;(add-hook 'hack-local-variables-hook
;; 	  (lambda ()
;; 	    (save-excursion
;; 	      (when (search-forward-regexp "^<\\?xml" 6 0)
;; 		(nxml-mode)
;; 		))))

;; Default mode is latex, not tex:
(setq tex-default-mode 'latex-mode)
    

Gustavo Sverzut Barbieri barbieri gmail.com