summaryrefslogtreecommitdiffhomepage
path: root/pt-br/elisp-pt.html.markdown
blob: 8378003ebe9eecd8f06adca1aa31c452fee4e63e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
---
language: elisp
contributors:
    - ["Bastien Guerry", "http://bzg.fr"]
translators:
    - ["Lucas Tadeu Teixeira", "http://ltt.me"]
lang: pt-br
filename: learn-emacs-lisp-pt.el
---

```scheme
;; Introdução ao Emacs Lisp em 15 minutos (v0.2d)
;;
;; Autor: Bastien / @bzg2 / http://bzg.fr
;;
;; Antes de começar, leia este texto escrito Peter Norvig:
;; http://norvig.com/21-days.html
;;
;; Agora instale GNU Emacs 24.3:
;;
;; Debian: apt-get install emacs (ou veja as instruções da sua distribuição)
;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
;;
;; Informações mais gerais podem ser encontradas em:
;; http://www.gnu.org/software/emacs/#Obtaining

;; Aviso importante:
;;
;; Realizar este tutorial não danificará seu computador, a menos
;; que você fique tão irritado a ponto de jogá-lo no chão. Neste caso,
;; me abstenho de qualquer responsabilidade. Divirta-se!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Abra o Emacs.
;;
;; Aperte a tecla `q' para ocultar a mensagem de boas vindas.
;;
;; Agora olhe para a linha cinza na parte inferior da janela:
;;
;; "*scratch*" é o nome do espaço de edição em que você se encontra.
;; Este espaço de edição é chamado "buffer".
;;
;; O buffer de rascunho (i.e., "scratch") é o buffer padrão quando
;; o Emacs é aberto. Você nunca está editando arquivos: você está
;; editando buffers que você pode salvar em um arquivo.
;;
;; "Lisp interaction" refere-se a um conjunto de comandos disponíveis aqui.
;;
;; O Emacs possui um conjunto de comandos embutidos (disponíveis em
;; qualquer buffer) e vários subconjuntos de comandos disponíveis
;; quando você ativa um modo específico. Aqui nós utilizamos
;; `lisp-interaction-mode', que possui comandos para interpretar e navegar
;; em código Elisp.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Pontos e vírgulas iniciam comentários em qualquer parte de uma linha.
;;
;; Programas codificados em Elisp são compostos por expressões simbólicas
;; (conhecidas também por "sexps"):
(+ 2 2)

;; Esta expressão simbólica significa "Some 2 e 2".

;; "Sexps" são envoltas em parêntese, possivelmente aninhados:
(+ 2 (+ 1 1))

;; Uma expressão simbólica contém átomos ou outras expressões
;; simbólicas. Nos exemplos acima, 1 e 2 são átomos;
;; (+ 2 (+ 1 1)) e (+ 1 1) são expressões simbólicas.

;; No modo `lisp-interaction-mode' você pode interpretar "sexps".
;; Posicione o cursor logo após o parêntese de fechamento e,
;; então, segure apertado Ctrl e aperte a tecla j ("C-j", em resumo).

(+ 3 (+ 1 2))
;;           ^ posicione o cursor aqui
;; `C-j' => 6

;; `C-j' insere o resultado da interpretação da expressão no buffer.

;; `C-xC-e' exibe o mesmo resultado na linha inferior do Emacs,
;; chamada de "echo area".  Nós geralmente utilizaremos `C-xC-e',
;; já que não queremos poluir o buffer com texto desnecessário.

;; `setq' armazena um valor em uma variável:
(setq my-name "Bastien")
;; `C-xC-e' => "Bastien" (texto exibido no echo area)

;; `insert' insere "Hello!" na posição em que se encontra seu cursor:
(insert "Hello!")
;; `C-xC-e' => "Hello!"

;; Nós executamos `insert' com apenas um argumento ("Hello!"), mas
;; mais argumentos podem ser passados --  aqui utilizamos dois:

(insert "Hello" " world!")
;; `C-xC-e' => "Hello world!"

;; Você pode utilizar variávies no lugar de strings:
(insert "Hello, I am " my-name)
;; `C-xC-e' => "Hello, I am Bastien"

;; Você pode combinar "sexps" em funções:
(defun hello () (insert "Hello, I am " my-name))
;; `C-xC-e' => hello

;; Você pode interpretar chamadas de funções:
(hello)
;; `C-xC-e' => Hello, I am Bastien

;; Os parênteses vazios na definição da função significam que ela
;; não aceita argumentos. Mas sempre utilizar `my-name' é um tédio!
;; Vamos dizer à função para aceitar um argumento (o argumento é
;; chamado "name"):

(defun hello (name) (insert "Hello " name))
;; `C-xC-e' => hello

;; Agora vamos executar a função com a string "you" como o valor
;; para seu único parâmetro:
(hello "you")
;; `C-xC-e' => "Hello you"

;; Aí sim!

;; Respire um pouco.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Agora mude para um novo buffer chamado "*test*":

(switch-to-buffer-other-window "*test*")
;; `C-xC-e'
;; => [a tela exibirá duas janelas e o cursor estará no buffer *test*]

;; Posicione o mouse sobre a janela superior e clique com o botão
;; esquerdo para voltar. Ou você pode utilizar `C-xo' (i.e. segure
;; ctrl-x e aperte o) para voltar para a outra janela, de forma interativa.

;; Você pode combinar várias "sexps" com `progn':
(progn
  (switch-to-buffer-other-window "*test*")
  (hello "you"))
;; `C-xC-e'
;; => [A tela exibirá duas janelas e o cursor estará no buffer *test*]

;; Agora, se você não se importar, pararei de pedir que você aperte
;; `C-xC-e': faça isso para cada "sexp" que escrevermos.

;; Sempre volte para o buffer *scratch* com o mouse ou `C-xo'.

;; Frequentemente, é útil apagar o conteúdo do buffer:
(progn
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello "there"))

;; Ou voltar para a outra janela:
(progn
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello "you")
  (other-window 1))

;; Você pode armazenar um valor em uma variável local utilizando `let':
(let ((local-name "you"))
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello local-name)
  (other-window 1))

;; Neste caso, não é necessário utilizar `progn' já que `let' combina
;; várias "sexps".

;; Vamos formatar uma string:
(format "Hello %s!\n" "visitor")

;; %s é um espaço reservado para uma string, substituído por "visitor".
;; \n é um caractere de nova linha.

;; Vamos refinar nossa função utilizando `format':
(defun hello (name)
  (insert (format "Hello %s!\n" name)))

(hello "you")

;; Vamos criar outra função que utilize `let':
(defun greeting (name)
  (let ((your-name "Bastien"))
    (insert (format "Hello %s!\n\nI am %s."
                    name       ; the argument of the function
                    your-name  ; the let-bound variable "Bastien"
                    ))))

;; E executá-la:
(greeting "you")

;; Algumas funções são interativas:
(read-from-minibuffer "Enter your name: ")

;; Ao ser interpretada, esta função retorna o que você digitou no prompt.

;; Vamos fazer nossa função `greeting' pedir pelo seu nome:
(defun greeting (from-name)
  (let ((your-name (read-from-minibuffer "Enter your name: ")))
    (insert (format "Hello!\n\nI am %s and you are %s."
                    from-name ; the argument of the function
                    your-name ; the let-bound var, entered at prompt
                    ))))

(greeting "Bastien")

;; Vamos finalizá-la fazendo-a exibir os resultados em outra janela:
(defun greeting (from-name)
  (let ((your-name (read-from-minibuffer "Enter your name: ")))
    (switch-to-buffer-other-window "*test*")
    (erase-buffer)
    (insert (format "Hello %s!\n\nI am %s." your-name from-name))
    (other-window 1)))

;; Agora teste-a:
(greeting "Bastien")

;; Respire um pouco.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Vamos armazenar uma lista de nomes:
(setq list-of-names '("Sarah" "Chloe" "Mathilde"))

;; Pegue o primeiro elemento desta lista utilizando `car':
(car list-of-names)

;; Pegue uma lista de todos os elementos, exceto o primeiro, utilizando
;; `cdr':
(cdr list-of-names)

;; Adicione um elemento ao início da lista com `push':
(push "Stephanie" list-of-names)

;; NOTA: `car' e `cdr' não modificam a lista, `push' sim.
;; Esta é uma diferença importante: algumas funções não têm qualquer
;; efeito colateral (como `car'), enquanto outras sim (como `push').

;; Vamos executar `hello' para cada elemento em `list-of-names':
(mapcar 'hello list-of-names)

;; Refine `greeting' para saudar todos os nomes em `list-of-names':
(defun greeting ()
    (switch-to-buffer-other-window "*test*")
    (erase-buffer)
    (mapcar 'hello list-of-names)
    (other-window 1))

(greeting)

;; Você se lembra da função `hello' que nós definimos lá em cima? Ela
;; recebe um argumento, um nome. `mapcar' executa `hello', sucessivamente,
;; utilizando cada elemento de `list-of-names' como argumento para `hello'.

;; Agora vamos arrumar, um pouco, o que nós temos escrito no buffer:

(defun replace-hello-by-bonjour ()
    (switch-to-buffer-other-window "*test*")
    (goto-char (point-min))
    (while (search-forward "Hello")
      (replace-match "Bonjour"))
    (other-window 1))

;; (goto-char (point-min)) vai para o início do buffer.
;; (search-forward "Hello") busca pela string "Hello".
;; (while x y) interpreta a(s) sexp(s) y enquanto x retornar algo.
;; Se x retornar `nil' (nada), nós saímos do laço.

(replace-hello-by-bonjour)

;; Você deveria ver todas as ocorrências de "Hello" no buffer *test*
;; substituídas por "Bonjour".

;; Você deveria, também, receber um erro: "Search failed: Hello".
;;
;; Para evitar este erro, você precisa dizer ao `search-forward' se ele
;; deveria parar de buscar em algum ponto no buffer, e se ele deveria
;; falhar de forma silenciosa quando nada fosse encontrado:

;; (search-forward "Hello" nil t) dá conta do recado:

;; O argumento `nil' diz: a busca não está limitada a uma posição.
;; O argumento `t' diz: falhe silenciosamente quando nada for encontrado.

;; Nós utilizamos esta "sexp" na função abaixo, que não gera um erro:

(defun hello-to-bonjour ()
    (switch-to-buffer-other-window "*test*")
    (erase-buffer)
    ;; Say hello to names in `list-of-names'
    (mapcar 'hello list-of-names)
    (goto-char (point-min))
    ;; Replace "Hello" by "Bonjour"
    (while (search-forward "Hello" nil t)
      (replace-match "Bonjour"))
    (other-window 1))

(hello-to-bonjour)

;; Vamos colorir os nomes:

(defun boldify-names ()
    (switch-to-buffer-other-window "*test*")
    (goto-char (point-min))
    (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
      (add-text-properties (match-beginning 1)
                           (match-end 1)
                           (list 'face 'bold)))
    (other-window 1))

;; Esta função introduz `re-search-forward': ao invés de buscar
;; pela string "Bonjour", você busca por um padrão utilizando uma
;; "expressão regular" (abreviada pelo prefixo "re-").

;; A expressão regular é "Bonjour \\(.+\\)!" e lê-se:
;; a string "Bonjour ", e
;; um grupo de               | que é o \\( ... \\)
;;   quaisquer caracteres    | que é o .
;;   possivelmente repetidos | que é o +
;; e a string "!".

;; Preparado? Teste!

(boldify-names)

;; `add-text-properties' adiciona... propriedades de texto, como uma fonte.

;; OK, terminamos por aqui. Feliz Hacking!

;; Se você quiser saber mais sobre uma variável ou função:
;;
;; C-h v uma-variável RET
;; C-h f uma-função RET
;;
;; Para ler o manual de Emacs Lisp que vem com o Emacs:
;;
;; C-h i m elisp RET
;;
;; Para ler uma introdução online ao Emacs Lisp:
;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html

;; Agradecimentos a estas pessoas por seu feedback e sugestões:
;; - Wes Hardaker
;; - notbob
;; - Kevin Montuori
;; - Arne Babenhauserheide
;; - Alan Schmitt
;; - LinXitoW
;; - Aaron Meurer
```