Tuesday, February 5, 2008

Emacs Lisp: A Note of a Newbie

(Please Note that all the codes/commands are tried in x86 based system running in Windows XP and XEmacs 21.4.20)

I have been learning elisp for couple of weeks just before Steve Yegge came up with his blog on Emergency Elisp. It is a good introduction to a programming language which is bound to an editor (or the other way around?). His blog talks about the basics of elisp in a nut shell, although lot of people have pointed out mistakes in it, but I feel it must have helped people like me who are learning elisp or will do so in the future. Also if you have looked for elisp tutorials in Google you must have bumped on to “An Introduction to Programming in Emacs Lisp” or “Emacs lisp Tutorial” . The elisp manual is good for people who have played with the language for some time; but for people who want to start learning elisp it is may not be a good place to be.

So why am I writing this blog? I found no mention of buffers and windows related stuffs in Steve’s post; as a programmer I felt I should keep notes of my work (as I do in some of my blogs).

When we configure SLIME and Emacs we add some lines to our init.el file which reads some thing like:

(add-to-list ‘load-path ….)

So the first thing is how to inspect a variable in Emacs, C-h v will prompt for the name of the variable you want to check and as soon as you enter the name of the variable it shows you the content of it. Like if I have a variable foo and want to see what the value of foo is.

Similarly if we want to see the documentation of any function we can use C-h f and enter the name of the function to see its documentation.

But don’t be fooled by these “control h” stuffs as they are nothing but either elisp functions or commands which are bound to some key combinations and keymaps. One can make a function interactive with the user by a using a built in function called (interactive).

Buffers and Windows

Buffers are lisp objects which hold texts for future editing. So as soon as you start Emacs it starts in a buffer. The most famous buffer is *scratch* buffer. If you do not have any customizations or filename mentioned while opening Emacs, it opens in this buffer by default. Let’s check some buffer related functions.

Let’s try out a mini project, suppose I have to create a function which will create documents in a predefined manner. How do I do that? The format is as follows:

Author:

Author Email:

Company:

Abstract:

From there on the author will create the rest of the document.

(Note here that I am not going into a lot of details in this and please do take care of the details required before creating a real project.)

Here is a way how we can do it elisp (please feel free to comment if you have any other idea i.e. more lispy way of doing this).

Programmer, who has his lineage from C or Java or JavaScript, knows that if he has to output some string with values extracted from a variable he has to write something like:-

C: printf(“Author:%s”, auth);

Java: System.out.println(“Author:” + auth);

JavaScript: alert(“Author:”+auth);

Common Lisp: (format t “Author:~a~%” auth)

Same applies here also but we do the formatting as following:

(format "Author:%s " auth)

I will just quickly note what all the in build functions does and how I have used them.

  1. insert: This function inserts a formatted string in to the current buffer.
  2. newline: As the name suggest it appends a new line.
  3. switch-to-buffer: This function switches to a buffer and displays the buffer.
  4. create-file-buffer: This will create a buffer with the filename (if the buffer exists it appends some extras apropos) and returns that buffer.
  5. save-buffer: This function will prompt the user to save the buffer.

(Refer to elisp manual for details of these function)

Here is the code:

(defun create-the-doc-template (auth &optional email company)

(insert (format "Author:%s " auth))

(newline)

(if (eq email nil)

(insert "Author Email:")

(insert (format "Author Email:%s " email)))

(newline)

(if (eq company nil)

(insert "Company:")

(insert (format "Company:%s " email)))

(newline)

(insert "Abstract:"))

(defun create-file-as-doc(filename Author &optional Auth-Email Comp)

(switch-to-buffer (create-file-buffer filename))

(create-the-doc-template Author Auth-Email Comp)

(save-buffer))

(create-file-as-doc "hello-emacs.txt" "samik" "samikc@gmail.com" "ABC")

(create-file-as-doc "hello-emacs.txt" “samik”)

Now once you execute the first call it should look like the following:

Keyboard Macro

The best thing about elisp is that it allows you to hack Emacs completely and you can record a keyboard macro and use it by using a set functions and variables.

The variable last-kbd-board macro holds the last macro that you have defined and execute-kbd-macro does repeat the last macro defined by you in the current line. This can help you build a function that will repeat the macro in vary large file.

(defun do-macro()

(interactive)

(execute-kbd-macro last-kbd-macro))

So that’s all for now…

Thanks for reading.

2 comments:

bozster613 said...

You also might wish to use the excellent Open Source Software liveCD GNUstep for emacs lisp and your other programming explorations, and as an alternative to Windows XP. From GNUstep's long list of software packages, here are the emacsen-related packages:

emacs.app 9.0~pre3b-1
The GNU Emacs editor on GNUstep

emacs.app-data 9.0~pre3b-1
The GNU Emacs editor on GNUstep data files

emacs21-bin-common 21.4a+1-1
The GNU Emacs editor's shared, architecture

emacs21-common 21.4a+1-1
The GNU Emacs editor's shared, architecture

emacs21-nox 21.4a+1-1
The GNU Emacs editor (without X support)

emacsen-common 1.4.17
Common facilities for all emacsen

Best of success with this!
-A F/OSS-friendly visitor

Xah Lee said...

Nice blog.
Why not use emacs 22?
It has a new feature that allows you to use a function in your regex replacement. That's very useful to me. It has also better unicode support, very impotant to me... and a bunch of others.

btw, you don't have to (insert newline) by itself. You can just (insert "something" "...\n" "something")