Skip to content

Commit

Permalink
Reformatting commit
Browse files Browse the repository at this point in the history
Moved to using code blocks for displaying bigs blocks of code, instead of continued lines, each line double-back-ticked - much nicer to do...
  • Loading branch information
hypernumbers committed Jan 24, 2011
1 parent 176bf67 commit 9c49ea7
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 134 deletions.
26 changes: 14 additions & 12 deletions contents/emacs-and-the-dot-emacs-file.rst
Expand Up @@ -32,18 +32,20 @@ Notice that the modeline now says something like `Wrote /home/gordonguthrie/.ema

Now open the `.emacs` file. Mine looks like:

| ``(custom-set-variables``
| ``;; custom-set-variables was added by Custom.``
| ``;; If you edit it by hand, you could mess it up, so be careful.``
| ``;; Your init file should contain only one such instance.``
| ``;; If there is more than one, they won't work right.``
| ``)``
| ``(custom-set-faces``
| ``;; custom-set-faces was added by Custom.``
| ``;; If you edit it by hand, you could mess it up, so be careful.``
| ``;; Your init file should contain only one such instance.``
| ``;; If there is more than one, they won't work right.``
| ``'(default ((t (:inherit nil :stipple nil :background "white" :foreground "black" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 143 :width normal :foundry "bitstream" :family "Courier 10 Pitch")))))``
::

(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(default ((t (:inherit nil :stipple nil :background "white" :foreground "black" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 143 :width normal :foundry "bitstream" :family "Courier 10 Pitch")))))

Emacs has *saved options* into the `.emacs` file. Emacs marks the code that it adds with quotes as above. If you see big chunks of code like this in your `.emacs` file - that's what it is. Don't panic.

Expand Down
16 changes: 9 additions & 7 deletions contents/lesson-2-2-primitive-data-types-1.rst
Expand Up @@ -150,13 +150,15 @@ Certain functions expect certain types - for instance ``+`` expects numbers as i

This is in a window called \*backtrace\*. It is worth looking at the output in some detail.

| ``Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p "two")``
| ``+(1 "two")``
| ``eval((+ 1 "two"))``
| ``eval-last-sexp-1(t)``
| ``eval-last-sexp(t)``
| ``eval-print-last-sexp()``
| ``call-interactively(eval-print-last-sexp nil nil)``
::

Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p "two")
+(1 "two")
eval((+ 1 "two"))
eval-last-sexp-1(t)
eval-last-sexp(t)
eval-print-last-sexp()
call-interactively(eval-print-last-sexp nil nil)

The first line of this give us some details of the problem, it is a Lisp error - the predicate function ``number-or-marker-p`` on the parameter ``two`` threw an ``wrong-type-argument`` error. We will look at the debugger later on in the book. If you go back to the list of Emacs specific types you will see that there is one called marker. The operator ``+`` can operate on numbers or markers and so it uses this special predicate function to test the arguments before running the function.

Expand Down
16 changes: 9 additions & 7 deletions contents/lesson-2-4-symbols-and-variables.rst
Expand Up @@ -47,13 +47,15 @@ Variables don't just exist with default values. If you try and use a random symb
:You Type: ``(+ 1 do_tell)``
:Result: You are dropped into the debugger

| ``Debugger entered--Lisp error: (void-variable do_tell)``
| ``(+ 1 do_tell)``
| ``eval((+ 1 do_tell))``
| ``eval-last-sexp-1(t)``
| ``eval-last-sexp(t)``
| ``eval-print-last-sexp()``
| ``call-interactively(eval-print-last-sexp nil nil)``
::

Debugger entered--Lisp error: (void-variable do_tell)
(+ 1 do_tell)
eval((+ 1 do_tell))
eval-last-sexp-1(t)
eval-last-sexp(t)
eval-print-last-sexp()
call-interactively(eval-print-last-sexp nil nil)

The variable ``do_tell`` has been created but its value is *void* and it cannot be used.

Expand Down
112 changes: 64 additions & 48 deletions contents/lesson-3-1-writing-functions.rst
Expand Up @@ -14,11 +14,15 @@ The option ``--no-site-file`` means that emacs doesn't load any eLisp from the s

Start by creating a new directory, and in that create a file called *message.el*. The contents of that file is a single eLisp expression:

``(message "Bonjour Tout Le Monde")``
::

(message "Bonjour Tout Le Monde")

The file should be executed by running this batch command in the directory in which you have created *message.el*

``emacs --no-site-file --script message.el``
::

emacs --no-site-file --script message.el

The output should be ``Bonjour Tout Le Monde``

Expand All @@ -28,18 +32,22 @@ Defining A Simple Function

We will start by defining a function. Create a file with the following code in it:

| ``(defun bonjour () (message "Bonjour Tout Le Monde"))``
| ``(bonjour)``
::

(defun bonjour () (message "Bonjour Tout Le Monde"))
(bonjour)

On executing this file the output will be:

``Bonjour Tout Le Monde``
::

Bonjour Tout Le Monde

Lets understand what we are seeing. Consider the first line - the operator ``defun`` indicates that we are defining a function. Here it is taking 3 parameters:

| **1** ``bonjour`` which is the name of the function
| **2** ``()`` which is a list of the parameters that the function will take
| **3** ``(message "Bonjour Tout Le Monde")`` is the body of code that will executed when the function is run
| *1* ``bonjour`` which is the name of the function
| *2* ``()`` which is a list of the parameters that the function will take
| *3* ``(message "Bonjour Tout Le Monde")`` is the body of code that will executed when the function is run
The second line simply executes the fuction ``bonjour``. The function definition states that ``bonjour`` takes no parameters (the list of parameters is empty).

Expand All @@ -49,14 +57,18 @@ Defining A More Complex Function

Lets create a function that takes multiple arguments:

| ``(defun tough_maths (i j k)``
| ``"jeepers maths is tough!"``
| ``(message (number-to-string (+ i j k))))``
| ``(tough_maths 3 4 5)``
::

(defun tough_maths (i j k)
"jeepers maths is tough!"
(message (number-to-string (+ i j k))))
(tough_maths 3 4 5)

When executed this will return:

``12``
::
12

In this case (unlike the simple case) ``defun`` takes 4 parameters and not three. The second paramater ```(i j k)`` is a list of parameters that the function takes. The third parameter is the documentation - it can be a string broken over many lines. The fourth parameter is the body of the function as in the previous example. Notice that in order to write the output the value of the expression ``(+ i j k)`` must be cast to a string with the operator ``number-to-string``.

Expand All @@ -68,45 +80,49 @@ We have seen that the function ``defun`` has variable arity - that is to say it

Lets write a variable arity function:

| ``(defun variable_arity (a &optional b &rest c)``
| ``"This is a function which has variable arity"``
| ``(message (concat "variable a is " a))``
| ``(message (concat "variable b is " b))``
| ``(if c (message "c is not an empty list") (message "c is an empty list")))``
| ``(message "run the fn with 1 variable")``
| ``(variable_arity "eh")``
| ``(message "run the fn with 2 variables")``
| ``(variable_arity "eh" "bee")``
| ``(message "run the fn with 3 variables")``
| ``(variable_arity "eh" "bee" "see")``
| ``(message "run the fn with 4 variables")``
| ``(variable_arity "eh" "bee" "see" "dee")``
| ``(message "run the fn with 5 variables")``
| ``(variable_arity "eh" "bee" "see" "dee" "eee")``
::

(defun variable_arity (a &optional b &rest c)
"This is a function which has variable arity"
(message (concat "variable a is " a))
(message (concat "variable b is " b))
(if c (message "c is not an empty list") (message "c is an empty list")))
(message "run the fn with 1 variable")
(variable_arity "eh")
(message "run the fn with 2 variables")
(variable_arity "eh" "bee")
(message "run the fn with 3 variables")
(variable_arity "eh" "bee" "see")
(message "run the fn with 4 variables")
(variable_arity "eh" "bee" "see" "dee")
(message "run the fn with 5 variables")
(variable_arity "eh" "bee" "see" "dee" "eee")


The result is:

| ``run the fn with 1 variable``
| ``variable a is eh``
| ``variable b is``
| ``c is an empty list``
| ``run the fn with 2 variables``
| ``variable a is eh``
| ``variable b is bee``
| ``c is an empty list``
| ``run the fn with 3 variables``
| ``variable a is eh``
| ``variable b is bee``
| ``c is not an empty list``
| ``run the fn with 4 variables``
| ``variable a is eh``
| ``variable b is bee``
| ``c is not an empty list``
| ``run the fn with 5 variables``
| ``variable a is eh``
| ``variable b is bee``
| ``c is not an empty list``
::

run the fn with 1 variable
variable a is eh
variable b is
c is an empty list
run the fn with 2 variables
variable a is eh
variable b is bee
c is an empty list
run the fn with 3 variables
variable a is eh
variable b is bee
c is not an empty list
run the fn with 4 variables
variable a is eh
variable b is bee
c is not an empty list
run the fn with 5 variables
variable a is eh
variable b is bee
c is not an empty list

The important part of this is the first part of the function definition ``(defun variable_arity (a &optional b &rest c)...``. ``a`` is a required option - calling ``variable_arity`` with zero parameters will result in an error. The marker ``&optional b`` indicates that the subsequent parameter ``b`` is optional. In this function there is only one optional function but a clause like ``(i j &optional k l m)`` would have three optional arguments. The final clause ``&rest c`` indicates that all parameters from 3 onwards will be collected into the variable ``c`` as a list. You can have either ``&optional`` or ``&rest`` or both together as in this function.

Expand Down
63 changes: 40 additions & 23 deletions contents/lesson-4-2-adding-custom-functions-to-emacs.rst
Expand Up @@ -18,10 +18,12 @@ A Simple Custom Function

Open the ``.emacs`` file (or create it if it doesn't exist) and add the following function:

| ``(defun doodlebug ()``
| ``"Nonce function"``
| ``(interactive)``
| ``(message "Howdie-doodie fella"))``
::

(defun doodlebug ()
"Nonce function"
(interactive)
(message "Howdie-doodie fella"))

The first time you do this, edit the ``.emacs`` file and then open Emacs. If you edit it in Emacs you will need to quit and restart.

Expand All @@ -31,7 +33,9 @@ This function can be run simply. The command *[Alt][x]* is used to a run a funct

You should then see the output in the minibuffer:

``Howdie-doodie fella``
::

Howdie-doodie fella

Look carefully at the function definition. The third parameter of the list is the expression ``(interactive)`` - this is necessary if we are to invoke the function from either a key-binding or the minibuffer.

Expand All @@ -41,32 +45,39 @@ A Custom Function With User Input

Lets edit the function to take some parameters:

| ``(defun doodlebug (a b c)``
| ``"Nonce function"``
| ``(interactive "sAdjective: \nsNoun: \nsExclamation: \n")``
| ``(message "Its a %s thing, this %s, so it is, %s" a b c))``
::

(defun doodlebug (a b c)
"Nonce function"
(interactive "sAdjective: \nsNoun: \nsExclamation: \n")
(message "Its a %s thing, this %s, so it is, %s" a b c))

You can't reload the ``.emacs`` file, but you can manually re-evaluated by using the command *Emacs-Lisp -> Evaluate Buffer* in the ``.emacs`` buffer.

When you run this version of the function with *[Alt][x]doodlebug* it will offer up three prompts, to wit:

| ``Adjective:``
| ``Noun:``
| ``Exclamation:``
::

Adjective:
Noun:
Exclamation:

As you type in a string at each prompt (ending with *[Return]*) each of the strings wll be bound to the variables ``a``, ``b`` and ``c`` in turn.

This behaviour in enabled by the new form of the *interactive* expresion. The string which has been added to that expression consists of 6 seperate components:

| ``s``
| ``Adjective: \n``
| ``s``
| ``Noun: \n``
| ``s``
| ``Exclamation: \n``
::

s
Adjective: \n
s
Noun: \n
s
Exclamation: \n

The 2nd, 4th and 6th parts are the prompts which will be shown in the minibuffer. The three ``s``'s are Interactive Codes which refer to strings (ie key sequences terminated with *[Return]* which are entered at the prompt. There are a range of other Interative Codes, some of which are:


| ``a`` - a function name
| ``b`` - the name of an existing buffer
| ``B`` - the name of a buffer which may or may not exist
Expand All @@ -82,18 +93,24 @@ Binding The Custom Function To A Key Sequence

To bind the custom function to a key sequence add the following line to the ``.emacs`` file.

``(global-set-key [f5] 'doodlebug)``
::

(global-set-key [f5] 'doodlebug)

This expression will bind the function ``doodlebug`` to the *F5* function key. Once you have re-evaluated the ``.emacs`` buffer you will be able to fire the function with the *F5* key.

We can identify which function is bound to which key with the command:

``(lookup-key (current-global-map) [f5])``
::

(lookup-key (current-global-map) [f5])

The rules for binding keys are a bit complex. We can use the operator ``kbd`` to generate the appropriate input to ``global-set-key`` and ``lookup-key``, for instance:

| ``(global-set-key (kbd "C-c a") 'doodlebug)``
| ``(lookup-key (current-global-map) (kbd "C-c a"))``

::

(global-set-key (kbd "C-c a") 'doodlebug)
(lookup-key (current-global-map) (kbd "C-c a"))

The expression ``(kbd "C-c a")`` generates the appropriate keymap for the key sequence *[C-c][a]*.

Expand Down

0 comments on commit 9c49ea7

Please sign in to comment.