diff options
Diffstat (limited to 'info/eintr-1')
-rw-r--r-- | info/eintr-1 | 7277 |
1 files changed, 0 insertions, 7277 deletions
diff --git a/info/eintr-1 b/info/eintr-1 deleted file mode 100644 index 1845645c391..00000000000 --- a/info/eintr-1 +++ /dev/null @@ -1,7277 +0,0 @@ -This is ../info/eintr, produced by makeinfo version 4.8 from -emacs-lisp-intro.texi. - -INFO-DIR-SECTION Emacs -START-INFO-DIR-ENTRY -* Emacs Lisp Intro: (eintr). - A simple introduction to Emacs Lisp programming. -END-INFO-DIR-ENTRY - -This is an `Introduction to Programming in Emacs Lisp', for people who -are not programmers. - -Edition 3.01, 2006 Oct 31 - -Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1997, 2001, 2002, -2003, 2004, 2005, 2006 Free Software Foundation, Inc. - -Published by the: - - GNU Press, Website: http://www.gnupress.org - a division of the General: press@gnu.org - Free Software Foundation, Inc. Orders: sales@gnu.org - 51 Franklin Street, Fifth Floor Tel: +1 (617) 542-5942 - Boston, MA 02110-1301 USA Fax: +1 (617) 542-2652 - - -ISBN 1-882114-43-4 - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or -any later version published by the Free Software Foundation; there -being no Invariant Section, with the Front-Cover Texts being "A GNU -Manual", and with the Back-Cover Texts as in (a) below. A copy of the -license is included in the section entitled "GNU Free Documentation -License". - -(a) The FSF's Back-Cover Text is: "You have freedom to copy and modify -this GNU Manual, like GNU software. Copies published by the Free -Software Foundation raise funds for GNU development." - - -File: eintr, Node: Top, Next: Preface, Prev: (dir), Up: (dir) - -An Introduction to Programming in Emacs Lisp -******************************************** - -This is an `Introduction to Programming in Emacs Lisp', for people who -are not programmers. - -Edition 3.01, 2006 Oct 31 - -Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1997, 2001, 2002, -2003, 2004, 2005, 2006 Free Software Foundation, Inc. - -Published by the: - - GNU Press, Website: http://www.gnupress.org - a division of the General: press@gnu.org - Free Software Foundation, Inc. Orders: sales@gnu.org - 51 Franklin Street, Fifth Floor Tel: +1 (617) 542-5942 - Boston, MA 02110-1301 USA Fax: +1 (617) 542-2652 - - -ISBN 1-882114-43-4 - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or -any later version published by the Free Software Foundation; there -being no Invariant Section, with the Front-Cover Texts being "A GNU -Manual", and with the Back-Cover Texts as in (a) below. A copy of the -license is included in the section entitled "GNU Free Documentation -License". - -(a) The FSF's Back-Cover Text is: "You have freedom to copy and modify -this GNU Manual, like GNU software. Copies published by the Free -Software Foundation raise funds for GNU development." - -This master menu first lists each chapter and index; then it lists -every node in every chapter. - -* Menu: - -* Preface:: What to look for. -* List Processing:: What is Lisp? -* Practicing Evaluation:: Running several programs. -* Writing Defuns:: How to write function definitions. -* Buffer Walk Through:: Exploring a few buffer-related functions. -* More Complex:: A few, even more complex functions. -* Narrowing & Widening:: Restricting your and Emacs attention to - a region. -* car cdr & cons:: Fundamental functions in Lisp. -* Cutting & Storing Text:: Removing text and saving it. -* List Implementation:: How lists are implemented in the computer. -* Yanking:: Pasting stored text. -* Loops & Recursion:: How to repeat a process. -* Regexp Search:: Regular expression searches. -* Counting Words:: A review of repetition and regexps. -* Words in a defun:: Counting words in a `defun'. -* Readying a Graph:: A prototype graph printing function. -* Emacs Initialization:: How to write a `.emacs' file. -* Debugging:: How to run the Emacs Lisp debuggers. -* Conclusion:: Now you have the basics. -* the-the:: An appendix: how to find reduplicated words. -* Kill Ring:: An appendix: how the kill ring works. -* Full Graph:: How to create a graph with labelled axes. -* Free Software and Free Manuals:: -* GNU Free Documentation License:: -* Index:: -* About the Author:: - - --- The Detailed Node Listing --- - -Preface - -* Why:: Why learn Emacs Lisp? -* On Reading this Text:: Read, gain familiarity, pick up habits.... -* Who You Are:: For whom this is written. -* Lisp History:: -* Note for Novices:: You can read this as a novice. -* Thank You:: - -List Processing - -* Lisp Lists:: What are lists? -* Run a Program:: Any list in Lisp is a program ready to run. -* Making Errors:: Generating an error message. -* Names & Definitions:: Names of symbols and function definitions. -* Lisp Interpreter:: What the Lisp interpreter does. -* Evaluation:: Running a program. -* Variables:: Returning a value from a variable. -* Arguments:: Passing information to a function. -* set & setq:: Setting the value of a variable. -* Summary:: The major points. -* Error Message Exercises:: - -Lisp Lists - -* Numbers Lists:: List have numbers, other lists, in them. -* Lisp Atoms:: Elemental entities. -* Whitespace in Lists:: Formatting lists to be readable. -* Typing Lists:: How GNU Emacs helps you type lists. - -The Lisp Interpreter - -* Complications:: Variables, Special forms, Lists within. -* Byte Compiling:: Specially processing code for speed. - -Evaluation - -* Evaluating Inner Lists:: Lists within lists... - -Variables - -* fill-column Example:: -* Void Function:: The error message for a symbol - without a function. -* Void Variable:: The error message for a symbol without a value. - -Arguments - -* Data types:: Types of data passed to a function. -* Args as Variable or List:: An argument can be the value - of a variable or list. -* Variable Number of Arguments:: Some functions may take a - variable number of arguments. -* Wrong Type of Argument:: Passing an argument of the wrong type - to a function. -* message:: A useful function for sending messages. - -Setting the Value of a Variable - -* Using set:: Setting values. -* Using setq:: Setting a quoted value. -* Counting:: Using `setq' to count. - -Practicing Evaluation - -* How to Evaluate:: Typing editing commands or C-x C-e - causes evaluation. -* Buffer Names:: Buffers and files are different. -* Getting Buffers:: Getting a buffer itself, not merely its name. -* Switching Buffers:: How to change to another buffer. -* Buffer Size & Locations:: Where point is located and the size of - the buffer. -* Evaluation Exercise:: - -How To Write Function Definitions - -* Primitive Functions:: -* defun:: The `defun' special form. -* Install:: Install a function definition. -* Interactive:: Making a function interactive. -* Interactive Options:: Different options for `interactive'. -* Permanent Installation:: Installing code permanently. -* let:: Creating and initializing local variables. -* if:: What if? -* else:: If--then--else expressions. -* Truth & Falsehood:: What Lisp considers false and true. -* save-excursion:: Keeping track of point, mark, and buffer. -* Review:: -* defun Exercises:: - -Install a Function Definition - -* Effect of installation:: -* Change a defun:: How to change a function definition. - -Make a Function Interactive - -* Interactive multiply-by-seven:: An overview. -* multiply-by-seven in detail:: The interactive version. - -`let' - -* Prevent confusion:: -* Parts of let Expression:: -* Sample let Expression:: -* Uninitialized let Variables:: - -The `if' Special Form - -* if in more detail:: -* type-of-animal in detail:: An example of an `if' expression. - -Truth and Falsehood in Emacs Lisp - -* nil explained:: `nil' has two meanings. - -`save-excursion' - -* Point and mark:: A review of various locations. -* Template for save-excursion:: - -A Few Buffer--Related Functions - -* Finding More:: How to find more information. -* simplified-beginning-of-buffer:: Shows `goto-char', - `point-min', and `push-mark'. -* mark-whole-buffer:: Almost the same as `beginning-of-buffer'. -* append-to-buffer:: Uses `save-excursion' and - `insert-buffer-substring'. -* Buffer Related Review:: Review. -* Buffer Exercises:: - -The Definition of `mark-whole-buffer' - -* mark-whole-buffer overview:: -* Body of mark-whole-buffer:: Only three lines of code. - -The Definition of `append-to-buffer' - -* append-to-buffer overview:: -* append interactive:: A two part interactive expression. -* append-to-buffer body:: Incorporates a `let' expression. -* append save-excursion:: How the `save-excursion' works. - -A Few More Complex Functions - -* copy-to-buffer:: With `set-buffer', `get-buffer-create'. -* insert-buffer:: Read-only, and with `or'. -* beginning-of-buffer:: Shows `goto-char', - `point-min', and `push-mark'. -* Second Buffer Related Review:: -* optional Exercise:: - -The Definition of `insert-buffer' - -* insert-buffer code:: -* insert-buffer interactive:: When you can read, but not write. -* insert-buffer body:: The body has an `or' and a `let'. -* if & or:: Using an `if' instead of an `or'. -* Insert or:: How the `or' expression works. -* Insert let:: Two `save-excursion' expressions. -* New insert-buffer:: - -The Interactive Expression in `insert-buffer' - -* Read-only buffer:: When a buffer cannot be modified. -* b for interactive:: An existing buffer or else its name. - -Complete Definition of `beginning-of-buffer' - -* Optional Arguments:: -* beginning-of-buffer opt arg:: Example with optional argument. -* beginning-of-buffer complete:: - -`beginning-of-buffer' with an Argument - -* Disentangle beginning-of-buffer:: -* Large buffer case:: -* Small buffer case:: - -Narrowing and Widening - -* Narrowing advantages:: The advantages of narrowing -* save-restriction:: The `save-restriction' special form. -* what-line:: The number of the line that point is on. -* narrow Exercise:: - -`car', `cdr', `cons': Fundamental Functions - -* Strange Names:: An historical aside: why the strange names? -* car & cdr:: Functions for extracting part of a list. -* cons:: Constructing a list. -* nthcdr:: Calling `cdr' repeatedly. -* nth:: -* setcar:: Changing the first element of a list. -* setcdr:: Changing the rest of a list. -* cons Exercise:: - -`cons' - -* Build a list:: -* length:: How to find the length of a list. - -Cutting and Storing Text - -* Storing Text:: Text is stored in a list. -* zap-to-char:: Cutting out text up to a character. -* kill-region:: Cutting text out of a region. -* copy-region-as-kill:: A definition for copying text. -* Digression into C:: Minor note on C programming language macros. -* defvar:: How to give a variable an initial value. -* cons & search-fwd Review:: -* search Exercises:: - -`zap-to-char' - -* Complete zap-to-char:: The complete implementation. -* zap-to-char interactive:: A three part interactive expression. -* zap-to-char body:: A short overview. -* search-forward:: How to search for a string. -* progn:: The `progn' special form. -* Summing up zap-to-char:: Using `point' and `search-forward'. - -`kill-region' - -* Complete kill-region:: The function definition. -* condition-case:: Dealing with a problem. -* Lisp macro:: - -`copy-region-as-kill' - -* Complete copy-region-as-kill:: The complete function definition. -* copy-region-as-kill body:: The body of `copy-region-as-kill'. - -The Body of `copy-region-as-kill' - -* last-command & this-command:: -* kill-append function:: -* kill-new function:: - -Initializing a Variable with `defvar' - -* See variable current value:: -* defvar and asterisk:: - -How Lists are Implemented - -* Lists diagrammed:: -* Symbols as Chest:: Exploring a powerful metaphor. -* List Exercise:: - -Yanking Text Back - -* Kill Ring Overview:: -* kill-ring-yank-pointer:: The kill ring is a list. -* yank nthcdr Exercises:: The `kill-ring-yank-pointer' variable. - -Loops and Recursion - -* while:: Causing a stretch of code to repeat. -* dolist dotimes:: -* Recursion:: Causing a function to call itself. -* Looping exercise:: - -`while' - -* Looping with while:: Repeat so long as test returns true. -* Loop Example:: A `while' loop that uses a list. -* print-elements-of-list:: Uses `while', `car', `cdr'. -* Incrementing Loop:: A loop with an incrementing counter. -* Decrementing Loop:: A loop with a decrementing counter. - -A Loop with an Incrementing Counter - -* Incrementing Example:: Counting pebbles in a triangle. -* Inc Example parts:: The parts of the function definition. -* Inc Example altogether:: Putting the function definition together. - -Loop with a Decrementing Counter - -* Decrementing Example:: More pebbles on the beach. -* Dec Example parts:: The parts of the function definition. -* Dec Example altogether:: Putting the function definition together. - -Save your time: `dolist' and `dotimes' - -* dolist:: -* dotimes:: - -Recursion - -* Building Robots:: Same model, different serial number ... -* Recursive Definition Parts:: Walk until you stop ... -* Recursion with list:: Using a list as the test whether to recurse. -* Recursive triangle function:: -* Recursion with cond:: -* Recursive Patterns:: Often used templates. -* No Deferment:: Don't store up work ... -* No deferment solution:: - -Recursion in Place of a Counter - -* Recursive Example arg of 1 or 2:: -* Recursive Example arg of 3 or 4:: - -Recursive Patterns - -* Every:: -* Accumulate:: -* Keep:: - -Regular Expression Searches - -* sentence-end:: The regular expression for `sentence-end'. -* re-search-forward:: Very similar to `search-forward'. -* forward-sentence:: A straightforward example of regexp search. -* forward-paragraph:: A somewhat complex example. -* etags:: How to create your own `TAGS' table. -* Regexp Review:: -* re-search Exercises:: - -`forward-sentence' - -* Complete forward-sentence:: -* fwd-sentence while loops:: Two `while' loops. -* fwd-sentence re-search:: A regular expression search. - -`forward-paragraph': a Goldmine of Functions - -* forward-paragraph in brief:: Key parts of the function definition. -* fwd-para let:: The `let*' expression. -* fwd-para while:: The forward motion `while' loop. - -Counting: Repetition and Regexps - -* Why Count Words:: -* count-words-region:: Use a regexp, but find a problem. -* recursive-count-words:: Start with case of no words in region. -* Counting Exercise:: - -The `count-words-region' Function - -* Design count-words-region:: The definition using a `while' loop. -* Whitespace Bug:: The Whitespace Bug in `count-words-region'. - -Counting Words in a `defun' - -* Divide and Conquer:: -* Words and Symbols:: What to count? -* Syntax:: What constitutes a word or symbol? -* count-words-in-defun:: Very like `count-words'. -* Several defuns:: Counting several defuns in a file. -* Find a File:: Do you want to look at a file? -* lengths-list-file:: A list of the lengths of many definitions. -* Several files:: Counting in definitions in different files. -* Several files recursively:: Recursively counting in different files. -* Prepare the data:: Prepare the data for display in a graph. - -Count Words in `defuns' in Different Files - -* lengths-list-many-files:: Return a list of the lengths of defuns. -* append:: Attach one list to another. - -Prepare the Data for Display in a Graph - -* Sorting:: Sorting lists. -* Files List:: Making a list of files. -* Counting function definitions:: - -Readying a Graph - -* Columns of a graph:: -* graph-body-print:: How to print the body of a graph. -* recursive-graph-body-print:: -* Printed Axes:: -* Line Graph Exercise:: - -Your `.emacs' File - -* Default Configuration:: -* Site-wide Init:: You can write site-wide init files. -* defcustom:: Emacs will write code for you. -* Beginning a .emacs File:: How to write a `.emacs file'. -* Text and Auto-fill:: Automatically wrap lines. -* Mail Aliases:: Use abbreviations for email addresses. -* Indent Tabs Mode:: Don't use tabs with TeX -* Keybindings:: Create some personal keybindings. -* Keymaps:: More about key binding. -* Loading Files:: Load (i.e., evaluate) files automatically. -* Autoload:: Make functions available. -* Simple Extension:: Define a function; bind it to a key. -* X11 Colors:: Colors in X. -* Miscellaneous:: -* Mode Line:: How to customize your mode line. - -Debugging - -* debug:: How to use the built-in debugger. -* debug-on-entry:: Start debugging when you call a function. -* debug-on-quit:: Start debugging when you quit with C-g. -* edebug:: How to use Edebug, a source level debugger. -* Debugging Exercises:: - -Handling the Kill Ring - -* current-kill:: -* yank:: Paste a copy of a clipped element. -* yank-pop:: Insert element pointed to. -* ring file:: - -The `current-kill' Function - -* Understanding current-kill:: - -`current-kill' in Outline - -* Digression concerning error:: How to mislead humans, but not computers. -* Determining the Element:: - -A Graph with Labelled Axes - -* Labelled Example:: -* print-graph Varlist:: `let' expression in `print-graph'. -* print-Y-axis:: Print a label for the vertical axis. -* print-X-axis:: Print a horizontal label. -* Print Whole Graph:: The function to print a complete graph. - -The `print-Y-axis' Function - -* Height of label:: What height for the Y axis? -* Compute a Remainder:: How to compute the remainder of a division. -* Y Axis Element:: Construct a line for the Y axis. -* Y-axis-column:: Generate a list of Y axis labels. -* print-Y-axis Penultimate:: A not quite final version. - -The `print-X-axis' Function - -* Similarities differences:: Much like `print-Y-axis', but not exactly. -* X Axis Tic Marks:: Create tic marks for the horizontal axis. - -Printing the Whole Graph - -* The final version:: A few changes. -* Test print-graph:: Run a short test. -* Graphing words in defuns:: Executing the final code. -* lambda:: How to write an anonymous function. -* mapcar:: Apply a function to elements of a list. -* Another Bug:: Yet another bug ... most insidious. -* Final printed graph:: The graph itself! - - -File: eintr, Node: Preface, Next: List Processing, Prev: Top, Up: Top - -Preface -******* - -Most of the GNU Emacs integrated environment is written in the -programming language called Emacs Lisp. The code written in this -programming language is the software--the sets of instructions--that -tell the computer what to do when you give it commands. Emacs is -designed so that you can write new code in Emacs Lisp and easily -install it as an extension to the editor. - -(GNU Emacs is sometimes called an "extensible editor", but it does much -more than provide editing capabilities. It is better to refer to Emacs -as an "extensible computing environment". However, that phrase is -quite a mouthful. It is easier to refer to Emacs simply as an editor. -Moreover, everything you do in Emacs--find the Mayan date and phases of -the moon, simplify polynomials, debug code, manage files, read letters, -write books--all these activities are kinds of editing in the most -general sense of the word.) - -* Menu: - -* Why:: -* On Reading this Text:: -* Who You Are:: -* Lisp History:: -* Note for Novices:: -* Thank You:: - - -File: eintr, Node: Why, Next: On Reading this Text, Prev: Preface, Up: Preface - -Why Study Emacs Lisp? -===================== - -Although Emacs Lisp is usually thought of in association only with -Emacs, it is a full computer programming language. You can use Emacs -Lisp as you would any other programming language. - -Perhaps you want to understand programming; perhaps you want to extend -Emacs; or perhaps you want to become a programmer. This introduction to -Emacs Lisp is designed to get you started: to guide you in learning the -fundamentals of programming, and more importantly, to show you how you -can teach yourself to go further. - - -File: eintr, Node: On Reading this Text, Next: Who You Are, Prev: Why, Up: Preface - -On Reading this Text -==================== - -All through this document, you will see little sample programs you can -run inside of Emacs. If you read this document in Info inside of GNU -Emacs, you can run the programs as they appear. (This is easy to do and -is explained when the examples are presented.) Alternatively, you can -read this introduction as a printed book while sitting beside a computer -running Emacs. (This is what I like to do; I like printed books.) If -you don't have a running Emacs beside you, you can still read this book, -but in this case, it is best to treat it as a novel or as a travel guide -to a country not yet visited: interesting, but not the same as being -there. - -Much of this introduction is dedicated to walk-throughs or guided tours -of code used in GNU Emacs. These tours are designed for two purposes: -first, to give you familiarity with real, working code (code you use -every day); and, second, to give you familiarity with the way Emacs -works. It is interesting to see how a working environment is -implemented. Also, I hope that you will pick up the habit of browsing -through source code. You can learn from it and mine it for ideas. -Having GNU Emacs is like having a dragon's cave of treasures. - -In addition to learning about Emacs as an editor and Emacs Lisp as a -programming language, the examples and guided tours will give you an -opportunity to get acquainted with Emacs as a Lisp programming -environment. GNU Emacs supports programming and provides tools that -you will want to become comfortable using, such as `M-.' (the key which -invokes the `find-tag' command). You will also learn about buffers and -other objects that are part of the environment. Learning about these -features of Emacs is like learning new routes around your home town. - -Finally, I hope to convey some of the skills for using Emacs to learn -aspects of programming that you don't know. You can often use Emacs to -help you understand what puzzles you or to find out how to do something -new. This self-reliance is not only a pleasure, but an advantage. - - -File: eintr, Node: Who You Are, Next: Lisp History, Prev: On Reading this Text, Up: Preface - -For Whom This is Written -======================== - -This text is written as an elementary introduction for people who are -not programmers. If you are a programmer, you may not be satisfied with -this primer. The reason is that you may have become expert at reading -reference manuals and be put off by the way this text is organized. - -An expert programmer who reviewed this text said to me: - - I prefer to learn from reference manuals. I "dive into" each - paragraph, and "come up for air" between paragraphs. - - When I get to the end of a paragraph, I assume that that subject is - done, finished, that I know everything I need (with the possible - exception of the case when the next paragraph starts talking about - it in more detail). I expect that a well written reference manual - will not have a lot of redundancy, and that it will have excellent - pointers to the (one) place where the information I want is. - -This introduction is not written for this person! - -Firstly, I try to say everything at least three times: first, to -introduce it; second, to show it in context; and third, to show it in a -different context, or to review it. - -Secondly, I hardly ever put all the information about a subject in one -place, much less in one paragraph. To my way of thinking, that imposes -too heavy a burden on the reader. Instead I try to explain only what -you need to know at the time. (Sometimes I include a little extra -information so you won't be surprised later when the additional -information is formally introduced.) - -When you read this text, you are not expected to learn everything the -first time. Frequently, you need only make, as it were, a `nodding -acquaintance' with some of the items mentioned. My hope is that I have -structured the text and given you enough hints that you will be alert to -what is important, and concentrate on it. - -You will need to "dive into" some paragraphs; there is no other way to -read them. But I have tried to keep down the number of such -paragraphs. This book is intended as an approachable hill, rather than -as a daunting mountain. - -This introduction to `Programming in Emacs Lisp' has a companion -document, *Note The GNU Emacs Lisp Reference Manual: (elisp)Top. The -reference manual has more detail than this introduction. In the -reference manual, all the information about one topic is concentrated -in one place. You should turn to it if you are like the programmer -quoted above. And, of course, after you have read this `Introduction', -you will find the `Reference Manual' useful when you are writing your -own programs. - - -File: eintr, Node: Lisp History, Next: Note for Novices, Prev: Who You Are, Up: Preface - -Lisp History -============ - -Lisp was first developed in the late 1950s at the Massachusetts -Institute of Technology for research in artificial intelligence. The -great power of the Lisp language makes it superior for other purposes as -well, such as writing editor commands and integrated environments. - -GNU Emacs Lisp is largely inspired by Maclisp, which was written at MIT -in the 1960s. It is somewhat inspired by Common Lisp, which became a -standard in the 1980s. However, Emacs Lisp is much simpler than Common -Lisp. (The standard Emacs distribution contains an optional extensions -file, `cl.el', that adds many Common Lisp features to Emacs Lisp.) - - -File: eintr, Node: Note for Novices, Next: Thank You, Prev: Lisp History, Up: Preface - -A Note for Novices -================== - -If you don't know GNU Emacs, you can still read this document -profitably. However, I recommend you learn Emacs, if only to learn to -move around your computer screen. You can teach yourself how to use -Emacs with the on-line tutorial. To use it, type `C-h t'. (This means -you press and release the <CTRL> key and the `h' at the same time, and -then press and release `t'.) - -Also, I often refer to one of Emacs' standard commands by listing the -keys which you press to invoke the command and then giving the name of -the command in parentheses, like this: `M-C-\' (`indent-region'). What -this means is that the `indent-region' command is customarily invoked -by typing `M-C-\'. (You can, if you wish, change the keys that are -typed to invoke the command; this is called "rebinding". *Note -Keymaps: Keymaps.) The abbreviation `M-C-\' means that you type your -<META> key, <CTRL> key and <\> key all at the same time. (On many -modern keyboards the <META> key is labelled <ALT>.) Sometimes a -combination like this is called a keychord, since it is similar to the -way you play a chord on a piano. If your keyboard does not have a -<META> key, the <ESC> key prefix is used in place of it. In this case, -`M-C-\' means that you press and release your <ESC> key and then type -the <CTRL> key and the <\> key at the same time. But usually `M-C-\' -means press the <CTRL> key along with the key that is labelled <ALT> -and, at the same time, press the <\> key. - -In addition to typing a lone keychord, you can prefix what you type -with `C-u', which is called the `universal argument'. The `C-u' -keychord passes an argument to the subsequent command. Thus, to indent -a region of plain text by 6 spaces, mark the region, and then type -`C-u 6 M-C-\'. (If you do not specify a number, Emacs either passes -the number 4 to the command or otherwise runs the command differently -than it would otherwise.) *Note Numeric Arguments: (emacs)Arguments. - -If you are reading this in Info using GNU Emacs, you can read through -this whole document just by pressing the space bar, <SPC>. (To learn -about Info, type `C-h i' and then select Info.) - -A note on terminology: when I use the word Lisp alone, I often am -referring to the various dialects of Lisp in general, but when I speak -of Emacs Lisp, I am referring to GNU Emacs Lisp in particular. - - -File: eintr, Node: Thank You, Prev: Note for Novices, Up: Preface - -Thank You -========= - -My thanks to all who helped me with this book. My especial thanks to -Jim Blandy, Noah Friedman, Jim Kingdon, Roland McGrath, Frank Ritter, -Randy Smith, Richard M. Stallman, and Melissa Weisshaus. My thanks -also go to both Philip Johnson and David Stampe for their patient -encouragement. My mistakes are my own. - - Robert J. Chassell - - -File: eintr, Node: List Processing, Next: Practicing Evaluation, Prev: Preface, Up: Top - -1 List Processing -***************** - -To the untutored eye, Lisp is a strange programming language. In Lisp -code there are parentheses everywhere. Some people even claim that the -name stands for `Lots of Isolated Silly Parentheses'. But the claim is -unwarranted. Lisp stands for LISt Processing, and the programming -language handles _lists_ (and lists of lists) by putting them between -parentheses. The parentheses mark the boundaries of the list. -Sometimes a list is preceded by a single apostrophe or quotation mark, -`''(1) Lists are the basis of Lisp. - -* Menu: - -* Lisp Lists:: -* Run a Program:: -* Making Errors:: -* Names & Definitions:: -* Lisp Interpreter:: -* Evaluation:: -* Variables:: -* Arguments:: -* set & setq:: -* Summary:: -* Error Message Exercises:: - ----------- Footnotes ---------- - -(1) The single apostrophe or quotation mark is an abbreviation for the -function `quote'; you need not think about functions now; functions are -defined in *Note Generate an Error Message: Making Errors. - - -File: eintr, Node: Lisp Lists, Next: Run a Program, Prev: List Processing, Up: List Processing - -1.1 Lisp Lists -============== - -In Lisp, a list looks like this: `'(rose violet daisy buttercup)'. -This list is preceded by a single apostrophe. It could just as well be -written as follows, which looks more like the kind of list you are -likely to be familiar with: - - '(rose - violet - daisy - buttercup) - -The elements of this list are the names of the four different flowers, -separated from each other by whitespace and surrounded by parentheses, -like flowers in a field with a stone wall around them. - -* Menu: - -* Numbers Lists:: -* Lisp Atoms:: -* Whitespace in Lists:: -* Typing Lists:: - - -File: eintr, Node: Numbers Lists, Next: Lisp Atoms, Prev: Lisp Lists, Up: Lisp Lists - -Numbers, Lists inside of Lists ------------------------------- - -Lists can also have numbers in them, as in this list: `(+ 2 2)'. This -list has a plus-sign, `+', followed by two `2's, each separated by -whitespace. - -In Lisp, both data and programs are represented the same way; that is, -they are both lists of words, numbers, or other lists, separated by -whitespace and surrounded by parentheses. (Since a program looks like -data, one program may easily serve as data for another; this is a very -powerful feature of Lisp.) (Incidentally, these two parenthetical -remarks are _not_ Lisp lists, because they contain `;' and `.' as -punctuation marks.) - -Here is another list, this time with a list inside of it: - - '(this list has (a list inside of it)) - -The components of this list are the words `this', `list', `has', and -the list `(a list inside of it)'. The interior list is made up of the -words `a', `list', `inside', `of', `it'. - - -File: eintr, Node: Lisp Atoms, Next: Whitespace in Lists, Prev: Numbers Lists, Up: Lisp Lists - -1.1.1 Lisp Atoms ----------------- - -In Lisp, what we have been calling words are called "atoms". This term -comes from the historical meaning of the word atom, which means -`indivisible'. As far as Lisp is concerned, the words we have been -using in the lists cannot be divided into any smaller parts and still -mean the same thing as part of a program; likewise with numbers and -single character symbols like `+'. On the other hand, unlike an -ancient atom, a list can be split into parts. (*Note `car' `cdr' & -`cons' Fundamental Functions: car cdr & cons.) - -In a list, atoms are separated from each other by whitespace. They can -be right next to a parenthesis. - -Technically speaking, a list in Lisp consists of parentheses surrounding -atoms separated by whitespace or surrounding other lists or surrounding -both atoms and other lists. A list can have just one atom in it or -have nothing in it at all. A list with nothing in it looks like this: -`()', and is called the "empty list". Unlike anything else, an empty -list is considered both an atom and a list at the same time. - -The printed representation of both atoms and lists are called "symbolic -expressions" or, more concisely, "s-expressions". The word -"expression" by itself can refer to either the printed representation, -or to the atom or list as it is held internally in the computer. -Often, people use the term "expression" indiscriminately. (Also, in -many texts, the word "form" is used as a synonym for expression.) - -Incidentally, the atoms that make up our universe were named such when -they were thought to be indivisible; but it has been found that physical -atoms are not indivisible. Parts can split off an atom or it can -fission into two parts of roughly equal size. Physical atoms were named -prematurely, before their truer nature was found. In Lisp, certain -kinds of atom, such as an array, can be separated into parts; but the -mechanism for doing this is different from the mechanism for splitting a -list. As far as list operations are concerned, the atoms of a list are -unsplittable. - -As in English, the meanings of the component letters of a Lisp atom are -different from the meaning the letters make as a word. For example, -the word for the South American sloth, the `ai', is completely -different from the two words, `a', and `i'. - -There are many kinds of atom in nature but only a few in Lisp: for -example, "numbers", such as 37, 511, or 1729, and "symbols", such as -`+', `foo', or `forward-line'. The words we have listed in the -examples above are all symbols. In everyday Lisp conversation, the -word "atom" is not often used, because programmers usually try to be -more specific about what kind of atom they are dealing with. Lisp -programming is mostly about symbols (and sometimes numbers) within -lists. (Incidentally, the preceding three word parenthetical remark is -a proper list in Lisp, since it consists of atoms, which in this case -are symbols, separated by whitespace and enclosed by parentheses, -without any non-Lisp punctuation.) - -In addition, text between double quotation marks--even sentences or -paragraphs--is an atom. Here is an example: - - '(this list includes "text between quotation marks.") - -In Lisp, all of the quoted text including the punctuation mark and the -blank spaces is a single atom. This kind of atom is called a "string" -(for `string of characters') and is the sort of thing that is used for -messages that a computer can print for a human to read. Strings are a -different kind of atom than numbers or symbols and are used differently. - - -File: eintr, Node: Whitespace in Lists, Next: Typing Lists, Prev: Lisp Atoms, Up: Lisp Lists - -1.1.2 Whitespace in Lists -------------------------- - -The amount of whitespace in a list does not matter. From the point of -view of the Lisp language, - - '(this list - looks like this) - -is exactly the same as this: - - '(this list looks like this) - -Both examples show what to Lisp is the same list, the list made up of -the symbols `this', `list', `looks', `like', and `this' in that order. - -Extra whitespace and newlines are designed to make a list more readable -by humans. When Lisp reads the expression, it gets rid of all the extra -whitespace (but it needs to have at least one space between atoms in -order to tell them apart.) - -Odd as it seems, the examples we have seen cover almost all of what Lisp -lists look like! Every other list in Lisp looks more or less like one -of these examples, except that the list may be longer and more complex. -In brief, a list is between parentheses, a string is between quotation -marks, a symbol looks like a word, and a number looks like a number. -(For certain situations, square brackets, dots and a few other special -characters may be used; however, we will go quite far without them.) - - -File: eintr, Node: Typing Lists, Prev: Whitespace in Lists, Up: Lisp Lists - -1.1.3 GNU Emacs Helps You Type Lists ------------------------------------- - -When you type a Lisp expression in GNU Emacs using either Lisp -Interaction mode or Emacs Lisp mode, you have available to you several -commands to format the Lisp expression so it is easy to read. For -example, pressing the <TAB> key automatically indents the line the -cursor is on by the right amount. A command to properly indent the -code in a region is customarily bound to `M-C-\'. Indentation is -designed so that you can see which elements of a list belong to which -list--elements of a sub-list are indented more than the elements of the -enclosing list. - -In addition, when you type a closing parenthesis, Emacs momentarily -jumps the cursor back to the matching opening parenthesis, so you can -see which one it is. This is very useful, since every list you type in -Lisp must have its closing parenthesis match its opening parenthesis. -(*Note Major Modes: (emacs)Major Modes, for more information about -Emacs' modes.) - - -File: eintr, Node: Run a Program, Next: Making Errors, Prev: Lisp Lists, Up: List Processing - -1.2 Run a Program -================= - -A list in Lisp--any list--is a program ready to run. If you run it -(for which the Lisp jargon is "evaluate"), the computer will do one of -three things: do nothing except return to you the list itself; send you -an error message; or, treat the first symbol in the list as a command -to do something. (Usually, of course, it is the last of these three -things that you really want!) - -The single apostrophe, `'', that I put in front of some of the example -lists in preceding sections is called a "quote"; when it precedes a -list, it tells Lisp to do nothing with the list, other than take it as -it is written. But if there is no quote preceding a list, the first -item of the list is special: it is a command for the computer to obey. -(In Lisp, these commands are called _functions_.) The list `(+ 2 2)' -shown above did not have a quote in front of it, so Lisp understands -that the `+' is an instruction to do something with the rest of the -list: add the numbers that follow. - -If you are reading this inside of GNU Emacs in Info, here is how you can -evaluate such a list: place your cursor immediately after the right -hand parenthesis of the following list and then type `C-x C-e': - - (+ 2 2) - -You will see the number `4' appear in the echo area. (In the jargon, -what you have just done is "evaluate the list." The echo area is the -line at the bottom of the screen that displays or "echoes" text.) Now -try the same thing with a quoted list: place the cursor right after -the following list and type `C-x C-e': - - '(this is a quoted list) - -You will see `(this is a quoted list)' appear in the echo area. - -In both cases, what you are doing is giving a command to the program -inside of GNU Emacs called the "Lisp interpreter"--giving the -interpreter a command to evaluate the expression. The name of the Lisp -interpreter comes from the word for the task done by a human who comes -up with the meaning of an expression--who "interprets" it. - -You can also evaluate an atom that is not part of a list--one that is -not surrounded by parentheses; again, the Lisp interpreter translates -from the humanly readable expression to the language of the computer. -But before discussing this (*note Variables::), we will discuss what the -Lisp interpreter does when you make an error. - - -File: eintr, Node: Making Errors, Next: Names & Definitions, Prev: Run a Program, Up: List Processing - -1.3 Generate an Error Message -============================= - -Partly so you won't worry if you do it accidentally, we will now give a -command to the Lisp interpreter that generates an error message. This -is a harmless activity; and indeed, we will often try to generate error -messages intentionally. Once you understand the jargon, error messages -can be informative. Instead of being called "error" messages, they -should be called "help" messages. They are like signposts to a -traveller in a strange country; deciphering them can be hard, but once -understood, they can point the way. - -The error message is generated by a built-in GNU Emacs debugger. We -will `enter the debugger'. You get out of the debugger by typing `q'. - -What we will do is evaluate a list that is not quoted and does not have -a meaningful command as its first element. Here is a list almost -exactly the same as the one we just used, but without the single-quote -in front of it. Position the cursor right after it and type `C-x C-e': - - (this is an unquoted list) - -What you see depends on which version of Emacs you are running. GNU -Emacs version 22 provides more information than version 20 and before. -First, the more recent result of generating an error; then the earlier, -version 20 result. - -In GNU Emacs version 22, a `*Backtrace*' window will open up and you -will see the following in it: - - ---------- Buffer: *Backtrace* ---------- - Debugger entered--Lisp error: (void-function this) - (this is an unquoted list) - eval((this is an unquoted list)) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) - ---------- Buffer: *Backtrace* ---------- - -Your cursor will be in this window (you may have to wait a few seconds -before it becomes visible). To quit the debugger and make the debugger -window go away, type: - - q - -Please type `q' right now, so you become confident that you can get out -of the debugger. Then, type `C-x C-e' again to re-enter it. - -Based on what we already know, we can almost read this error message. - -You read the `*Backtrace*' buffer from the bottom up; it tells you what -Emacs did. When you typed `C-x C-e', you made an interactive call to -the command `eval-last-sexp'. `eval' is an abbreviation for `evaluate' -and `sexp' is an abbreviation for `symbolic expression'. The command -means `evaluate last symbolic expression', which is the expression just -before your cursor. - -Each line above tells you what the Lisp interpreter evaluated next. -The most recent action is at the top. The buffer is called the -`*Backtrace*' buffer because it enables you to track Emacs backwards. - -At the top of the `*Backtrace*' buffer, you see the line: - - Debugger entered--Lisp error: (void-function this) - -The Lisp interpreter tried to evaluate the first atom of the list, the -word `this'. It is this action that generated the error message -`void-function this'. - -The message contains the words `void-function' and `this'. - -The word `function' was mentioned once before. It is a very important -word. For our purposes, we can define it by saying that a "function" -is a set of instructions to the computer that tell the computer to do -something. - -Now we can begin to understand the error message: `void-function this'. -The function (that is, the word `this') does not have a definition of -any set of instructions for the computer to carry out. - -The slightly odd word, `void-function', is designed to cover the way -Emacs Lisp is implemented, which is that when a symbol does not have a -function definition attached to it, the place that should contain the -instructions is `void'. - -On the other hand, since we were able to add 2 plus 2 successfully, by -evaluating `(+ 2 2)', we can infer that the symbol `+' must have a set -of instructions for the computer to obey and those instructions must be -to add the numbers that follow the `+'. - -In GNU Emacs version 20, and in earlier versions, you will see only one -line of error message; it will appear in the echo area and look like -this: - - Symbol's function definition is void: this - -(Also, your terminal may beep at you--some do, some don't; and others -blink. This is just a device to get your attention.) The message goes -away as soon as you type another key, even just to move the cursor. - -We know the meaning of the word `Symbol'. It refers to the first atom -of the list, the word `this'. The word `function' refers to the -instructions that tell the computer what to do. (Technically, the -symbol tells the computer where to find the instructions, but this is a -complication we can ignore for the moment.) - -The error message can be understood: `Symbol's function definition is -void: this'. The symbol (that is, the word `this') lacks instructions -for the computer to carry out. - - -File: eintr, Node: Names & Definitions, Next: Lisp Interpreter, Prev: Making Errors, Up: List Processing - -1.4 Symbol Names and Function Definitions -========================================= - -We can articulate another characteristic of Lisp based on what we have -discussed so far--an important characteristic: a symbol, like `+', is -not itself the set of instructions for the computer to carry out. -Instead, the symbol is used, perhaps temporarily, as a way of locating -the definition or set of instructions. What we see is the name through -which the instructions can be found. Names of people work the same -way. I can be referred to as `Bob'; however, I am not the letters `B', -`o', `b' but am, or was, the consciousness consistently associated with -a particular life-form. The name is not me, but it can be used to -refer to me. - -In Lisp, one set of instructions can be attached to several names. For -example, the computer instructions for adding numbers can be linked to -the symbol `plus' as well as to the symbol `+' (and are in some -dialects of Lisp). Among humans, I can be referred to as `Robert' as -well as `Bob' and by other words as well. - -On the other hand, a symbol can have only one function definition -attached to it at a time. Otherwise, the computer would be confused as -to which definition to use. If this were the case among people, only -one person in the world could be named `Bob'. However, the function -definition to which the name refers can be changed readily. (*Note -Install a Function Definition: Install.) - -Since Emacs Lisp is large, it is customary to name symbols in a way -that identifies the part of Emacs to which the function belongs. Thus, -all the names for functions that deal with Texinfo start with -`texinfo-' and those for functions that deal with reading mail start -with `rmail-'. - - -File: eintr, Node: Lisp Interpreter, Next: Evaluation, Prev: Names & Definitions, Up: List Processing - -1.5 The Lisp Interpreter -======================== - -Based on what we have seen, we can now start to figure out what the -Lisp interpreter does when we command it to evaluate a list. First, it -looks to see whether there is a quote before the list; if there is, the -interpreter just gives us the list. On the other hand, if there is no -quote, the interpreter looks at the first element in the list and sees -whether it has a function definition. If it does, the interpreter -carries out the instructions in the function definition. Otherwise, -the interpreter prints an error message. - -This is how Lisp works. Simple. There are added complications which we -will get to in a minute, but these are the fundamentals. Of course, to -write Lisp programs, you need to know how to write function definitions -and attach them to names, and how to do this without confusing either -yourself or the computer. - -* Menu: - -* Complications:: -* Byte Compiling:: - - -File: eintr, Node: Complications, Next: Byte Compiling, Prev: Lisp Interpreter, Up: Lisp Interpreter - -Complications -------------- - -Now, for the first complication. In addition to lists, the Lisp -interpreter can evaluate a symbol that is not quoted and does not have -parentheses around it. The Lisp interpreter will attempt to determine -the symbol's value as a "variable". This situation is described in the -section on variables. (*Note Variables::.) - -The second complication occurs because some functions are unusual and do -not work in the usual manner. Those that don't are called "special -forms". They are used for special jobs, like defining a function, and -there are not many of them. In the next few chapters, you will be -introduced to several of the more important special forms. - -The third and final complication is this: if the function that the Lisp -interpreter is looking at is not a special form, and if it is part of a -list, the Lisp interpreter looks to see whether the list has a list -inside of it. If there is an inner list, the Lisp interpreter first -figures out what it should do with the inside list, and then it works on -the outside list. If there is yet another list embedded inside the -inner list, it works on that one first, and so on. It always works on -the innermost list first. The interpreter works on the innermost list -first, to evaluate the result of that list. The result may be used by -the enclosing expression. - -Otherwise, the interpreter works left to right, from one expression to -the next. - - -File: eintr, Node: Byte Compiling, Prev: Complications, Up: Lisp Interpreter - -1.5.1 Byte Compiling --------------------- - -One other aspect of interpreting: the Lisp interpreter is able to -interpret two kinds of entity: humanly readable code, on which we will -focus exclusively, and specially processed code, called "byte compiled" -code, which is not humanly readable. Byte compiled code runs faster -than humanly readable code. - -You can transform humanly readable code into byte compiled code by -running one of the compile commands such as `byte-compile-file'. Byte -compiled code is usually stored in a file that ends with a `.elc' -extension rather than a `.el' extension. You will see both kinds of -file in the `emacs/lisp' directory; the files to read are those with -`.el' extensions. - -As a practical matter, for most things you might do to customize or -extend Emacs, you do not need to byte compile; and I will not discuss -the topic here. *Note Byte Compilation: (elisp)Byte Compilation, for a -full description of byte compilation. - - -File: eintr, Node: Evaluation, Next: Variables, Prev: Lisp Interpreter, Up: List Processing - -1.6 Evaluation -============== - -When the Lisp interpreter works on an expression, the term for the -activity is called "evaluation". We say that the interpreter -`evaluates the expression'. I've used this term several times before. -The word comes from its use in everyday language, `to ascertain the -value or amount of; to appraise', according to `Webster's New -Collegiate Dictionary'. - -After evaluating an expression, the Lisp interpreter will most likely -"return" the value that the computer produces by carrying out the -instructions it found in the function definition, or perhaps it will -give up on that function and produce an error message. (The interpreter -may also find itself tossed, so to speak, to a different function or it -may attempt to repeat continually what it is doing for ever and ever in -what is called an `infinite loop'. These actions are less common; and -we can ignore them.) Most frequently, the interpreter returns a value. - -At the same time the interpreter returns a value, it may do something -else as well, such as move a cursor or copy a file; this other kind of -action is called a "side effect". Actions that we humans think are -important, such as printing results, are often "side effects" to the -Lisp interpreter. The jargon can sound peculiar, but it turns out that -it is fairly easy to learn to use side effects. - -In summary, evaluating a symbolic expression most commonly causes the -Lisp interpreter to return a value and perhaps carry out a side effect; -or else produce an error. - -* Menu: - -* Evaluating Inner Lists:: - - -File: eintr, Node: Evaluating Inner Lists, Prev: Evaluation, Up: Evaluation - -1.6.1 Evaluating Inner Lists ----------------------------- - -If evaluation applies to a list that is inside another list, the outer -list may use the value returned by the first evaluation as information -when the outer list is evaluated. This explains why inner expressions -are evaluated first: the values they return are used by the outer -expressions. - -We can investigate this process by evaluating another addition example. -Place your cursor after the following expression and type `C-x C-e': - - (+ 2 (+ 3 3)) - -The number 8 will appear in the echo area. - -What happens is that the Lisp interpreter first evaluates the inner -expression, `(+ 3 3)', for which the value 6 is returned; then it -evaluates the outer expression as if it were written `(+ 2 6)', which -returns the value 8. Since there are no more enclosing expressions to -evaluate, the interpreter prints that value in the echo area. - -Now it is easy to understand the name of the command invoked by the -keystrokes `C-x C-e': the name is `eval-last-sexp'. The letters `sexp' -are an abbreviation for `symbolic expression', and `eval' is an -abbreviation for `evaluate'. The command means `evaluate last symbolic -expression'. - -As an experiment, you can try evaluating the expression by putting the -cursor at the beginning of the next line immediately following the -expression, or inside the expression. - -Here is another copy of the expression: - - (+ 2 (+ 3 3)) - -If you place the cursor at the beginning of the blank line that -immediately follows the expression and type `C-x C-e', you will still -get the value 8 printed in the echo area. Now try putting the cursor -inside the expression. If you put it right after the next to last -parenthesis (so it appears to sit on top of the last parenthesis), you -will get a 6 printed in the echo area! This is because the command -evaluates the expression `(+ 3 3)'. - -Now put the cursor immediately after a number. Type `C-x C-e' and you -will get the number itself. In Lisp, if you evaluate a number, you get -the number itself--this is how numbers differ from symbols. If you -evaluate a list starting with a symbol like `+', you will get a value -returned that is the result of the computer carrying out the -instructions in the function definition attached to that name. If a -symbol by itself is evaluated, something different happens, as we will -see in the next section. - - -File: eintr, Node: Variables, Next: Arguments, Prev: Evaluation, Up: List Processing - -1.7 Variables -============= - -In Emacs Lisp, a symbol can have a value attached to it just as it can -have a function definition attached to it. The two are different. The -function definition is a set of instructions that a computer will obey. -A value, on the other hand, is something, such as number or a name, -that can vary (which is why such a symbol is called a variable). The -value of a symbol can be any expression in Lisp, such as a symbol, -number, list, or string. A symbol that has a value is often called a -"variable". - -A symbol can have both a function definition and a value attached to it -at the same time. Or it can have just one or the other. The two are -separate. This is somewhat similar to the way the name Cambridge can -refer to the city in Massachusetts and have some information attached -to the name as well, such as "great programming center". - -Another way to think about this is to imagine a symbol as being a chest -of drawers. The function definition is put in one drawer, the value in -another, and so on. What is put in the drawer holding the value can be -changed without affecting the contents of the drawer holding the -function definition, and vice-verse. - -* Menu: - -* fill-column Example:: -* Void Function:: -* Void Variable:: - - -File: eintr, Node: fill-column Example, Next: Void Function, Prev: Variables, Up: Variables - -`fill-column', an Example Variable ----------------------------------- - -The variable `fill-column' illustrates a symbol with a value attached -to it: in every GNU Emacs buffer, this symbol is set to some value, -usually 72 or 70, but sometimes to some other value. To find the value -of this symbol, evaluate it by itself. If you are reading this in Info -inside of GNU Emacs, you can do this by putting the cursor after the -symbol and typing `C-x C-e': - - fill-column - -After I typed `C-x C-e', Emacs printed the number 72 in my echo area. -This is the value for which `fill-column' is set for me as I write -this. It may be different for you in your Info buffer. Notice that -the value returned as a variable is printed in exactly the same way as -the value returned by a function carrying out its instructions. From -the point of view of the Lisp interpreter, a value returned is a value -returned. What kind of expression it came from ceases to matter once -the value is known. - -A symbol can have any value attached to it or, to use the jargon, we can -"bind" the variable to a value: to a number, such as 72; to a string, -`"such as this"'; to a list, such as `(spruce pine oak)'; we can even -bind a variable to a function definition. - -A symbol can be bound to a value in several ways. *Note Setting the -Value of a Variable: set & setq, for information about one way to do -this. - - -File: eintr, Node: Void Function, Next: Void Variable, Prev: fill-column Example, Up: Variables - -1.7.1 Error Message for a Symbol Without a Function ---------------------------------------------------- - -When we evaluated `fill-column' to find its value as a variable, we did -not place parentheses around the word. This is because we did not -intend to use it as a function name. - -If `fill-column' were the first or only element of a list, the Lisp -interpreter would attempt to find the function definition attached to -it. But `fill-column' has no function definition. Try evaluating this: - - (fill-column) - -In GNU Emacs version 22, you will create a `*Backtrace*' buffer that -says: - - ---------- Buffer: *Backtrace* ---------- - Debugger entered--Lisp error: (void-function fill-column) - (fill-column) - eval((fill-column)) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) - ---------- Buffer: *Backtrace* ---------- - -(Remember, to quit the debugger and make the debugger window go away, -type `q' in the `*Backtrace*' buffer.) - - -File: eintr, Node: Void Variable, Prev: Void Function, Up: Variables - -1.7.2 Error Message for a Symbol Without a Value ------------------------------------------------- - -If you attempt to evaluate a symbol that does not have a value bound to -it, you will receive an error message. You can see this by -experimenting with our 2 plus 2 addition. In the following expression, -put your cursor right after the `+', before the first number 2, type -`C-x C-e': - - (+ 2 2) - -In GNU Emacs 22, you will create a `*Backtrace*' buffer that says: - - ---------- Buffer: *Backtrace* ---------- - Debugger entered--Lisp error: (void-variable +) - eval(+) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) - ---------- Buffer: *Backtrace* ---------- - -(As with the other times we entered the debugger, you can quit by -typing `q' in the `*Backtrace*' buffer.) - -This backtrace is different from the very first error message we saw, -which said, `Debugger entered--Lisp error: (void-function this)'. In -this case, the function does not have a value as a variable; while in -the other error message, the function (the word `this') did not have a -definition. - -In this experiment with the `+', what we did was cause the Lisp -interpreter to evaluate the `+' and look for the value of the variable -instead of the function definition. We did this by placing the cursor -right after the symbol rather than after the parenthesis of the -enclosing list as we did before. As a consequence, the Lisp interpreter -evaluated the preceding s-expression, which in this case was the `+' by -itself. - -Since `+' does not have a value bound to it, just the function -definition, the error message reported that the symbol's value as a -variable was void. - - -File: eintr, Node: Arguments, Next: set & setq, Prev: Variables, Up: List Processing - -1.8 Arguments -============= - -To see how information is passed to functions, let's look again at our -old standby, the addition of two plus two. In Lisp, this is written as -follows: - - (+ 2 2) - -If you evaluate this expression, the number 4 will appear in your echo -area. What the Lisp interpreter does is add the numbers that follow -the `+'. - -The numbers added by `+' are called the "arguments" of the function -`+'. These numbers are the information that is given to or "passed" to -the function. - -The word `argument' comes from the way it is used in mathematics and -does not refer to a disputation between two people; instead it refers to -the information presented to the function, in this case, to the `+'. -In Lisp, the arguments to a function are the atoms or lists that follow -the function. The values returned by the evaluation of these atoms or -lists are passed to the function. Different functions require -different numbers of arguments; some functions require none at all.(1) - -* Menu: - -* Data types:: -* Args as Variable or List:: -* Variable Number of Arguments:: -* Wrong Type of Argument:: -* message:: - ----------- Footnotes ---------- - -(1) It is curious to track the path by which the word `argument' came -to have two different meanings, one in mathematics and the other in -everyday English. According to the `Oxford English Dictionary', the -word derives from the Latin for `to make clear, prove'; thus it came to -mean, by one thread of derivation, `the evidence offered as proof', -which is to say, `the information offered', which led to its meaning in -Lisp. But in the other thread of derivation, it came to mean `to -assert in a manner against which others may make counter assertions', -which led to the meaning of the word as a disputation. (Note here that -the English word has two different definitions attached to it at the -same time. By contrast, in Emacs Lisp, a symbol cannot have two -different function definitions at the same time.) - - -File: eintr, Node: Data types, Next: Args as Variable or List, Prev: Arguments, Up: Arguments - -1.8.1 Arguments' Data Types ---------------------------- - -The type of data that should be passed to a function depends on what -kind of information it uses. The arguments to a function such as `+' -must have values that are numbers, since `+' adds numbers. Other -functions use different kinds of data for their arguments. - -For example, the `concat' function links together or unites two or more -strings of text to produce a string. The arguments are strings. -Concatenating the two character strings `abc', `def' produces the -single string `abcdef'. This can be seen by evaluating the following: - - (concat "abc" "def") - -The value produced by evaluating this expression is `"abcdef"'. - -A function such as `substring' uses both a string and numbers as -arguments. The function returns a part of the string, a substring of -the first argument. This function takes three arguments. Its first -argument is the string of characters, the second and third arguments are -numbers that indicate the beginning and end of the substring. The -numbers are a count of the number of characters (including spaces and -punctuations) from the beginning of the string. - -For example, if you evaluate the following: - - (substring "The quick brown fox jumped." 16 19) - -you will see `"fox"' appear in the echo area. The arguments are the -string and the two numbers. - -Note that the string passed to `substring' is a single atom even though -it is made up of several words separated by spaces. Lisp counts -everything between the two quotation marks as part of the string, -including the spaces. You can think of the `substring' function as a -kind of `atom smasher' since it takes an otherwise indivisible atom and -extracts a part. However, `substring' is only able to extract a -substring from an argument that is a string, not from another type of -atom such as a number or symbol. - - -File: eintr, Node: Args as Variable or List, Next: Variable Number of Arguments, Prev: Data types, Up: Arguments - -1.8.2 An Argument as the Value of a Variable or List ----------------------------------------------------- - -An argument can be a symbol that returns a value when it is evaluated. -For example, when the symbol `fill-column' by itself is evaluated, it -returns a number. This number can be used in an addition. - -Position the cursor after the following expression and type `C-x C-e': - - (+ 2 fill-column) - -The value will be a number two more than what you get by evaluating -`fill-column' alone. For me, this is 74, because my value of -`fill-column' is 72. - -As we have just seen, an argument can be a symbol that returns a value -when evaluated. In addition, an argument can be a list that returns a -value when it is evaluated. For example, in the following expression, -the arguments to the function `concat' are the strings `"The "' and -`" red foxes."' and the list `(number-to-string (+ 2 fill-column))'. - - (concat "The " (number-to-string (+ 2 fill-column)) " red foxes.") - -If you evaluate this expression--and if, as with my Emacs, -`fill-column' evaluates to 72--`"The 74 red foxes."' will appear in the -echo area. (Note that you must put spaces after the word `The' and -before the word `red' so they will appear in the final string. The -function `number-to-string' converts the integer that the addition -function returns to a string. `number-to-string' is also known as -`int-to-string'.) - - -File: eintr, Node: Variable Number of Arguments, Next: Wrong Type of Argument, Prev: Args as Variable or List, Up: Arguments - -1.8.3 Variable Number of Arguments ----------------------------------- - -Some functions, such as `concat', `+' or `*', take any number of -arguments. (The `*' is the symbol for multiplication.) This can be -seen by evaluating each of the following expressions in the usual way. -What you will see in the echo area is printed in this text after `=>', -which you may read as `evaluates to'. - -In the first set, the functions have no arguments: - - (+) => 0 - - (*) => 1 - -In this set, the functions have one argument each: - - (+ 3) => 3 - - (* 3) => 3 - -In this set, the functions have three arguments each: - - (+ 3 4 5) => 12 - - (* 3 4 5) => 60 - - -File: eintr, Node: Wrong Type of Argument, Next: message, Prev: Variable Number of Arguments, Up: Arguments - -1.8.4 Using the Wrong Type Object as an Argument ------------------------------------------------- - -When a function is passed an argument of the wrong type, the Lisp -interpreter produces an error message. For example, the `+' function -expects the values of its arguments to be numbers. As an experiment we -can pass it the quoted symbol `hello' instead of a number. Position -the cursor after the following expression and type `C-x C-e': - - (+ 2 'hello) - -When you do this you will generate an error message. What has happened -is that `+' has tried to add the 2 to the value returned by `'hello', -but the value returned by `'hello' is the symbol `hello', not a number. -Only numbers can be added. So `+' could not carry out its addition. - -In GNU Emacs version 22, you will create and enter a `*Backtrace*' -buffer that says: - - - ---------- Buffer: *Backtrace* ---------- - Debugger entered--Lisp error: - (wrong-type-argument number-or-marker-p hello) - +(2 hello) - eval((+ 2 (quote hello))) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) - ---------- Buffer: *Backtrace* ---------- - -As usual, the error message tries to be helpful and makes sense after -you learn how to read it.(1) - -The first part of the error message is straightforward; it says `wrong -type argument'. Next comes the mysterious jargon word -`number-or-marker-p'. This word is trying to tell you what kind of -argument the `+' expected. - -The symbol `number-or-marker-p' says that the Lisp interpreter is -trying to determine whether the information presented it (the value of -the argument) is a number or a marker (a special object representing a -buffer position). What it does is test to see whether the `+' is being -given numbers to add. It also tests to see whether the argument is -something called a marker, which is a specific feature of Emacs Lisp. -(In Emacs, locations in a buffer are recorded as markers. When the -mark is set with the `C-@' or `C-<SPC>' command, its position is kept -as a marker. The mark can be considered a number--the number of -characters the location is from the beginning of the buffer.) In Emacs -Lisp, `+' can be used to add the numeric value of marker positions as -numbers. - -The `p' of `number-or-marker-p' is the embodiment of a practice started -in the early days of Lisp programming. The `p' stands for `predicate'. -In the jargon used by the early Lisp researchers, a predicate refers -to a function to determine whether some property is true or false. So -the `p' tells us that `number-or-marker-p' is the name of a function -that determines whether it is true or false that the argument supplied -is a number or a marker. Other Lisp symbols that end in `p' include -`zerop', a function that tests whether its argument has the value of -zero, and `listp', a function that tests whether its argument is a list. - -Finally, the last part of the error message is the symbol `hello'. -This is the value of the argument that was passed to `+'. If the -addition had been passed the correct type of object, the value passed -would have been a number, such as 37, rather than a symbol like -`hello'. But then you would not have got the error message. - ----------- Footnotes ---------- - -(1) `(quote hello)' is an expansion of the abbreviation `'hello'. - - -File: eintr, Node: message, Prev: Wrong Type of Argument, Up: Arguments - -1.8.5 The `message' Function ----------------------------- - -Like `+', the `message' function takes a variable number of arguments. -It is used to send messages to the user and is so useful that we will -describe it here. - -A message is printed in the echo area. For example, you can print a -message in your echo area by evaluating the following list: - - (message "This message appears in the echo area!") - -The whole string between double quotation marks is a single argument -and is printed in toto. (Note that in this example, the message itself -will appear in the echo area within double quotes; that is because you -see the value returned by the `message' function. In most uses of -`message' in programs that you write, the text will be printed in the -echo area as a side-effect, without the quotes. *Note -`multiply-by-seven' in detail: multiply-by-seven in detail, for an -example of this.) - -However, if there is a `%s' in the quoted string of characters, the -`message' function does not print the `%s' as such, but looks to the -argument that follows the string. It evaluates the second argument and -prints the value at the location in the string where the `%s' is. - -You can see this by positioning the cursor after the following -expression and typing `C-x C-e': - - (message "The name of this buffer is: %s." (buffer-name)) - -In Info, `"The name of this buffer is: *info*."' will appear in the -echo area. The function `buffer-name' returns the name of the buffer -as a string, which the `message' function inserts in place of `%s'. - -To print a value as an integer, use `%d' in the same way as `%s'. For -example, to print a message in the echo area that states the value of -the `fill-column', evaluate the following: - - (message "The value of fill-column is %d." fill-column) - -On my system, when I evaluate this list, `"The value of fill-column is -72."' appears in my echo area(1). - -If there is more than one `%s' in the quoted string, the value of the -first argument following the quoted string is printed at the location -of the first `%s' and the value of the second argument is printed at -the location of the second `%s', and so on. - -For example, if you evaluate the following, - - (message "There are %d %s in the office!" - (- fill-column 14) "pink elephants") - -a rather whimsical message will appear in your echo area. On my system -it says, `"There are 58 pink elephants in the office!"'. - -The expression `(- fill-column 14)' is evaluated and the resulting -number is inserted in place of the `%d'; and the string in double -quotes, `"pink elephants"', is treated as a single argument and -inserted in place of the `%s'. (That is to say, a string between -double quotes evaluates to itself, like a number.) - -Finally, here is a somewhat complex example that not only illustrates -the computation of a number, but also shows how you can use an -expression within an expression to generate the text that is substituted -for `%s': - - (message "He saw %d %s" - (- fill-column 32) - (concat "red " - (substring - "The quick brown foxes jumped." 16 21) - " leaping.")) - -In this example, `message' has three arguments: the string, `"He saw %d -%s"', the expression, `(- fill-column 32)', and the expression -beginning with the function `concat'. The value resulting from the -evaluation of `(- fill-column 32)' is inserted in place of the `%d'; -and the value returned by the expression beginning with `concat' is -inserted in place of the `%s'. - -When your fill column is 70 and you evaluate the expression, the -message `"He saw 38 red foxes leaping."' appears in your echo area. - ----------- Footnotes ---------- - -(1) Actually, you can use `%s' to print a number. It is non-specific. -`%d' prints only the part of a number left of a decimal point, and not -anything that is not a number. - - -File: eintr, Node: set & setq, Next: Summary, Prev: Arguments, Up: List Processing - -1.9 Setting the Value of a Variable -=================================== - -There are several ways by which a variable can be given a value. One of -the ways is to use either the function `set' or the function `setq'. -Another way is to use `let' (*note let::). (The jargon for this -process is to "bind" a variable to a value.) - -The following sections not only describe how `set' and `setq' work but -also illustrate how arguments are passed. - -* Menu: - -* Using set:: -* Using setq:: -* Counting:: - - -File: eintr, Node: Using set, Next: Using setq, Prev: set & setq, Up: set & setq - -1.9.1 Using `set' ------------------ - -To set the value of the symbol `flowers' to the list `'(rose violet -daisy buttercup)', evaluate the following expression by positioning the -cursor after the expression and typing `C-x C-e'. - - (set 'flowers '(rose violet daisy buttercup)) - -The list `(rose violet daisy buttercup)' will appear in the echo area. -This is what is _returned_ by the `set' function. As a side effect, -the symbol `flowers' is bound to the list; that is, the symbol -`flowers', which can be viewed as a variable, is given the list as its -value. (This process, by the way, illustrates how a side effect to the -Lisp interpreter, setting the value, can be the primary effect that we -humans are interested in. This is because every Lisp function must -return a value if it does not get an error, but it will only have a -side effect if it is designed to have one.) - -After evaluating the `set' expression, you can evaluate the symbol -`flowers' and it will return the value you just set. Here is the -symbol. Place your cursor after it and type `C-x C-e'. - - flowers - -When you evaluate `flowers', the list `(rose violet daisy buttercup)' -appears in the echo area. - -Incidentally, if you evaluate `'flowers', the variable with a quote in -front of it, what you will see in the echo area is the symbol itself, -`flowers'. Here is the quoted symbol, so you can try this: - - 'flowers - -Note also, that when you use `set', you need to quote both arguments to -`set', unless you want them evaluated. Since we do not want either -argument evaluated, neither the variable `flowers' nor the list `(rose -violet daisy buttercup)', both are quoted. (When you use `set' without -quoting its first argument, the first argument is evaluated before -anything else is done. If you did this and `flowers' did not have a -value already, you would get an error message that the `Symbol's value -as variable is void'; on the other hand, if `flowers' did return a -value after it was evaluated, the `set' would attempt to set the value -that was returned. There are situations where this is the right thing -for the function to do; but such situations are rare.) - - -File: eintr, Node: Using setq, Next: Counting, Prev: Using set, Up: set & setq - -1.9.2 Using `setq' ------------------- - -As a practical matter, you almost always quote the first argument to -`set'. The combination of `set' and a quoted first argument is so -common that it has its own name: the special form `setq'. This special -form is just like `set' except that the first argument is quoted -automatically, so you don't need to type the quote mark yourself. -Also, as an added convenience, `setq' permits you to set several -different variables to different values, all in one expression. - -To set the value of the variable `carnivores' to the list `'(lion tiger -leopard)' using `setq', the following expression is used: - - (setq carnivores '(lion tiger leopard)) - -This is exactly the same as using `set' except the first argument is -automatically quoted by `setq'. (The `q' in `setq' means `quote'.) - -With `set', the expression would look like this: - - (set 'carnivores '(lion tiger leopard)) - -Also, `setq' can be used to assign different values to different -variables. The first argument is bound to the value of the second -argument, the third argument is bound to the value of the fourth -argument, and so on. For example, you could use the following to -assign a list of trees to the symbol `trees' and a list of herbivores -to the symbol `herbivores': - - (setq trees '(pine fir oak maple) - herbivores '(gazelle antelope zebra)) - -(The expression could just as well have been on one line, but it might -not have fit on a page; and humans find it easier to read nicely -formatted lists.) - -Although I have been using the term `assign', there is another way of -thinking about the workings of `set' and `setq'; and that is to say -that `set' and `setq' make the symbol _point_ to the list. This latter -way of thinking is very common and in forthcoming chapters we shall -come upon at least one symbol that has `pointer' as part of its name. -The name is chosen because the symbol has a value, specifically a list, -attached to it; or, expressed another way, the symbol is set to "point" -to the list. - - -File: eintr, Node: Counting, Prev: Using setq, Up: set & setq - -1.9.3 Counting --------------- - -Here is an example that shows how to use `setq' in a counter. You -might use this to count how many times a part of your program repeats -itself. First set a variable to zero; then add one to the number each -time the program repeats itself. To do this, you need a variable that -serves as a counter, and two expressions: an initial `setq' expression -that sets the counter variable to zero; and a second `setq' expression -that increments the counter each time it is evaluated. - - (setq counter 0) ; Let's call this the initializer. - - (setq counter (+ counter 1)) ; This is the incrementer. - - counter ; This is the counter. - -(The text following the `;' are comments. *Note Change a Function -Definition: Change a defun.) - -If you evaluate the first of these expressions, the initializer, `(setq -counter 0)', and then evaluate the third expression, `counter', the -number `0' will appear in the echo area. If you then evaluate the -second expression, the incrementer, `(setq counter (+ counter 1))', the -counter will get the value 1. So if you again evaluate `counter', the -number `1' will appear in the echo area. Each time you evaluate the -second expression, the value of the counter will be incremented. - -When you evaluate the incrementer, `(setq counter (+ counter 1))', the -Lisp interpreter first evaluates the innermost list; this is the -addition. In order to evaluate this list, it must evaluate the variable -`counter' and the number `1'. When it evaluates the variable -`counter', it receives its current value. It passes this value and the -number `1' to the `+' which adds them together. The sum is then -returned as the value of the inner list and passed to the `setq' which -sets the variable `counter' to this new value. Thus, the value of the -variable, `counter', is changed. - - -File: eintr, Node: Summary, Next: Error Message Exercises, Prev: set & setq, Up: List Processing - -1.10 Summary -============ - -Learning Lisp is like climbing a hill in which the first part is the -steepest. You have now climbed the most difficult part; what remains -becomes easier as you progress onwards. - -In summary, - - * Lisp programs are made up of expressions, which are lists or - single atoms. - - * Lists are made up of zero or more atoms or inner lists, separated - by whitespace and surrounded by parentheses. A list can be empty. - - * Atoms are multi-character symbols, like `forward-paragraph', single - character symbols like `+', strings of characters between double - quotation marks, or numbers. - - * A number evaluates to itself. - - * A string between double quotes also evaluates to itself. - - * When you evaluate a symbol by itself, its value is returned. - - * When you evaluate a list, the Lisp interpreter looks at the first - symbol in the list and then at the function definition bound to - that symbol. Then the instructions in the function definition are - carried out. - - * A single quotation mark, ' , tells the Lisp interpreter that it - should return the following expression as written, and not - evaluate it as it would if the quote were not there. - - * Arguments are the information passed to a function. The arguments - to a function are computed by evaluating the rest of the elements - of the list of which the function is the first element. - - * A function always returns a value when it is evaluated (unless it - gets an error); in addition, it may also carry out some action - called a "side effect". In many cases, a function's primary - purpose is to create a side effect. - - -File: eintr, Node: Error Message Exercises, Prev: Summary, Up: List Processing - -1.11 Exercises -============== - -A few simple exercises: - - * Generate an error message by evaluating an appropriate symbol that - is not within parentheses. - - * Generate an error message by evaluating an appropriate symbol that - is between parentheses. - - * Create a counter that increments by two rather than one. - - * Write an expression that prints a message in the echo area when - evaluated. - - -File: eintr, Node: Practicing Evaluation, Next: Writing Defuns, Prev: List Processing, Up: Top - -2 Practicing Evaluation -*********************** - -Before learning how to write a function definition in Emacs Lisp, it is -useful to spend a little time evaluating various expressions that have -already been written. These expressions will be lists with the -functions as their first (and often only) element. Since some of the -functions associated with buffers are both simple and interesting, we -will start with those. In this section, we will evaluate a few of -these. In another section, we will study the code of several other -buffer-related functions, to see how they were written. - -* Menu: - -* How to Evaluate:: -* Buffer Names:: -* Getting Buffers:: -* Switching Buffers:: -* Buffer Size & Locations:: -* Evaluation Exercise:: - - -File: eintr, Node: How to Evaluate, Next: Buffer Names, Prev: Practicing Evaluation, Up: Practicing Evaluation - -How to Evaluate -=============== - -Whenever you give an editing command to Emacs Lisp, such as the command -to move the cursor or to scroll the screen, you are evaluating an -expression, the first element of which is a function. This is how -Emacs works. - -When you type keys, you cause the Lisp interpreter to evaluate an -expression and that is how you get your results. Even typing plain text -involves evaluating an Emacs Lisp function, in this case, one that uses -`self-insert-command', which simply inserts the character you typed. -The functions you evaluate by typing keystrokes are called -"interactive" functions, or "commands"; how you make a function -interactive will be illustrated in the chapter on how to write function -definitions. *Note Making a Function Interactive: Interactive. - -In addition to typing keyboard commands, we have seen a second way to -evaluate an expression: by positioning the cursor after a list and -typing `C-x C-e'. This is what we will do in the rest of this section. -There are other ways to evaluate an expression as well; these will be -described as we come to them. - -Besides being used for practicing evaluation, the functions shown in the -next few sections are important in their own right. A study of these -functions makes clear the distinction between buffers and files, how to -switch to a buffer, and how to determine a location within it. - - -File: eintr, Node: Buffer Names, Next: Getting Buffers, Prev: How to Evaluate, Up: Practicing Evaluation - -2.1 Buffer Names -================ - -The two functions, `buffer-name' and `buffer-file-name', show the -difference between a file and a buffer. When you evaluate the -following expression, `(buffer-name)', the name of the buffer appears -in the echo area. When you evaluate `(buffer-file-name)', the name of -the file to which the buffer refers appears in the echo area. Usually, -the name returned by `(buffer-name)' is the same as the name of the -file to which it refers, and the name returned by `(buffer-file-name)' -is the full path-name of the file. - -A file and a buffer are two different entities. A file is information -recorded permanently in the computer (unless you delete it). A buffer, -on the other hand, is information inside of Emacs that will vanish at -the end of the editing session (or when you kill the buffer). Usually, -a buffer contains information that you have copied from a file; we say -the buffer is "visiting" that file. This copy is what you work on and -modify. Changes to the buffer do not change the file, until you save -the buffer. When you save the buffer, the buffer is copied to the file -and is thus saved permanently. - -If you are reading this in Info inside of GNU Emacs, you can evaluate -each of the following expressions by positioning the cursor after it and -typing `C-x C-e'. - - (buffer-name) - - (buffer-file-name) - -When I do this in Info, the value returned by evaluating -`(buffer-name)' is `"*info*"', and the value returned by evaluating -`(buffer-file-name)' is `nil'. - -On the other hand, while I am writing this Introduction, the value -returned by evaluating `(buffer-name)' is `"introduction.texinfo"', and -the value returned by evaluating `(buffer-file-name)' is -`"/gnu/work/intro/introduction.texinfo"'. - -The former is the name of the buffer and the latter is the name of the -file. In Info, the buffer name is `"*info*"'. Info does not point to -any file, so the result of evaluating `(buffer-file-name)' is `nil'. -The symbol `nil' is from the Latin word for `nothing'; in this case, it -means that the buffer is not associated with any file. (In Lisp, `nil' -is also used to mean `false' and is a synonym for the empty list, `()'.) - -When I am writing, the name of my buffer is `"introduction.texinfo"'. -The name of the file to which it points is -`"/gnu/work/intro/introduction.texinfo"'. - -(In the expressions, the parentheses tell the Lisp interpreter to treat -`buffer-name' and `buffer-file-name' as functions; without the -parentheses, the interpreter would attempt to evaluate the symbols as -variables. *Note Variables::.) - -In spite of the distinction between files and buffers, you will often -find that people refer to a file when they mean a buffer and vice-verse. -Indeed, most people say, "I am editing a file," rather than saying, "I -am editing a buffer which I will soon save to a file." It is almost -always clear from context what people mean. When dealing with computer -programs, however, it is important to keep the distinction in mind, -since the computer is not as smart as a person. - -The word `buffer', by the way, comes from the meaning of the word as a -cushion that deadens the force of a collision. In early computers, a -buffer cushioned the interaction between files and the computer's -central processing unit. The drums or tapes that held a file and the -central processing unit were pieces of equipment that were very -different from each other, working at their own speeds, in spurts. The -buffer made it possible for them to work together effectively. -Eventually, the buffer grew from being an intermediary, a temporary -holding place, to being the place where work is done. This -transformation is rather like that of a small seaport that grew into a -great city: once it was merely the place where cargo was warehoused -temporarily before being loaded onto ships; then it became a business -and cultural center in its own right. - -Not all buffers are associated with files. For example, a `*scratch*' -buffer does not visit any file. Similarly, a `*Help*' buffer is not -associated with any file. - -In the old days, when you lacked a `~/.emacs' file and started an Emacs -session by typing the command `emacs' alone, without naming any files, -Emacs started with the `*scratch*' buffer visible. Nowadays, you will -see a splash screen. You can follow one of the commands suggested on -the splash screen, visit a file, or press the spacebar to reach the -`*scratch*' buffer. - -If you switch to the `*scratch*' buffer, type `(buffer-name)', position -the cursor after it, and then type `C-x C-e' to evaluate the -expression. The name `"*scratch*"' will be returned and will appear in -the echo area. `"*scratch*"' is the name of the buffer. When you type -`(buffer-file-name)' in the `*scratch*' buffer and evaluate that, `nil' -will appear in the echo area, just as it does when you evaluate -`(buffer-file-name)' in Info. - -Incidentally, if you are in the `*scratch*' buffer and want the value -returned by an expression to appear in the `*scratch*' buffer itself -rather than in the echo area, type `C-u C-x C-e' instead of `C-x C-e'. -This causes the value returned to appear after the expression. The -buffer will look like this: - - (buffer-name)"*scratch*" - -You cannot do this in Info since Info is read-only and it will not allow -you to change the contents of the buffer. But you can do this in any -buffer you can edit; and when you write code or documentation (such as -this book), this feature is very useful. - - -File: eintr, Node: Getting Buffers, Next: Switching Buffers, Prev: Buffer Names, Up: Practicing Evaluation - -2.2 Getting Buffers -=================== - -The `buffer-name' function returns the _name_ of the buffer; to get the -buffer _itself_, a different function is needed: the `current-buffer' -function. If you use this function in code, what you get is the buffer -itself. - -A name and the object or entity to which the name refers are different -from each other. You are not your name. You are a person to whom -others refer by name. If you ask to speak to George and someone hands -you a card with the letters `G', `e', `o', `r', `g', and `e' written on -it, you might be amused, but you would not be satisfied. You do not -want to speak to the name, but to the person to whom the name refers. -A buffer is similar: the name of the scratch buffer is `*scratch*', but -the name is not the buffer. To get a buffer itself, you need to use a -function such as `current-buffer'. - -However, there is a slight complication: if you evaluate -`current-buffer' in an expression on its own, as we will do here, what -you see is a printed representation of the name of the buffer without -the contents of the buffer. Emacs works this way for two reasons: the -buffer may be thousands of lines long--too long to be conveniently -displayed; and, another buffer may have the same contents but a -different name, and it is important to distinguish between them. - -Here is an expression containing the function: - - (current-buffer) - -If you evaluate this expression in Info in Emacs in the usual way, -`#<buffer *info*>' will appear in the echo area. The special format -indicates that the buffer itself is being returned, rather than just -its name. - -Incidentally, while you can type a number or symbol into a program, you -cannot do that with the printed representation of a buffer: the only way -to get a buffer itself is with a function such as `current-buffer'. - -A related function is `other-buffer'. This returns the most recently -selected buffer other than the one you are in currently, not a printed -representation of its name. If you have recently switched back and -forth from the `*scratch*' buffer, `other-buffer' will return that -buffer. - -You can see this by evaluating the expression: - - (other-buffer) - -You should see `#<buffer *scratch*>' appear in the echo area, or the -name of whatever other buffer you switched back from most recently(1). - ----------- Footnotes ---------- - -(1) Actually, by default, if the buffer from which you just switched is -visible to you in another window, `other-buffer' will choose the most -recent buffer that you cannot see; this is a subtlety that I often -forget. - - -File: eintr, Node: Switching Buffers, Next: Buffer Size & Locations, Prev: Getting Buffers, Up: Practicing Evaluation - -2.3 Switching Buffers -===================== - -The `other-buffer' function actually provides a buffer when it is used -as an argument to a function that requires one. We can see this by -using `other-buffer' and `switch-to-buffer' to switch to a different -buffer. - -But first, a brief introduction to the `switch-to-buffer' function. -When you switched back and forth from Info to the `*scratch*' buffer to -evaluate `(buffer-name)', you most likely typed `C-x b' and then typed -`*scratch*'(1) when prompted in the minibuffer for the name of the -buffer to which you wanted to switch. The keystrokes, `C-x b', cause -the Lisp interpreter to evaluate the interactive function -`switch-to-buffer'. As we said before, this is how Emacs works: -different keystrokes call or run different functions. For example, -`C-f' calls `forward-char', `M-e' calls `forward-sentence', and so on. - -By writing `switch-to-buffer' in an expression, and giving it a buffer -to switch to, we can switch buffers just the way `C-x b' does. - -Here is the Lisp expression: - - (switch-to-buffer (other-buffer)) - -The symbol `switch-to-buffer' is the first element of the list, so the -Lisp interpreter will treat it as a function and carry out the -instructions that are attached to it. But before doing that, the -interpreter will note that `other-buffer' is inside parentheses and -work on that symbol first. `other-buffer' is the first (and in this -case, the only) element of this list, so the Lisp interpreter calls or -runs the function. It returns another buffer. Next, the interpreter -runs `switch-to-buffer', passing to it, as an argument, the other -buffer, which is what Emacs will switch to. If you are reading this in -Info, try this now. Evaluate the expression. (To get back, type `C-x -b <RET>'.)(2) - -In the programming examples in later sections of this document, you will -see the function `set-buffer' more often than `switch-to-buffer'. This -is because of a difference between computer programs and humans: humans -have eyes and expect to see the buffer on which they are working on -their computer terminals. This is so obvious, it almost goes without -saying. However, programs do not have eyes. When a computer program -works on a buffer, that buffer does not need to be visible on the -screen. - -`switch-to-buffer' is designed for humans and does two different -things: it switches the buffer to which Emacs' attention is directed; -and it switches the buffer displayed in the window to the new buffer. -`set-buffer', on the other hand, does only one thing: it switches the -attention of the computer program to a different buffer. The buffer on -the screen remains unchanged (of course, normally nothing happens there -until the command finishes running). - -Also, we have just introduced another jargon term, the word "call". -When you evaluate a list in which the first symbol is a function, you -are calling that function. The use of the term comes from the notion of -the function as an entity that can do something for you if you `call' -it--just as a plumber is an entity who can fix a leak if you call him -or her. - ----------- Footnotes ---------- - -(1) Or rather, to save typing, you probably only typed `RET' if the -default buffer was `*scratch*', or if it was different, then you typed -just part of the name, such as `*sc', pressed your `TAB' key to cause -it to expand to the full name, and then typed your `RET' key. - -(2) Remember, this expression will move you to your most recent other -buffer that you cannot see. If you really want to go to your most -recently selected buffer, even if you can still see it, you need to -evaluate the following more complex expression: - - (switch-to-buffer (other-buffer (current-buffer) t)) - -In this case, the first argument to `other-buffer' tells it which -buffer to skip--the current one--and the second argument tells -`other-buffer' it is OK to switch to a visible buffer. In regular use, -`switch-to-buffer' takes you to an invisible window since you would -most likely use `C-x o' (`other-window') to go to another visible -buffer. - - -File: eintr, Node: Buffer Size & Locations, Next: Evaluation Exercise, Prev: Switching Buffers, Up: Practicing Evaluation - -2.4 Buffer Size and the Location of Point -========================================= - -Finally, let's look at several rather simple functions, `buffer-size', -`point', `point-min', and `point-max'. These give information about -the size of a buffer and the location of point within it. - -The function `buffer-size' tells you the size of the current buffer; -that is, the function returns a count of the number of characters in -the buffer. - - (buffer-size) - -You can evaluate this in the usual way, by positioning the cursor after -the expression and typing `C-x C-e'. - -In Emacs, the current position of the cursor is called "point". The -expression `(point)' returns a number that tells you where the cursor -is located as a count of the number of characters from the beginning of -the buffer up to point. - -You can see the character count for point in this buffer by evaluating -the following expression in the usual way: - - (point) - -As I write this, the value of `point' is 65724. The `point' function -is frequently used in some of the examples later in this book. - -The value of point depends, of course, on its location within the -buffer. If you evaluate point in this spot, the number will be larger: - - (point) - -For me, the value of point in this location is 66043, which means that -there are 319 characters (including spaces) between the two expressions. - -The function `point-min' is somewhat similar to `point', but it returns -the value of the minimum permissible value of point in the current -buffer. This is the number 1 unless "narrowing" is in effect. -(Narrowing is a mechanism whereby you can restrict yourself, or a -program, to operations on just a part of a buffer. *Note Narrowing and -Widening: Narrowing & Widening.) Likewise, the function `point-max' -returns the value of the maximum permissible value of point in the -current buffer. - - -File: eintr, Node: Evaluation Exercise, Prev: Buffer Size & Locations, Up: Practicing Evaluation - -2.5 Exercise -============ - -Find a file with which you are working and move towards its middle. -Find its buffer name, file name, length, and your position in the file. - - -File: eintr, Node: Writing Defuns, Next: Buffer Walk Through, Prev: Practicing Evaluation, Up: Top - -3 How To Write Function Definitions -*********************************** - -When the Lisp interpreter evaluates a list, it looks to see whether the -first symbol on the list has a function definition attached to it; or, -put another way, whether the symbol points to a function definition. If -it does, the computer carries out the instructions in the definition. A -symbol that has a function definition is called, simply, a function -(although, properly speaking, the definition is the function and the -symbol refers to it.) - -* Menu: - -* Primitive Functions:: -* defun:: -* Install:: -* Interactive:: -* Interactive Options:: -* Permanent Installation:: -* let:: -* if:: -* else:: -* Truth & Falsehood:: -* save-excursion:: -* Review:: -* defun Exercises:: - - -File: eintr, Node: Primitive Functions, Next: defun, Prev: Writing Defuns, Up: Writing Defuns - -An Aside about Primitive Functions -================================== - -All functions are defined in terms of other functions, except for a few -"primitive" functions that are written in the C programming language. -When you write functions' definitions, you will write them in Emacs -Lisp and use other functions as your building blocks. Some of the -functions you will use will themselves be written in Emacs Lisp (perhaps -by you) and some will be primitives written in C. The primitive -functions are used exactly like those written in Emacs Lisp and behave -like them. They are written in C so we can easily run GNU Emacs on any -computer that has sufficient power and can run C. - -Let me re-emphasize this: when you write code in Emacs Lisp, you do not -distinguish between the use of functions written in C and the use of -functions written in Emacs Lisp. The difference is irrelevant. I -mention the distinction only because it is interesting to know. Indeed, -unless you investigate, you won't know whether an already-written -function is written in Emacs Lisp or C. - - -File: eintr, Node: defun, Next: Install, Prev: Primitive Functions, Up: Writing Defuns - -3.1 The `defun' Special Form -============================ - -In Lisp, a symbol such as `mark-whole-buffer' has code attached to it -that tells the computer what to do when the function is called. This -code is called the "function definition" and is created by evaluating a -Lisp expression that starts with the symbol `defun' (which is an -abbreviation for _define function_). Because `defun' does not evaluate -its arguments in the usual way, it is called a "special form". - -In subsequent sections, we will look at function definitions from the -Emacs source code, such as `mark-whole-buffer'. In this section, we -will describe a simple function definition so you can see how it looks. -This function definition uses arithmetic because it makes for a simple -example. Some people dislike examples using arithmetic; however, if -you are such a person, do not despair. Hardly any of the code we will -study in the remainder of this introduction involves arithmetic or -mathematics. The examples mostly involve text in one way or another. - -A function definition has up to five parts following the word `defun': - - 1. The name of the symbol to which the function definition should be - attached. - - 2. A list of the arguments that will be passed to the function. If no - arguments will be passed to the function, this is an empty list, - `()'. - - 3. Documentation describing the function. (Technically optional, but - strongly recommended.) - - 4. Optionally, an expression to make the function interactive so you - can use it by typing `M-x' and then the name of the function; or by - typing an appropriate key or keychord. - - 5. The code that instructs the computer what to do: the "body" of the - function definition. - -It is helpful to think of the five parts of a function definition as -being organized in a template, with slots for each part: - - (defun FUNCTION-NAME (ARGUMENTS...) - "OPTIONAL-DOCUMENTATION..." - (interactive ARGUMENT-PASSING-INFO) ; optional - BODY...) - -As an example, here is the code for a function that multiplies its -argument by 7. (This example is not interactive. *Note Making a -Function Interactive: Interactive, for that information.) - - (defun multiply-by-seven (number) - "Multiply NUMBER by seven." - (* 7 number)) - -This definition begins with a parenthesis and the symbol `defun', -followed by the name of the function. - -The name of the function is followed by a list that contains the -arguments that will be passed to the function. This list is called the -"argument list". In this example, the list has only one element, the -symbol, `number'. When the function is used, the symbol will be bound -to the value that is used as the argument to the function. - -Instead of choosing the word `number' for the name of the argument, I -could have picked any other name. For example, I could have chosen the -word `multiplicand'. I picked the word `number' because it tells what -kind of value is intended for this slot; but I could just as well have -chosen the word `multiplicand' to indicate the role that the value -placed in this slot will play in the workings of the function. I could -have called it `foogle', but that would have been a bad choice because -it would not tell humans what it means. The choice of name is up to -the programmer and should be chosen to make the meaning of the function -clear. - -Indeed, you can choose any name you wish for a symbol in an argument -list, even the name of a symbol used in some other function: the name -you use in an argument list is private to that particular definition. -In that definition, the name refers to a different entity than any use -of the same name outside the function definition. Suppose you have a -nick-name `Shorty' in your family; when your family members refer to -`Shorty', they mean you. But outside your family, in a movie, for -example, the name `Shorty' refers to someone else. Because a name in an -argument list is private to the function definition, you can change the -value of such a symbol inside the body of a function without changing -its value outside the function. The effect is similar to that produced -by a `let' expression. (*Note `let': let.) - -The argument list is followed by the documentation string that -describes the function. This is what you see when you type `C-h f' and -the name of a function. Incidentally, when you write a documentation -string like this, you should make the first line a complete sentence -since some commands, such as `apropos', print only the first line of a -multi-line documentation string. Also, you should not indent the -second line of a documentation string, if you have one, because that -looks odd when you use `C-h f' (`describe-function'). The -documentation string is optional, but it is so useful, it should be -included in almost every function you write. - -The third line of the example consists of the body of the function -definition. (Most functions' definitions, of course, are longer than -this.) In this function, the body is the list, `(* 7 number)', which -says to multiply the value of NUMBER by 7. (In Emacs Lisp, `*' is the -function for multiplication, just as `+' is the function for addition.) - -When you use the `multiply-by-seven' function, the argument `number' -evaluates to the actual number you want used. Here is an example that -shows how `multiply-by-seven' is used; but don't try to evaluate this -yet! - - (multiply-by-seven 3) - -The symbol `number', specified in the function definition in the next -section, is given or "bound to" the value 3 in the actual use of the -function. Note that although `number' was inside parentheses in the -function definition, the argument passed to the `multiply-by-seven' -function is not in parentheses. The parentheses are written in the -function definition so the computer can figure out where the argument -list ends and the rest of the function definition begins. - -If you evaluate this example, you are likely to get an error message. -(Go ahead, try it!) This is because we have written the function -definition, but not yet told the computer about the definition--we have -not yet installed (or `loaded') the function definition in Emacs. -Installing a function is the process that tells the Lisp interpreter the -definition of the function. Installation is described in the next -section. - - -File: eintr, Node: Install, Next: Interactive, Prev: defun, Up: Writing Defuns - -3.2 Install a Function Definition -================================= - -If you are reading this inside of Info in Emacs, you can try out the -`multiply-by-seven' function by first evaluating the function -definition and then evaluating `(multiply-by-seven 3)'. A copy of the -function definition follows. Place the cursor after the last -parenthesis of the function definition and type `C-x C-e'. When you do -this, `multiply-by-seven' will appear in the echo area. (What this -means is that when a function definition is evaluated, the value it -returns is the name of the defined function.) At the same time, this -action installs the function definition. - - (defun multiply-by-seven (number) - "Multiply NUMBER by seven." - (* 7 number)) - -By evaluating this `defun', you have just installed `multiply-by-seven' -in Emacs. The function is now just as much a part of Emacs as -`forward-word' or any other editing function you use. -(`multiply-by-seven' will stay installed until you quit Emacs. To -reload code automatically whenever you start Emacs, see *Note -Installing Code Permanently: Permanent Installation.) - -* Menu: - -* Effect of installation:: -* Change a defun:: - - -File: eintr, Node: Effect of installation, Next: Change a defun, Prev: Install, Up: Install - -The effect of installation --------------------------- - -You can see the effect of installing `multiply-by-seven' by evaluating -the following sample. Place the cursor after the following expression -and type `C-x C-e'. The number 21 will appear in the echo area. - - (multiply-by-seven 3) - -If you wish, you can read the documentation for the function by typing -`C-h f' (`describe-function') and then the name of the function, -`multiply-by-seven'. When you do this, a `*Help*' window will appear -on your screen that says: - - multiply-by-seven is a Lisp function. - (multiply-by-seven NUMBER) - - Multiply NUMBER by seven. - -(To return to a single window on your screen, type `C-x 1'.) - - -File: eintr, Node: Change a defun, Prev: Effect of installation, Up: Install - -3.2.1 Change a Function Definition ----------------------------------- - -If you want to change the code in `multiply-by-seven', just rewrite it. -To install the new version in place of the old one, evaluate the -function definition again. This is how you modify code in Emacs. It is -very simple. - -As an example, you can change the `multiply-by-seven' function to add -the number to itself seven times instead of multiplying the number by -seven. It produces the same answer, but by a different path. At the -same time, we will add a comment to the code; a comment is text that -the Lisp interpreter ignores, but that a human reader may find useful -or enlightening. The comment is that this is the "second version". - - (defun multiply-by-seven (number) ; Second version. - "Multiply NUMBER by seven." - (+ number number number number number number number)) - -The comment follows a semicolon, `;'. In Lisp, everything on a line -that follows a semicolon is a comment. The end of the line is the end -of the comment. To stretch a comment over two or more lines, begin -each line with a semicolon. - -*Note Beginning a `.emacs' File: Beginning a .emacs File, and *Note -Comments: (elisp)Comments, for more about comments. - -You can install this version of the `multiply-by-seven' function by -evaluating it in the same way you evaluated the first function: place -the cursor after the last parenthesis and type `C-x C-e'. - -In summary, this is how you write code in Emacs Lisp: you write a -function; install it; test it; and then make fixes or enhancements and -install it again. - - -File: eintr, Node: Interactive, Next: Interactive Options, Prev: Install, Up: Writing Defuns - -3.3 Make a Function Interactive -=============================== - -You make a function interactive by placing a list that begins with the -special form `interactive' immediately after the documentation. A user -can invoke an interactive function by typing `M-x' and then the name of -the function; or by typing the keys to which it is bound, for example, -by typing `C-n' for `next-line' or `C-x h' for `mark-whole-buffer'. - -Interestingly, when you call an interactive function interactively, the -value returned is not automatically displayed in the echo area. This -is because you often call an interactive function for its side effects, -such as moving forward by a word or line, and not for the value -returned. If the returned value were displayed in the echo area each -time you typed a key, it would be very distracting. - -* Menu: - -* Interactive multiply-by-seven:: -* multiply-by-seven in detail:: - - -File: eintr, Node: Interactive multiply-by-seven, Next: multiply-by-seven in detail, Prev: Interactive, Up: Interactive - -An Interactive `multiply-by-seven', An Overview ------------------------------------------------ - -Both the use of the special form `interactive' and one way to display a -value in the echo area can be illustrated by creating an interactive -version of `multiply-by-seven'. - -Here is the code: - - (defun multiply-by-seven (number) ; Interactive version. - "Multiply NUMBER by seven." - (interactive "p") - (message "The result is %d" (* 7 number))) - -You can install this code by placing your cursor after it and typing -`C-x C-e'. The name of the function will appear in your echo area. -Then, you can use this code by typing `C-u' and a number and then -typing `M-x multiply-by-seven' and pressing <RET>. The phrase `The -result is ...' followed by the product will appear in the echo area. - -Speaking more generally, you invoke a function like this in either of -two ways: - - 1. By typing a prefix argument that contains the number to be passed, - and then typing `M-x' and the name of the function, as with `C-u 3 - M-x forward-sentence'; or, - - 2. By typing whatever key or keychord the function is bound to, as - with `C-u 3 M-e'. - -Both the examples just mentioned work identically to move point forward -three sentences. (Since `multiply-by-seven' is not bound to a key, it -could not be used as an example of key binding.) - -(*Note Some Keybindings: Keybindings, to learn how to bind a command to -a key.) - -A prefix argument is passed to an interactive function by typing the -<META> key followed by a number, for example, `M-3 M-e', or by typing -`C-u' and then a number, for example, `C-u 3 M-e' (if you type `C-u' -without a number, it defaults to 4). - - -File: eintr, Node: multiply-by-seven in detail, Prev: Interactive multiply-by-seven, Up: Interactive - -3.3.1 An Interactive `multiply-by-seven' ----------------------------------------- - -Let's look at the use of the special form `interactive' and then at the -function `message' in the interactive version of `multiply-by-seven'. -You will recall that the function definition looks like this: - - (defun multiply-by-seven (number) ; Interactive version. - "Multiply NUMBER by seven." - (interactive "p") - (message "The result is %d" (* 7 number))) - -In this function, the expression, `(interactive "p")', is a list of two -elements. The `"p"' tells Emacs to pass the prefix argument to the -function and use its value for the argument of the function. - -The argument will be a number. This means that the symbol `number' -will be bound to a number in the line: - - (message "The result is %d" (* 7 number)) - -For example, if your prefix argument is 5, the Lisp interpreter will -evaluate the line as if it were: - - (message "The result is %d" (* 7 5)) - -(If you are reading this in GNU Emacs, you can evaluate this expression -yourself.) First, the interpreter will evaluate the inner list, which -is `(* 7 5)'. This returns a value of 35. Next, it will evaluate the -outer list, passing the values of the second and subsequent elements of -the list to the function `message'. - -As we have seen, `message' is an Emacs Lisp function especially -designed for sending a one line message to a user. (*Note The -`message' function: message.) In summary, the `message' function -prints its first argument in the echo area as is, except for -occurrences of `%d' or `%s' (and various other %-sequences which we -have not mentioned). When it sees a control sequence, the function -looks to the second or subsequent arguments and prints the value of the -argument in the location in the string where the control sequence is -located. - -In the interactive `multiply-by-seven' function, the control string is -`%d', which requires a number, and the value returned by evaluating `(* -7 5)' is the number 35. Consequently, the number 35 is printed in -place of the `%d' and the message is `The result is 35'. - -(Note that when you call the function `multiply-by-seven', the message -is printed without quotes, but when you call `message', the text is -printed in double quotes. This is because the value returned by -`message' is what appears in the echo area when you evaluate an -expression whose first element is `message'; but when embedded in a -function, `message' prints the text as a side effect without quotes.) - - -File: eintr, Node: Interactive Options, Next: Permanent Installation, Prev: Interactive, Up: Writing Defuns - -3.4 Different Options for `interactive' -======================================= - -In the example, `multiply-by-seven' used `"p"' as the argument to -`interactive'. This argument told Emacs to interpret your typing -either `C-u' followed by a number or <META> followed by a number as a -command to pass that number to the function as its argument. Emacs has -more than twenty characters predefined for use with `interactive'. In -almost every case, one of these options will enable you to pass the -right information interactively to a function. (*Note Code Characters -for `interactive': (elisp)Interactive Codes.) - -Consider the function `zap-to-char'. Its interactive expression is - - (interactive "p\ncZap to char: ") - -The first part of the argument to `interactive' is `p', with which you -are already familiar. This argument tells Emacs to interpret a -`prefix', as a number to be passed to the function. You can specify a -prefix either by typing `C-u' followed by a number or by typing <META> -followed by a number. The prefix is the number of specified -characters. Thus, if your prefix is three and the specified character -is `x', then you will delete all the text up to and including the third -next `x'. If you do not set a prefix, then you delete all the text up -to and including the specified character, but no more. - -The `c' tells the function the name of the character to which to delete. - -More formally, a function with two or more arguments can have -information passed to each argument by adding parts to the string that -follows `interactive'. When you do this, the information is passed to -each argument in the same order it is specified in the `interactive' -list. In the string, each part is separated from the next part by a -`\n', which is a newline. For example, you can follow `p' with a `\n' -and an `cZap to char: '. This causes Emacs to pass the value of the -prefix argument (if there is one) and the character. - -In this case, the function definition looks like the following, where -`arg' and `char' are the symbols to which `interactive' binds the -prefix argument and the specified character: - - (defun NAME-OF-FUNCTION (arg char) - "DOCUMENTATION..." - (interactive "p\ncZap to char: ") - BODY-OF-FUNCTION...) - -(The space after the colon in the prompt makes it look better when you -are prompted. *Note The Definition of `copy-to-buffer': -copy-to-buffer, for an example.) - -When a function does not take arguments, `interactive' does not require -any. Such a function contains the simple expression `(interactive)'. -The `mark-whole-buffer' function is like this. - -Alternatively, if the special letter-codes are not right for your -application, you can pass your own arguments to `interactive' as a list. - -*Note The Definition of `append-to-buffer': append-to-buffer, for an -example. *Note Using `Interactive': (elisp)Using Interactive, for a -more complete explanation about this technique. - - -File: eintr, Node: Permanent Installation, Next: let, Prev: Interactive Options, Up: Writing Defuns - -3.5 Install Code Permanently -============================ - -When you install a function definition by evaluating it, it will stay -installed until you quit Emacs. The next time you start a new session -of Emacs, the function will not be installed unless you evaluate the -function definition again. - -At some point, you may want to have code installed automatically -whenever you start a new session of Emacs. There are several ways of -doing this: - - * If you have code that is just for yourself, you can put the code - for the function definition in your `.emacs' initialization file. - When you start Emacs, your `.emacs' file is automatically - evaluated and all the function definitions within it are installed. - *Note Your `.emacs' File: Emacs Initialization. - - * Alternatively, you can put the function definitions that you want - installed in one or more files of their own and use the `load' - function to cause Emacs to evaluate and thereby install each of the - functions in the files. *Note Loading Files: Loading Files. - - * Thirdly, if you have code that your whole site will use, it is - usual to put it in a file called `site-init.el' that is loaded when - Emacs is built. This makes the code available to everyone who uses - your machine. (See the `INSTALL' file that is part of the Emacs - distribution.) - -Finally, if you have code that everyone who uses Emacs may want, you -can post it on a computer network or send a copy to the Free Software -Foundation. (When you do this, please license the code and its -documentation under a license that permits other people to run, copy, -study, modify, and redistribute the code and which protects you from -having your work taken from you.) If you send a copy of your code to -the Free Software Foundation, and properly protect yourself and others, -it may be included in the next release of Emacs. In large part, this -is how Emacs has grown over the past years, by donations. - - -File: eintr, Node: let, Next: if, Prev: Permanent Installation, Up: Writing Defuns - -3.6 `let' -========= - -The `let' expression is a special form in Lisp that you will need to -use in most function definitions. - -`let' is used to attach or bind a symbol to a value in such a way that -the Lisp interpreter will not confuse the variable with a variable of -the same name that is not part of the function. - -To understand why the `let' special form is necessary, consider the -situation in which you own a home that you generally refer to as `the -house', as in the sentence, "The house needs painting." If you are -visiting a friend and your host refers to `the house', he is likely to -be referring to _his_ house, not yours, that is, to a different house. - -If your friend is referring to his house and you think he is referring -to your house, you may be in for some confusion. The same thing could -happen in Lisp if a variable that is used inside of one function has -the same name as a variable that is used inside of another function, -and the two are not intended to refer to the same value. The `let' -special form prevents this kind of confusion. - -* Menu: - -* Prevent confusion:: -* Parts of let Expression:: -* Sample let Expression:: -* Uninitialized let Variables:: - - -File: eintr, Node: Prevent confusion, Next: Parts of let Expression, Prev: let, Up: let - -`let' Prevents Confusion ------------------------- - -The `let' special form prevents confusion. `let' creates a name for a -"local variable" that overshadows any use of the same name outside the -`let' expression. This is like understanding that whenever your host -refers to `the house', he means his house, not yours. (Symbols used in -argument lists work the same way. *Note The `defun' Special Form: -defun.) - -Local variables created by a `let' expression retain their value _only_ -within the `let' expression itself (and within expressions called -within the `let' expression); the local variables have no effect -outside the `let' expression. - -Another way to think about `let' is that it is like a `setq' that is -temporary and local. The values set by `let' are automatically undone -when the `let' is finished. The setting only affects expressions that -are inside the bounds of the `let' expression. In computer science -jargon, we would say "the binding of a symbol is visible only in -functions called in the `let' form; in Emacs Lisp, scoping is dynamic, -not lexical." - -`let' can create more than one variable at once. Also, `let' gives -each variable it creates an initial value, either a value specified by -you, or `nil'. (In the jargon, this is called `binding the variable to -the value'.) After `let' has created and bound the variables, it -executes the code in the body of the `let', and returns the value of -the last expression in the body, as the value of the whole `let' -expression. (`Execute' is a jargon term that means to evaluate a list; -it comes from the use of the word meaning `to give practical effect to' -(`Oxford English Dictionary'). Since you evaluate an expression to -perform an action, `execute' has evolved as a synonym to `evaluate'.) - - -File: eintr, Node: Parts of let Expression, Next: Sample let Expression, Prev: Prevent confusion, Up: let - -3.6.1 The Parts of a `let' Expression -------------------------------------- - -A `let' expression is a list of three parts. The first part is the -symbol `let'. The second part is a list, called a "varlist", each -element of which is either a symbol by itself or a two-element list, -the first element of which is a symbol. The third part of the `let' -expression is the body of the `let'. The body usually consists of one -or more lists. - -A template for a `let' expression looks like this: - - (let VARLIST BODY...) - -The symbols in the varlist are the variables that are given initial -values by the `let' special form. Symbols by themselves are given the -initial value of `nil'; and each symbol that is the first element of a -two-element list is bound to the value that is returned when the Lisp -interpreter evaluates the second element. - -Thus, a varlist might look like this: `(thread (needles 3))'. In this -case, in a `let' expression, Emacs binds the symbol `thread' to an -initial value of `nil', and binds the symbol `needles' to an initial -value of 3. - -When you write a `let' expression, what you do is put the appropriate -expressions in the slots of the `let' expression template. - -If the varlist is composed of two-element lists, as is often the case, -the template for the `let' expression looks like this: - - (let ((VARIABLE VALUE) - (VARIABLE VALUE) - ...) - BODY...) - - -File: eintr, Node: Sample let Expression, Next: Uninitialized let Variables, Prev: Parts of let Expression, Up: let - -3.6.2 Sample `let' Expression ------------------------------ - -The following expression creates and gives initial values to the two -variables `zebra' and `tiger'. The body of the `let' expression is a -list which calls the `message' function. - - (let ((zebra 'stripes) - (tiger 'fierce)) - (message "One kind of animal has %s and another is %s." - zebra tiger)) - -Here, the varlist is `((zebra 'stripes) (tiger 'fierce))'. - -The two variables are `zebra' and `tiger'. Each variable is the first -element of a two-element list and each value is the second element of -its two-element list. In the varlist, Emacs binds the variable `zebra' -to the value `stripes'(1), and binds the variable `tiger' to the value -`fierce'. In this example, both values are symbols preceded by a -quote. The values could just as well have been another list or a -string. The body of the `let' follows after the list holding the -variables. In this example, the body is a list that uses the `message' -function to print a string in the echo area. - -You may evaluate the example in the usual fashion, by placing the -cursor after the last parenthesis and typing `C-x C-e'. When you do -this, the following will appear in the echo area: - - "One kind of animal has stripes and another is fierce." - -As we have seen before, the `message' function prints its first -argument, except for `%s'. In this example, the value of the variable -`zebra' is printed at the location of the first `%s' and the value of -the variable `tiger' is printed at the location of the second `%s'. - ----------- Footnotes ---------- - -(1) According to Jared Diamond in `Guns, Germs, and Steel', "... zebras -become impossibly dangerous as they grow older" but the claim here is -that they do not become fierce like a tiger. (1997, W. W. Norton and -Co., ISBN 0-393-03894-2, page 171) - - -File: eintr, Node: Uninitialized let Variables, Prev: Sample let Expression, Up: let - -3.6.3 Uninitialized Variables in a `let' Statement --------------------------------------------------- - -If you do not bind the variables in a `let' statement to specific -initial values, they will automatically be bound to an initial value of -`nil', as in the following expression: - - (let ((birch 3) - pine - fir - (oak 'some)) - (message - "Here are %d variables with %s, %s, and %s value." - birch pine fir oak)) - -Here, the varlist is `((birch 3) pine fir (oak 'some))'. - -If you evaluate this expression in the usual way, the following will -appear in your echo area: - - "Here are 3 variables with nil, nil, and some value." - -In this example, Emacs binds the symbol `birch' to the number 3, binds -the symbols `pine' and `fir' to `nil', and binds the symbol `oak' to -the value `some'. - -Note that in the first part of the `let', the variables `pine' and -`fir' stand alone as atoms that are not surrounded by parentheses; this -is because they are being bound to `nil', the empty list. But `oak' is -bound to `some' and so is a part of the list `(oak 'some)'. Similarly, -`birch' is bound to the number 3 and so is in a list with that number. -(Since a number evaluates to itself, the number does not need to be -quoted. Also, the number is printed in the message using a `%d' rather -than a `%s'.) The four variables as a group are put into a list to -delimit them from the body of the `let'. - - -File: eintr, Node: if, Next: else, Prev: let, Up: Writing Defuns - -3.7 The `if' Special Form -========================= - -A third special form, in addition to `defun' and `let', is the -conditional `if'. This form is used to instruct the computer to make -decisions. You can write function definitions without using `if', but -it is used often enough, and is important enough, to be included here. -It is used, for example, in the code for the function -`beginning-of-buffer'. - -The basic idea behind an `if', is that "_if_ a test is true, _then_ an -expression is evaluated." If the test is not true, the expression is -not evaluated. For example, you might make a decision such as, "if it -is warm and sunny, then go to the beach!" - -* Menu: - -* if in more detail:: -* type-of-animal in detail:: - - -File: eintr, Node: if in more detail, Next: type-of-animal in detail, Prev: if, Up: if - -`if' in more detail -------------------- - -An `if' expression written in Lisp does not use the word `then'; the -test and the action are the second and third elements of the list whose -first element is `if'. Nonetheless, the test part of an `if' -expression is often called the "if-part" and the second argument is -often called the "then-part". - -Also, when an `if' expression is written, the true-or-false-test is -usually written on the same line as the symbol `if', but the action to -carry out if the test is true, the "then-part", is written on the -second and subsequent lines. This makes the `if' expression easier to -read. - - (if TRUE-OR-FALSE-TEST - ACTION-TO-CARRY-OUT-IF-TEST-IS-TRUE) - -The true-or-false-test will be an expression that is evaluated by the -Lisp interpreter. - -Here is an example that you can evaluate in the usual manner. The test -is whether the number 5 is greater than the number 4. Since it is, the -message `5 is greater than 4!' will be printed. - - (if (> 5 4) ; if-part - (message "5 is greater than 4!")) ; then-part - -(The function `>' tests whether its first argument is greater than its -second argument and returns true if it is.) - -Of course, in actual use, the test in an `if' expression will not be -fixed for all time as it is by the expression `(> 5 4)'. Instead, at -least one of the variables used in the test will be bound to a value -that is not known ahead of time. (If the value were known ahead of -time, we would not need to run the test!) - -For example, the value may be bound to an argument of a function -definition. In the following function definition, the character of the -animal is a value that is passed to the function. If the value bound to -`characteristic' is `fierce', then the message, `It's a tiger!' will be -printed; otherwise, `nil' will be returned. - - (defun type-of-animal (characteristic) - "Print message in echo area depending on CHARACTERISTIC. - If the CHARACTERISTIC is the symbol `fierce', - then warn of a tiger." - (if (equal characteristic 'fierce) - (message "It's a tiger!"))) - -If you are reading this inside of GNU Emacs, you can evaluate the -function definition in the usual way to install it in Emacs, and then -you can evaluate the following two expressions to see the results: - - (type-of-animal 'fierce) - - (type-of-animal 'zebra) - -When you evaluate `(type-of-animal 'fierce)', you will see the -following message printed in the echo area: `"It's a tiger!"'; and when -you evaluate `(type-of-animal 'zebra)' you will see `nil' printed in -the echo area. - - -File: eintr, Node: type-of-animal in detail, Prev: if in more detail, Up: if - -3.7.1 The `type-of-animal' Function in Detail ---------------------------------------------- - -Let's look at the `type-of-animal' function in detail. - -The function definition for `type-of-animal' was written by filling the -slots of two templates, one for a function definition as a whole, and a -second for an `if' expression. - -The template for every function that is not interactive is: - - (defun NAME-OF-FUNCTION (ARGUMENT-LIST) - "DOCUMENTATION..." - BODY...) - -The parts of the function that match this template look like this: - - (defun type-of-animal (characteristic) - "Print message in echo area depending on CHARACTERISTIC. - If the CHARACTERISTIC is the symbol `fierce', - then warn of a tiger." - BODY: THE `if' EXPRESSION) - -The name of function is `type-of-animal'; it is passed the value of one -argument. The argument list is followed by a multi-line documentation -string. The documentation string is included in the example because it -is a good habit to write documentation string for every function -definition. The body of the function definition consists of the `if' -expression. - -The template for an `if' expression looks like this: - - (if TRUE-OR-FALSE-TEST - ACTION-TO-CARRY-OUT-IF-THE-TEST-RETURNS-TRUE) - -In the `type-of-animal' function, the code for the `if' looks like this: - - (if (equal characteristic 'fierce) - (message "It's a tiger!"))) - -Here, the true-or-false-test is the expression: - - (equal characteristic 'fierce) - -In Lisp, `equal' is a function that determines whether its first -argument is equal to its second argument. The second argument is the -quoted symbol `'fierce' and the first argument is the value of the -symbol `characteristic'--in other words, the argument passed to this -function. - -In the first exercise of `type-of-animal', the argument `fierce' is -passed to `type-of-animal'. Since `fierce' is equal to `fierce', the -expression, `(equal characteristic 'fierce)', returns a value of true. -When this happens, the `if' evaluates the second argument or then-part -of the `if': `(message "It's tiger!")'. - -On the other hand, in the second exercise of `type-of-animal', the -argument `zebra' is passed to `type-of-animal'. `zebra' is not equal -to `fierce', so the then-part is not evaluated and `nil' is returned by -the `if' expression. - - -File: eintr, Node: else, Next: Truth & Falsehood, Prev: if, Up: Writing Defuns - -3.8 If-then-else Expressions -============================ - -An `if' expression may have an optional third argument, called the -"else-part", for the case when the true-or-false-test returns false. -When this happens, the second argument or then-part of the overall `if' -expression is _not_ evaluated, but the third or else-part _is_ -evaluated. You might think of this as the cloudy day alternative for -the decision "if it is warm and sunny, then go to the beach, else read -a book!". - -The word "else" is not written in the Lisp code; the else-part of an -`if' expression comes after the then-part. In the written Lisp, the -else-part is usually written to start on a line of its own and is -indented less than the then-part: - - (if TRUE-OR-FALSE-TEST - ACTION-TO-CARRY-OUT-IF-THE-TEST-RETURNS-TRUE - ACTION-TO-CARRY-OUT-IF-THE-TEST-RETURNS-FALSE) - -For example, the following `if' expression prints the message `4 is not -greater than 5!' when you evaluate it in the usual way: - - (if (> 4 5) ; if-part - (message "5 is greater than 4!") ; then-part - (message "4 is not greater than 5!")) ; else-part - -Note that the different levels of indentation make it easy to -distinguish the then-part from the else-part. (GNU Emacs has several -commands that automatically indent `if' expressions correctly. *Note -GNU Emacs Helps You Type Lists: Typing Lists.) - -We can extend the `type-of-animal' function to include an else-part by -simply incorporating an additional part to the `if' expression. - -You can see the consequences of doing this if you evaluate the following -version of the `type-of-animal' function definition to install it and -then evaluate the two subsequent expressions to pass different -arguments to the function. - - (defun type-of-animal (characteristic) ; Second version. - "Print message in echo area depending on CHARACTERISTIC. - If the CHARACTERISTIC is the symbol `fierce', - then warn of a tiger; - else say it's not fierce." - (if (equal characteristic 'fierce) - (message "It's a tiger!") - (message "It's not fierce!"))) - - - (type-of-animal 'fierce) - - (type-of-animal 'zebra) - -When you evaluate `(type-of-animal 'fierce)', you will see the -following message printed in the echo area: `"It's a tiger!"'; but when -you evaluate `(type-of-animal 'zebra)', you will see `"It's not -fierce!"'. - -(Of course, if the CHARACTERISTIC were `ferocious', the message `"It's -not fierce!"' would be printed; and it would be misleading! When you -write code, you need to take into account the possibility that some -such argument will be tested by the `if' and write your program -accordingly.) - - -File: eintr, Node: Truth & Falsehood, Next: save-excursion, Prev: else, Up: Writing Defuns - -3.9 Truth and Falsehood in Emacs Lisp -===================================== - -There is an important aspect to the truth test in an `if' expression. -So far, we have spoken of `true' and `false' as values of predicates as -if they were new kinds of Emacs Lisp objects. In fact, `false' is just -our old friend `nil'. Anything else--anything at all--is `true'. - -The expression that tests for truth is interpreted as "true" if the -result of evaluating it is a value that is not `nil'. In other words, -the result of the test is considered true if the value returned is a -number such as 47, a string such as `"hello"', or a symbol (other than -`nil') such as `flowers', or a list (so long as it is not empty), or -even a buffer! - -* Menu: - -* nil explained:: - - -File: eintr, Node: nil explained, Prev: Truth & Falsehood, Up: Truth & Falsehood - -An explanation of `nil' ------------------------ - -Before illustrating a test for truth, we need an explanation of `nil'. - -In Emacs Lisp, the symbol `nil' has two meanings. First, it means the -empty list. Second, it means false and is the value returned when a -true-or-false-test tests false. `nil' can be written as an empty list, -`()', or as `nil'. As far as the Lisp interpreter is concerned, `()' -and `nil' are the same. Humans, however, tend to use `nil' for false -and `()' for the empty list. - -In Emacs Lisp, any value that is not `nil'--is not the empty list--is -considered true. This means that if an evaluation returns something -that is not an empty list, an `if' expression will test true. For -example, if a number is put in the slot for the test, it will be -evaluated and will return itself, since that is what numbers do when -evaluated. In this conditional, the `if' expression will test true. -The expression tests false only when `nil', an empty list, is returned -by evaluating the expression. - -You can see this by evaluating the two expressions in the following -examples. - -In the first example, the number 4 is evaluated as the test in the `if' -expression and returns itself; consequently, the then-part of the -expression is evaluated and returned: `true' appears in the echo area. -In the second example, the `nil' indicates false; consequently, the -else-part of the expression is evaluated and returned: `false' appears -in the echo area. - - (if 4 - 'true - 'false) - - (if nil - 'true - 'false) - -Incidentally, if some other useful value is not available for a test -that returns true, then the Lisp interpreter will return the symbol `t' -for true. For example, the expression `(> 5 4)' returns `t' when -evaluated, as you can see by evaluating it in the usual way: - - (> 5 4) - -On the other hand, this function returns `nil' if the test is false. - - (> 4 5) - - -File: eintr, Node: save-excursion, Next: Review, Prev: Truth & Falsehood, Up: Writing Defuns - -3.10 `save-excursion' -===================== - -The `save-excursion' function is the fourth and final special form that -we will discuss in this chapter. - -In Emacs Lisp programs used for editing, the `save-excursion' function -is very common. It saves the location of point and mark, executes the -body of the function, and then restores point and mark to their -previous positions if their locations were changed. Its primary -purpose is to keep the user from being surprised and disturbed by -unexpected movement of point or mark. - -* Menu: - -* Point and mark:: -* Template for save-excursion:: - - -File: eintr, Node: Point and mark, Next: Template for save-excursion, Prev: save-excursion, Up: save-excursion - -Point and Mark --------------- - -Before discussing `save-excursion', however, it may be useful first to -review what point and mark are in GNU Emacs. "Point" is the current -location of the cursor. Wherever the cursor is, that is point. More -precisely, on terminals where the cursor appears to be on top of a -character, point is immediately before the character. In Emacs Lisp, -point is an integer. The first character in a buffer is number one, -the second is number two, and so on. The function `point' returns the -current position of the cursor as a number. Each buffer has its own -value for point. - -The "mark" is another position in the buffer; its value can be set with -a command such as `C-<SPC>' (`set-mark-command'). If a mark has been -set, you can use the command `C-x C-x' (`exchange-point-and-mark') to -cause the cursor to jump to the mark and set the mark to be the -previous position of point. In addition, if you set another mark, the -position of the previous mark is saved in the mark ring. Many mark -positions can be saved this way. You can jump the cursor to a saved -mark by typing `C-u C-<SPC>' one or more times. - -The part of the buffer between point and mark is called "the region". -Numerous commands work on the region, including `center-region', -`count-lines-region', `kill-region', and `print-region'. - -The `save-excursion' special form saves the locations of point and mark -and restores those positions after the code within the body of the -special form is evaluated by the Lisp interpreter. Thus, if point were -in the beginning of a piece of text and some code moved point to the end -of the buffer, the `save-excursion' would put point back to where it -was before, after the expressions in the body of the function were -evaluated. - -In Emacs, a function frequently moves point as part of its internal -workings even though a user would not expect this. For example, -`count-lines-region' moves point. To prevent the user from being -bothered by jumps that are both unexpected and (from the user's point of -view) unnecessary, `save-excursion' is often used to keep point and -mark in the location expected by the user. The use of `save-excursion' -is good housekeeping. - -To make sure the house stays clean, `save-excursion' restores the -values of point and mark even if something goes wrong in the code inside -of it (or, to be more precise and to use the proper jargon, "in case of -abnormal exit"). This feature is very helpful. - -In addition to recording the values of point and mark, `save-excursion' -keeps track of the current buffer, and restores it, too. This means -you can write code that will change the buffer and have -`save-excursion' switch you back to the original buffer. This is how -`save-excursion' is used in `append-to-buffer'. (*Note The Definition -of `append-to-buffer': append-to-buffer.) - - -File: eintr, Node: Template for save-excursion, Prev: Point and mark, Up: save-excursion - -3.10.1 Template for a `save-excursion' Expression -------------------------------------------------- - -The template for code using `save-excursion' is simple: - - (save-excursion - BODY...) - -The body of the function is one or more expressions that will be -evaluated in sequence by the Lisp interpreter. If there is more than -one expression in the body, the value of the last one will be returned -as the value of the `save-excursion' function. The other expressions -in the body are evaluated only for their side effects; and -`save-excursion' itself is used only for its side effect (which is -restoring the positions of point and mark). - -In more detail, the template for a `save-excursion' expression looks -like this: - - (save-excursion - FIRST-EXPRESSION-IN-BODY - SECOND-EXPRESSION-IN-BODY - THIRD-EXPRESSION-IN-BODY - ... - LAST-EXPRESSION-IN-BODY) - -An expression, of course, may be a symbol on its own or a list. - -In Emacs Lisp code, a `save-excursion' expression often occurs within -the body of a `let' expression. It looks like this: - - (let VARLIST - (save-excursion - BODY...)) - - -File: eintr, Node: Review, Next: defun Exercises, Prev: save-excursion, Up: Writing Defuns - -3.11 Review -=========== - -In the last few chapters we have introduced a fair number of functions -and special forms. Here they are described in brief, along with a few -similar functions that have not been mentioned yet. - -`eval-last-sexp' - Evaluate the last symbolic expression before the current location - of point. The value is printed in the echo area unless the - function is invoked with an argument; in that case, the output is - printed in the current buffer. This command is normally bound to - `C-x C-e'. - -`defun' - Define function. This special form has up to five parts: the name, - a template for the arguments that will be passed to the function, - documentation, an optional interactive declaration, and the body - of the definition. - - For example, in an early version of Emacs, the function definition - was as follows. (It is slightly more complex now that it seeks - the first non-whitespace character rather than the first visible - character.) - - (defun back-to-indentation () - "Move point to first visible character on line." - (interactive) - (beginning-of-line 1) - (skip-chars-forward " \t")) - -`interactive' - Declare to the interpreter that the function can be used - interactively. This special form may be followed by a string with - one or more parts that pass the information to the arguments of the - function, in sequence. These parts may also tell the interpreter - to prompt for information. Parts of the string are separated by - newlines, `\n'. - - Common code characters are: - - `b' - The name of an existing buffer. - - `f' - The name of an existing file. - - `p' - The numeric prefix argument. (Note that this `p' is lower - case.) - - `r' - Point and the mark, as two numeric arguments, smallest first. - This is the only code letter that specifies two successive - arguments rather than one. - - *Note Code Characters for `interactive': (elisp)Interactive Codes, - for a complete list of code characters. - -`let' - Declare that a list of variables is for use within the body of the - `let' and give them an initial value, either `nil' or a specified - value; then evaluate the rest of the expressions in the body of - the `let' and return the value of the last one. Inside the body - of the `let', the Lisp interpreter does not see the values of the - variables of the same names that are bound outside of the `let'. - - For example, - - (let ((foo (buffer-name)) - (bar (buffer-size))) - (message - "This buffer is %s and has %d characters." - foo bar)) - -`save-excursion' - Record the values of point and mark and the current buffer before - evaluating the body of this special form. Restore the values of - point and mark and buffer afterward. - - For example, - - (message "We are %d characters into this buffer." - (- (point) - (save-excursion - (goto-char (point-min)) (point)))) - -`if' - Evaluate the first argument to the function; if it is true, - evaluate the second argument; else evaluate the third argument, if - there is one. - - The `if' special form is called a "conditional". There are other - conditionals in Emacs Lisp, but `if' is perhaps the most commonly - used. - - For example, - - (if (string-equal - (number-to-string 22) - (substring (emacs-version) 10 12)) - (message "This is version 22 Emacs") - (message "This is not version 22 Emacs")) - -`equal' -`eq' - Test whether two objects are the same. `equal' uses one meaning - of the word `same' and `eq' uses another: `equal' returns true if - the two objects have a similar structure and contents, such as two - copies of the same book. On the other hand, `eq', returns true if - both arguments are actually the same object. - -`<' -`>' -`<=' -`>=' - The `<' function tests whether its first argument is smaller than - its second argument. A corresponding function, `>', tests whether - the first argument is greater than the second. Likewise, `<=' - tests whether the first argument is less than or equal to the - second and `>=' tests whether the first argument is greater than - or equal to the second. In all cases, both arguments must be - numbers or markers (markers indicate positions in buffers). - -`=' - The `=' function tests whether two arguments, , both numbers or - markers, are equal. - -`string<' -`string-lessp' -`string=' -`string-equal' - The `string-lessp' function tests whether its first argument is - smaller than the second argument. A shorter, alternative name for - the same function (a `defalias') is `string<'. - - The arguments to `string-lessp' must be strings or symbols; the - ordering is lexicographic, so case is significant. The print - names of symbols are used instead of the symbols themselves. - - An empty string, `""', a string with no characters in it, is - smaller than any string of characters. - - `string-equal' provides the corresponding test for equality. Its - shorter, alternative name is `string='. There are no string test - functions that correspond to >, `>=', or `<='. - -`message' - Print a message in the echo area. The first argument is a string - that can contain `%s', `%d', or `%c' to print the value of - arguments that follow the string. The argument used by `%s' must - be a string or a symbol; the argument used by `%d' must be a - number. The argument used by `%c' must be an ASCII code number; - it will be printed as the character with that ASCII code. - (Various other %-sequences have not been mentioned.) - -`setq' -`set' - The `setq' function sets the value of its first argument to the - value of the second argument. The first argument is automatically - quoted by `setq'. It does the same for succeeding pairs of - arguments. Another function, `set', takes only two arguments and - evaluates both of them before setting the value returned by its - first argument to the value returned by its second argument. - -`buffer-name' - Without an argument, return the name of the buffer, as a string. - -`buffer-file-name' - Without an argument, return the name of the file the buffer is - visiting. - -`current-buffer' - Return the buffer in which Emacs is active; it may not be the - buffer that is visible on the screen. - -`other-buffer' - Return the most recently selected buffer (other than the buffer - passed to `other-buffer' as an argument and other than the current - buffer). - -`switch-to-buffer' - Select a buffer for Emacs to be active in and display it in the - current window so users can look at it. Usually bound to `C-x b'. - -`set-buffer' - Switch Emacs' attention to a buffer on which programs will run. - Don't alter what the window is showing. - -`buffer-size' - Return the number of characters in the current buffer. - -`point' - Return the value of the current position of the cursor, as an - integer counting the number of characters from the beginning of the - buffer. - -`point-min' - Return the minimum permissible value of point in the current - buffer. This is 1, unless narrowing is in effect. - -`point-max' - Return the value of the maximum permissible value of point in the - current buffer. This is the end of the buffer, unless narrowing - is in effect. - - -File: eintr, Node: defun Exercises, Prev: Review, Up: Writing Defuns - -3.12 Exercises -============== - - * Write a non-interactive function that doubles the value of its - argument, a number. Make that function interactive. - - * Write a function that tests whether the current value of - `fill-column' is greater than the argument passed to the function, - and if so, prints an appropriate message. - - -File: eintr, Node: Buffer Walk Through, Next: More Complex, Prev: Writing Defuns, Up: Top - -4 A Few Buffer-Related Functions -******************************** - -In this chapter we study in detail several of the functions used in GNU -Emacs. This is called a "walk-through". These functions are used as -examples of Lisp code, but are not imaginary examples; with the -exception of the first, simplified function definition, these functions -show the actual code used in GNU Emacs. You can learn a great deal from -these definitions. The functions described here are all related to -buffers. Later, we will study other functions. - -* Menu: - -* Finding More:: -* simplified-beginning-of-buffer:: -* mark-whole-buffer:: -* append-to-buffer:: -* Buffer Related Review:: -* Buffer Exercises:: - - -File: eintr, Node: Finding More, Next: simplified-beginning-of-buffer, Prev: Buffer Walk Through, Up: Buffer Walk Through - -4.1 Finding More Information -============================ - -In this walk-through, I will describe each new function as we come to -it, sometimes in detail and sometimes briefly. If you are interested, -you can get the full documentation of any Emacs Lisp function at any -time by typing `C-h f' and then the name of the function (and then -<RET>). Similarly, you can get the full documentation for a variable -by typing `C-h v' and then the name of the variable (and then <RET>). - -When a function is written in Emacs Lisp, `describe-function' will also -tell you the location of the function definition. - -Put point into the name of the file that contains the function and -press the <RET> key. In this case, <RET> means `push-button' rather -than `return' or `enter'. Emacs will take you directly to the function -definition. - -More generally, if you want to see a function in its original source -file, you can use the `find-tags' function to jump to it. `find-tags' -works with a wide variety of languages, not just Lisp, and C, and it -works with non-programming text as well. For example, `find-tags' will -jump to the various nodes in the Texinfo source file of this document. - -The `find-tags' function depends on `tags tables' that record the -locations of the functions, variables, and other items to which -`find-tags' jumps. - -To use the `find-tags' command, type `M-.' (i.e., press the period key -while holding down the <META> key, or else type the <ESC> key and then -type the period key), and then, at the prompt, type in the name of the -function whose source code you want to see, such as -`mark-whole-buffer', and then type <RET>. Emacs will switch buffers -and display the source code for the function on your screen. To switch -back to your current buffer, type `C-x b <RET>'. (On some keyboards, -the <META> key is labelled <ALT>.) - -Depending on how the initial default values of your copy of Emacs are -set, you may also need to specify the location of your `tags table', -which is a file called `TAGS'. For example, if you are interested in -Emacs sources, the tags table you will most likely want, if it has -already been created for you, will be in a subdirectory of the -`/usr/local/share/emacs/' directory; thus you would use the `M-x -visit-tags-table' command and specify a pathname such as -`/usr/local/share/emacs/22.0.100/lisp/TAGS'. If the tags table has not -already been created, you will have to create it yourself. It will in -a file such as `/usr/local/src/emacs/src/TAGS'. - -To create a `TAGS' file in a specific directory, switch to that -directory in Emacs using `M-x cd' command, or list the directory with -`C-x d' (`dired'). Then run the compile command, with `etags *.el' as -the command to execute: - - M-x compile RET etags *.el RET - -For more information, see *Note Create Your Own `TAGS' File: etags. - -After you become more familiar with Emacs Lisp, you will find that you -will frequently use `find-tags' to navigate your way around source code; -and you will create your own `TAGS' tables. - -Incidentally, the files that contain Lisp code are conventionally -called "libraries". The metaphor is derived from that of a specialized -library, such as a law library or an engineering library, rather than a -general library. Each library, or file, contains functions that relate -to a particular topic or activity, such as `abbrev.el' for handling -abbreviations and other typing shortcuts, and `help.el' for on-line -help. (Sometimes several libraries provide code for a single activity, -as the various `rmail...' files provide code for reading electronic -mail.) In `The GNU Emacs Manual', you will see sentences such as "The -`C-h p' command lets you search the standard Emacs Lisp libraries by -topic keywords." - - -File: eintr, Node: simplified-beginning-of-buffer, Next: mark-whole-buffer, Prev: Finding More, Up: Buffer Walk Through - -4.2 A Simplified `beginning-of-buffer' Definition -================================================= - -The `beginning-of-buffer' command is a good function to start with -since you are likely to be familiar with it and it is easy to -understand. Used as an interactive command, `beginning-of-buffer' -moves the cursor to the beginning of the buffer, leaving the mark at the -previous position. It is generally bound to `M-<'. - -In this section, we will discuss a shortened version of the function -that shows how it is most frequently used. This shortened function -works as written, but it does not contain the code for a complex option. -In another section, we will describe the entire function. (*Note -Complete Definition of `beginning-of-buffer': beginning-of-buffer.) - -Before looking at the code, let's consider what the function definition -has to contain: it must include an expression that makes the function -interactive so it can be called by typing `M-x beginning-of-buffer' or -by typing a keychord such as `M-<'; it must include code to leave a -mark at the original position in the buffer; and it must include code -to move the cursor to the beginning of the buffer. - -Here is the complete text of the shortened version of the function: - - (defun simplified-beginning-of-buffer () - "Move point to the beginning of the buffer; - leave mark at previous position." - (interactive) - (push-mark) - (goto-char (point-min))) - -Like all function definitions, this definition has five parts following -the special form `defun': - - 1. The name: in this example, `simplified-beginning-of-buffer'. - - 2. A list of the arguments: in this example, an empty list, `()', - - 3. The documentation string. - - 4. The interactive expression. - - 5. The body. - -In this function definition, the argument list is empty; this means that -this function does not require any arguments. (When we look at the -definition for the complete function, we will see that it may be passed -an optional argument.) - -The interactive expression tells Emacs that the function is intended to -be used interactively. In this example, `interactive' does not have an -argument because `simplified-beginning-of-buffer' does not require one. - -The body of the function consists of the two lines: - - (push-mark) - (goto-char (point-min)) - -The first of these lines is the expression, `(push-mark)'. When this -expression is evaluated by the Lisp interpreter, it sets a mark at the -current position of the cursor, wherever that may be. The position of -this mark is saved in the mark ring. - -The next line is `(goto-char (point-min))'. This expression jumps the -cursor to the minimum point in the buffer, that is, to the beginning of -the buffer (or to the beginning of the accessible portion of the buffer -if it is narrowed. *Note Narrowing and Widening: Narrowing & Widening.) - -The `push-mark' command sets a mark at the place where the cursor was -located before it was moved to the beginning of the buffer by the -`(goto-char (point-min))' expression. Consequently, you can, if you -wish, go back to where you were originally by typing `C-x C-x'. - -That is all there is to the function definition! - -When you are reading code such as this and come upon an unfamiliar -function, such as `goto-char', you can find out what it does by using -the `describe-function' command. To use this command, type `C-h f' and -then type in the name of the function and press <RET>. The -`describe-function' command will print the function's documentation -string in a `*Help*' window. For example, the documentation for -`goto-char' is: - - Set point to POSITION, a number or marker. - Beginning of buffer is position (point-min), end is (point-max). - -The function's one argument is the desired position. - -(The prompt for `describe-function' will offer you the symbol under or -preceding the cursor, so you can save typing by positioning the cursor -right over or after the function and then typing `C-h f <RET>'.) - -The `end-of-buffer' function definition is written in the same way as -the `beginning-of-buffer' definition except that the body of the -function contains the expression `(goto-char (point-max))' in place of -`(goto-char (point-min))'. - - -File: eintr, Node: mark-whole-buffer, Next: append-to-buffer, Prev: simplified-beginning-of-buffer, Up: Buffer Walk Through - -4.3 The Definition of `mark-whole-buffer' -========================================= - -The `mark-whole-buffer' function is no harder to understand than the -`simplified-beginning-of-buffer' function. In this case, however, we -will look at the complete function, not a shortened version. - -The `mark-whole-buffer' function is not as commonly used as the -`beginning-of-buffer' function, but is useful nonetheless: it marks a -whole buffer as a region by putting point at the beginning and a mark -at the end of the buffer. It is generally bound to `C-x h'. - -* Menu: - -* mark-whole-buffer overview:: -* Body of mark-whole-buffer:: - - -File: eintr, Node: mark-whole-buffer overview, Next: Body of mark-whole-buffer, Prev: mark-whole-buffer, Up: mark-whole-buffer - -An overview of `mark-whole-buffer' ----------------------------------- - -In GNU Emacs 22, the code for the complete function looks like this: - - (defun mark-whole-buffer () - "Put point at beginning and mark at end of buffer. - You probably should not use this function in Lisp programs; - it is usually a mistake for a Lisp function to use any subroutine - that uses or sets the mark." - (interactive) - (push-mark (point)) - (push-mark (point-max) nil t) - (goto-char (point-min))) - -Like all other functions, the `mark-whole-buffer' function fits into -the template for a function definition. The template looks like this: - - (defun NAME-OF-FUNCTION (ARGUMENT-LIST) - "DOCUMENTATION..." - (INTERACTIVE-EXPRESSION...) - BODY...) - -Here is how the function works: the name of the function is -`mark-whole-buffer'; it is followed by an empty argument list, `()', -which means that the function does not require arguments. The -documentation comes next. - -The next line is an `(interactive)' expression that tells Emacs that -the function will be used interactively. These details are similar to -the `simplified-beginning-of-buffer' function described in the previous -section. - - -File: eintr, Node: Body of mark-whole-buffer, Prev: mark-whole-buffer overview, Up: mark-whole-buffer - -4.3.1 Body of `mark-whole-buffer' ---------------------------------- - -The body of the `mark-whole-buffer' function consists of three lines of -code: - - (push-mark (point)) - (push-mark (point-max) nil t) - (goto-char (point-min)) - -The first of these lines is the expression, `(push-mark (point))'. - -This line does exactly the same job as the first line of the body of -the `simplified-beginning-of-buffer' function, which is written -`(push-mark)'. In both cases, the Lisp interpreter sets a mark at the -current position of the cursor. - -I don't know why the expression in `mark-whole-buffer' is written -`(push-mark (point))' and the expression in `beginning-of-buffer' is -written `(push-mark)'. Perhaps whoever wrote the code did not know -that the arguments for `push-mark' are optional and that if `push-mark' -is not passed an argument, the function automatically sets mark at the -location of point by default. Or perhaps the expression was written so -as to parallel the structure of the next line. In any case, the line -causes Emacs to determine the position of point and set a mark there. - -In earlier versions of GNU Emacs, the next line of `mark-whole-buffer' -was `(push-mark (point-max))'. This expression sets a mark at the -point in the buffer that has the highest number. This will be the end -of the buffer (or, if the buffer is narrowed, the end of the accessible -portion of the buffer. *Note Narrowing and Widening: Narrowing & -Widening, for more about narrowing.) After this mark has been set, the -previous mark, the one set at point, is no longer set, but Emacs -remembers its position, just as all other recent marks are always -remembered. This means that you can, if you wish, go back to that -position by typing `C-u C-<SPC>' twice. - -In GNU Emacs 22, the `(point-max)' is slightly more complicated. The -line reads - - (push-mark (point-max) nil t) - -The expression works nearly the same as before. It sets a mark at the -highest numbered place in the buffer that it can. However, in this -version, `push-mark' has two additional arguments. The second argument -to `push-mark' is `nil'. This tells the function it _should_ display a -message that says `Mark set' when it pushes the mark. The third -argument is `t'. This tells `push-mark' to activate the mark when -Transient Mark mode is turned on. Transient Mark mode highlights the -currently active region. It is often turned off. - -Finally, the last line of the function is `(goto-char (point-min)))'. -This is written exactly the same way as it is written in -`beginning-of-buffer'. The expression moves the cursor to the minimum -point in the buffer, that is, to the beginning of the buffer (or to the -beginning of the accessible portion of the buffer). As a result of -this, point is placed at the beginning of the buffer and mark is set at -the end of the buffer. The whole buffer is, therefore, the region. - - -File: eintr, Node: append-to-buffer, Next: Buffer Related Review, Prev: mark-whole-buffer, Up: Buffer Walk Through - -4.4 The Definition of `append-to-buffer' -======================================== - -The `append-to-buffer' command is more complex than the -`mark-whole-buffer' command. What it does is copy the region (that is, -the part of the buffer between point and mark) from the current buffer -to a specified buffer. - -* Menu: - -* append-to-buffer overview:: -* append interactive:: -* append-to-buffer body:: -* append save-excursion:: - - -File: eintr, Node: append-to-buffer overview, Next: append interactive, Prev: append-to-buffer, Up: append-to-buffer - -An Overview of `append-to-buffer' ---------------------------------- - -The `append-to-buffer' command uses the `insert-buffer-substring' -function to copy the region. `insert-buffer-substring' is described by -its name: it takes a string of characters from part of a buffer, a -"substring", and inserts them into another buffer. - -Most of `append-to-buffer' is concerned with setting up the conditions -for `insert-buffer-substring' to work: the code must specify both the -buffer to which the text will go, the window it comes from and goes to, -and the region that will be copied. - -Here is the complete text of the function: - - (defun append-to-buffer (buffer start end) - "Append to specified buffer the text of the region. - It is inserted into that buffer before its point. - - When calling from a program, give three arguments: - BUFFER (or buffer name), START and END. - START and END specify the portion of the current buffer to be copied." - (interactive - (list (read-buffer "Append to buffer: " (other-buffer - (current-buffer) t)) - (region-beginning) (region-end))) - (let ((oldbuf (current-buffer))) - (save-excursion - (let* ((append-to (get-buffer-create buffer)) - (windows (get-buffer-window-list append-to t t)) - point) - (set-buffer append-to) - (setq point (point)) - (barf-if-buffer-read-only) - (insert-buffer-substring oldbuf start end) - (dolist (window windows) - (when (= (window-point window) point) - (set-window-point window (point)))))))) - -The function can be understood by looking at it as a series of -filled-in templates. - -The outermost template is for the function definition. In this -function, it looks like this (with several slots filled in): - - (defun append-to-buffer (buffer start end) - "DOCUMENTATION..." - (interactive ...) - BODY...) - -The first line of the function includes its name and three arguments. -The arguments are the `buffer' to which the text will be copied, and -the `start' and `end' of the region in the current buffer that will be -copied. - -The next part of the function is the documentation, which is clear and -complete. As is conventional, the three arguments are written in upper -case so you will notice them easily. Even better, they are described -in the same order as in the argument list. - -Note that the documentation distinguishes between a buffer and its -name. (The function can handle either.) - - -File: eintr, Node: append interactive, Next: append-to-buffer body, Prev: append-to-buffer overview, Up: append-to-buffer - -4.4.1 The `append-to-buffer' Interactive Expression ---------------------------------------------------- - -Since the `append-to-buffer' function will be used interactively, the -function must have an `interactive' expression. (For a review of -`interactive', see *Note Making a Function Interactive: Interactive.) -The expression reads as follows: - - (interactive - (list (read-buffer - "Append to buffer: " - (other-buffer (current-buffer) t)) - (region-beginning) - (region-end))) - -This expression is not one with letters standing for parts, as -described earlier. Instead, it starts a list with thee parts. - -The first part of the list is an expression to read the name of a -buffer and return it as a string. That is `read-buffer'. The function -requires a prompt as its first argument, `"Append to buffer: "'. Its -second argument tells the command what value to provide if you don't -specify anything. - -In this case that second argument is an expression containing the -function `other-buffer', an exception, and a `t', standing for true. - -The first argument to `other-buffer', the exception, is yet another -function, `current-buffer'. That is not going to be returned. The -second argument is the symbol for true, `t'. that tells `other-buffer' -that it may show visible buffers (except in this case, it will not show -the current buffer, which makes sense). - -The expression looks like this: - - (other-buffer (current-buffer) t) - -The second and third arguments to the `list' expression are -`(region-beginning)' and `(region-end)'. These two functions specify -the beginning and end of the text to be appended. - -Originally, the command used the letters `B' and `r'. The whole -`interactive' expression looked like this: - - (interactive "BAppend to buffer: \nr") - -But when that was done, the default value of the buffer switched to was -invisible. That was not wanted. - -(The prompt was separated from the second argument with a newline, -`\n'. It was followed by an `r' that told Emacs to bind the two -arguments that follow the symbol `buffer' in the function's argument -list (that is, `start' and `end') to the values of point and mark. -That argument worked fine.) - - -File: eintr, Node: append-to-buffer body, Next: append save-excursion, Prev: append interactive, Up: append-to-buffer - -4.4.2 The Body of `append-to-buffer' ------------------------------------- - -The body of the `append-to-buffer' function begins with `let'. - -As we have seen before (*note `let': let.), the purpose of a `let' -expression is to create and give initial values to one or more -variables that will only be used within the body of the `let'. This -means that such a variable will not be confused with any variable of -the same name outside the `let' expression. - -We can see how the `let' expression fits into the function as a whole -by showing a template for `append-to-buffer' with the `let' expression -in outline: - - (defun append-to-buffer (buffer start end) - "DOCUMENTATION..." - (interactive ...) - (let ((VARIABLE VALUE)) - BODY...) - -The `let' expression has three elements: - - 1. The symbol `let'; - - 2. A varlist containing, in this case, a single two-element list, - `(VARIABLE VALUE)'; - - 3. The body of the `let' expression. - -In the `append-to-buffer' function, the varlist looks like this: - - (oldbuf (current-buffer)) - -In this part of the `let' expression, the one variable, `oldbuf', is -bound to the value returned by the `(current-buffer)' expression. The -variable, `oldbuf', is used to keep track of the buffer in which you -are working and from which you will copy. - -The element or elements of a varlist are surrounded by a set of -parentheses so the Lisp interpreter can distinguish the varlist from -the body of the `let'. As a consequence, the two-element list within -the varlist is surrounded by a circumscribing set of parentheses. The -line looks like this: - - (let ((oldbuf (current-buffer))) - ... ) - -The two parentheses before `oldbuf' might surprise you if you did not -realize that the first parenthesis before `oldbuf' marks the boundary -of the varlist and the second parenthesis marks the beginning of the -two-element list, `(oldbuf (current-buffer))'. - - -File: eintr, Node: append save-excursion, Prev: append-to-buffer body, Up: append-to-buffer - -4.4.3 `save-excursion' in `append-to-buffer' --------------------------------------------- - -The body of the `let' expression in `append-to-buffer' consists of a -`save-excursion' expression. - -The `save-excursion' function saves the locations of point and mark, -and restores them to those positions after the expressions in the body -of the `save-excursion' complete execution. In addition, -`save-excursion' keeps track of the original buffer, and restores it. -This is how `save-excursion' is used in `append-to-buffer'. - -Incidentally, it is worth noting here that a Lisp function is normally -formatted so that everything that is enclosed in a multi-line spread is -indented more to the right than the first symbol. In this function -definition, the `let' is indented more than the `defun', and the -`save-excursion' is indented more than the `let', like this: - - (defun ... - ... - ... - (let... - (save-excursion - ... - -This formatting convention makes it easy to see that the lines in the -body of the `save-excursion' are enclosed by the parentheses associated -with `save-excursion', just as the `save-excursion' itself is enclosed -by the parentheses associated with the `let': - - (let ((oldbuf (current-buffer))) - (save-excursion - ... - (set-buffer ...) - (insert-buffer-substring oldbuf start end) - ...)) - -The use of the `save-excursion' function can be viewed as a process of -filling in the slots of a template: - - (save-excursion - FIRST-EXPRESSION-IN-BODY - SECOND-EXPRESSION-IN-BODY - ... - LAST-EXPRESSION-IN-BODY) - -In this function, the body of the `save-excursion' contains only one -expression, the `let*' expression. You know about a `let' function. -The `let*' function is different. It has a `*' in its name. It -enables Emacs to set each variable in its varlist in sequence, one -after another. - -Its critical feature is that variables later in the varlist can make -use of the values to which Emacs set variables earlier in the varlist. -*Note The `let*' expression: fwd-para let. - -We will skip functions like `let*' and focus on two: the `set-buffer' -function and the `insert-buffer-substring' function. - -In the old days, the `set-buffer' expression was simply - - (set-buffer (get-buffer-create buffer)) - -but now it is - - (set-buffer append-to) - -`append-to' is bound to `(get-buffer-create buffer)' earlier on in the -`let*' expression. That extra binding would not be necessary except -for that `append-to' is used later in the varlist as an argument to -`get-buffer-window-list'. - -The `append-to-buffer' function definition inserts text from the buffer -in which you are currently to a named buffer. It happens that -`insert-buffer-substring' copies text from another buffer to the -current buffer, just the reverse--that is why the `append-to-buffer' -definition starts out with a `let' that binds the local symbol `oldbuf' -to the value returned by `current-buffer'. - -The `insert-buffer-substring' expression looks like this: - - (insert-buffer-substring oldbuf start end) - -The `insert-buffer-substring' function copies a string _from_ the -buffer specified as its first argument and inserts the string into the -present buffer. In this case, the argument to -`insert-buffer-substring' is the value of the variable created and -bound by the `let', namely the value of `oldbuf', which was the current -buffer when you gave the `append-to-buffer' command. - -After `insert-buffer-substring' has done its work, `save-excursion' -will restore the action to the original buffer and `append-to-buffer' -will have done its job. - -Written in skeletal form, the workings of the body look like this: - - (let (BIND-`oldbuf'-TO-VALUE-OF-`current-buffer') - (save-excursion ; Keep track of buffer. - CHANGE-BUFFER - INSERT-SUBSTRING-FROM-`oldbuf'-INTO-BUFFER) - - CHANGE-BACK-TO-ORIGINAL-BUFFER-WHEN-FINISHED - LET-THE-LOCAL-MEANING-OF-`oldbuf'-DISAPPEAR-WHEN-FINISHED - -In summary, `append-to-buffer' works as follows: it saves the value of -the current buffer in the variable called `oldbuf'. It gets the new -buffer (creating one if need be) and switches Emacs' attention to it. -Using the value of `oldbuf', it inserts the region of text from the old -buffer into the new buffer; and then using `save-excursion', it brings -you back to your original buffer. - -In looking at `append-to-buffer', you have explored a fairly complex -function. It shows how to use `let' and `save-excursion', and how to -change to and come back from another buffer. Many function definitions -use `let', `save-excursion', and `set-buffer' this way. - - -File: eintr, Node: Buffer Related Review, Next: Buffer Exercises, Prev: append-to-buffer, Up: Buffer Walk Through - -4.5 Review -========== - -Here is a brief summary of the various functions discussed in this -chapter. - -`describe-function' -`describe-variable' - Print the documentation for a function or variable. - Conventionally bound to `C-h f' and `C-h v'. - -`find-tag' - Find the file containing the source for a function or variable and - switch buffers to it, positioning point at the beginning of the - item. Conventionally bound to `M-.' (that's a period following the - <META> key). - -`save-excursion' - Save the location of point and mark and restore their values after - the arguments to `save-excursion' have been evaluated. Also, - remember the current buffer and return to it. - -`push-mark' - Set mark at a location and record the value of the previous mark - on the mark ring. The mark is a location in the buffer that will - keep its relative position even if text is added to or removed - from the buffer. - -`goto-char' - Set point to the location specified by the value of the argument, - which can be a number, a marker, or an expression that returns - the number of a position, such as `(point-min)'. - -`insert-buffer-substring' - Copy a region of text from a buffer that is passed to the function - as an argument and insert the region into the current buffer. - -`mark-whole-buffer' - Mark the whole buffer as a region. Normally bound to `C-x h'. - -`set-buffer' - Switch the attention of Emacs to another buffer, but do not change - the window being displayed. Used when the program rather than a - human is to work on a different buffer. - -`get-buffer-create' -`get-buffer' - Find a named buffer or create one if a buffer of that name does not - exist. The `get-buffer' function returns `nil' if the named - buffer does not exist. - - -File: eintr, Node: Buffer Exercises, Prev: Buffer Related Review, Up: Buffer Walk Through - -4.6 Exercises -============= - - * Write your own `simplified-end-of-buffer' function definition; - then test it to see whether it works. - - * Use `if' and `get-buffer' to write a function that prints a - message telling you whether a buffer exists. - - * Using `find-tag', find the source for the `copy-to-buffer' - function. - - -File: eintr, Node: More Complex, Next: Narrowing & Widening, Prev: Buffer Walk Through, Up: Top - -5 A Few More Complex Functions -****************************** - -In this chapter, we build on what we have learned in previous chapters -by looking at more complex functions. The `copy-to-buffer' function -illustrates use of two `save-excursion' expressions in one definition, -while the `insert-buffer' function illustrates use of an asterisk in an -`interactive' expression, use of `or', and the important distinction -between a name and the object to which the name refers. - -* Menu: - -* copy-to-buffer:: -* insert-buffer:: -* beginning-of-buffer:: -* Second Buffer Related Review:: -* optional Exercise:: - - -File: eintr, Node: copy-to-buffer, Next: insert-buffer, Prev: More Complex, Up: More Complex - -5.1 The Definition of `copy-to-buffer' -====================================== - -After understanding how `append-to-buffer' works, it is easy to -understand `copy-to-buffer'. This function copies text into a buffer, -but instead of adding to the second buffer, it replaces all the -previous text in the second buffer. - -The body of `copy-to-buffer' looks like this, - - ... - (interactive "BCopy to buffer: \nr") - (let ((oldbuf (current-buffer))) - (with-current-buffer (get-buffer-create buffer) - (barf-if-buffer-read-only) - (erase-buffer) - (save-excursion - (insert-buffer-substring oldbuf start end))))) - -The `copy-to-buffer' function has a simpler `interactive' expression -than `append-to-buffer'. - -The definition then says - - (with-current-buffer (get-buffer-create buffer) ... - -First, look at the earliest inner expression; that is evaluated first. -That expression starts with `get-buffer-create buffer'. The function -tells the computer to use the buffer with the name specified as the one -to which you are copying, or if such a buffer does not exist, to create -it. Then, the `with-current-buffer' function evaluates its body with -that buffer temporarily current. - -(This demonstrates another way to shift the computer's attention but -not the user's. The `append-to-buffer' function showed how to do the -same with `save-excursion' and `set-buffer'. `with-current-buffer' is -a newer, and arguably easier, mechanism.) - -The `barf-if-buffer-read-only' function sends you an error message -saying the buffer is read-only if you cannot modify it. - -The next line has the `erase-buffer' function as its sole contents. -That function erases the buffer. - -Finally, the last two lines contain the `save-excursion' expression -with `insert-buffer-substring' as its body. The -`insert-buffer-substring' expression copies the text from the buffer -you are in (and you have not seen the computer shift its attention, so -you don't know that that buffer is now called `oldbuf'). - -Incidentally, this is what is meant by `replacement'. To replace text, -Emacs erases the previous text and then inserts new text. - -In outline, the body of `copy-to-buffer' looks like this: - - (let (BIND-`oldbuf'-TO-VALUE-OF-`current-buffer') - (WITH-THE-BUFFER-YOU-ARE-COPYING-TO - (BUT-DO-NOT-ERASE-OR-COPY-TO-A-READ-ONLY-BUFFER) - (erase-buffer) - (save-excursion - INSERT-SUBSTRING-FROM-`oldbuf'-INTO-BUFFER))) - - -File: eintr, Node: insert-buffer, Next: beginning-of-buffer, Prev: copy-to-buffer, Up: More Complex - -5.2 The Definition of `insert-buffer' -===================================== - -`insert-buffer' is yet another buffer-related function. This command -copies another buffer _into_ the current buffer. It is the reverse of -`append-to-buffer' or `copy-to-buffer', since they copy a region of -text _from_ the current buffer to another buffer. - -Here is a discussion based on the original code. The code was -simplified in 2003 and is harder to understand. - -*Note New Body for `insert-buffer': New insert-buffer, to see a -discussion of the new body.) - -In addition, this code illustrates the use of `interactive' with a -buffer that might be "read-only" and the important distinction between -the name of an object and the object actually referred to. - -* Menu: - -* insert-buffer code:: -* insert-buffer interactive:: -* insert-buffer body:: -* if & or:: -* Insert or:: -* Insert let:: -* New insert-buffer :: - - -File: eintr, Node: insert-buffer code, Next: insert-buffer interactive, Prev: insert-buffer, Up: insert-buffer - -The Code for `insert-buffer' ----------------------------- - -Here is the earlier code: - - (defun insert-buffer (buffer) - "Insert after point the contents of BUFFER. - Puts mark after the inserted text. - BUFFER may be a buffer or a buffer name." - (interactive "*bInsert buffer: ") - (or (bufferp buffer) - (setq buffer (get-buffer buffer))) - (let (start end newmark) - (save-excursion - (save-excursion - (set-buffer buffer) - (setq start (point-min) end (point-max))) - (insert-buffer-substring buffer start end) - (setq newmark (point))) - (push-mark newmark))) - -As with other function definitions, you can use a template to see an -outline of the function: - - (defun insert-buffer (buffer) - "DOCUMENTATION..." - (interactive "*bInsert buffer: ") - BODY...) - - -File: eintr, Node: insert-buffer interactive, Next: insert-buffer body, Prev: insert-buffer code, Up: insert-buffer - -5.2.1 The Interactive Expression in `insert-buffer' ---------------------------------------------------- - -In `insert-buffer', the argument to the `interactive' declaration has -two parts, an asterisk, `*', and `bInsert buffer: '. - -* Menu: - -* Read-only buffer:: -* b for interactive:: - - -File: eintr, Node: Read-only buffer, Next: b for interactive, Prev: insert-buffer interactive, Up: insert-buffer interactive - -A Read-only Buffer -.................. - -The asterisk is for the situation when the current buffer is a -read-only buffer--a buffer that cannot be modified. If `insert-buffer' -is called when the current buffer is read-only, a message to this -effect is printed in the echo area and the terminal may beep or blink -at you; you will not be permitted to insert anything into current -buffer. The asterisk does not need to be followed by a newline to -separate it from the next argument. - - -File: eintr, Node: b for interactive, Prev: Read-only buffer, Up: insert-buffer interactive - -`b' in an Interactive Expression -................................ - -The next argument in the interactive expression starts with a lower -case `b'. (This is different from the code for `append-to-buffer', -which uses an upper-case `B'. *Note The Definition of -`append-to-buffer': append-to-buffer.) The lower-case `b' tells the -Lisp interpreter that the argument for `insert-buffer' should be an -existing buffer or else its name. (The upper-case `B' option provides -for the possibility that the buffer does not exist.) Emacs will prompt -you for the name of the buffer, offering you a default buffer, with -name completion enabled. If the buffer does not exist, you receive a -message that says "No match"; your terminal may beep at you as well. - -The new and simplified code generates a list for `interactive'. It -uses the `barf-if-buffer-read-only' and `read-buffer' functions with -which we are already familiar and the `progn' special form with which -we are not. (It will be described later.) - - -File: eintr, Node: insert-buffer body, Next: if & or, Prev: insert-buffer interactive, Up: insert-buffer - -5.2.2 The Body of the `insert-buffer' Function ----------------------------------------------- - -The body of the `insert-buffer' function has two major parts: an `or' -expression and a `let' expression. The purpose of the `or' expression -is to ensure that the argument `buffer' is bound to a buffer and not -just the name of a buffer. The body of the `let' expression contains -the code which copies the other buffer into the current buffer. - -In outline, the two expressions fit into the `insert-buffer' function -like this: - - (defun insert-buffer (buffer) - "DOCUMENTATION..." - (interactive "*bInsert buffer: ") - (or ... - ... - (let (VARLIST) - BODY-OF-`let'... ) - -To understand how the `or' expression ensures that the argument -`buffer' is bound to a buffer and not to the name of a buffer, it is -first necessary to understand the `or' function. - -Before doing this, let me rewrite this part of the function using `if' -so that you can see what is done in a manner that will be familiar. - - -File: eintr, Node: if & or, Next: Insert or, Prev: insert-buffer body, Up: insert-buffer - -5.2.3 `insert-buffer' With an `if' Instead of an `or' ------------------------------------------------------ - -The job to be done is to make sure the value of `buffer' is a buffer -itself and not the name of a buffer. If the value is the name, then -the buffer itself must be got. - -You can imagine yourself at a conference where an usher is wandering -around holding a list with your name on it and looking for you: the -usher is "bound" to your name, not to you; but when the usher finds you -and takes your arm, the usher becomes "bound" to you. - -In Lisp, you might describe this situation like this: - - (if (not (holding-on-to-guest)) - (find-and-take-arm-of-guest)) - -We want to do the same thing with a buffer--if we do not have the -buffer itself, we want to get it. - -Using a predicate called `bufferp' that tells us whether we have a -buffer (rather than its name), we can write the code like this: - - (if (not (bufferp buffer)) ; if-part - (setq buffer (get-buffer buffer))) ; then-part - -Here, the true-or-false-test of the `if' expression is -`(not (bufferp buffer))'; and the then-part is the expression -`(setq buffer (get-buffer buffer))'. - -In the test, the function `bufferp' returns true if its argument is a -buffer--but false if its argument is the name of the buffer. (The last -character of the function name `bufferp' is the character `p'; as we -saw earlier, such use of `p' is a convention that indicates that the -function is a predicate, which is a term that means that the function -will determine whether some property is true or false. *Note Using the -Wrong Type Object as an Argument: Wrong Type of Argument.) - -The function `not' precedes the expression `(bufferp buffer)', so the -true-or-false-test looks like this: - - (not (bufferp buffer)) - -`not' is a function that returns true if its argument is false and -false if its argument is true. So if `(bufferp buffer)' returns true, -the `not' expression returns false and vice-verse: what is "not true" -is false and what is "not false" is true. - -Using this test, the `if' expression works as follows: when the value -of the variable `buffer' is actually a buffer rather than its name, the -true-or-false-test returns false and the `if' expression does not -evaluate the then-part. This is fine, since we do not need to do -anything to the variable `buffer' if it really is a buffer. - -On the other hand, when the value of `buffer' is not a buffer itself, -but the name of a buffer, the true-or-false-test returns true and the -then-part of the expression is evaluated. In this case, the then-part -is `(setq buffer (get-buffer buffer))'. This expression uses the -`get-buffer' function to return an actual buffer itself, given its -name. The `setq' then sets the variable `buffer' to the value of the -buffer itself, replacing its previous value (which was the name of the -buffer). - - -File: eintr, Node: Insert or, Next: Insert let, Prev: if & or, Up: insert-buffer - -5.2.4 The `or' in the Body --------------------------- - -The purpose of the `or' expression in the `insert-buffer' function is -to ensure that the argument `buffer' is bound to a buffer and not just -to the name of a buffer. The previous section shows how the job could -have been done using an `if' expression. However, the `insert-buffer' -function actually uses `or'. To understand this, it is necessary to -understand how `or' works. - -An `or' function can have any number of arguments. It evaluates each -argument in turn and returns the value of the first of its arguments -that is not `nil'. Also, and this is a crucial feature of `or', it -does not evaluate any subsequent arguments after returning the first -non-`nil' value. - -The `or' expression looks like this: - - (or (bufferp buffer) - (setq buffer (get-buffer buffer))) - -The first argument to `or' is the expression `(bufferp buffer)'. This -expression returns true (a non-`nil' value) if the buffer is actually a -buffer, and not just the name of a buffer. In the `or' expression, if -this is the case, the `or' expression returns this true value and does -not evaluate the next expression--and this is fine with us, since we do -not want to do anything to the value of `buffer' if it really is a -buffer. - -On the other hand, if the value of `(bufferp buffer)' is `nil', which -it will be if the value of `buffer' is the name of a buffer, the Lisp -interpreter evaluates the next element of the `or' expression. This is -the expression `(setq buffer (get-buffer buffer))'. This expression -returns a non-`nil' value, which is the value to which it sets the -variable `buffer'--and this value is a buffer itself, not the name of a -buffer. - -The result of all this is that the symbol `buffer' is always bound to a -buffer itself rather than to the name of a buffer. All this is -necessary because the `set-buffer' function in a following line only -works with a buffer itself, not with the name to a buffer. - -Incidentally, using `or', the situation with the usher would be written -like this: - - (or (holding-on-to-guest) (find-and-take-arm-of-guest)) - - -File: eintr, Node: Insert let, Next: New insert-buffer, Prev: Insert or, Up: insert-buffer - -5.2.5 The `let' Expression in `insert-buffer' ---------------------------------------------- - -After ensuring that the variable `buffer' refers to a buffer itself and -not just to the name of a buffer, the `insert-buffer function' -continues with a `let' expression. This specifies three local -variables, `start', `end', and `newmark' and binds them to the initial -value `nil'. These variables are used inside the remainder of the -`let' and temporarily hide any other occurrence of variables of the -same name in Emacs until the end of the `let'. - -The body of the `let' contains two `save-excursion' expressions. -First, we will look at the inner `save-excursion' expression in detail. -The expression looks like this: - - (save-excursion - (set-buffer buffer) - (setq start (point-min) end (point-max))) - -The expression `(set-buffer buffer)' changes Emacs' attention from the -current buffer to the one from which the text will copied. In that -buffer, the variables `start' and `end' are set to the beginning and -end of the buffer, using the commands `point-min' and `point-max'. -Note that we have here an illustration of how `setq' is able to set two -variables in the same expression. The first argument of `setq' is set -to the value of its second, and its third argument is set to the value -of its fourth. - -After the body of the inner `save-excursion' is evaluated, the -`save-excursion' restores the original buffer, but `start' and `end' -remain set to the values of the beginning and end of the buffer from -which the text will be copied. - -The outer `save-excursion' expression looks like this: - - (save-excursion - (INNER-`save-excursion'-EXPRESSION - (GO-TO-NEW-BUFFER-AND-SET-`start'-AND-`end') - (insert-buffer-substring buffer start end) - (setq newmark (point))) - -The `insert-buffer-substring' function copies the text _into_ the -current buffer _from_ the region indicated by `start' and `end' in -`buffer'. Since the whole of the second buffer lies between `start' -and `end', the whole of the second buffer is copied into the buffer you -are editing. Next, the value of point, which will be at the end of the -inserted text, is recorded in the variable `newmark'. - -After the body of the outer `save-excursion' is evaluated, point and -mark are relocated to their original places. - -However, it is convenient to locate a mark at the end of the newly -inserted text and locate point at its beginning. The `newmark' -variable records the end of the inserted text. In the last line of the -`let' expression, the `(push-mark newmark)' expression function sets a -mark to this location. (The previous location of the mark is still -accessible; it is recorded on the mark ring and you can go back to it -with `C-u C-<SPC>'.) Meanwhile, point is located at the beginning of -the inserted text, which is where it was before you called the insert -function, the position of which was saved by the first `save-excursion'. - -The whole `let' expression looks like this: - - (let (start end newmark) - (save-excursion - (save-excursion - (set-buffer buffer) - (setq start (point-min) end (point-max))) - (insert-buffer-substring buffer start end) - (setq newmark (point))) - (push-mark newmark)) - -Like the `append-to-buffer' function, the `insert-buffer' function uses -`let', `save-excursion', and `set-buffer'. In addition, the function -illustrates one way to use `or'. All these functions are building -blocks that we will find and use again and again. - - -File: eintr, Node: New insert-buffer, Prev: Insert let, Up: insert-buffer - -5.2.6 New Body for `insert-buffer' ----------------------------------- - -The body in the GNU Emacs 22 version is more confusing than the -original. - -It consists of two expressions, - - (push-mark - (save-excursion - (insert-buffer-substring (get-buffer buffer)) - (point))) - - nil - -except, and this is what confuses novices, very important work is done -inside the `push-mark' expression. - -The `get-buffer' function returns a buffer with the name provided. You -will note that the function is _not_ called `get-buffer-create'; it -does not create a buffer if one does not already exist. The buffer -returned by `get-buffer', an existing buffer, is passed to -`insert-buffer-substring', which inserts the whole of the buffer (since -you did not specify anything else). - -The location into which the buffer is inserted is recorded by -`push-mark'. Then the function returns `nil', the value of its last -command. Put another way, the `insert-buffer' function exists only to -produce a side effect, inserting another buffer, not to return any -value. - - -File: eintr, Node: beginning-of-buffer, Next: Second Buffer Related Review, Prev: insert-buffer, Up: More Complex - -5.3 Complete Definition of `beginning-of-buffer' -================================================ - -The basic structure of the `beginning-of-buffer' function has already -been discussed. (*Note A Simplified `beginning-of-buffer' Definition: -simplified-beginning-of-buffer.) This section describes the complex -part of the definition. - -As previously described, when invoked without an argument, -`beginning-of-buffer' moves the cursor to the beginning of the buffer -(in truth, the accessible portion of the buffer), leaving the mark at -the previous position. However, when the command is invoked with a -number between one and ten, the function considers that number to be a -fraction of the length of the buffer, measured in tenths, and Emacs -moves the cursor that fraction of the way from the beginning of the -buffer. Thus, you can either call this function with the key command -`M-<', which will move the cursor to the beginning of the buffer, or -with a key command such as `C-u 7 M-<' which will move the cursor to a -point 70% of the way through the buffer. If a number bigger than ten -is used for the argument, it moves to the end of the buffer. - -The `beginning-of-buffer' function can be called with or without an -argument. The use of the argument is optional. - -* Menu: - -* Optional Arguments:: -* beginning-of-buffer opt arg:: -* beginning-of-buffer complete:: - - -File: eintr, Node: Optional Arguments, Next: beginning-of-buffer opt arg, Prev: beginning-of-buffer, Up: beginning-of-buffer - -5.3.1 Optional Arguments ------------------------- - -Unless told otherwise, Lisp expects that a function with an argument in -its function definition will be called with a value for that argument. -If that does not happen, you get an error and a message that says -`Wrong number of arguments'. - -However, optional arguments are a feature of Lisp: a particular -"keyword" is used to tell the Lisp interpreter that an argument is -optional. The keyword is `&optional'. (The `&' in front of `optional' -is part of the keyword.) In a function definition, if an argument -follows the keyword `&optional', no value need be passed to that -argument when the function is called. - -The first line of the function definition of `beginning-of-buffer' -therefore looks like this: - - (defun beginning-of-buffer (&optional arg) - -In outline, the whole function looks like this: - - (defun beginning-of-buffer (&optional arg) - "DOCUMENTATION..." - (interactive "P") - (or (IS-THE-ARGUMENT-A-CONS-CELL arg) - (and ARE-BOTH-TRANSIENT-MARK-MODE-AND-MARK-ACTIVE-TRUE) - (push-mark)) - (let (DETERMINE-SIZE-AND-SET-IT) - (goto-char - (IF-THERE-IS-AN-ARGUMENT - FIGURE-OUT-WHERE-TO-GO - ELSE-GO-TO - (point-min)))) - DO-NICETY - -The function is similar to the `simplified-beginning-of-buffer' -function except that the `interactive' expression has `"P"' as an -argument and the `goto-char' function is followed by an if-then-else -expression that figures out where to put the cursor if there is an -argument that is not a cons cell. - -(Since I do not explain a cons cell for many more chapters, please -consider ignoring the function `consp'. *Note How Lists are -Implemented: List Implementation, and *Note Cons Cell and List Types: -(elisp)Cons Cell Type.) - -The `"P"' in the `interactive' expression tells Emacs to pass a prefix -argument, if there is one, to the function in raw form. A prefix -argument is made by typing the <META> key followed by a number, or by -typing `C-u' and then a number. (If you don't type a number, `C-u' -defaults to a cons cell with a 4. A lowercase `"p"' in the -`interactive' expression causes the function to convert a prefix arg to -a number.) - -The true-or-false-test of the `if' expression looks complex, but it is -not: it checks whether `arg' has a value that is not `nil' and whether -it is a cons cell. (That is what `consp' does; it checks whether its -argument is a cons cell.) If `arg' has a value that is not `nil' (and -is not a cons cell), which will be the case if `beginning-of-buffer' is -called with a numeric argument, then this true-or-false-test will -return true and the then-part of the `if' expression will be evaluated. -On the other hand, if `beginning-of-buffer' is not called with an -argument, the value of `arg' will be `nil' and the else-part of the -`if' expression will be evaluated. The else-part is simply -`point-min', and when this is the outcome, the whole `goto-char' -expression is `(goto-char (point-min))', which is how we saw the -`beginning-of-buffer' function in its simplified form. - - -File: eintr, Node: beginning-of-buffer opt arg, Next: beginning-of-buffer complete, Prev: Optional Arguments, Up: beginning-of-buffer - -5.3.2 `beginning-of-buffer' with an Argument --------------------------------------------- - -When `beginning-of-buffer' is called with an argument, an expression is -evaluated which calculates what value to pass to `goto-char'. This -expression is rather complicated at first sight. It includes an inner -`if' expression and much arithmetic. It looks like this: - - (if (> (buffer-size) 10000) - ;; Avoid overflow for large buffer sizes! - (* (prefix-numeric-value arg) - (/ size 10)) - (/ - (+ 10 - (* - size (prefix-numeric-value arg))) 10))) - -* Menu: - -* Disentangle beginning-of-buffer:: -* Large buffer case:: -* Small buffer case:: - - -File: eintr, Node: Disentangle beginning-of-buffer, Next: Large buffer case, Prev: beginning-of-buffer opt arg, Up: beginning-of-buffer opt arg - -Disentangle `beginning-of-buffer' -................................. - -Like other complex-looking expressions, the conditional expression -within `beginning-of-buffer' can be disentangled by looking at it as -parts of a template, in this case, the template for an if-then-else -expression. In skeletal form, the expression looks like this: - - (if (BUFFER-IS-LARGE - DIVIDE-BUFFER-SIZE-BY-10-AND-MULTIPLY-BY-ARG - ELSE-USE-ALTERNATE-CALCULATION - -The true-or-false-test of this inner `if' expression checks the size of -the buffer. The reason for this is that the old Version 18 Emacs used -numbers that are no bigger than eight million or so and in the -computation that followed, the programmer feared that Emacs might try -to use over-large numbers if the buffer were large. The term -`overflow', mentioned in the comment, means numbers that are over -large. Version 21 Emacs uses larger numbers, but this code has not -been touched, if only because people now look at buffers that are far, -far larger than ever before. - -There are two cases: if the buffer is large and if it is not. - - -File: eintr, Node: Large buffer case, Next: Small buffer case, Prev: Disentangle beginning-of-buffer, Up: beginning-of-buffer opt arg - -What happens in a large buffer -.............................. - -In `beginning-of-buffer', the inner `if' expression tests whether the -size of the buffer is greater than 10,000 characters. To do this, it -uses the `>' function and the computation of `size' that comes from the -let expression. - -In the old days, the function `buffer-size' was used. Not only was -that function called several times, it gave the size of the whole -buffer, not the accessible part. The computation makes much more sense -when it handles just the accessible part. (*Note Narrowing and -Widening: Narrowing & Widening, for more information on focusing -attention to an `accessible' part.) - -The line looks like this: - - (if (> size 10000) - -When the buffer is large, the then-part of the `if' expression is -evaluated. It reads like this (after formatting for easy reading): - - (* - (prefix-numeric-value arg) - (/ size 10)) - -This expression is a multiplication, with two arguments to the function -`*'. - -The first argument is `(prefix-numeric-value arg)'. When `"P"' is used -as the argument for `interactive', the value passed to the function as -its argument is passed a "raw prefix argument", and not a number. (It -is a number in a list.) To perform the arithmetic, a conversion is -necessary, and `prefix-numeric-value' does the job. - -The second argument is `(/ size 10)'. This expression divides the -numeric value by ten -- the numeric value of the size of the accessible -portion of the buffer. This produces a number that tells how many -characters make up one tenth of the buffer size. (In Lisp, `/' is used -for division, just as `*' is used for multiplication.) - -In the multiplication expression as a whole, this amount is multiplied -by the value of the prefix argument--the multiplication looks like this: - - (* NUMERIC-VALUE-OF-PREFIX-ARG - NUMBER-OF-CHARACTERS-IN-ONE-TENTH-OF-THE-ACCESSIBLE-BUFFER) - -If, for example, the prefix argument is `7', the one-tenth value will -be multiplied by 7 to give a position 70% of the way through. - -The result of all this is that if the accessible portion of the buffer -is large, the `goto-char' expression reads like this: - - (goto-char (* (prefix-numeric-value arg) - (/ size 10))) - -This puts the cursor where we want it. - - -File: eintr, Node: Small buffer case, Prev: Large buffer case, Up: beginning-of-buffer opt arg - -What happens in a small buffer -.............................. - -If the buffer contains fewer than 10,000 characters, a slightly -different computation is performed. You might think this is not -necessary, since the first computation could do the job. However, in a -small buffer, the first method may not put the cursor on exactly the -desired line; the second method does a better job. - -The code looks like this: - - (/ (+ 10 (* size (prefix-numeric-value arg))) 10)) - -This is code in which you figure out what happens by discovering how the -functions are embedded in parentheses. It is easier to read if you -reformat it with each expression indented more deeply than its -enclosing expression: - - (/ - (+ 10 - (* - size - (prefix-numeric-value arg))) - 10)) - -Looking at parentheses, we see that the innermost operation is -`(prefix-numeric-value arg)', which converts the raw argument to a -number. In the following expression, this number is multiplied by the -size of the accessible portion of the buffer: - - (* size (prefix-numeric-value arg)) - -This multiplication creates a number that may be larger than the size of -the buffer--seven times larger if the argument is 7, for example. Ten -is then added to this number and finally the large number is divided by -ten to provide a value that is one character larger than the percentage -position in the buffer. - -The number that results from all this is passed to `goto-char' and the -cursor is moved to that point. - - -File: eintr, Node: beginning-of-buffer complete, Prev: beginning-of-buffer opt arg, Up: beginning-of-buffer - -5.3.3 The Complete `beginning-of-buffer' ----------------------------------------- - -Here is the complete text of the `beginning-of-buffer' function: - - (defun beginning-of-buffer (&optional arg) - "Move point to the beginning of the buffer; - leave mark at previous position. - With \\[universal-argument] prefix, - do not set mark at previous position. - With numeric arg N, - put point N/10 of the way from the beginning. - - If the buffer is narrowed, - this command uses the beginning and size - of the accessible part of the buffer. - - Don't use this command in Lisp programs! - \(goto-char (point-min)) is faster - and avoids clobbering the mark." - (interactive "P") - (or (consp arg) - (and transient-mark-mode mark-active) - (push-mark)) - (let ((size (- (point-max) (point-min)))) - (goto-char (if (and arg (not (consp arg))) - (+ (point-min) - (if (> size 10000) - ;; Avoid overflow for large buffer sizes! - (* (prefix-numeric-value arg) - (/ size 10)) - (/ (+ 10 (* size (prefix-numeric-value arg))) 10))) - (point-min)))) - (if arg (forward-line 1))) - -Except for two small points, the previous discussion shows how this -function works. The first point deals with a detail in the -documentation string, and the second point concerns the last line of -the function. - -In the documentation string, there is reference to an expression: - - \\[universal-argument] - -A `\\' is used before the first square bracket of this expression. -This `\\' tells the Lisp interpreter to substitute whatever key is -currently bound to the `[...]'. In the case of `universal-argument', -that is usually `C-u', but it might be different. (*Note Tips for -Documentation Strings: (elisp)Documentation Tips, for more information.) - -Finally, the last line of the `beginning-of-buffer' command says to -move point to the beginning of the next line if the command is invoked -with an argument: - - (if arg (forward-line 1))) - -This puts the cursor at the beginning of the first line after the -appropriate tenths position in the buffer. This is a flourish that -means that the cursor is always located _at least_ the requested tenths -of the way through the buffer, which is a nicety that is, perhaps, not -necessary, but which, if it did not occur, would be sure to draw -complaints. - -On the other hand, it also means that if you specify the command with a -`C-u', but without a number, that is to say, if the `raw prefix -argument' is simply a cons cell, then the command puts you at the -beginning of the second line ... I don't know whether this is intended -or whether no one has dealt with the code to avoid this happening. - - -File: eintr, Node: Second Buffer Related Review, Next: optional Exercise, Prev: beginning-of-buffer, Up: More Complex - -5.4 Review -========== - -Here is a brief summary of some of the topics covered in this chapter. - -`or' - Evaluate each argument in sequence, and return the value of the - first argument that is not `nil'; if none return a value that is - not `nil', return `nil'. In brief, return the first true value of - the arguments; return a true value if one _or_ any of the others - are true. - -`and' - Evaluate each argument in sequence, and if any are `nil', return - `nil'; if none are `nil', return the value of the last argument. - In brief, return a true value only if all the arguments are true; - return a true value if one _and_ each of the others is true. - -`&optional' - A keyword used to indicate that an argument to a function - definition is optional; this means that the function can be - evaluated without the argument, if desired. - -`prefix-numeric-value' - Convert the `raw prefix argument' produced by `(interactive "P")' - to a numeric value. - -`forward-line' - Move point forward to the beginning of the next line, or if the - argument is greater than one, forward that many lines. If it - can't move as far forward as it is supposed to, `forward-line' - goes forward as far as it can and then returns a count of the - number of additional lines it was supposed to move but couldn't. - -`erase-buffer' - Delete the entire contents of the current buffer. - -`bufferp' - Return `t' if its argument is a buffer; otherwise return `nil'. - - -File: eintr, Node: optional Exercise, Prev: Second Buffer Related Review, Up: More Complex - -5.5 `optional' Argument Exercise -================================ - -Write an interactive function with an optional argument that tests -whether its argument, a number, is greater than or equal to, or else, -less than the value of `fill-column', and tells you which, in a -message. However, if you do not pass an argument to the function, use -56 as a default value. - - -File: eintr, Node: Narrowing & Widening, Next: car cdr & cons, Prev: More Complex, Up: Top - -6 Narrowing and Widening -************************ - -Narrowing is a feature of Emacs that makes it possible for you to focus -on a specific part of a buffer, and work without accidentally changing -other parts. Narrowing is normally disabled since it can confuse -novices. - -* Menu: - -* Narrowing advantages:: -* save-restriction:: -* what-line:: -* narrow Exercise:: - - -File: eintr, Node: Narrowing advantages, Next: save-restriction, Prev: Narrowing & Widening, Up: Narrowing & Widening - -The Advantages of Narrowing -=========================== - -With narrowing, the rest of a buffer is made invisible, as if it weren't -there. This is an advantage if, for example, you want to replace a word -in one part of a buffer but not in another: you narrow to the part you -want and the replacement is carried out only in that section, not in -the rest of the buffer. Searches will only work within a narrowed -region, not outside of one, so if you are fixing a part of a document, -you can keep yourself from accidentally finding parts you do not need -to fix by narrowing just to the region you want. (The key binding for -`narrow-to-region' is `C-x n n'.) - -However, narrowing does make the rest of the buffer invisible, which -can scare people who inadvertently invoke narrowing and think they have -deleted a part of their file. Moreover, the `undo' command (which is -usually bound to `C-x u') does not turn off narrowing (nor should it), -so people can become quite desperate if they do not know that they can -return the rest of a buffer to visibility with the `widen' command. -(The key binding for `widen' is `C-x n w'.) - -Narrowing is just as useful to the Lisp interpreter as to a human. -Often, an Emacs Lisp function is designed to work on just part of a -buffer; or conversely, an Emacs Lisp function needs to work on all of a -buffer that has been narrowed. The `what-line' function, for example, -removes the narrowing from a buffer, if it has any narrowing and when -it has finished its job, restores the narrowing to what it was. On the -other hand, the `count-lines' function, which is called by `what-line', -uses narrowing to restrict itself to just that portion of the buffer in -which it is interested and then restores the previous situation. - - -File: eintr, Node: save-restriction, Next: what-line, Prev: Narrowing advantages, Up: Narrowing & Widening - -6.1 The `save-restriction' Special Form -======================================= - -In Emacs Lisp, you can use the `save-restriction' special form to keep -track of whatever narrowing is in effect, if any. When the Lisp -interpreter meets with `save-restriction', it executes the code in the -body of the `save-restriction' expression, and then undoes any changes -to narrowing that the code caused. If, for example, the buffer is -narrowed and the code that follows `save-restriction' gets rid of the -narrowing, `save-restriction' returns the buffer to its narrowed region -afterwards. In the `what-line' command, any narrowing the buffer may -have is undone by the `widen' command that immediately follows the -`save-restriction' command. Any original narrowing is restored just -before the completion of the function. - -The template for a `save-restriction' expression is simple: - - (save-restriction - BODY... ) - -The body of the `save-restriction' is one or more expressions that will -be evaluated in sequence by the Lisp interpreter. - -Finally, a point to note: when you use both `save-excursion' and -`save-restriction', one right after the other, you should use -`save-excursion' outermost. If you write them in reverse order, you -may fail to record narrowing in the buffer to which Emacs switches -after calling `save-excursion'. Thus, when written together, -`save-excursion' and `save-restriction' should be written like this: - - (save-excursion - (save-restriction - BODY...)) - -In other circumstances, when not written together, the `save-excursion' -and `save-restriction' special forms must be written in the order -appropriate to the function. - -For example, - - (save-restriction - (widen) - (save-excursion - BODY...)) - - -File: eintr, Node: what-line, Next: narrow Exercise, Prev: save-restriction, Up: Narrowing & Widening - -6.2 `what-line' -=============== - -The `what-line' command tells you the number of the line in which the -cursor is located. The function illustrates the use of the -`save-restriction' and `save-excursion' commands. Here is the original -text of the function: - - (defun what-line () - "Print the current line number (in the buffer) of point." - (interactive) - (save-restriction - (widen) - (save-excursion - (beginning-of-line) - (message "Line %d" - (1+ (count-lines 1 (point))))))) - -(In recent versions of GNU Emacs, the `what-line' function has been -expanded to tell you your line number in a narrowed buffer as well as -your line number in a widened buffer. The recent version is more -complex than the version shown here. If you feel adventurous, you -might want to look at it after figuring out how this version works. -You will probably need to use `C-h f' (`describe-function'). The newer -version uses a conditional to determine whether the buffer has been -narrowed. - -(Also, it uses `line-number-at-pos', which among other simple -expressions, such as `(goto-char (point-min))', moves point to the -beginning of the current line with `(forward-line 0)' rather than -`beginning-of-line'.) - -The `what-line' function as shown here has a documentation line and is -interactive, as you would expect. The next two lines use the functions -`save-restriction' and `widen'. - -The `save-restriction' special form notes whatever narrowing is in -effect, if any, in the current buffer and restores that narrowing after -the code in the body of the `save-restriction' has been evaluated. - -The `save-restriction' special form is followed by `widen'. This -function undoes any narrowing the current buffer may have had when -`what-line' was called. (The narrowing that was there is the narrowing -that `save-restriction' remembers.) This widening makes it possible -for the line counting commands to count from the beginning of the -buffer. Otherwise, they would have been limited to counting within the -accessible region. Any original narrowing is restored just before the -completion of the function by the `save-restriction' special form. - -The call to `widen' is followed by `save-excursion', which saves the -location of the cursor (i.e., of point) and of the mark, and restores -them after the code in the body of the `save-excursion' uses the -`beginning-of-line' function to move point. - -(Note that the `(widen)' expression comes between the -`save-restriction' and `save-excursion' special forms. When you write -the two `save- ...' expressions in sequence, write `save-excursion' -outermost.) - -The last two lines of the `what-line' function are functions to count -the number of lines in the buffer and then print the number in the echo -area. - - (message "Line %d" - (1+ (count-lines 1 (point))))))) - -The `message' function prints a one-line message at the bottom of the -Emacs screen. The first argument is inside of quotation marks and is -printed as a string of characters. However, it may contain a `%d' -expression to print a following argument. `%d' prints the argument as -a decimal, so the message will say something such as `Line 243'. - -The number that is printed in place of the `%d' is computed by the last -line of the function: - - (1+ (count-lines 1 (point))) - -What this does is count the lines from the first position of the -buffer, indicated by the `1', up to `(point)', and then add one to that -number. (The `1+' function adds one to its argument.) We add one to -it because line 2 has only one line before it, and `count-lines' counts -only the lines _before_ the current line. - -After `count-lines' has done its job, and the message has been printed -in the echo area, the `save-excursion' restores point and mark to their -original positions; and `save-restriction' restores the original -narrowing, if any. - - -File: eintr, Node: narrow Exercise, Prev: what-line, Up: Narrowing & Widening - -6.3 Exercise with Narrowing -=========================== - -Write a function that will display the first 60 characters of the -current buffer, even if you have narrowed the buffer to its latter half -so that the first line is inaccessible. Restore point, mark, and -narrowing. For this exercise, you need to use a whole potpourri of -functions, including `save-restriction', `widen', `goto-char', -`point-min', `message', and `buffer-substring'. - -(`buffer-substring' is a previously unmentioned function you will have -to investigate yourself; or perhaps you will have to use -`buffer-substring-no-properties' or `filter-buffer-substring' ..., yet -other functions. Text properties are a feature otherwise not discussed -here. *Note Text Properties: (elisp)Text Properties. - -Additionally, do you really need `goto-char' or `point-min'? Or can -you write the function without them?) - - -File: eintr, Node: car cdr & cons, Next: Cutting & Storing Text, Prev: Narrowing & Widening, Up: Top - -7 `car', `cdr', `cons': Fundamental Functions -********************************************* - -In Lisp, `car', `cdr', and `cons' are fundamental functions. The -`cons' function is used to construct lists, and the `car' and `cdr' -functions are used to take them apart. - -In the walk through of the `copy-region-as-kill' function, we will see -`cons' as well as two variants on `cdr', namely, `setcdr' and `nthcdr'. -(*Note copy-region-as-kill::.) - -* Menu: - -* Strange Names:: -* car & cdr:: -* cons:: -* nthcdr:: -* nth:: -* setcar:: -* setcdr:: -* cons Exercise:: - - -File: eintr, Node: Strange Names, Next: car & cdr, Prev: car cdr & cons, Up: car cdr & cons - -Strange Names -============= - -The name of the `cons' function is not unreasonable: it is an -abbreviation of the word `construct'. The origins of the names for -`car' and `cdr', on the other hand, are esoteric: `car' is an acronym -from the phrase `Contents of the Address part of the Register'; and -`cdr' (pronounced `could-er') is an acronym from the phrase `Contents -of the Decrement part of the Register'. These phrases refer to -specific pieces of hardware on the very early computer on which the -original Lisp was developed. Besides being obsolete, the phrases have -been completely irrelevant for more than 25 years to anyone thinking -about Lisp. Nonetheless, although a few brave scholars have begun to -use more reasonable names for these functions, the old terms are still -in use. In particular, since the terms are used in the Emacs Lisp -source code, we will use them in this introduction. - - -File: eintr, Node: car & cdr, Next: cons, Prev: Strange Names, Up: car cdr & cons - -7.1 `car' and `cdr' -=================== - -The CAR of a list is, quite simply, the first item in the list. Thus -the CAR of the list `(rose violet daisy buttercup)' is `rose'. - -If you are reading this in Info in GNU Emacs, you can see this by -evaluating the following: - - (car '(rose violet daisy buttercup)) - -After evaluating the expression, `rose' will appear in the echo area. - -Clearly, a more reasonable name for the `car' function would be `first' -and this is often suggested. - -`car' does not remove the first item from the list; it only reports -what it is. After `car' has been applied to a list, the list is still -the same as it was. In the jargon, `car' is `non-destructive'. This -feature turns out to be important. - -The CDR of a list is the rest of the list, that is, the `cdr' function -returns the part of the list that follows the first item. Thus, while -the CAR of the list `'(rose violet daisy buttercup)' is `rose', the -rest of the list, the value returned by the `cdr' function, is `(violet -daisy buttercup)'. - -You can see this by evaluating the following in the usual way: - - (cdr '(rose violet daisy buttercup)) - -When you evaluate this, `(violet daisy buttercup)' will appear in the -echo area. - -Like `car', `cdr' does not remove any elements from the list--it just -returns a report of what the second and subsequent elements are. - -Incidentally, in the example, the list of flowers is quoted. If it were -not, the Lisp interpreter would try to evaluate the list by calling -`rose' as a function. In this example, we do not want to do that. - -Clearly, a more reasonable name for `cdr' would be `rest'. - -(There is a lesson here: when you name new functions, consider very -carefully what you are doing, since you may be stuck with the names for -far longer than you expect. The reason this document perpetuates these -names is that the Emacs Lisp source code uses them, and if I did not -use them, you would have a hard time reading the code; but do, please, -try to avoid using these terms yourself. The people who come after you -will be grateful to you.) - -When `car' and `cdr' are applied to a list made up of symbols, such as -the list `(pine fir oak maple)', the element of the list returned by -the function `car' is the symbol `pine' without any parentheses around -it. `pine' is the first element in the list. However, the CDR of the -list is a list itself, `(fir oak maple)', as you can see by evaluating -the following expressions in the usual way: - - (car '(pine fir oak maple)) - - (cdr '(pine fir oak maple)) - -On the other hand, in a list of lists, the first element is itself a -list. `car' returns this first element as a list. For example, the -following list contains three sub-lists, a list of carnivores, a list -of herbivores and a list of sea mammals: - - (car '((lion tiger cheetah) - (gazelle antelope zebra) - (whale dolphin seal))) - -In this example, the first element or CAR of the list is the list of -carnivores, `(lion tiger cheetah)', and the rest of the list is -`((gazelle antelope zebra) (whale dolphin seal))'. - - (cdr '((lion tiger cheetah) - (gazelle antelope zebra) - (whale dolphin seal))) - -It is worth saying again that `car' and `cdr' are non-destructive--that -is, they do not modify or change lists to which they are applied. This -is very important for how they are used. - -Also, in the first chapter, in the discussion about atoms, I said that -in Lisp, "certain kinds of atom, such as an array, can be separated -into parts; but the mechanism for doing this is different from the -mechanism for splitting a list. As far as Lisp is concerned, the atoms -of a list are unsplittable." (*Note Lisp Atoms::.) The `car' and -`cdr' functions are used for splitting lists and are considered -fundamental to Lisp. Since they cannot split or gain access to the -parts of an array, an array is considered an atom. Conversely, the -other fundamental function, `cons', can put together or construct a -list, but not an array. (Arrays are handled by array-specific -functions. *Note Arrays: (elisp)Arrays.) - - -File: eintr, Node: cons, Next: nthcdr, Prev: car & cdr, Up: car cdr & cons - -7.2 `cons' -========== - -The `cons' function constructs lists; it is the inverse of `car' and -`cdr'. For example, `cons' can be used to make a four element list -from the three element list, `(fir oak maple)': - - (cons 'pine '(fir oak maple)) - -After evaluating this list, you will see - - (pine fir oak maple) - -appear in the echo area. `cons' causes the creation of a new list in -which the element is followed by the elements of the original list. - -We often say that ``cons' puts a new element at the beginning of a -list; it attaches or pushes elements onto the list', but this phrasing -can be misleading, since `cons' does not change an existing list, but -creates a new one. - -Like `car' and `cdr', `cons' is non-destructive. - -* Menu: - -* Build a list:: -* length:: - - -File: eintr, Node: Build a list, Next: length, Prev: cons, Up: cons - -Build a list ------------- - -`cons' must have a list to attach to.(1) You cannot start from -absolutely nothing. If you are building a list, you need to provide at -least an empty list at the beginning. Here is a series of `cons' -expressions that build up a list of flowers. If you are reading this -in Info in GNU Emacs, you can evaluate each of the expressions in the -usual way; the value is printed in this text after `=>', which you may -read as `evaluates to'. - - (cons 'buttercup ()) - => (buttercup) - - (cons 'daisy '(buttercup)) - => (daisy buttercup) - - (cons 'violet '(daisy buttercup)) - => (violet daisy buttercup) - - (cons 'rose '(violet daisy buttercup)) - => (rose violet daisy buttercup) - -In the first example, the empty list is shown as `()' and a list made -up of `buttercup' followed by the empty list is constructed. As you -can see, the empty list is not shown in the list that was constructed. -All that you see is `(buttercup)'. The empty list is not counted as an -element of a list because there is nothing in an empty list. Generally -speaking, an empty list is invisible. - -The second example, `(cons 'daisy '(buttercup))' constructs a new, two -element list by putting `daisy' in front of `buttercup'; and the third -example constructs a three element list by putting `violet' in front of -`daisy' and `buttercup'. - ----------- Footnotes ---------- - -(1) Actually, you can `cons' an element to an atom to produce a dotted -pair. Dotted pairs are not discussed here; see *Note Dotted Pair -Notation: (elisp)Dotted Pair Notation. - - -File: eintr, Node: length, Prev: Build a list, Up: cons - -7.2.1 Find the Length of a List: `length' ------------------------------------------ - -You can find out how many elements there are in a list by using the Lisp -function `length', as in the following examples: - - (length '(buttercup)) - => 1 - - (length '(daisy buttercup)) - => 2 - - (length (cons 'violet '(daisy buttercup))) - => 3 - -In the third example, the `cons' function is used to construct a three -element list which is then passed to the `length' function as its -argument. - -We can also use `length' to count the number of elements in an empty -list: - - (length ()) - => 0 - -As you would expect, the number of elements in an empty list is zero. - -An interesting experiment is to find out what happens if you try to find -the length of no list at all; that is, if you try to call `length' -without giving it an argument, not even an empty list: - - (length ) - -What you see, if you evaluate this, is the error message - - Lisp error: (wrong-number-of-arguments length 0) - -This means that the function receives the wrong number of arguments, -zero, when it expects some other number of arguments. In this case, -one argument is expected, the argument being a list whose length the -function is measuring. (Note that _one_ list is _one_ argument, even -if the list has many elements inside it.) - -The part of the error message that says `length' is the name of the -function. - - -File: eintr, Node: nthcdr, Next: nth, Prev: cons, Up: car cdr & cons - -7.3 `nthcdr' -============ - -The `nthcdr' function is associated with the `cdr' function. What it -does is take the CDR of a list repeatedly. - -If you take the CDR of the list `(pine fir oak maple)', you will be -returned the list `(fir oak maple)'. If you repeat this on what was -returned, you will be returned the list `(oak maple)'. (Of course, -repeated CDRing on the original list will just give you the original -CDR since the function does not change the list. You need to evaluate -the CDR of the CDR and so on.) If you continue this, eventually you -will be returned an empty list, which in this case, instead of being -shown as `()' is shown as `nil'. - -For review, here is a series of repeated CDRs, the text following the -`=>' shows what is returned. - - (cdr '(pine fir oak maple)) - =>(fir oak maple) - - (cdr '(fir oak maple)) - => (oak maple) - - (cdr '(oak maple)) - =>(maple) - - (cdr '(maple)) - => nil - - (cdr 'nil) - => nil - - (cdr ()) - => nil - -You can also do several CDRs without printing the values in between, -like this: - - (cdr (cdr '(pine fir oak maple))) - => (oak maple) - -In this example, the Lisp interpreter evaluates the innermost list -first. The innermost list is quoted, so it just passes the list as it -is to the innermost `cdr'. This `cdr' passes a list made up of the -second and subsequent elements of the list to the outermost `cdr', -which produces a list composed of the third and subsequent elements of -the original list. In this example, the `cdr' function is repeated and -returns a list that consists of the original list without its first two -elements. - -The `nthcdr' function does the same as repeating the call to `cdr'. In -the following example, the argument 2 is passed to the function -`nthcdr', along with the list, and the value returned is the list -without its first two items, which is exactly the same as repeating -`cdr' twice on the list: - - (nthcdr 2 '(pine fir oak maple)) - => (oak maple) - -Using the original four element list, we can see what happens when -various numeric arguments are passed to `nthcdr', including 0, 1, and 5: - - ;; Leave the list as it was. - (nthcdr 0 '(pine fir oak maple)) - => (pine fir oak maple) - - ;; Return a copy without the first element. - (nthcdr 1 '(pine fir oak maple)) - => (fir oak maple) - - ;; Return a copy of the list without three elements. - (nthcdr 3 '(pine fir oak maple)) - => (maple) - - ;; Return a copy lacking all four elements. - (nthcdr 4 '(pine fir oak maple)) - => nil - - ;; Return a copy lacking all elements. - (nthcdr 5 '(pine fir oak maple)) - => nil - - -File: eintr, Node: nth, Next: setcar, Prev: nthcdr, Up: car cdr & cons - -7.4 `nth' -========= - -The `nthcdr' function takes the CDR of a list repeatedly. The `nth' -function takes the CAR of the result returned by `nthcdr'. It returns -the Nth element of the list. - -Thus, if it were not defined in C for speed, the definition of `nth' -would be: - - (defun nth (n list) - "Returns the Nth element of LIST. - N counts from zero. If LIST is not that long, nil is returned." - (car (nthcdr n list))) - -(Originally, `nth' was defined in Emacs Lisp in `subr.el', but its -definition was redone in C in the 1980s.) - -The `nth' function returns a single element of a list. This can be -very convenient. - -Note that the elements are numbered from zero, not one. That is to -say, the first element of a list, its CAR is the zeroth element. This -is called `zero-based' counting and often bothers people who are -accustomed to the first element in a list being number one, which is -`one-based'. - -For example: - - (nth 0 '("one" "two" "three")) - => "one" - - (nth 1 '("one" "two" "three")) - => "two" - -It is worth mentioning that `nth', like `nthcdr' and `cdr', does not -change the original list--the function is non-destructive. This is in -sharp contrast to the `setcar' and `setcdr' functions. - - -File: eintr, Node: setcar, Next: setcdr, Prev: nth, Up: car cdr & cons - -7.5 `setcar' -============ - -As you might guess from their names, the `setcar' and `setcdr' -functions set the CAR or the CDR of a list to a new value. They -actually change the original list, unlike `car' and `cdr' which leave -the original list as it was. One way to find out how this works is to -experiment. We will start with the `setcar' function. - -First, we can make a list and then set the value of a variable to the -list, using the `setq' function. Here is a list of animals: - - (setq animals '(antelope giraffe lion tiger)) - -If you are reading this in Info inside of GNU Emacs, you can evaluate -this expression in the usual fashion, by positioning the cursor after -the expression and typing `C-x C-e'. (I'm doing this right here as I -write this. This is one of the advantages of having the interpreter -built into the computing environment. Incidentally, when there is -nothing on the line after the final parentheses, such as a comment, -point can be on the next line. Thus, if your cursor is in the first -column of the next line, you do not need to move it. Indeed, Emacs -permits any amount of white space after the final parenthesis.) - -When we evaluate the variable `animals', we see that it is bound to the -list `(antelope giraffe lion tiger)': - - animals - => (antelope giraffe lion tiger) - -Put another way, the variable `animals' points to the list `(antelope -giraffe lion tiger)'. - -Next, evaluate the function `setcar' while passing it two arguments, -the variable `animals' and the quoted symbol `hippopotamus'; this is -done by writing the three element list `(setcar animals 'hippopotamus)' -and then evaluating it in the usual fashion: - - (setcar animals 'hippopotamus) - -After evaluating this expression, evaluate the variable `animals' -again. You will see that the list of animals has changed: - - animals - => (hippopotamus giraffe lion tiger) - -The first element on the list, `antelope' is replaced by `hippopotamus'. - -So we can see that `setcar' did not add a new element to the list as -`cons' would have; it replaced `antelope' with `hippopotamus'; it -_changed_ the list. - - -File: eintr, Node: setcdr, Next: cons Exercise, Prev: setcar, Up: car cdr & cons - -7.6 `setcdr' -============ - -The `setcdr' function is similar to the `setcar' function, except that -the function replaces the second and subsequent elements of a list -rather than the first element. - -(To see how to change the last element of a list, look ahead to *Note -The `kill-new' function: kill-new function, which uses the `nthcdr' and -`setcdr' functions.) - -To see how this works, set the value of the variable to a list of -domesticated animals by evaluating the following expression: - - (setq domesticated-animals '(horse cow sheep goat)) - -If you now evaluate the list, you will be returned the list `(horse cow -sheep goat)': - - domesticated-animals - => (horse cow sheep goat) - -Next, evaluate `setcdr' with two arguments, the name of the variable -which has a list as its value, and the list to which the CDR of the -first list will be set; - - (setcdr domesticated-animals '(cat dog)) - -If you evaluate this expression, the list `(cat dog)' will appear in -the echo area. This is the value returned by the function. The result -we are interested in is the "side effect", which we can see by -evaluating the variable `domesticated-animals': - - domesticated-animals - => (horse cat dog) - -Indeed, the list is changed from `(horse cow sheep goat)' to `(horse -cat dog)'. The CDR of the list is changed from `(cow sheep goat)' to -`(cat dog)'. - - -File: eintr, Node: cons Exercise, Prev: setcdr, Up: car cdr & cons - -7.7 Exercise -============ - -Construct a list of four birds by evaluating several expressions with -`cons'. Find out what happens when you `cons' a list onto itself. -Replace the first element of the list of four birds with a fish. -Replace the rest of that list with a list of other fish. - - -File: eintr, Node: Cutting & Storing Text, Next: List Implementation, Prev: car cdr & cons, Up: Top - -8 Cutting and Storing Text -************************** - -Whenever you cut or clip text out of a buffer with a `kill' command in -GNU Emacs, it is stored in a list and you can bring it back with a -`yank' command. - -(The use of the word `kill' in Emacs for processes which specifically -_do not_ destroy the values of the entities is an unfortunate -historical accident. A much more appropriate word would be `clip' since -that is what the kill commands do; they clip text out of a buffer and -put it into storage from which it can be brought back. I have often -been tempted to replace globally all occurrences of `kill' in the Emacs -sources with `clip' and all occurrences of `killed' with `clipped'.) - -* Menu: - -* Storing Text:: -* zap-to-char:: -* kill-region:: -* copy-region-as-kill:: -* Digression into C:: -* defvar:: -* cons & search-fwd Review:: -* search Exercises:: - - -File: eintr, Node: Storing Text, Next: zap-to-char, Prev: Cutting & Storing Text, Up: Cutting & Storing Text - -Storing Text in a List -====================== - -When text is cut out of a buffer, it is stored on a list. Successive -pieces of text are stored on the list successively, so the list might -look like this: - - ("a piece of text" "previous piece") - -The function `cons' can be used to create a new list from a piece of -text (an `atom', to use the jargon) and an existing list, like this: - - (cons "another piece" - '("a piece of text" "previous piece")) - -If you evaluate this expression, a list of three elements will appear in -the echo area: - - ("another piece" "a piece of text" "previous piece") - -With the `car' and `nthcdr' functions, you can retrieve whichever piece -of text you want. For example, in the following code, `nthcdr 1 ...' -returns the list with the first item removed; and the `car' returns the -first element of that remainder--the second element of the original -list: - - (car (nthcdr 1 '("another piece" - "a piece of text" - "previous piece"))) - => "a piece of text" - -The actual functions in Emacs are more complex than this, of course. -The code for cutting and retrieving text has to be written so that -Emacs can figure out which element in the list you want--the first, -second, third, or whatever. In addition, when you get to the end of -the list, Emacs should give you the first element of the list, rather -than nothing at all. - -The list that holds the pieces of text is called the "kill ring". This -chapter leads up to a description of the kill ring and how it is used -by first tracing how the `zap-to-char' function works. This function -uses (or `calls') a function that invokes a function that manipulates -the kill ring. Thus, before reaching the mountains, we climb the -foothills. - -A subsequent chapter describes how text that is cut from the buffer is -retrieved. *Note Yanking Text Back: Yanking. - - -File: eintr, Node: zap-to-char, Next: kill-region, Prev: Storing Text, Up: Cutting & Storing Text - -8.1 `zap-to-char' -================= - -The `zap-to-char' function changed a little between GNU Emacs version -19 and GNU Emacs version 22. However, `zap-to-char' calls another -function, `kill-region', which enjoyed a major rewrite. - -The `kill-region' function in Emacs 19 is complex, but does not use -code that is important at this time. We will skip it. - -The `kill-region' function in Emacs 22 is easier to read than the same -function in Emacs 19 and introduces a very important concept, that of -error handling. We will walk through the function. - -But first, let us look at the interactive `zap-to-char' function. - -* Menu: - -* Complete zap-to-char:: -* zap-to-char interactive:: -* zap-to-char body:: -* search-forward:: -* progn:: -* Summing up zap-to-char:: - - -File: eintr, Node: Complete zap-to-char, Next: zap-to-char interactive, Prev: zap-to-char, Up: zap-to-char - -The Complete `zap-to-char' Implementation ------------------------------------------ - -The GNU Emacs version 19 and version 21 implementations of the -`zap-to-char' function are nearly identical in form, and they work -alike. The function removes the text in the region between the -location of the cursor (i.e., of point) up to and including the next -occurrence of a specified character. The text that `zap-to-char' -removes is put in the kill ring; and it can be retrieved from the kill -ring by typing `C-y' (`yank'). If the command is given an argument, it -removes text through that number of occurrences. Thus, if the cursor -were at the beginning of this sentence and the character were `s', -`Thus' would be removed. If the argument were two, `Thus, if the curs' -would be removed, up to and including the `s' in `cursor'. - -If the specified character is not found, `zap-to-char' will say "Search -failed", tell you the character you typed, and not remove any text. - -In order to determine how much text to remove, `zap-to-char' uses a -search function. Searches are used extensively in code that -manipulates text, and we will focus attention on them as well as on the -deletion command. - -Here is the complete text of the version 22 implementation of the -function: - - (defun zap-to-char (arg char) - "Kill up to and including ARG'th occurrence of CHAR. - Case is ignored if `case-fold-search' is non-nil in the current buffer. - Goes backward if ARG is negative; error if CHAR not found." - (interactive "p\ncZap to char: ") - (if (char-table-p translation-table-for-input) - (setq char (or (aref translation-table-for-input char) char))) - (kill-region (point) (progn - (search-forward (char-to-string char) nil nil arg) - (point)))) - - -File: eintr, Node: zap-to-char interactive, Next: zap-to-char body, Prev: Complete zap-to-char, Up: zap-to-char - -8.1.1 The `interactive' Expression ----------------------------------- - -The interactive expression in the `zap-to-char' command looks like this: - - (interactive "p\ncZap to char: ") - -The part within quotation marks, `"p\ncZap to char: "', specifies two -different things. First, and most simply, is the `p'. This part is -separated from the next part by a newline, `\n'. The `p' means that -the first argument to the function will be passed the value of a -`processed prefix'. The prefix argument is passed by typing `C-u' and -a number, or `M-' and a number. If the function is called -interactively without a prefix, 1 is passed to this argument. - -The second part of `"p\ncZap to char: "' is `cZap to char: '. In this -part, the lower case `c' indicates that `interactive' expects a prompt -and that the argument will be a character. The prompt follows the `c' -and is the string `Zap to char: ' (with a space after the colon to make -it look good). - -What all this does is prepare the arguments to `zap-to-char' so they -are of the right type, and give the user a prompt. - -In a read-only buffer, the `zap-to-char' function copies the text to -the kill ring, but does not remove it. The echo area displays a -message saying that the buffer is read-only. Also, the terminal may -beep or blink at you. - -Let us continue with the interactive specification. - - -File: eintr, Node: zap-to-char body, Next: search-forward, Prev: zap-to-char interactive, Up: zap-to-char - -8.1.2 The Body of `zap-to-char' -------------------------------- - -The body of the `zap-to-char' function contains the code that kills -(that is, removes) the text in the region from the current position of -the cursor up to and including the specified character. - -The documentation is thorough. You do need to know the jargon meaning -of the word `kill'. - -The first part of the code looks like this: - - (if (char-table-p translation-table-for-input) - (setq char (or (aref translation-table-for-input char) char))) - (kill-region (point) (progn - (search-forward (char-to-string char) nil nil arg) - (point))) - -`char-table-p' is an hitherto unseen function. It determines whether -its argument is a character table. When it is, it sets the character -passed to `zap-to-char' to one of them, if that character exists, or to -the character itself. (This becomes important for certain characters -in non-European languages. The `aref' function extracts an element -from an array. It is an array-specific function that is not described -in this document. *Note Arrays: (elisp)Arrays.) - -`(point)' is the current position of the cursor. - -The next part of the code is an expression using `progn'. The body of -the `progn' consists of calls to `search-forward' and `point'. - -It is easier to understand how `progn' works after learning about -`search-forward', so we will look at `search-forward' and then at -`progn'. - - -File: eintr, Node: search-forward, Next: progn, Prev: zap-to-char body, Up: zap-to-char - -8.1.3 The `search-forward' Function ------------------------------------ - -The `search-forward' function is used to locate the -zapped-for-character in `zap-to-char'. If the search is successful, -`search-forward' leaves point immediately after the last character in -the target string. (In `zap-to-char', the target string is just one -character long. `zap-to-char' uses the function `char-to-string' to -ensure that the computer treats that character as a string.) If the -search is backwards, `search-forward' leaves point just before the -first character in the target. Also, `search-forward' returns `t' for -true. (Moving point is therefore a `side effect'.) - -In `zap-to-char', the `search-forward' function looks like this: - - (search-forward (char-to-string char) nil nil arg) - -The `search-forward' function takes four arguments: - - 1. The first argument is the target, what is searched for. This must - be a string, such as `"z"'. - - As it happens, the argument passed to `zap-to-char' is a single - character. Because of the way computers are built, the Lisp - interpreter may treat a single character as being different from a - string of characters. Inside the computer, a single character has - a different electronic format than a string of one character. (A - single character can often be recorded in the computer using - exactly one byte; but a string may be longer, and the computer - needs to be ready for this.) Since the `search-forward' function - searches for a string, the character that the `zap-to-char' - function receives as its argument must be converted inside the - computer from one format to the other; otherwise the - `search-forward' function will fail. The `char-to-string' - function is used to make this conversion. - - 2. The second argument bounds the search; it is specified as a - position in the buffer. In this case, the search can go to the - end of the buffer, so no bound is set and the second argument is - `nil'. - - 3. The third argument tells the function what it should do if the - search fails--it can signal an error (and print a message) or it - can return `nil'. A `nil' as the third argument causes the - function to signal an error when the search fails. - - 4. The fourth argument to `search-forward' is the repeat count--how - many occurrences of the string to look for. This argument is - optional and if the function is called without a repeat count, - this argument is passed the value 1. If this argument is - negative, the search goes backwards. - -In template form, a `search-forward' expression looks like this: - - (search-forward "TARGET-STRING" - LIMIT-OF-SEARCH - WHAT-TO-DO-IF-SEARCH-FAILS - REPEAT-COUNT) - -We will look at `progn' next. - - -File: eintr, Node: progn, Next: Summing up zap-to-char, Prev: search-forward, Up: zap-to-char - -8.1.4 The `progn' Special Form ------------------------------- - -`progn' is a special form that causes each of its arguments to be -evaluated in sequence and then returns the value of the last one. The -preceding expressions are evaluated only for the side effects they -perform. The values produced by them are discarded. - -The template for a `progn' expression is very simple: - - (progn - BODY...) - -In `zap-to-char', the `progn' expression has to do two things: put -point in exactly the right position; and return the location of point -so that `kill-region' will know how far to kill to. - -The first argument to the `progn' is `search-forward'. When -`search-forward' finds the string, the function leaves point -immediately after the last character in the target string. (In this -case the target string is just one character long.) If the search is -backwards, `search-forward' leaves point just before the first -character in the target. The movement of point is a side effect. - -The second and last argument to `progn' is the expression `(point)'. -This expression returns the value of point, which in this case will be -the location to which it has been moved by `search-forward'. (In the -source, a line that tells the function to go to the previous character, -if it is going forward, was commented out in 1999; I don't remember -whether that feature or mis-feature was ever a part of the distributed -source.) The value of `point' is returned by the `progn' expression -and is passed to `kill-region' as `kill-region''s second argument. - - -File: eintr, Node: Summing up zap-to-char, Prev: progn, Up: zap-to-char - -8.1.5 Summing up `zap-to-char' ------------------------------- - -Now that we have seen how `search-forward' and `progn' work, we can see -how the `zap-to-char' function works as a whole. - -The first argument to `kill-region' is the position of the cursor when -the `zap-to-char' command is given--the value of point at that time. -Within the `progn', the search function then moves point to just after -the zapped-to-character and `point' returns the value of this location. -The `kill-region' function puts together these two values of point, -the first one as the beginning of the region and the second one as the -end of the region, and removes the region. - -The `progn' special form is necessary because the `kill-region' command -takes two arguments; and it would fail if `search-forward' and `point' -expressions were written in sequence as two additional arguments. The -`progn' expression is a single argument to `kill-region' and returns -the one value that `kill-region' needs for its second argument. - - -File: eintr, Node: kill-region, Next: copy-region-as-kill, Prev: zap-to-char, Up: Cutting & Storing Text - -8.2 `kill-region' -================= - -The `zap-to-char' function uses the `kill-region' function. This -function clips text from a region and copies that text to the kill -ring, from which it may be retrieved. - -The Emacs 22 version of that function uses `condition-case' and -`copy-region-as-kill', both of which we will explain. `condition-case' -is an important special form. - -In essence, the `kill-region' function calls `condition-case', which -takes three arguments. In this function, the first argument does -nothing. The second argument contains the code that does the work when -all goes well. The third argument contains the code that is called in -the event of an error. - -* Menu: - -* Complete kill-region:: -* condition-case:: -* Lisp macro:: - - -File: eintr, Node: Complete kill-region, Next: condition-case, Prev: kill-region, Up: kill-region - -The Complete `kill-region' Definition -------------------------------------- - -We will go through the `condition-case' code in a moment. First, let -us look at the definition of `kill-region', with comments added: - - (defun kill-region (beg end) - "Kill (\"cut\") text between point and mark. - This deletes the text from the buffer and saves it in the kill ring. - The command \\[yank] can retrieve it from there. ... " - - ;; * Since order matters, pass point first. - (interactive (list (point) (mark))) - ;; * And tell us if we cannot cut the text. - (unless (and beg end) - (error "The mark is not set now, so there is no region")) - - ;; * `condition-case' takes three arguments. - ;; If the first argument is nil, as it is here, - ;; information about the error signal is not - ;; stored for use by another function. - (condition-case nil - - ;; * The second argument to `condition-case' tells the - ;; Lisp interpreter what to do when all goes well. - - ;; It starts with a `let' function that extracts the string - ;; and tests whether it exists. If so (that is what the - ;; `when' checks), it calls an `if' function that determines - ;; whether the previous command was another call to - ;; `kill-region'; if it was, then the new text is appended to - ;; the previous text; if not, then a different function, - ;; `kill-new', is called. - - ;; The `kill-append' function concatenates the new string and - ;; the old. The `kill-new' function inserts text into a new - ;; item in the kill ring. - - ;; `when' is an `if' without an else-part. The second `when' - ;; again checks whether the current string exists; in - ;; addition, it checks whether the previous command was - ;; another call to `kill-region'. If one or the other - ;; condition is true, then it sets the current command to - ;; be `kill-region'. - (let ((string (filter-buffer-substring beg end t))) - (when string ;STRING is nil if BEG = END - ;; Add that string to the kill ring, one way or another. - (if (eq last-command 'kill-region) - ;; - `yank-handler' is an optional argument to - ;; `kill-region' that tells the `kill-append' and - ;; `kill-new' functions how deal with properties - ;; added to the text, such as `bold' or `italics'. - (kill-append string (< end beg) yank-handler) - (kill-new string nil yank-handler))) - (when (or string (eq last-command 'kill-region)) - (setq this-command 'kill-region)) - nil) - - ;; * The third argument to `condition-case' tells the interpreter - ;; what to do with an error. - ;; The third argument has a conditions part and a body part. - ;; If the conditions are met (in this case, - ;; if text or buffer are read-only) - ;; then the body is executed. - ;; The first part of the third argument is the following: - ((buffer-read-only text-read-only) ;; the if-part - ;; ... the then-part - (copy-region-as-kill beg end) - ;; Next, also as part of the then-part, set this-command, so - ;; it will be set in an error - (setq this-command 'kill-region) - ;; Finally, in the then-part, send a message if you may copy - ;; the text to the kill ring without signally an error, but - ;; don't if you may not. - (if kill-read-only-ok - (progn (message "Read only text copied to kill ring") nil) - (barf-if-buffer-read-only) - ;; If the buffer isn't read-only, the text is. - (signal 'text-read-only (list (current-buffer))))) - - -File: eintr, Node: condition-case, Next: Lisp macro, Prev: Complete kill-region, Up: kill-region - -8.2.1 `condition-case' ----------------------- - -As we have seen earlier (*note Generate an Error Message: Making -Errors.), when the Emacs Lisp interpreter has trouble evaluating an -expression, it provides you with help; in the jargon, this is called -"signaling an error". Usually, the computer stops the program and -shows you a message. - -However, some programs undertake complicated actions. They should not -simply stop on an error. In the `kill-region' function, the most -likely error is that you will try to kill text that is read-only and -cannot be removed. So the `kill-region' function contains code to -handle this circumstance. This code, which makes up the body of the -`kill-region' function, is inside of a `condition-case' special form. - -The template for `condition-case' looks like this: - - (condition-case - VAR - BODYFORM - ERROR-HANDLER...) - -The second argument, BODYFORM, is straightforward. The -`condition-case' special form causes the Lisp interpreter to evaluate -the code in BODYFORM. If no error occurs, the special form returns the -code's value and produces the side-effects, if any. - -In short, the BODYFORM part of a `condition-case' expression determines -what should happen when everything works correctly. - -However, if an error occurs, among its other actions, the function -generating the error signal will define one or more error condition -names. - -An error handler is the third argument to `condition case'. An error -handler has two parts, a CONDITION-NAME and a BODY. If the -CONDITION-NAME part of an error handler matches a condition name -generated by an error, then the BODY part of the error handler is run. - -As you will expect, the CONDITION-NAME part of an error handler may be -either a single condition name or a list of condition names. - -Also, a complete `condition-case' expression may contain more than one -error handler. When an error occurs, the first applicable handler is -run. - -Lastly, the first argument to the `condition-case' expression, the VAR -argument, is sometimes bound to a variable that contains information -about the error. However, if that argument is nil, as is the case in -`kill-region', that information is discarded. - -In brief, in the `kill-region' function, the code `condition-case' -works like this: - - IF NO ERRORS, RUN ONLY THIS CODE - BUT, IF ERRORS, RUN THIS OTHER CODE. - - -File: eintr, Node: Lisp macro, Prev: condition-case, Up: kill-region - -8.2.2 Lisp macro ----------------- - -The part of the `condition-case' expression that is evaluated in the -expectation that all goes well has a `when'. The code uses `when' to -determine whether the `string' variable points to text that exists. - -A `when' expression is simply a programmers' convenience. It is an -`if' without the possibility of an else clause. In your mind, you can -replace `when' with `if' and understand what goes on. That is what the -Lisp interpreter does. - -Technically speaking, `when' is a Lisp macro. A Lisp "macro" enables -you to define new control constructs and other language features. It -tells the interpreter how to compute another Lisp expression which will -in turn compute the value. In this case, the `other expression' is an -`if' expression. For more about Lisp macros, see *Note Macros: -(elisp)Macros. The C programming language also provides macros. These -are different, but also useful. - -If the string has content, then another conditional expression is -executed. This is an `if' with both a then-part and an else-part. - - (if (eq last-command 'kill-region) - (kill-append string (< end beg) yank-handler) - (kill-new string nil yank-handler)) - -The then-part is evaluated if the previous command was another call to -`kill-region'; if not, the else-part is evaluated. - -`yank-handler' is an optional argument to `kill-region' that tells the -`kill-append' and `kill-new' functions how deal with properties added -to the text, such as `bold' or `italics'. - -`last-command' is a variable that comes with Emacs that we have not -seen before. Normally, whenever a function is executed, Emacs sets the -value of `last-command' to the previous command. - -In this segment of the definition, the `if' expression checks whether -the previous command was `kill-region'. If it was, - - (kill-append string (< end beg) yank-handler) - -concatenates a copy of the newly clipped text to the just previously -clipped text in the kill ring. - - -File: eintr, Node: copy-region-as-kill, Next: Digression into C, Prev: kill-region, Up: Cutting & Storing Text - -8.3 `copy-region-as-kill' -========================= - -The `copy-region-as-kill' function copies a region of text from a -buffer and (via either `kill-append' or `kill-new') saves it in the -`kill-ring'. - -If you call `copy-region-as-kill' immediately after a `kill-region' -command, Emacs appends the newly copied text to the previously copied -text. This means that if you yank back the text, you get it all, from -both this and the previous operation. On the other hand, if some other -command precedes the `copy-region-as-kill', the function copies the -text into a separate entry in the kill ring. - -* Menu: - -* Complete copy-region-as-kill:: -* copy-region-as-kill body:: - - -File: eintr, Node: Complete copy-region-as-kill, Next: copy-region-as-kill body, Prev: copy-region-as-kill, Up: copy-region-as-kill - -The complete `copy-region-as-kill' function definition ------------------------------------------------------- - -Here is the complete text of the version 22 `copy-region-as-kill' -function: - - (defun copy-region-as-kill (beg end) - "Save the region as if killed, but don't kill it. - In Transient Mark mode, deactivate the mark. - If `interprogram-cut-function' is non-nil, also save the text for a window - system cut and paste." - (interactive "r") - (if (eq last-command 'kill-region) - (kill-append (filter-buffer-substring beg end) (< end beg)) - (kill-new (filter-buffer-substring beg end))) - (if transient-mark-mode - (setq deactivate-mark t)) - nil) - -As usual, this function can be divided into its component parts: - - (defun copy-region-as-kill (ARGUMENT-LIST) - "DOCUMENTATION..." - (interactive "r") - BODY...) - -The arguments are `beg' and `end' and the function is interactive with -`"r"', so the two arguments must refer to the beginning and end of the -region. If you have been reading though this document from the -beginning, understanding these parts of a function is almost becoming -routine. - -The documentation is somewhat confusing unless you remember that the -word `kill' has a meaning different from usual. The `Transient Mark' -and `interprogram-cut-function' comments explain certain side-effects. - -After you once set a mark, a buffer always contains a region. If you -wish, you can use Transient Mark mode to highlight the region -temporarily. (No one wants to highlight the region all the time, so -Transient Mark mode highlights it only at appropriate times. Many -people turn off Transient Mark mode, so the region is never -highlighted.) - -Also, a windowing system allows you to copy, cut, and paste among -different programs. In the X windowing system, for example, the -`interprogram-cut-function' function is `x-select-text', which works -with the windowing system's equivalent of the Emacs kill ring. - -The body of the `copy-region-as-kill' function starts with an `if' -clause. What this clause does is distinguish between two different -situations: whether or not this command is executed immediately after a -previous `kill-region' command. In the first case, the new region is -appended to the previously copied text. Otherwise, it is inserted into -the beginning of the kill ring as a separate piece of text from the -previous piece. - -The last two lines of the function prevent the region from lighting up -if Transient Mark mode is turned on. - -The body of `copy-region-as-kill' merits discussion in detail. - - -File: eintr, Node: copy-region-as-kill body, Prev: Complete copy-region-as-kill, Up: copy-region-as-kill - -8.3.1 The Body of `copy-region-as-kill' ---------------------------------------- - -The `copy-region-as-kill' function works in much the same way as the -`kill-region' function. Both are written so that two or more kills in -a row combine their text into a single entry. If you yank back the -text from the kill ring, you get it all in one piece. Moreover, kills -that kill forward from the current position of the cursor are added to -the end of the previously copied text and commands that copy text -backwards add it to the beginning of the previously copied text. This -way, the words in the text stay in the proper order. - -Like `kill-region', the `copy-region-as-kill' function makes use of the -`last-command' variable that keeps track of the previous Emacs command. - -* Menu: - -* last-command & this-command:: -* kill-append function:: -* kill-new function:: - - -File: eintr, Node: last-command & this-command, Next: kill-append function, Prev: copy-region-as-kill body, Up: copy-region-as-kill body - -`last-command' and `this-command' -................................. - -Normally, whenever a function is executed, Emacs sets the value of -`this-command' to the function being executed (which in this case would -be `copy-region-as-kill'). At the same time, Emacs sets the value of -`last-command' to the previous value of `this-command'. - -In the first part of the body of the `copy-region-as-kill' function, an -`if' expression determines whether the value of `last-command' is -`kill-region'. If so, the then-part of the `if' expression is -evaluated; it uses the `kill-append' function to concatenate the text -copied at this call to the function with the text already in the first -element (the CAR) of the kill ring. On the other hand, if the value of -`last-command' is not `kill-region', then the `copy-region-as-kill' -function attaches a new element to the kill ring using the `kill-new' -function. - -The `if' expression reads as follows; it uses `eq', which is a function -we have not yet seen: - - (if (eq last-command 'kill-region) - ;; then-part - (kill-append (filter-buffer-substring beg end) (< end beg)) - ;; else-part - (kill-new (filter-buffer-substring beg end))) - -(The `filter-buffer-substring' function returns a filtered substring of -the buffer, if any. Optionally--the arguments are not here, so neither -is done--the function may delete the initial text or return the text -without its properties; this function is a replacement for the older -`buffer-substring' function, which came before text properties were -implemented.) - -The `eq' function tests whether its first argument is the same Lisp -object as its second argument. The `eq' function is similar to the -`equal' function in that it is used to test for equality, but differs -in that it determines whether two representations are actually the same -object inside the computer, but with different names. `equal' -determines whether the structure and contents of two expressions are -the same. - -If the previous command was `kill-region', then the Emacs Lisp -interpreter calls the `kill-append' function - - -File: eintr, Node: kill-append function, Next: kill-new function, Prev: last-command & this-command, Up: copy-region-as-kill body - -The `kill-append' function -.......................... - -The `kill-append' function looks like this: - - (defun kill-append (string before-p &optional yank-handler) - "Append STRING to the end of the latest kill in the kill ring. - If BEFORE-P is non-nil, prepend STRING to the kill. - ... " - (let* ((cur (car kill-ring))) - (kill-new (if before-p (concat string cur) (concat cur string)) - (or (= (length cur) 0) - (equal yank-handler (get-text-property 0 'yank-handler cur))) - yank-handler))) - -The `kill-append' function is fairly straightforward. It uses the -`kill-new' function, which we will discuss in more detail in a moment. - -(Also, the function provides an optional argument called -`yank-handler'; when invoked, this argument tells the function how to -deal with properties added to the text, such as `bold' or `italics'.) - -It has a `let*' function to set the value of the first element of the -kill ring to `cur'. (I do not know why the function does not use `let' -instead; only one value is set in the expression. Perhaps this is a -bug that produces no problems?) - -Consider the conditional that is one of the two arguments to -`kill-new'. It uses `concat' to concatenate the new text to the CAR of -the kill ring. Whether it prepends or appends the text depends on the -results of an `if' expression: - - (if before-p ; if-part - (concat string cur) ; then-part - (concat cur string)) ; else-part - -If the region being killed is before the region that was killed in the -last command, then it should be prepended before the material that was -saved in the previous kill; and conversely, if the killed text follows -what was just killed, it should be appended after the previous text. -The `if' expression depends on the predicate `before-p' to decide -whether the newly saved text should be put before or after the -previously saved text. - -The symbol `before-p' is the name of one of the arguments to -`kill-append'. When the `kill-append' function is evaluated, it is -bound to the value returned by evaluating the actual argument. In this -case, this is the expression `(< end beg)'. This expression does not -directly determine whether the killed text in this command is located -before or after the kill text of the last command; what it does is -determine whether the value of the variable `end' is less than the -value of the variable `beg'. If it is, it means that the user is most -likely heading towards the beginning of the buffer. Also, the result -of evaluating the predicate expression, `(< end beg)', will be true and -the text will be prepended before the previous text. On the other -hand, if the value of the variable `end' is greater than the value of -the variable `beg', the text will be appended after the previous text. - -When the newly saved text will be prepended, then the string with the -new text will be concatenated before the old text: - - (concat string cur) - -But if the text will be appended, it will be concatenated after the old -text: - - (concat cur string)) - -To understand how this works, we first need to review the `concat' -function. The `concat' function links together or unites two strings -of text. The result is a string. For example: - - (concat "abc" "def") - => "abcdef" - - (concat "new " - (car '("first element" "second element"))) - => "new first element" - - (concat (car - '("first element" "second element")) " modified") - => "first element modified" - -We can now make sense of `kill-append': it modifies the contents of the -kill ring. The kill ring is a list, each element of which is saved -text. The `kill-append' function uses the `kill-new' function which in -turn uses the `setcar' function. - - -File: eintr, Node: kill-new function, Prev: kill-append function, Up: copy-region-as-kill body - -The `kill-new' function -....................... - -The `kill-new' function looks like this: - - (defun kill-new (string &optional replace yank-handler) - "Make STRING the latest kill in the kill ring. - Set `kill-ring-yank-pointer' to point to it. - - If `interprogram-cut-function' is non-nil, apply it to STRING. - Optional second argument REPLACE non-nil means that STRING will replace - the front of the kill ring, rather than being added to the list. - ..." - (if (> (length string) 0) - (if yank-handler - (put-text-property 0 (length string) - 'yank-handler yank-handler string)) - (if yank-handler - (signal 'args-out-of-range - (list string "yank-handler specified for empty string")))) - (if (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) - (if (and replace kill-ring) - (setcar kill-ring string) - (push string kill-ring) - (if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) - (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) - -(Notice that the function is not interactive.) - -As usual, we can look at this function in parts. - -The function definition has an optional `yank-handler' argument, which -when invoked tells the function how to deal with properties added to -the text, such as `bold' or `italics'. We will skip that. - -The first line of the documentation makes sense: - - Make STRING the latest kill in the kill ring. - -Let's skip over the rest of the documentation for the moment. - -Also, let's skip over the initial `if' expression and those lines of -code involving `menu-bar-update-yank-menu'. We will explain them below. - -The critical lines are these: - - (if (and replace kill-ring) - ;; then - (setcar kill-ring string) - ;; else - (push string kill-ring) - (setq kill-ring (cons string kill-ring)) - (if (> (length kill-ring) kill-ring-max) - ;; avoid overly long kill ring - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) - (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) - -The conditional test is `(and replace kill-ring)'. This will be true -when two conditions are met: the kill ring has something in it, and -the `replace' variable is true. - -When the `kill-append' function sets `replace' to be true and when the -kill ring has at least one item in it, the `setcar' expression is -executed: - - (setcar kill-ring string) - -The `setcar' function actually changes the first element of the -`kill-ring' list to the value of `string'. It replaces the first -element. - -On the other hand, if the kill ring is empty, or replace is false, the -else-part of the condition is executed: - - (push string kill-ring) - -`push' puts its first argument onto the second. It is the same as the -older - - (setq kill-ring (cons string kill-ring)) - -or the newer - - (add-to-list kill-ring string) - -When it is false, the expression first constructs a new version of the -kill ring by prepending `string' to the existing kill ring as a new -element (that is what the `push' does). Then it executes a second `if' -clause. This second `if' clause keeps the kill ring from growing too -long. - -Let's look at these two expressions in order. - -The `push' line of the else-part sets the new value of the kill ring to -what results from adding the string being killed to the old kill ring. - -We can see how this works with an example. - -First, - - (setq example-list '("here is a clause" "another clause")) - -After evaluating this expression with `C-x C-e', you can evaluate -`example-list' and see what it returns: - - example-list - => ("here is a clause" "another clause") - -Now, we can add a new element on to this list by evaluating the -following expression: - - (push "a third clause" example-list) - -When we evaluate `example-list', we find its value is: - - example-list - => ("a third clause" "here is a clause" "another clause") - -Thus, the third clause is added to the list by `push'. - -Now for the second part of the `if' clause. This expression keeps the -kill ring from growing too long. It looks like this: - - (if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) - -The code checks whether the length of the kill ring is greater than the -maximum permitted length. This is the value of `kill-ring-max' (which -is 60, by default). If the length of the kill ring is too long, then -this code sets the last element of the kill ring to `nil'. It does -this by using two functions, `nthcdr' and `setcdr'. - -We looked at `setcdr' earlier (*note `setcdr': setcdr.). It sets the -CDR of a list, just as `setcar' sets the CAR of a list. In this case, -however, `setcdr' will not be setting the CDR of the whole kill ring; -the `nthcdr' function is used to cause it to set the CDR of the next to -last element of the kill ring--this means that since the CDR of the -next to last element is the last element of the kill ring, it will set -the last element of the kill ring. - -The `nthcdr' function works by repeatedly taking the CDR of a list--it -takes the CDR of the CDR of the CDR ... It does this N times and -returns the results. (*Note `nthcdr': nthcdr.) - -Thus, if we had a four element list that was supposed to be three -elements long, we could set the CDR of the next to last element to -`nil', and thereby shorten the list. (If you sent the last element to -some other value than `nil', which you could do, then you would not -have shortened the list. *Note `setcdr': setcdr.) - -You can see shortening by evaluating the following three expressions in -turn. First set the value of `trees' to `(maple oak pine birch)', then -set the CDR of its second CDR to `nil' and then find the value of -`trees': - - (setq trees '(maple oak pine birch)) - => (maple oak pine birch) - - (setcdr (nthcdr 2 trees) nil) - => nil - - trees - => (maple oak pine) - -(The value returned by the `setcdr' expression is `nil' since that is -what the CDR is set to.) - -To repeat, in `kill-new', the `nthcdr' function takes the CDR a number -of times that is one less than the maximum permitted size of the kill -ring and `setcdr' sets the CDR of that element (which will be the rest -of the elements in the kill ring) to `nil'. This prevents the kill -ring from growing too long. - -The next to last expression in the `kill-new' function is - - (setq kill-ring-yank-pointer kill-ring) - -The `kill-ring-yank-pointer' is a global variable that is set to be the -`kill-ring'. - -Even though the `kill-ring-yank-pointer' is called a `pointer', it is a -variable just like the kill ring. However, the name has been chosen to -help humans understand how the variable is used. The variable is used -in functions such as `yank' and `yank-pop' (*note Yanking Text Back: -Yanking.). - -Now, to return to an early expression in the body of the function: - - (if (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) - -It starts with an `if' expression - -In this case, the expression tests first to see whether -`menu-bar-update-yank-menu' exists as a function, and if so, calls it. -The `fboundp' function returns true if the symbol it is testing has a -function definition that `is not void'. If the symbol's function -definition were void, we would receive an error message, as we did when -we created errors intentionally (*note Generate an Error Message: -Making Errors.). - -The then-part contains an expression whose first element is the -function `and'. - -The `and' special form evaluates each of its arguments until one of the -arguments returns a value of `nil', in which case the `and' expression -returns `nil'; however, if none of the arguments returns a value of -`nil', the value resulting from evaluating the last argument is -returned. (Since such a value is not `nil', it is considered true in -Emacs Lisp.) In other words, an `and' expression returns a true value -only if all its arguments are true. (*Note Second Buffer Related -Review::.) - -The expression determines whether the second argument to -`menu-bar-update-yank-menu' is true or not. - -`menu-bar-update-yank-menu' is one of the functions that make it -possible to use the `Select and Paste' menu in the Edit item of a menu -bar; using a mouse, you can look at the various pieces of text you have -saved and select one piece to paste. - -The last expression in the `kill-new' function adds the newly copied -string to whatever facility exists for copying and pasting among -different programs running in a windowing system. In the X Windowing -system, for example, the `x-select-text' function takes the string and -stores it in memory operated by X. You can paste the string in another -program, such as an Xterm. - -The expression looks like this: - - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) - -If an `interprogram-cut-function' exists, then Emacs executes -`funcall', which in turn calls its first argument as a function and -passes the remaining arguments to it. (Incidentally, as far as I can -see, this `if' expression could be replaced by an `and' expression -similar to the one in the first part of the function.) - -We are not going to discuss windowing systems and other programs -further, but merely note that this is a mechanism that enables GNU -Emacs to work easily and well with other programs. - -This code for placing text in the kill ring, either concatenated with -an existing element or as a new element, leads us to the code for -bringing back text that has been cut out of the buffer--the yank -commands. However, before discussing the yank commands, it is better -to learn how lists are implemented in a computer. This will make clear -such mysteries as the use of the term `pointer'. - - -File: eintr, Node: Digression into C, Next: defvar, Prev: copy-region-as-kill, Up: Cutting & Storing Text - -8.4 Digression into C -===================== - -The `copy-region-as-kill' function (*note `copy-region-as-kill': -copy-region-as-kill.) uses the `filter-buffer-substring' function, -which in turn uses the `delete-and-extract-region' function. It -removes the contents of a region and you cannot get them back. - -Unlike the other code discussed here, the `delete-and-extract-region' -function is not written in Emacs Lisp; it is written in C and is one of -the primitives of the GNU Emacs system. Since it is very simple, I -will digress briefly from Lisp and describe it here. - -Like many of the other Emacs primitives, `delete-and-extract-region' is -written as an instance of a C macro, a macro being a template for code. -The complete macro looks like this: - - DEFUN ("buffer-substring-no-properties", Fbuffer_substring_no_properties, - Sbuffer_substring_no_properties, 2, 2, 0, - doc: /* Return the characters of part of the buffer, - without the text properties. - The two arguments START and END are character positions; - they can be in either order. */) - (start, end) - Lisp_Object start, end; - { - register int b, e; - - validate_region (&start, &end); - b = XINT (start); - e = XINT (end); - - return make_buffer_string (b, e, 0); - } - -Without going into the details of the macro writing process, let me -point out that this macro starts with the word `DEFUN'. The word -`DEFUN' was chosen since the code serves the same purpose as `defun' -does in Lisp. (The `DEFUN' C macro is defined in `emacs/src/lisp.h'.) - -The word `DEFUN' is followed by seven parts inside of parentheses: - - * The first part is the name given to the function in Lisp, - `delete-and-extract-region'. - - * The second part is the name of the function in C, - `Fdelete_and_extract_region'. By convention, it starts with `F'. - Since C does not use hyphens in names, underscores are used - instead. - - * The third part is the name for the C constant structure that - records information on this function for internal use. It is the - name of the function in C but begins with an `S' instead of an `F'. - - * The fourth and fifth parts specify the minimum and maximum number - of arguments the function can have. This function demands exactly - 2 arguments. - - * The sixth part is nearly like the argument that follows the - `interactive' declaration in a function written in Lisp: a letter - followed, perhaps, by a prompt. The only difference from the Lisp - is when the macro is called with no arguments. Then you write a - `0' (which is a `null string'), as in this macro. - - If you were to specify arguments, you would place them between - quotation marks. The C macro for `goto-char' includes `"NGoto - char: "' in this position to indicate that the function expects a - raw prefix, in this case, a numerical location in a buffer, and - provides a prompt. - - * The seventh part is a documentation string, just like the one for a - function written in Emacs Lisp, except that every newline must be - written explicitly as `\n' followed by a backslash and carriage - return. - - Thus, the first two lines of documentation for `goto-char' are - written like this: - - "Set point to POSITION, a number or marker.\n\ - Beginning of buffer is position (point-min), end is (point-max). - -In a C macro, the formal parameters come next, with a statement of what -kind of object they are, followed by what might be called the `body' of -the macro. For `delete-and-extract-region' the `body' consists of the -following four lines: - - validate_region (&start, &end); - if (XINT (start) == XINT (end)) - return build_string (""); - return del_range_1 (XINT (start), XINT (end), 1, 1); - -The `validate_region' function checks whether the values passed as -the beginning and end of the region are the proper type and are within -range. If the beginning and end positions are the same, then return -and empty string. - -The `del_range_1' function actually deletes the text. It is a complex -function we will not look into. It updates the buffer and does other -things. However, it is worth looking at the two arguments passed to -`del_range'. These are `XINT (start)' and `XINT (end)'. - -As far as the C language is concerned, `start' and `end' are two -integers that mark the beginning and end of the region to be deleted(1). - -In early versions of Emacs, these two numbers were thirty-two bits -long, but the code is slowly being generalized to handle other lengths. -Three of the available bits are used to specify the type of -information; the remaining bits are used as `content'. - -`XINT' is a C macro that extracts the relevant number from the longer -collection of bits; the three other bits are discarded. - -The command in `delete-and-extract-region' looks like this: - - del_range_1 (XINT (start), XINT (end), 1, 1); - -It deletes the region between the beginning position, `start', and the -ending position, `end'. - -From the point of view of the person writing Lisp, Emacs is all very -simple; but hidden underneath is a great deal of complexity to make it -all work. - ----------- Footnotes ---------- - -(1) More precisely, and requiring more expert knowledge to understand, -the two integers are of type `Lisp_Object', which can also be a C union -instead of an integer type. - - -File: eintr, Node: defvar, Next: cons & search-fwd Review, Prev: Digression into C, Up: Cutting & Storing Text - -8.5 Initializing a Variable with `defvar' -========================================= - -The `copy-region-as-kill' function is written in Emacs Lisp. Two -functions within it, `kill-append' and `kill-new', copy a region in a -buffer and save it in a variable called the `kill-ring'. This section -describes how the `kill-ring' variable is created and initialized using -the `defvar' special form. - -(Again we note that the term `kill-ring' is a misnomer. The text that -is clipped out of the buffer can be brought back; it is not a ring of -corpses, but a ring of resurrectable text.) - -In Emacs Lisp, a variable such as the `kill-ring' is created and given -an initial value by using the `defvar' special form. The name comes -from "define variable". - -The `defvar' special form is similar to `setq' in that it sets the -value of a variable. It is unlike `setq' in two ways: first, it only -sets the value of the variable if the variable does not already have a -value. If the variable already has a value, `defvar' does not override -the existing value. Second, `defvar' has a documentation string. - -(Another special form, `defcustom', is designed for variables that -people customize. It has more features than `defvar'. (*Note Setting -Variables with `defcustom': defcustom.) - -* Menu: - -* See variable current value:: -* defvar and asterisk:: - |