原文链接:http://bzg.fr/learn-emacs-lisp-in-15-minutes.html
I was surprised not to find an introduction to Emacs Lisp on http://learnxinyminutes.com so I created one. I sent a pull request to the github repository, hopefully this will be merged at some point.
In the meantime, comments and feedback are very welcome.
Thanks to @squintar who kept encouraging me to write this for her own needs. Enjoy!
;; This gives an introduction to Emacs Lisp in 15 minutes (v0.2c)
;;
;; First make sure you read this text by Peter Norvig:
;; http://norvig.com/21-days.html
;;
;; Then install GNU Emacs 24.3:
;;
;; Debian: apt-get install emacs (or see your distro instructions)
;; MacOSX: 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
;;
;; More general information can be found at:
;; http://www.gnu.org/software/emacs/#Obtaining
;; Important warning:
;;
;; Going through this tutorial won't damage your computer unless
;; you get so angry that you throw it on the floor. In that case,
;; I hereby decline any responsability. Have fun!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Fire up Emacs.
;;
;; Hit the `q' key to dismiss the welcome message.
;;
;; Now look at the gray line at the bottom of the window:
;;
;; "*scratch*" is the name of the editing space you are now in.
;: This editing space is called a "buffer".
;;
;; The scratch buffer is the default buffer when opening Emacs.
;; You are never editing files: you are editing buffers that you
;; can save to a file.
;;
;; "Lisp interaction" refers to a set of commands available here.
;;
;; Emacs has a built-in set of commands available in every buffer,
;; and several subsets of commands available when you activate a
;; specific mode. Here we use the `lisp-interaction-mode', which
;; comes with commands to evaluate and navigate within Elisp code.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Semi-colons start comments anywhere on a line.
;;
;; Elisp programs are made of symbolic expressions ("sexps"):
(+ 2 2)
;; This symbolic expression reads as "Add 2 to 2".
;; Sexps are enclosed into parentheses, possibly nested:
(+ 2 (+ 1 1))
;; A symbolic expression contains atoms or other symbolic
;; expressions. In the above examples, 1 and 2 are atoms,
;; (+ 2 (+ 1 1)) and (+ 1 1) are symbolic expressions.
;; From `lisp-interaction-mode' you can evaluate sexps.
;; Put the cursor right after the closing parenthesis then
;; hold down the control and hit the j keys ("C-j" for short).
(+ 3 (+ 1 2))
;; ^ cursor here
;; `C-j' => 6
;; `C-j' inserts the result of the evaluation in the buffer.
;; `C-xC-e' displays the same result in Emacs bottom line,
;: called the "minibuffer". We will generally use `C-xC-e',
;; as we don't want to clutter the buffer with useless text.
;; `setq' stores a value into a variable:
(setq my-name "Bastien")
;; `C-xC-e' => "Bastien" (displayed in the mini-buffer)
;; `insert' will insert "Hello!" where the cursor is:
(insert "Hello!")
;; `C-xC-e' => "Hello!"
;; We used `insert' with only one argument "Hello!", but
;; we can pass more arguments -- here we use two:
(insert "Hello" " world!")
;; `C-xC-e' => "Hello world!"
;; You can use variables instead of strings:
(insert "Hello, I am " my-name)
;; `C-xC-e' => "Hello, I am Bastien"
;; You can combine sexps into functions:
(defun hello () (insert "Hello, I am " my-name))
;; `C-xC-e' => hello
;; You can evaluate functions:
(hello)
;; `C-xC-e' => Hello, I am Bastien
;; The empty parentheses in the function's definition means that
;; it does not accept arguments. But always using `my-name' is
;; boring, let's tell the function to accept one argument (here
;; the argument is called "name"):
(defun hello (name) (insert "Hello " name))
;; `C-xC-e' => hello
;; Now let's call the function with the string "you" as the value
;; for its unique argument:
(hello "you")
;; `C-xC-e' => "Hello you"
;; Yeah!
;; Take a breath.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Now switch to a new buffer named "*test*" in another window:
(switch-to-buffer-other-window "*test*")
;; `C-xC-e'
;: => [screen has two windows and cursor is in the *test* buffer]
;; Mouse over the top window and left-click to go back. Or you can
;; use `C-xo' (i.e. hold down control-x and hit o) to go to the other
;; window interactively.
;; You can combine several sexps with `progn':
(progn
(switch-to-buffer-other-window "*test*")
(hello "you"))
;; `C-xC-e'
;: => [The screen has two windows and cursor is in the *test* buffer]
;; Now if you don't mind, I'll stop asking you to hit `C-xC-e': do it
;; for every sexp that follows.
;; Always go back to the *scratch* buffer with the mouse or `C-xo'.
;; It's often useful to erase the buffer:
(progn
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello "there"))
;; Or to go back to the other window:
(progn
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello "you")
(other-window 1))
;; You can bind a value to a local variable with `let':
(let ((local-name "you"))
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello local-name)
(other-window 1))
;; No need to use `progn' in that case, since `let' also combines
;; several sexps.
;; Let's format a string:
(format "Hello %s!\n" "visitor")
;; %s is a place-holder for a string, replaced by "Alice".
;; \n is the newline character.
;; Let's refine our function by using format:
(defun hello (name)
(insert (format "Hello %s!\n" name)))
(hello "you")
;; Let's create another function which uses `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"
))))
;; And evaluate it:
(greeting "you")
;; Some function are interactive:
(read-from-minibuffer "Enter your name: ")
;; Evaluating this function returns what you entered at the prompt.
;; Let's make our `greeting' function prompt for your name:
(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")
;; Let's complete it by displaying the results in the other window:
(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)))
;; Now test it:
(greeting "Bastien")
;; Take a breath.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Let's store a list of names:
(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
;; Get the first element of this list with `car':
(car list-of-names)
;; Get a list of all but the first element with `cdr':
(cdr list-of-names)
;; Add an element to the beginning of a list with `push':
(push "Stephanie" list-of-names)
;; NOTE: `car' and `cdr' don't modify the list, but `push' does.
;; This is an important difference: some functions don't have any
;; side-effects (like `car') while others have (like `push').
;; Let's call `hello' for each element in `list-of-names':
(mapcar 'hello list-of-names)
;; Refine `greeting' to say hello to everyone in `list-of-names':
(defun greeting ()
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(mapcar 'hello list-of-names)
(other-window 1))
(greeting)
;; Remember the `hello' function we defined above? It takes one
;; argument, a name. `mapcar' calls `hello', successively using each
;; element of `list-of-names' as the argument for `hello'.
;; Now let's arrange a bit what we have in the displayed 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)) goes to the beginning of the buffer.
;; (search-forward "Hello") searches for the string "Hello".
;; (while x y) evaluates the y sexp(s) while x returns something.
;; If x returns `nil' (nothing), we exit the while loop.
(replace-hello-by-bonjour)
;; You should see all occurrences of "Hello" in the *test* buffer
;; replaced by "Bonjour".
;; You should also get an error: "Search failed: Hello".
;;
;; To avoid this error, you need to tell `search-forward' whether it
;; should stop searching at some point in the buffer, and whether it
;; should silently fail when nothing is found:
;; (search-forward "Hello" nil t) does the trick:
;; The `nil' argument says: the search is not bound to a position.
;; The `t' argument says: silently fail when nothing is found.
;; We use this sexp in the function below, which doesn't throw an error:
(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)
;; Let's colorize the names:
(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))
;; This functions introduces `re-search-forward': instead of
;; searching for the string "Bonjour", you search for a pattern,
;; using a "regular expression" (abbreviated in the prefix "re-").
;; The regular expression is "Bonjour \\(.+\\)!" and it reads:
;; the string "Bonjour ", and
;; a group of | this is the \\( ... \\) construct
;; any character | this is the .
;; possibly repeated | this is the +
;; and the "!" string.
;; Ready? Test it!
(boldify-names)
;; `add-text-properties' adds... text properties, like a face.
;; OK, we are done. Happy hacking!
;; If you want to know more about a variable or a function:
;;
;; C-h v a-variable RET
;; C-h f a-function RET
;;
;; To read the Emacs Lisp manual with Emacs:
;;
;; C-h i m elisp RET
;;
;; To read an online introduction to Emacs Lisp:
;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
;; Thanks to these people for their feedback and suggestions:
;; - Wes Hardaker
;; - notbob
;; - Kevin Montuori
;; - Arne Babenhauserheide
;; - Alan Schmitt
分享到:
相关推荐
- **标题**:“An Introduction to Programming in Emacs Lisp”(Emacs Lisp编程入门) - **描述**:该资源是基于Emacs官方文档的重编版本,旨在提供更易阅读的字体样式。 #### 知识点详解 ##### 1. Emacs Lisp...
Programming in Emacs Lisp英文版
GNU Emacs Lisp 编程入门是一本非常专业的编程书籍,它详细地介绍了如何使用GNU Emacs Lisp这种编程语言来编写程序。GNU Emacs Lisp是一种用于GNU Emacs编辑器的编程语言,它是一种功能强大且灵活的编程工具,广泛...
15. **准备图表(Readying a Graph)**:介绍了如何在Emacs Lisp中生成图表。 16. **您的.emacs文件(Your ‘.emacs’ File)**:讲述了如何定制个人的Emacs配置文件。 17. **调试(Debugging)**:提供了调试技巧和...
GNU Emacs Lisp编程入门 GNU Emacs是一款著名的开源文本编辑器,以其高度可定制性和扩展性而闻名。Emacs的内核由C语言编写,但它的强大之处在于其内置的Lisp方言——Emacs Lisp(简称Elisp)。Elisp使得用户能够...
### GNU Emacs Lisp 参考手册知识点总结 #### 1. 引言 GNU Emacs Lisp 参考手册为Emacs版本22.1提供了详细的指导,该版本为修订版2.9,发布于2007年4月。该手册由Bil Lewis、Dan LaLiberte、Richard Stallman以及...
在“Atom-language-emacs-lisp.zip”这个压缩包中,主要关注的是对Emacs Lisp的支持。Emacs Lisp是一种用于扩展和定制GNU Emacs编辑器的Lisp方言。它提供了丰富的API和交互式编程环境,使得开发者可以编写自定义的...
Programming in Emacs Lisp: An Introduction (美)Robert J.Chassell 著 毛文涛、吕芳 译 洪峰 审校 本书的作者罗伯特·卡塞尔是自由软件基金会的合创人之一,也是理查德·斯托曼博士青年时期结交的挚友,他...
### Robert Chassell:An Introduction to Programming in Emacs Lisp #### 知识点概览 - **Lisp Lists**: 介绍Lisp列表的概念及其在Emacs Lisp中的应用。 - **Lisp Atoms**: 解释Lisp原子的基本概念以及它们在...
GNU EMACS lisp编程入门.djvuGNU EMACS lisp编程入门.djvuGNU EMACS lisp编程入门.djvuGNU EMACS lisp编程入门.djvuGNU EMACS lisp编程入门.djvuGNU EMACS lisp编程入门.djvuGNU EMACS lisp编程入门.djvu
### Emacs Lisp 函数手册知识点概览 #### 一、引言 Emacs Lisp(简称Elisp)是Emacs文本编辑器内置的一种高级编程语言。它不仅支持编辑文档时的脚本化操作,还具备完整的编程功能,使得用户可以扩展Emacs的功能。本...
### Emacs Lisp 参考手册知识点概述 #### 一、引言 Emacs Lisp(简称Elisp)是Emacs文本编辑器内置的一种高级编程语言。它不仅支持文本编辑操作,还能进行复杂的程序设计工作。Emacs Lisp参考手册为用户提供了一个...
### Emacs Lisp介绍与编程基础 #### 一、Emacs Lisp概览 Emacs Lisp(简称Elisp)是一种专为Emacs文本编辑器设计的高级动态编程语言。它不仅支持Emacs的功能扩展,还允许用户根据自己的需求定制和开发新的功能。...
### Lisp参考:深入理解Emacs Lisp编程语言 #### 引言 Emacs Lisp,作为GNU Emacs文本编辑器的核心编程语言,不仅为用户提供了强大的编辑功能,还赋予了开发者无限的扩展可能。它远非仅仅是一种“扩展语言”,实际...
Emacs Lisp(简称Elisp)是GNU Emacs编辑器的核心编程语言,它允许用户自定义、扩展和控制这个功能丰富的文本编辑器。作为一个强大的脚本语言,Elisp在程序员和Emacs爱好者中广受欢迎,不仅适合初学者,也满足高级...