Mercurial > emacs
changeset 73554:d092f1092ef0
* emacs-lisp-intro.texi: Many changes since it turned out that
many `simple' functions were rewritten. Changes to the text
regarding zap-to-char, mark-whole-buffer, append-to-buffer,
copy-to-buffer, beginning-of-buffer, what-line, and possibly
others. (I have not reviewed all yet.) This instance does build
for Info and TeX.
author | Robert J. Chassell <bob@rattlesnake.com> |
---|---|
date | Mon, 30 Oct 2006 22:15:21 +0000 |
parents | 916b67334531 |
children | 3f351640d09f |
files | lispintro/ChangeLog lispintro/emacs-lisp-intro.texi |
diffstat | 2 files changed, 3808 insertions(+), 2802 deletions(-) [+] |
line wrap: on
line diff
--- a/lispintro/ChangeLog Mon Oct 30 21:34:15 2006 +0000 +++ b/lispintro/ChangeLog Mon Oct 30 22:15:21 2006 +0000 @@ -1,3 +1,12 @@ +2006-10-30 Robert J. Chassell <bob@rattlesnake.com> + + * emacs-lisp-intro.texi: Many changes since it turned out that + many `simple' functions were rewritten. Changes to the text + regarding zap-to-char, mark-whole-buffer, append-to-buffer, + copy-to-buffer, beginning-of-buffer, what-line, and possibly + others. (I have not reviewed all yet.) This instance does build + for Info and TeX. + 2006-10-29 Chong Yidong <cyd@stupidchicken.com> * Makefile.in: Use relative paths to avoid advertising filesystem
--- a/lispintro/emacs-lisp-intro.texi Mon Oct 30 21:34:15 2006 +0000 +++ b/lispintro/emacs-lisp-intro.texi Mon Oct 30 22:15:21 2006 +0000 @@ -1,5 +1,6 @@ \input ../man/texinfo @c -*-texinfo-*- -@c change above to \input texinfo if building on own. +@c \input texinfo @c -*-texinfo-*- +@c change to \input texinfo if building on own. @comment %**start of header @setfilename ../info/eintr @c setfilename emacs-lisp-intro.info @@ -23,19 +24,25 @@ @comment %**end of header -@set edition-number 2.14 -@set update-date 2004 Oct 12 +@set edition-number 2.15 +@set update-date 2006 Oct 30 @ignore ## Summary of shell commands to create various output formats: pushd /usr/local/src/emacs/lispintro/ + ## pushd /u/intro/ ## Info output makeinfo --no-split --paragraph-indent=0 --verbose emacs-lisp-intro.texi + ## ;; (progn (when (bufferp (get-buffer "*info*")) (kill-buffer "*info*")) (info "/u/intro/emacs-lisp-intro.info")) + ## DVI output - texi2dvi emacs-lisp-intro.texi + texi2dvi /u/intro/emacs-lisp-intro.texi + + ## View DVI output; see below also + # xdvi -margins 24pt -topmargin 4pt -offsets 24pt -geometry 760x1140 -s 5 -useTeXpages -mousemode 1 /u/intro/emacs-lisp-intro.dvi & ## HTML output makeinfo --html --no-split --verbose emacs-lisp-intro.texi @@ -52,6 +59,8 @@ makeinfo --xml --no-split --paragraph-indent=0 \ --verbose emacs-lisp-intro.texi + popd + #### (You must be in the same directory as the viewed file.) ## View DVI output @@ -63,7 +72,20 @@ ## View Info output with standalone reader info emacs-lisp-intro.info - ## popd + ## popd + +Need to explain defcustom see (elisp)Customization (elisp)Variable Definitions + defsubst + defconst + + + +# as user `root' +# insert thumbdrive + mtusb # mount -v -t ext3 /dev/sda /mnt + cp -v /u/intro/emacs-lisp-intro.texi /mnt/backup/intro/emacs-lisp-intro.texi + umtusb # umount -v /mnt +# remove thumbdrive @end ignore @@ -166,7 +188,8 @@ @c in the Texinfo version 4.6 of the 2003 Jun 13 distribution. @tex -\global\def\xrefprintnodename#1{``#1''} +\global\def\xrefprintnodename#1{\unskip, ``#1''} +% \global\def\xrefprintnodename#1{, ``#1''} @end tex @c ---------------------------------------------------- @@ -280,6 +303,16 @@ every node in every chapter. @end ifnottex +@c >>>> Set pageno appropriately <<<< + +@c The first page of the Preface is a roman numeral; it is the first +@c right handed page after the Table of Contents; hence the following +@c setting must be for an odd negative number. + +@iftex +@global@pageno = -11 +@end iftex + @menu * Preface:: What to look for. * List Processing:: What is Lisp? @@ -371,34 +404,34 @@ Setting the Value of a Variable -* Using set:: Setting values. -* Using setq:: Setting a quoted value. -* Counting:: Using @code{setq} to count. +* Using set:: Setting values. +* Using setq:: Setting a quoted value. +* Counting:: Using @code{setq} to count. Practicing Evaluation -* How to Evaluate:: Typing editing commands or @kbd{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. +* How to Evaluate:: Typing editing commands or @kbd{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 @code{defun} special form. -* Install:: Install a function definition. -* Interactive:: Making a function interactive. -* Interactive Options:: Different options for @code{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. +* defun:: The @code{defun} special form. +* Install:: Install a function definition. +* Interactive:: Making a function interactive. +* Interactive Options:: Different options for @code{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:: @@ -473,6 +506,7 @@ * if & or:: Using an @code{if} instead of an @code{or}. * Insert or:: How the @code{or} expression works. * Insert let:: Two @code{save-excursion} expressions. +* New insert-buffer:: The Interactive Expression in @code{insert-buffer} @@ -519,9 +553,9 @@ * 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. -* copy-region-as-kill:: A definition for copying text. * cons & search-fwd Review:: * search Exercises:: @@ -538,12 +572,7 @@ * Complete kill-region:: The function definition. * condition-case:: Dealing with a problem. -* delete-and-extract-region:: Doing the work. - -Initializing a Variable with @code{defvar} - -* See variable current value:: -* defvar and asterisk:: An old-time convention. +* Lisp macro:: @code{copy-region-as-kill} @@ -556,6 +585,11 @@ * kill-append function:: * kill-new function:: +Initializing a Variable with @code{defvar} + +* See variable current value:: +* defvar and asterisk:: + How Lists are Implemented * Lists diagrammed:: @@ -564,9 +598,9 @@ Yanking Text Back -* Kill Ring Overview:: The kill ring is a list. -* kill-ring-yank-pointer:: The @code{kill-ring-yank-pointer} variable. -* yank nthcdr Exercises:: +* Kill Ring Overview:: +* kill-ring-yank-pointer:: The kill ring is a list. +* yank nthcdr Exercises:: The @code{kill-ring-yank-pointer} variable. Loops and Recursion @@ -643,11 +677,6 @@ * forward-paragraph in brief:: Key parts of the function definition. * fwd-para let:: The @code{let*} expression. * fwd-para while:: The forward motion @code{while} loop. -* fwd-para between paragraphs:: Movement between paragraphs. -* fwd-para within paragraph:: Movement within paragraphs. -* fwd-para no fill prefix:: When there is no fill prefix. -* fwd-para with fill prefix:: When there is a fill prefix. -* fwd-para summary:: Summary of @code{forward-paragraph} code. Counting: Repetition and Regexps @@ -721,28 +750,19 @@ Handling the Kill Ring -* rotate-yank-pointer:: Move a pointer along a list and around. +* current-kill:: * yank:: Paste a copy of a clipped element. -* yank-pop:: Insert first element pointed to. +* yank-pop:: Insert element pointed to. * ring file:: -The @code{rotate-yank-pointer} Function - -* Understanding rotate-yk-ptr:: -* rotate-yk-ptr body:: The body of @code{rotate-yank-pointer}. - -The Body of @code{rotate-yank-pointer} +The @code{current-kill} Function + +* Understanding current-kill:: + +@code{current-kill} in Outline * Digression concerning error:: How to mislead humans, but not computers. -* rotate-yk-ptr else-part:: The else-part of the @code{if} expression. -* Remainder Function:: The remainder, @code{%}, function. -* rotate-yk-ptr remainder:: Using @code{%} in @code{rotate-yank-pointer}. -* kill-rng-yk-ptr last elt:: Pointing to the last element. - -@code{yank} - -* rotate-yk-ptr arg:: Pass the argument to @code{rotate-yank-pointer}. -* rotate-yk-ptr negative arg:: Pass a negative argument. +* Determining the Element:: A Graph with Labelled Axes @@ -778,16 +798,6 @@ @end detailmenu @end menu -@c >>>> Set pageno appropriately <<<< - -@c The first page of the Preface is a roman numeral; it is the first -@c right handed page after the Table of Contents; hence the following -@c setting must be for an odd negative number. - -@iftex -@global@pageno = -11 -@end iftex - @node Preface, List Processing, Top, Top @comment node-name, next, previous, up @unnumbered Preface @@ -809,11 +819,11 @@ editing in the most general sense of the word.) @menu -* Why:: Why learn Emacs Lisp? -* On Reading this Text:: Read, gain familiarity, pick up habits.... -* Who You Are:: For whom this is written. +* Why:: +* On Reading this Text:: +* Who You Are:: * Lisp History:: -* Note for Novices:: You can read this as a novice. +* Note for Novices:: * Thank You:: @end menu @@ -1066,16 +1076,16 @@ Errors, , Generate an Error Message}.} Lists are the basis of Lisp. @menu -* 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. +* Lisp Lists:: +* Run a Program:: +* Making Errors:: +* Names & Definitions:: +* Lisp Interpreter:: +* Evaluation:: +* Variables:: +* Arguments:: +* set & setq:: +* Summary:: * Error Message Exercises:: @end menu @@ -1105,10 +1115,10 @@ @cindex Flowers in a field @menu -* Numbers Lists:: List have numbers, other lists, in them. -* Lisp Atoms:: Elemental entities. -* Whitespace in Lists:: Formating lists to be readable. -* Typing Lists:: How GNU Emacs helps you type lists. +* Numbers Lists:: +* Lisp Atoms:: +* Whitespace in Lists:: +* Typing Lists:: @end menu @node Numbers Lists, Lisp Atoms, Lisp Lists, Lisp Lists @@ -1151,8 +1161,8 @@ 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 @samp{+}. On the other hand, unlike an -atom, a list can be split into parts. (@xref{car cdr & cons, , -@code{car} @code{cdr} & @code{cons} Fundamental Functions}.) +ancient atom, a list can be split into parts. (@xref{car cdr & cons, +, @code{car} @code{cdr} & @code{cons} Fundamental Functions}.) In a list, atoms are separated from each other by whitespace. They can be right next to a parenthesis. @@ -1378,13 +1388,13 @@ @noindent What you see depends on which version of Emacs you are running. GNU -Emacs version 21 provides more information than version 20 and before. +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. @need 1250 @noindent -In GNU Emacs version 21, a @file{*Backtrace*} window will open up and +In GNU Emacs version 22, a @file{*Backtrace*} window will open up and you will see the following in it: @smallexample @@ -1501,7 +1511,7 @@ 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 @samp{Bob}; however, I am -not the letters @samp{B}, @samp{o}, @samp{b} but am, or were, the +not the letters @samp{B}, @samp{o}, @samp{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. @@ -1546,8 +1556,8 @@ yourself or the computer. @menu -* Complications:: Variables, Special forms, Lists within. -* Byte Compiling:: Specially processing code for speed. +* Complications:: +* Byte Compiling:: @end menu @node Complications, Byte Compiling, Lisp Interpreter, Lisp Interpreter @@ -1639,7 +1649,7 @@ or else produce an error. @menu -* Evaluating Inner Lists:: Lists within lists... +* Evaluating Inner Lists:: @end menu @node Evaluating Inner Lists, , Evaluation, Evaluation @@ -1741,9 +1751,8 @@ @menu * 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. +* Void Function:: +* Void Variable:: @end menu @node fill-column Example, Void Function, Variables, Variables @@ -1805,7 +1814,7 @@ @need 1250 @noindent -In GNU Emacs version 21, you will create a @file{*Backtrace*} buffer +In GNU Emacs version 22, you will create a @file{*Backtrace*} buffer that says: @smallexample @@ -1825,6 +1834,7 @@ (Remember, to quit the debugger and make the debugger window go away, type @kbd{q} in the @file{*Backtrace*} buffer.) +@ignore @need 800 In GNU Emacs 20 and before, you will produce an error message that says: @@ -1833,8 +1843,9 @@ @end smallexample @noindent -(The message will go away away as soon as you move the cursor or type +(The message will go away as soon as you move the cursor or type another key.) +@end ignore @node Void Variable, , Void Function, Variables @comment node-name, next, previous, up @@ -1854,7 +1865,7 @@ @need 1500 @noindent -In GNU Emacs 21, you will create a @file{*Backtrace*} buffer that +In GNU Emacs 22, you will create a @file{*Backtrace*} buffer that says: @smallexample @@ -1891,6 +1902,7 @@ definition, the error message reported that the symbol's value as a variable was void. +@ignore @need 800 In GNU Emacs version 20 and before, your error message will say: @@ -1899,7 +1911,8 @@ @end example @noindent -The meaning is the same as in GNU Emacs 21. +The meaning is the same as in GNU Emacs 22. +@end ignore @node Arguments, set & setq, Variables, List Processing @comment node-name, next, previous, up @@ -1945,14 +1958,11 @@ have two different function definitions at the same time.)} @menu -* 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. +* Data types:: +* Args as Variable or List:: +* Variable Number of Arguments:: +* Wrong Type of Argument:: +* message:: @end menu @node Data types, Args as Variable or List, Arguments, Arguments @@ -2028,7 +2038,7 @@ @noindent The value will be a number two more than what you get by evaluating -@code{fill-column} alone. For me, this is 74, because the value of +@code{fill-column} alone. For me, this is 74, because my value of @code{fill-column} is 72. As we have just seen, an argument can be a symbol that returns a value @@ -2038,7 +2048,7 @@ @w{@code{"The "}} and @w{@code{" red foxes."}} and the list @code{(number-to-string (+ 2 fill-column))}. -@c For Emacs 21, need number-to-string +@c For GNU Emacs 22, need number-to-string @smallexample (concat "The " (number-to-string (+ 2 fill-column)) " red foxes.") @end smallexample @@ -2122,7 +2132,7 @@ could not carry out its addition. @need 1250 -In GNU Emacs version 21, you will create and enter a +In GNU Emacs version 22, you will create and enter a @file{*Backtrace*} buffer that says: @noindent @@ -2180,6 +2190,7 @@ would have been a number, such as 37, rather than a symbol like @code{hello}. But then you would not have got the error message. +@ignore @need 1250 In GNU Emacs version 20 and before, the echo area displays an error message that says: @@ -2190,6 +2201,7 @@ This says, in different words, the same as the top line of the @file{*Backtrace*} buffer. +@end ignore @node message, , Wrong Type of Argument, Arguments @comment node-name, next, previous, up @@ -2300,8 +2312,9 @@ in place of the @samp{%d}; and the value returned by the expression beginning with @code{concat} is inserted in place of the @samp{%s}. -When I evaluate the expression, the message @code{"He saw 38 red -foxes leaping."} appears in my echo area. +When your fill column is 70 and you evaluate the expression, the +message @code{"He saw 38 red foxes leaping."} appears in your echo +area. @node set & setq, Summary, Arguments, List Processing @comment node-name, next, previous, up @@ -2319,9 +2332,9 @@ work but also illustrate how arguments are passed. @menu -* Using set:: Setting values. -* Using setq:: Setting a quoted value. -* Counting:: Using @code{setq} to count. +* Using set:: +* Using setq:: +* Counting:: @end menu @node Using set, Using setq, set & setq, set & setq @@ -2340,7 +2353,7 @@ @noindent The list @code{(rose violet daisy buttercup)} will appear in the echo area. This is what is @emph{returned} by the @code{set} function. As a -side effect, the symbol @code{flowers} is bound to the list ; that is, +side effect, the symbol @code{flowers} is bound to the list; that is, the symbol @code{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 @@ -2529,7 +2542,14 @@ Then the instructions in the function definition are carried out. @item -A single-quote, @code{'}, tells the Lisp interpreter that it should +A single quotation mark, +@ifinfo +' +@end ifinfo +@ifnotinfo +@code{'} +@end ifnotinfo +, 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. @@ -2584,13 +2604,11 @@ buffer-related functions, to see how they were written. @menu -* How to Evaluate:: Typing editing commands or @kbd{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. +* How to Evaluate:: +* Buffer Names:: +* Getting Buffers:: +* Switching Buffers:: +* Buffer Size & Locations:: * Evaluation Exercise:: @end menu @@ -2656,24 +2674,42 @@ each of the following expressions by positioning the cursor after it and typing @kbd{C-x C-e}. -@smallexample +@example @group (buffer-name) (buffer-file-name) @end group -@end smallexample - -@noindent -When I do this, @file{"introduction.texinfo"} is the value returned by -evaluating @code{(buffer-name)}, and -@file{"/gnu/work/intro/introduction.texinfo"} is the value returned by -evaluating @code{(buffer-file-name)}. The former is the name of the -buffer and the latter is the name of the file. (In the expressions, the -parentheses tell the Lisp interpreter to treat @code{buffer-name} and -@code{buffer-file-name} as functions; without the parentheses, the -interpreter would attempt to evaluate the symbols as variables. -@xref{Variables}.) +@end example + +@noindent +When I do this in Info, the value returned by evaluating +@code{(buffer-name)} is @file{"*info*"}, and the value returned by +evaluating @code{(buffer-file-name)} is @file{nil}. + +On the other hand, while I am writing this Introduction, the value +returned by evaluating @code{(buffer-name)} is +@file{"introduction.texinfo"}, and the value returned by evaluating +@code{(buffer-file-name)} is +@file{"/gnu/work/intro/introduction.texinfo"}. + +@cindex @code{nil}, history of word +The former is the name of the buffer and the latter is the name of the +file. In Info, the buffer name is @file{"*info*"}. Info does not +point to any file, so the result of evaluating +@code{(buffer-file-name)} is @file{nil}. The symbol @code{nil} is +from the Latin word for `nothing'; in this case, it means that the +buffer is not associated with any file. (In Lisp, @code{nil} is also +used to mean `false' and is a synonym for the empty list, @code{()}.) + +When I am writing, the name of my buffer is +@file{"introduction.texinfo"}. The name of the file to which it +points is @file{"/gnu/work/intro/introduction.texinfo"}. + +(In the expressions, the parentheses tell the Lisp interpreter to +treat @w{@code{buffer-name}} and @w{@code{buffer-file-name}} as +functions; without the parentheses, the interpreter would attempt to +evaluate the symbols as variables. @xref{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-versa. @@ -2698,23 +2734,25 @@ 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, when you start -an Emacs session by typing the command @code{emacs} alone, without -naming any files, Emacs will start with the @file{*scratch*} buffer on -the screen. This buffer is not visiting any file. Similarly, a +Not all buffers are associated with files. For example, a +@file{*scratch*} buffer does not visit any file. Similarly, a @file{*Help*} buffer is not associated with any file. -@cindex @code{nil}, history of word -If you switch to the @file{*scratch*} buffer, type @code{(buffer-name)}, -position the cursor after it, and type @kbd{C-x C-e} to evaluate the -expression, the name @code{"*scratch*"} is returned and will appear in -the echo area. @code{"*scratch*"} is the name of the buffer. However, -if you type @code{(buffer-file-name)} in the @file{*scratch*} buffer and -evaluate that, @code{nil} will appear in the echo area. @code{nil} is -from the Latin word for `nothing'; in this case, it means that the -@file{*scratch*} buffer is not associated with any file. (In Lisp, -@code{nil} is also used to mean `false' and is a synonym for the empty -list, @code{()}.) +In the old days, when you lacked a @file{~/.emacs} file and started an +Emacs session by typing the command @code{emacs} alone, without naming +any files, Emacs started with the @file{*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 @file{*scratch*} buffer. + +If you switch to the @file{*scratch*} buffer, type +@code{(buffer-name)}, position the cursor after it, and then type +@kbd{C-x C-e} to evaluate the expression. The name @code{"*scratch*"} +will be returned and will appear in the echo area. @code{"*scratch*"} +is the name of the buffer. When you type @code{(buffer-file-name)} in +the @file{*scratch*} buffer and evaluate that, @code{nil} will appear +in the echo area, just as it does when you evaluate +@code{(buffer-file-name)} in Info. Incidentally, if you are in the @file{*scratch*} buffer and want the value returned by an expression to appear in the @file{*scratch*} @@ -2771,18 +2809,20 @@ @end smallexample @noindent -If you evaluate the expression in the usual way, @file{#<buffer *info*>} -appears in the echo area. The special format indicates that the -buffer itself is being returned, rather than just its name. +If you evaluate this expression in Info in Emacs in the usual way, +@file{#<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 @code{current-buffer}. A related function is @code{other-buffer}. This returns the most -recently selected buffer other than the one you are in currently. If -you have recently switched back and forth from the @file{*scratch*} -buffer, @code{other-buffer} will return that buffer. +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 @file{*scratch*} buffer, @code{other-buffer} +will return that buffer. @need 800 You can see this by evaluating the expression: @@ -2815,12 +2855,13 @@ function. When you switched back and forth from Info to the @file{*scratch*} buffer to evaluate @code{(buffer-name)}, you most likely typed @kbd{C-x b} and then typed @file{*scratch*}@footnote{Or -rather, to save typing, you probably typed just part of the name, such -as @code{*sc}, and then pressed your @kbd{TAB} key to cause it to -expand to the full name; and then typed your @kbd{RET} key.} when -prompted in the minibuffer for the name of the buffer to which you -wanted to switch. The keystrokes, @kbd{C-x b}, cause the Lisp -interpreter to evaluate the interactive function +rather, to save typing, you probably only typed @kbd{RET} if the +default buffer was @file{*scratch*}, or if it was different, then you +typed just part of the name, such as @code{*sc}, pressed your +@kbd{TAB} key to cause it to expand to the full name, and then typed +your @kbd{RET} key.} when prompted in the minibuffer for the name of +the buffer to which you wanted to switch. The keystrokes, @kbd{C-x +b}, cause the Lisp interpreter to evaluate the interactive function @code{switch-to-buffer}. As we said before, this is how Emacs works: different keystrokes call or run different functions. For example, @kbd{C-f} calls @code{forward-char}, @kbd{M-e} calls @@ -2980,16 +3021,16 @@ @menu * Primitive Functions:: -* defun:: The @code{defun} special form. -* Install:: Install a function definition. -* Interactive:: Making a function interactive. -* Interactive Options:: Different options for @code{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. +* defun:: +* Install:: +* Interactive:: +* Interactive Options:: +* Permanent Installation:: +* let:: +* if:: +* else:: +* Truth & Falsehood:: +* save-excursion:: * Review:: * defun Exercises:: @end menu @@ -3226,10 +3267,9 @@ Emacs. To reload code automatically whenever you start Emacs, see @ref{Permanent Installation, , Installing Code Permanently}.) - @menu * Effect of installation:: -* Change a defun:: How to change a function definition. +* Change a defun:: @end menu @node Effect of installation, Change a defun, Install, Install @@ -3254,7 +3294,9 @@ @smallexample @group -multiply-by-seven: +multiply-by-seven is a Lisp function. +(multiply-by-seven NUMBER) + Multiply NUMBER by seven. @end group @end smallexample @@ -3329,8 +3371,8 @@ each time you typed a key, it would be very distracting. @menu -* Interactive multiply-by-seven:: An overview. -* multiply-by-seven in detail:: The interactive version. +* Interactive multiply-by-seven:: +* multiply-by-seven in detail:: @end menu @node Interactive multiply-by-seven, multiply-by-seven in detail, Interactive, Interactive @@ -3436,14 +3478,14 @@ subsequent elements of the list to the function @code{message}. As we have seen, @code{message} is an Emacs Lisp function especially -designed for sending a one line message to a user. (@xref{message, , The -@code{message} function}.) -In summary, the @code{message} function prints its first argument in the -echo area as is, except for occurrences of @samp{%d}, @samp{%s}, or -@samp{%c}. When it sees one of these control sequences, the function -looks to the second and subsequent arguments and prints the value of the -argument in the location in the string where the control sequence is -located. +designed for sending a one line message to a user. (@xref{message, , +The @code{message} function}.) In summary, the @code{message} +function prints its first argument in the echo area as is, except for +occurrences of @samp{%d} or @samp{%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 @code{multiply-by-seven} function, the control string is @samp{%d}, which requires a number, and the value returned by @@ -3476,62 +3518,67 @@ @code{interactive}, elisp, The GNU Emacs Lisp Reference Manual}.) @need 1250 -For example, the character @samp{r} causes Emacs to pass the beginning -and end of the region (the current values of point and mark) to the -function as two separate arguments. It is used as follows: - -@smallexample -(interactive "r") -@end smallexample - -On the other hand, a @samp{B} tells Emacs to ask for the name of a -buffer that will be passed to the function. When it sees a @samp{B}, -Emacs will ask for the name by prompting the user in the minibuffer, -using a string that follows the @samp{B}, as in @code{"BAppend to -buffer:@: "}. Not only will Emacs prompt for the name, but Emacs will -complete the name if you type enough of it and press @key{TAB}. - -A function with two or more arguments can have information passed to -each argument by adding parts to the string that follows -@code{interactive}. When you do this, the information is passed to -each argument in the same order it is specified in the +Consider the function @code{zap-to-char}. Its interactive expression +is + +@smallexample +(interactive "p\ncZap to char: ") +@end smallexample + +The first part of the argument to @code{interactive} is @samp{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 @kbd{C-u} followed by a number +or by typing @key{META} followed by a number. The prefix is the +number of specified characters. Thus, if your prefix is three and the +specified character is @samp{x}, then you will delete all the text up +to and including the third next @samp{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 @samp{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 @code{interactive}. When you do this, the information is +passed to each argument in the same order it is specified in the @code{interactive} list. In the string, each part is separated from the next part by a @samp{\n}, which is a newline. For example, you -could follow @code{"BAppend to buffer:@: "} with a @samp{\n} and an -@samp{r}. This would cause Emacs to pass the values of point and mark -to the function as well as prompt you for the buffer---three arguments -in all. - -In this case, the function definition would look like the following, -where @code{buffer}, @code{start}, and @code{end} are the symbols to -which @code{interactive} binds the buffer and the current values of the -beginning and ending of the region: - -@smallexample -@group -(defun @var{name-of-function} (buffer start end) +can follow @samp{p} with a @samp{\n} and an @samp{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 +@code{arg} and @code{char} are the symbols to which @code{interactive} +binds the prefix argument and the specified character: + +@smallexample +@group +(defun @var{name-of-function} (arg char) "@var{documentation}@dots{}" - (interactive "BAppend to buffer:@: \nr") + (interactive "p\ncZap to char: ") @var{body-of-function}@dots{}) @end group @end smallexample @noindent (The space after the colon in the prompt makes it look better when you -are prompted. The @code{append-to-buffer} function looks exactly like -this. @xref{append-to-buffer, , The Definition of -@code{append-to-buffer}}.) - -If a function does not have arguments, then @code{interactive} does not +are prompted. @xref{copy-to-buffer, , The Definition of +@code{copy-to-buffer}}, for an example.) + +When a function does not take arguments, @code{interactive} does not require any. Such a function contains the simple expression @code{(interactive)}. The @code{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 @code{interactive} as -a list. @xref{Using Interactive, , Using @code{Interactive}, elisp, The -GNU Emacs Lisp Reference Manual}, for more information about this advanced -technique. +a list. + +@xref{append-to-buffer, , The Definition of @code{append-to-buffer}}, +for an example. @xref{Using Interactive, , Using @code{Interactive}, +elisp, The GNU Emacs Lisp Reference Manual}, for a more complete +explanation about this technique. @node Permanent Installation, let, Interactive Options, Writing Defuns @comment node-name, next, previous, up @@ -3565,11 +3612,11 @@ @xref{Loading Files, , Loading Files}. @item -On the other hand, if you have code that your whole site will use, it -is usual to put it in a file called @file{site-init.el} that is loaded -when Emacs is built. This makes the code available to everyone who -uses your machine. (See the @file{INSTALL} file that is part of the -Emacs distribution.) +Thirdly, if you have code that your whole site will use, it is usual +to put it in a file called @file{site-init.el} that is loaded when +Emacs is built. This makes the code available to everyone who uses +your machine. (See the @file{INSTALL} file that is part of the Emacs +distribution.) @end itemize Finally, if you have code that everyone who uses Emacs may want, you @@ -3621,6 +3668,7 @@ @end ifnottex @cindex @samp{local variable} defined +@cindex @samp{variable, local}, defined The @code{let} special form prevents confusion. @code{let} creates a name for a @dfn{local variable} that overshadows any use of the same name outside the @code{let} expression. This is like understanding @@ -3726,13 +3774,17 @@ The two variables are @code{zebra} and @code{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 @code{zebra} to the value @code{stripes}, and binds the +variable @code{zebra} to the value @code{stripes}@footnote{According +to Jared Diamond in @cite{Guns, Germs, and Steel}, ``@dots{} 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)}, and binds the variable @code{tiger} to the value @code{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 @code{let} -follows after the list holding the variables. In this example, the body -is a list that uses the @code{message} function to print a string in -the echo area. +follows after the list holding the variables. In this example, the +body is a list that uses the @code{message} function to print a string +in the echo area. @need 1500 You may evaluate the example in the usual fashion, by placing the @@ -3818,7 +3870,7 @@ @menu * if in more detail:: -* type-of-animal in detail:: An example of an @code{if} expression. +* type-of-animal in detail:: @end menu @node if in more detail, type-of-animal in detail, if, if @@ -4086,8 +4138,8 @@ (Of course, if the @var{characteristic} were @code{ferocious}, the message @code{"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 @code{if} and -write your program accordingly.) +possibility that some such argument will be tested by the @code{if} +and write your program accordingly.) @node Truth & Falsehood, save-excursion, else, Writing Defuns @comment node-name, next, previous, up @@ -4106,11 +4158,11 @@ if the result of evaluating it is a value that is not @code{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 @code{"hello"}, or a -symbol (other than @code{nil}) such as @code{flowers}, or a list, or -even a buffer! - -@menu -* nil explained:: @code{nil} has two meanings. +symbol (other than @code{nil}) such as @code{flowers}, or a list (so +long as it is not empty), or even a buffer! + +@menu +* nil explained:: @end menu @node nil explained, , Truth & Falsehood, Truth & Falsehood @@ -4198,7 +4250,7 @@ unexpected movement of point or mark. @menu -* Point and mark:: A review of various locations. +* Point and mark:: * Template for save-excursion:: @end menu @@ -4256,8 +4308,8 @@ In addition to recording the values of point and mark, @code{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 @code{save-excursion} switch you back to the original buffer. This -is how @code{save-excursion} is used in @code{append-to-buffer}. +have @code{save-excursion} switch you back to the original buffer. +This is how @code{save-excursion} is used in @code{append-to-buffer}. (@xref{append-to-buffer, , The Definition of @code{append-to-buffer}}.) @node Template for save-excursion, , Point and mark, save-excursion @@ -4334,7 +4386,9 @@ definition. @need 1250 -For example: +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.) @smallexample @group @@ -4346,6 +4400,24 @@ @end group @end smallexample +@ignore +In GNU Emacs 22, + +(defun backward-to-indentation (&optional arg) + "Move backward ARG lines and position at first nonblank character." + (interactive "p") + (forward-line (- (or arg 1))) + (skip-chars-forward " \t")) + +(defun back-to-indentation () + "Move point to the first non-whitespace character on this line." + (interactive) + (beginning-of-line 1) + (skip-syntax-forward " " (line-end-position)) + ;; Move back over chars that have whitespace syntax but have the p flag. + (backward-prefix-chars)) +@end ignore + @item interactive Declare to the interpreter that the function can be used interactively. This special form may be followed by a string with one @@ -4430,10 +4502,10 @@ @smallexample @group (if (string-equal - (number-to-string 21) + (number-to-string 22) (substring (emacs-version) 10 12)) - (message "This is version 21 Emacs") - (message "This is not version 21 Emacs")) + (message "This is version 22 Emacs") + (message "This is not version 22 Emacs")) @end group @end smallexample @@ -4487,6 +4559,7 @@ be a string or a symbol; the argument used by @samp{%d} must be a number. The argument used by @samp{%c} must be an @sc{ascii} code number; it will be printed as the character with that @sc{ascii} code. +(Various other %-sequences have not been mentioned.) @item setq @itemx set @@ -4567,13 +4640,11 @@ buffers. Later, we will study other functions. @menu -* Finding More:: How to find more information. -* simplified-beginning-of-buffer:: Shows @code{goto-char}, - @code{point-min}, and @code{push-mark}. -* mark-whole-buffer:: Almost the same as @code{beginning-of-buffer}. -* append-to-buffer:: Uses @code{save-excursion} and - @code{insert-buffer-substring}. -* Buffer Related Review:: Review. +* Finding More:: +* simplified-beginning-of-buffer:: +* mark-whole-buffer:: +* append-to-buffer:: +* Buffer Related Review:: * Buffer Exercises:: @end menu @@ -4591,12 +4662,23 @@ then @key{RET}). @cindex Find source of function -In versions 20 and higher, when a function is written in Emacs Lisp, -@code{describe-function} will also tell you the location of the -function definition. If you move point over the file name and press +@c In version 22 +When a function is written in Emacs Lisp, @code{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 @key{RET} key. In this case, @key{RET} means +@code{push-button} rather than `return' or `enter'. Emacs will take +you directly to the function definition. + +@ignore +Not In version 22 + +If you move point over the file name and press the @key{RET} key, which in this case means @code{help-follow} rather than `return' or `enter', Emacs will take you directly to the function definition. +@end ignore More generally, if you want to see a function in its original source file, you can use the @code{find-tags} function to jump to it. @@ -4619,7 +4701,7 @@ @key{RET}}. (On some keyboards, the @key{META} key is labelled @key{ALT}.) -@c !!! 21.0.100 tags table location in this paragraph +@c !!! 22.0.100 tags table location in this paragraph @cindex TAGS table, specifying @findex find-tags Depending on how the initial default values of your copy of Emacs are @@ -4629,15 +4711,15 @@ if it has already been created for you, will be in a subdirectory of the @file{/usr/local/share/emacs/} directory; thus you would use the @code{M-x visit-tags-table} command and specify a pathname such as -@file{/usr/local/share/emacs/21.0.100/lisp/TAGS} or -@file{/usr/local/src/emacs/src/TAGS}. If the tags table has -not already been created, you will have to create it yourself. +@file{/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 @file{/usr/local/src/emacs/src/TAGS}. @need 1250 To create a @file{TAGS} file in a specific directory, switch to that directory in Emacs using @kbd{M-x cd} command, or list the directory with @kbd{C-x d} (@code{dired}). Then run the compile command, with -@w{@code{etags *.el}} as the command to execute +@w{@code{etags *.el}} as the command to execute: @smallexample M-x compile RET etags *.el RET @@ -4773,11 +4855,13 @@ @smallexample @group -One arg, a number. Set point to that number. -Beginning of buffer is position (point-min), -end is (point-max). -@end group -@end smallexample +Set point to POSITION, a number or marker. +Beginning of buffer is position (point-min), end is (point-max). +@end group +@end smallexample + +@noindent +The function's one argument is the desired position. @noindent (The prompt for @code{describe-function} will offer you the symbol @@ -4805,12 +4889,10 @@ a mark at the end of the buffer. It is generally bound to @kbd{C-x h}. - @menu * mark-whole-buffer overview:: -* Body of mark-whole-buffer:: Only three lines of code. -@end menu - +* Body of mark-whole-buffer:: +@end menu @node mark-whole-buffer overview, Body of mark-whole-buffer, mark-whole-buffer, mark-whole-buffer @ifnottex @@ -4818,15 +4900,18 @@ @end ifnottex @need 1250 -In GNU Emacs 20, the code for the complete function looks like this: +In GNU Emacs 22, the code for the complete function looks like this: @smallexample @group (defun mark-whole-buffer () - "Put point at beginning and mark at end of 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)) + (push-mark (point-max) nil t) (goto-char (point-min))) @end group @end smallexample @@ -4863,10 +4948,11 @@ The body of the @code{mark-whole-buffer} function consists of three lines of code: +@c GNU Emacs 22 @smallexample @group (push-mark (point)) -(push-mark (point-max)) +(push-mark (point-max) nil t) (goto-char (point-min)) @end group @end smallexample @@ -4889,34 +4975,36 @@ line causes Emacs to determine the position of point and set a mark there. -The next line of @code{mark-whole-buffer} is @code{(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. @xref{Narrowing & Widening, , Narrowing and 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 -@kbd{C-u C-@key{SPC}} twice. - -(In GNU Emacs 21, the @code{(push-mark (point-max)} is slightly more -complicated than shown here. The line reads +In earlier versions of GNU Emacs, the next line of +@code{mark-whole-buffer} was @code{(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. +@xref{Narrowing & Widening, , Narrowing and 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 @kbd{C-u +C-@key{SPC}} twice. + +@need 1250 +In GNU Emacs 22, the @code{(point-max)} is slightly more complicated. +The line reads @smallexample (push-mark (point-max) nil t) @end smallexample @noindent -(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, @code{push-mark} has two additional arguments. The -second argument to @code{push-mark} is @code{nil}. This tells the -function it @emph{should} display a message that says `Mark set' when -it pushes the mark. The third argument is @code{t}. This tells +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, @code{push-mark} has two additional arguments. The second +argument to @code{push-mark} is @code{nil}. This tells the function +it @emph{should} display a message that says `Mark set' when it pushes +the mark. The third argument is @code{t}. This tells @code{push-mark} to activate the mark when Transient Mark mode is turned on. Transient Mark mode highlights the currently active -region. It is usually turned off.) +region. It is often turned off. Finally, the last line of the function is @code{(goto-char (point-min)))}. This is written exactly the same way as it is written @@ -4932,16 +5020,16 @@ @section The Definition of @code{append-to-buffer} @findex append-to-buffer -The @code{append-to-buffer} command is very nearly as simple as the -@code{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. +The @code{append-to-buffer} command is more complex than the +@code{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:: A two part interactive expression. -* append-to-buffer body:: Incorporates a @code{let} expression. -* append save-excursion:: How the @code{save-excursion} works. +* append interactive:: +* append-to-buffer body:: +* append save-excursion:: @end menu @node append-to-buffer overview, append interactive, append-to-buffer, append-to-buffer @@ -4954,10 +5042,15 @@ @code{insert-buffer-substring} function to copy the region. @code{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 @code{append-to-buffer} is +inserts them into another buffer. + +Most of @code{append-to-buffer} is concerned with setting up the conditions for @code{insert-buffer-substring} to work: the code must specify both the -buffer to which the text will go and the region that will be copied. +buffer to which the text will go, the window it comes from and goes +to, and the region that will be copied. + +@need 1250 Here is the complete text of the function: @smallexample @@ -4969,13 +5062,26 @@ @group When calling from a program, give three arguments: -a buffer or the name of one, and two character numbers -specifying the portion of the current buffer to be copied." - (interactive "BAppend to buffer:@: \nr") +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))) +@end group +@group (let ((oldbuf (current-buffer))) (save-excursion - (set-buffer (get-buffer-create buffer)) - (insert-buffer-substring oldbuf start end)))) + (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)))))))) @end group @end smallexample @@ -4989,7 +5095,7 @@ @group (defun append-to-buffer (buffer start end) "@var{documentation}@dots{}" - (interactive "BAppend to buffer:@: \nr") + (interactive @dots{}) @var{body}@dots{}) @end group @end smallexample @@ -5000,7 +5106,12 @@ will be copied. The next part of the function is the documentation, which is clear and -complete. +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.) @node append interactive, append-to-buffer body, append-to-buffer overview, append-to-buffer @comment node-name, next, previous, up @@ -5012,30 +5123,94 @@ Function Interactive}.) The expression reads as follows: @smallexample +(interactive + (list (read-buffer + "Append to buffer: " + (other-buffer (current-buffer) t)) + (region-beginning) + (region-end))) +@end smallexample + +@noindent +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 @code{read-buffer}. The +function requires a prompt as its first argument, @samp{"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 @code{other-buffer}, an exception, and a @samp{t}, standing +for true. + +The first argument to @code{other-buffer}, the exception, is yet +another function, @code{current-buffer}. That is not going to be +returned. The second argument is the symbol for true, @code{t}. that +tells @code{other-buffer} that it may show visible buffers (except in +this case, it will not show the current buffer, which makes sense). + +@need 1250 +The expression looks like this: + +@smallexample +(other-buffer (current-buffer) t) +@end smallexample + +The second and third arguments to the @code{list} expression are +@code{(region-beginning)} and @code{(region-end)}. These two +functions specify the beginning and end of the text to be appended. + +@need 1250 +Originally, the command used the letters @samp{B} and @samp{r}. +The whole @code{interactive} expression looked like this: + +@smallexample (interactive "BAppend to buffer:@: \nr") @end smallexample @noindent -This expression has an argument inside of quotation marks and that -argument has two parts, separated by @samp{\n}. - -The first part is @samp{BAppend to buffer:@: }. Here, the @samp{B} -tells Emacs to ask for the name of the buffer that will be passed to the -function. Emacs will ask for the name by prompting the user in the -minibuffer, using the string following the @samp{B}, which is the string -@samp{Append to buffer:@: }. Emacs then binds the variable @code{buffer} -in the function's argument list to the specified buffer. - -The newline, @samp{\n}, separates the first part of the argument from -the second part. It is followed by an @samp{r} that tells Emacs to bind -the two arguments that follow the symbol @code{buffer} in the function's +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, +@samp{\n}. It was followed by an @samp{r} that told Emacs to bind the +two arguments that follow the symbol @code{buffer} in the function's argument list (that is, @code{start} and @code{end}) to the values of -point and mark. +point and mark. That argument worked fine.) @node append-to-buffer body, append save-excursion, append interactive, append-to-buffer @comment node-name, next, previous, up @subsection The Body of @code{append-to-buffer} +@ignore +in GNU Emacs 22 in /usr/local/src/emacs/lisp/simple.el + +(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)))))))) +@end ignore + The body of the @code{append-to-buffer} function begins with @code{let}. As we have seen before (@pxref{let, , @code{let}}), the purpose of a @@ -5052,7 +5227,7 @@ @group (defun append-to-buffer (buffer start end) "@var{documentation}@dots{}" - (interactive "BAppend to buffer:@: \nr") + (interactive @dots{}) (let ((@var{variable} @var{value})) @var{body}@dots{}) @end group @@ -5142,7 +5317,7 @@ @need 1500 @noindent -This formatting convention makes it easy to see that the two lines in +This formatting convention makes it easy to see that the lines in the body of the @code{save-excursion} are enclosed by the parentheses associated with @code{save-excursion}, just as the @code{save-excursion} itself is enclosed by the parentheses associated @@ -5152,8 +5327,10 @@ @group (let ((oldbuf (current-buffer))) (save-excursion - (set-buffer (get-buffer-create buffer)) - (insert-buffer-substring oldbuf start end)))) + @dots{} + (set-buffer @dots{}) + (insert-buffer-substring oldbuf start end) + @dots{})) @end group @end smallexample @@ -5174,70 +5351,84 @@ @need 1200 @noindent In this function, the body of the @code{save-excursion} contains only -two expressions. The body looks like this: - -@smallexample -@group -(set-buffer (get-buffer-create buffer)) -(insert-buffer-substring oldbuf start end) -@end group -@end smallexample - -When the @code{append-to-buffer} function is evaluated, the two -expressions in the body of the @code{save-excursion} are evaluated in -sequence. The value of the last expression is returned as the value of -the @code{save-excursion} function; the other expression is evaluated -only for its side effects. - -The first line in the body of the @code{save-excursion} uses the -@code{set-buffer} function to change the current buffer to the one -specified in the first argument to @code{append-to-buffer}. (Changing -the buffer is the side effect; as we have said before, in Lisp, a side -effect is often the primary thing we want.) The second line does the -primary work of the function. - -The @code{set-buffer} function changes Emacs' attention to the buffer to -which the text will be copied and from which @code{save-excursion} will -return. - -@need 800 -The line looks like this: +one expression, the @code{let*} expression. You know about a +@code{let} function. The @code{let*} function is different. It has a +@samp{*} 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. +@xref{fwd-para let, , The @code{let*} expression}. + +We will skip functions like @code{let*} and focus on two: the +@code{set-buffer} function and the @code{insert-buffer-substring} +function. + +@need 1250 +In the old days, the @code{set-buffer} expression was simply @smallexample (set-buffer (get-buffer-create buffer)) @end smallexample -The innermost expression of this list is @code{(get-buffer-create -buffer)}. This expression uses the @code{get-buffer-create} function, -which either gets the named buffer, or if it does not exist, creates one -with the given name. This means you can use @code{append-to-buffer} to -put text into a buffer that did not previously exist. - -@code{get-buffer-create} also keeps @code{set-buffer} from getting an -unnecessary error: @code{set-buffer} needs a buffer to go to; if you -were to specify a buffer that does not exist, Emacs would baulk. -Since @code{get-buffer-create} will create a buffer if none exists, -@code{set-buffer} is always provided with a buffer. - -@need 1250 -The last line of @code{append-to-buffer} does the work of appending -the text: +@need 1250 +@noindent +but now it is + +@smallexample +(set-buffer append-to) +@end smallexample + +@noindent +@code{append-to} is bound to @code{(get-buffer-create buffer)} earlier +on in the @code{let*} expression. That extra binding would not be +necessary except for that @code{append-to} is used later in the +varlist as an argument to @code{get-buffer-window-list}. + +@ignore +in GNU Emacs 22 + + (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)))))))) +@end ignore + +The @code{append-to-buffer} function definition inserts text from the +buffer in which you are currently to a named buffer. It happens that +@code{insert-buffer-substring} copies text from another buffer to the +current buffer, just the reverse---that is why the +@code{append-to-buffer} definition starts out with a @code{let} that +binds the local symbol @code{oldbuf} to the value returned by +@code{current-buffer}. + +@need 1250 +The @code{insert-buffer-substring} expression looks like this: @smallexample (insert-buffer-substring oldbuf start end) @end smallexample @noindent -The @code{insert-buffer-substring} function copies a string @emph{from} -the buffer specified as its first argument and inserts the string into -the present buffer. In this case, the argument to -@code{insert-buffer-substring} is the value of the variable created and -bound by the @code{let}, namely the value of @code{oldbuf}, which was -the current buffer when you gave the @code{append-to-buffer} command. +The @code{insert-buffer-substring} function copies a string +@emph{from} the buffer specified as its first argument and inserts the +string into the present buffer. In this case, the argument to +@code{insert-buffer-substring} is the value of the variable created +and bound by the @code{let}, namely the value of @code{oldbuf}, which +was the current buffer when you gave the @code{append-to-buffer} +command. After @code{insert-buffer-substring} has done its work, -@code{save-excursion} will restore the action to the original buffer and -@code{append-to-buffer} will have done its job. +@code{save-excursion} will restore the action to the original buffer +and @code{append-to-buffer} will have done its job. @need 800 Written in skeletal form, the workings of the body look like this: @@ -5251,16 +5442,15 @@ @var{change-back-to-original-buffer-when-finished} @var{let-the-local-meaning-of-}@code{oldbuf}@var{-disappear-when-finished} - -@end group -@end smallexample - -In summary, @code{append-to-buffer} works as follows: it saves the value -of the current buffer in the variable called @code{oldbuf}. It gets the -new buffer, creating one if need be, and switches Emacs to it. Using -the value of @code{oldbuf}, it inserts the region of text from the old -buffer into the new buffer; and then using @code{save-excursion}, it -brings you back to your original buffer. +@end group +@end smallexample + +In summary, @code{append-to-buffer} works as follows: it saves the +value of the current buffer in the variable called @code{oldbuf}. It +gets the new buffer (creating one if need be) and switches Emacs' +attention to it. Using the value of @code{oldbuf}, it inserts the +region of text from the old buffer into the new buffer; and then using +@code{save-excursion}, it brings you back to your original buffer. In looking at @code{append-to-buffer}, you have explored a fairly complex function. It shows how to use @code{let} and @@ -5351,10 +5541,9 @@ to which the name refers. @menu -* copy-to-buffer:: With @code{set-buffer}, @code{get-buffer-create}. -* insert-buffer:: Read-only, and with @code{or}. -* beginning-of-buffer:: Shows @code{goto-char}, - @code{point-min}, and @code{push-mark}. +* copy-to-buffer:: +* insert-buffer:: +* beginning-of-buffer:: * Second Buffer Related Review:: * optional Exercise:: @end menu @@ -5366,42 +5555,63 @@ After understanding how @code{append-to-buffer} works, it is easy to understand @code{copy-to-buffer}. This function copies text into a -buffer, but instead of adding to the second buffer, it replaces the -previous text in the second buffer. The code for the -@code{copy-to-buffer} function is almost the same as the code for -@code{append-to-buffer}, except that @code{erase-buffer} and a second -@code{save-excursion} are used. (@xref{append-to-buffer, , The -Definition of @code{append-to-buffer}}, for the description of -@code{append-to-buffer}.) - -@need 800 -The body of @code{copy-to-buffer} looks like this +buffer, but instead of adding to the second buffer, it replaces all the +previous text in the second buffer. + +@need 800 +The body of @code{copy-to-buffer} looks like this, @smallexample @group @dots{} -(interactive "BCopy to buffer:@: \nr") - (let ((oldbuf (current-buffer))) +(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 - (set-buffer (get-buffer-create buffer)) - (erase-buffer) - (save-excursion - (insert-buffer-substring oldbuf start end))))) -@end group -@end smallexample - -This code is similar to the code in @code{append-to-buffer}: it is -only after changing to the buffer to which the text will be copied -that the definition for this function diverges from the definition for -@code{append-to-buffer}: the @code{copy-to-buffer} function erases the -buffer's former contents. (This is what is meant by `replacement'; to -replace text, Emacs erases the previous text and then inserts new -text.) After erasing the previous contents of the buffer, -@code{save-excursion} is used for a second time and the new text is -inserted. - -Why is @code{save-excursion} used twice? Consider again what the -function does. + (insert-buffer-substring oldbuf start end))))) +@end group +@end smallexample + +The @code{copy-to-buffer} function has a simpler @code{interactive} +expression than @code{append-to-buffer}. + +@need 800 +The definition then says + +@smallexample +(with-current-buffer (get-buffer-create buffer) @dots{} +@end smallexample + +First, look at the earliest inner expression; that is evaluated first. +That expression starts with @code{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 @code{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 @code{append-to-buffer} function showed how to do +the same with @code{save-excursion} and @code{set-buffer}. +@code{with-current-buffer} is a newer, and arguably easier, +mechanism.) + +The @code{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 @code{erase-buffer} function as its sole +contents. That function erases the buffer. + +Finally, the last two lines contain the @code{save-excursion} +expression with @code{insert-buffer-substring} as its body. +The @code{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 +@code{oldbuf}). + +Incidently, this is what is meant by `replacement'. To replace text, +Emacs erases the previous text and then inserts new text. @need 1250 In outline, the body of @code{copy-to-buffer} looks like this: @@ -5409,27 +5619,14 @@ @smallexample @group (let (@var{bind-}@code{oldbuf}@var{-to-value-of-}@code{current-buffer}) - (save-excursion ; @r{First use of @code{save-excursion}.} - @var{change-buffer} + (@var{with-the-buffer-you-are-copying-to} + (@var{but-do-not-erase-or-copy-to-a-read-only-buffer}) (erase-buffer) - (save-excursion ; @r{Second use of @code{save-excursion}.} + (save-excursion @var{insert-substring-from-}@code{oldbuf}@var{-into-buffer}))) @end group @end smallexample -The first use of @code{save-excursion} returns Emacs to the buffer from -which the text is being copied. That is clear, and is just like its use -in @code{append-to-buffer}. Why the second use? The reason is that -@code{insert-buffer-substring} always leaves point at the @emph{end} of -the region being inserted. The second @code{save-excursion} causes -Emacs to leave point at the beginning of the text being inserted. In -most circumstances, users prefer to find point at the beginning of -inserted text. (Of course, the @code{copy-to-buffer} function returns -the user to the original buffer when done---but if the user @emph{then} -switches to the copied-to buffer, point will go to the beginning of the -text. Thus, this use of a second @code{save-excursion} is a little -nicety.) - @node insert-buffer, beginning-of-buffer, copy-to-buffer, More Complex @comment node-name, next, previous, up @section The Definition of @code{insert-buffer} @@ -5443,17 +5640,21 @@ Here is a discussion based on the original code. The code was simplified in 2003 and is harder to understand. +@xref{New insert-buffer, , New Body for @code{insert-buffer}}, to see +a discussion of the new body.) + In addition, this code illustrates the use of @code{interactive} with a buffer that might be @dfn{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:: When you can read, but not write. -* insert-buffer body:: The body has an @code{or} and a @code{let}. -* if & or:: Using an @code{if} instead of an @code{or}. -* Insert or:: How the @code{or} expression works. -* Insert let:: Two @code{save-excursion} expressions. +* insert-buffer interactive:: +* insert-buffer body:: +* if & or:: +* Insert or:: +* Insert let:: +* New insert-buffer :: @end menu @node insert-buffer code, insert-buffer interactive, insert-buffer, insert-buffer @@ -5462,7 +5663,7 @@ @end ifnottex @need 800 -Here is the code: +Here is the earlier code: @smallexample @group @@ -5511,8 +5712,8 @@ buffer:@: }. @menu -* Read-only buffer:: When a buffer cannot be modified. -* b for interactive:: An existing buffer or else its name. +* Read-only buffer:: +* b for interactive:: @end menu @node Read-only buffer, b for interactive, insert-buffer interactive, insert-buffer interactive @@ -5546,6 +5747,11 @@ 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 @code{interactive}. +It uses the @code{barf-if-buffer-read-only} and @code{read-buffer} +functions with which we are already familiar and the @code{progn} +special form with which we are not. (It will be described later.) + @node insert-buffer body, if & or, insert-buffer interactive, insert-buffer @comment node-name, next, previous, up @subsection The Body of the @code{insert-buffer} Function @@ -5722,7 +5928,7 @@ (or (holding-on-to-guest) (find-and-take-arm-of-guest)) @end smallexample -@node Insert let, , Insert or, insert-buffer +@node Insert let, New insert-buffer , Insert or, insert-buffer @comment node-name, next, previous, up @subsection The @code{let} Expression in @code{insert-buffer} @@ -5821,6 +6027,45 @@ use @code{or}. All these functions are building blocks that we will find and use again and again. +@node New insert-buffer , , Insert let, insert-buffer +@comment node-name, next, previous, up +@subsection New Body for @code{insert-buffer} +@findex insert-buffer, new version body +@findex new version body for insert-buffer + +The body in the GNU Emacs 22 version is more confusing than the original. + +@need 1250 +It consists of two expressions, + +@smallexample +@group + (push-mark + (save-excursion + (insert-buffer-substring (get-buffer buffer)) + (point))) + + nil +@end group +@end smallexample + +@noindent +except, and this is what confuses novices, very important work is done +inside the @code{push-mark} expression. + +The @code{get-buffer} function returns a buffer with the name +provided. You will note that the function is @emph{not} called +@code{get-buffer-create}; it does not create a buffer if one does not +already exist. The buffer returned by @code{get-buffer}, an existing +buffer, is passed to @code{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 +@code{push-mark}. Then the function returns @code{nil}, the value of +its last command. Put another way, the @code{insert-buffer} function +exists only to produce a side effect, inserting another buffer, not to +return any value. + @node beginning-of-buffer, Second Buffer Related Review, insert-buffer, More Complex @comment node-name, next, previous, up @section Complete Definition of @code{beginning-of-buffer} @@ -5833,23 +6078,24 @@ As previously described, when invoked without an argument, @code{beginning-of-buffer} moves the cursor to the beginning 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 @kbd{M-<}, which will move the cursor to -the beginning of the buffer, or with a key command such as @kbd{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. +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 @kbd{M-<}, which will move the cursor to the beginning of the +buffer, or with a key command such as @kbd{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 @code{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:: Example with optional argument. +* beginning-of-buffer opt arg:: * beginning-of-buffer complete:: @end menu @@ -5864,12 +6110,12 @@ @cindex Optional arguments @cindex Keyword @findex optional -However, optional arguments are a feature of Lisp: a @dfn{keyword} may -be used to tell the Lisp interpreter that an argument is optional. -The keyword is @code{&optional}. (The @samp{&} in front of +However, optional arguments are a feature of Lisp: a particular +@dfn{keyword} is used to tell the Lisp interpreter that an argument is +optional. The keyword is @code{&optional}. (The @samp{&} in front of @samp{optional} is part of the keyword.) In a function definition, if -an argument follows the keyword @code{&optional}, a value does not -need to be passed to that argument when the function is called. +an argument follows the keyword @code{&optional}, no value need be +passed to that argument when the function is called. @need 1200 The first line of the function definition of @code{beginning-of-buffer} @@ -5887,12 +6133,16 @@ (defun beginning-of-buffer (&optional arg) "@var{documentation}@dots{}" (interactive "P") - (push-mark) + (or (@var{is-the-argument-a-cons-cell} arg) + (and @var{are-both-transient-mark-mode-and-mark-active-true}) + (push-mark)) + (let (@var{determine-size-and-set-it}) (goto-char (@var{if-there-is-an-argument} @var{figure-out-where-to-go} @var{else-go-to} (point-min)))) + @var{do-nicety} @end group @end smallexample @@ -5900,26 +6150,37 @@ function except that the @code{interactive} expression has @code{"P"} as an argument and the @code{goto-char} function is followed by an if-then-else expression that figures out where to put the cursor if -there is an argument. - -The @code{"P"} in the @code{interactive} expression tells Emacs to pass -a prefix argument, if there is one, to the function. A prefix argument -is made by typing the @key{META} key followed by a number, or by typing -@kbd{C-u} and then a number (if you don't type a number, @kbd{C-u} -defaults to 4). - -The true-or-false-test of the @code{if} expression is simple: it is -simply the argument @code{arg}. If @code{arg} has a value that is not -@code{nil}, which will be the case if @code{beginning-of-buffer} is -called with an argument, then this true-or-false-test will return true -and the then-part of the @code{if} expression will be evaluated. On the +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 @code{consp}. @xref{List +Implementation, , How Lists are Implemented}, and @ref{Cons Cell Type, +, Cons Cell and List Types, elisp, The GNU Emacs Lisp Reference +Manual}.) + +The @code{"P"} in the @code{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 @key{META} key followed by a +number, or by typing @kbd{C-u} and then a number. (If you don't type +a number, @kbd{C-u} defaults to a cons cell with a 4. A lowercase +@code{"p"} in the @code{interactive} expression causes the function to +convert a prefix arg to a number.) + +The true-or-false-test of the @code{if} expression looks complex, but +it is not: it checks whether @code{arg} has a value that is not +@code{nil} and whether it is a cons cell. (That is what @code{consp} +does; it checks whether its argument is a cons cell.) If @code{arg} +has a value that is not @code{nil} (and is not a cons cell), which +will be the case if @code{beginning-of-buffer} is called with a +numeric argument, then this true-or-false-test will return true and +the then-part of the @code{if} expression will be evaluated. On the other hand, if @code{beginning-of-buffer} is not called with an argument, the value of @code{arg} will be @code{nil} and the else-part -of the @code{if} expression will be evaluated. The else-part is simply -@code{point-min}, and when this is the outcome, the whole -@code{goto-char} expression is @code{(goto-char (point-min))}, which is -how we saw the @code{beginning-of-buffer} function in its simplified -form. +of the @code{if} expression will be evaluated. The else-part is +simply @code{point-min}, and when this is the outcome, the whole +@code{goto-char} expression is @code{(goto-char (point-min))}, which +is how we saw the @code{beginning-of-buffer} function in its +simplified form. @node beginning-of-buffer opt arg, beginning-of-buffer complete, Optional Arguments, beginning-of-buffer @subsection @code{beginning-of-buffer} with an Argument @@ -5934,11 +6195,12 @@ @group (if (> (buffer-size) 10000) ;; @r{Avoid overflow for large buffer sizes!} - (* (prefix-numeric-value arg) (/ (buffer-size) 10)) + (* (prefix-numeric-value arg) + (/ size 10)) (/ (+ 10 (* - (buffer-size) (prefix-numeric-value arg))) 10)) + size (prefix-numeric-value arg))) 10))) @end group @end smallexample @@ -5984,13 +6246,21 @@ In @code{beginning-of-buffer}, the inner @code{if} expression tests whether the size of the buffer is greater than 10,000 characters. To do -this, it uses the @code{>} function and the @code{buffer-size} function. +this, it uses the @code{>} function and the computation of @code{size} +that comes from the let expression. + +In the old days, the function @code{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. (@xref{Narrowing & +Widening, , Narrowing and Widening}, for more information on focusing +attention to an `accessible' part.) @need 800 The line looks like this: @smallexample -(if (> (buffer-size) 10000) +(if (> size 10000) @end smallexample @need 1200 @@ -6002,7 +6272,7 @@ @group (* (prefix-numeric-value arg) - (/ (buffer-size) 10)) + (/ size 10)) @end group @end smallexample @@ -6019,11 +6289,12 @@ @findex / @r{(division)} @cindex Division -The second argument is @code{(/ (buffer-size) 10)}. This expression -divides the numeric value of the buffer by ten. This produces a number -that tells how many characters make up one tenth of the buffer size. -(In Lisp, @code{/} is used for division, just as @code{*} is -used for multiplication.) +The second argument is @code{(/ 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, +@code{/} is used for division, just as @code{*} is used for +multiplication.) @need 1200 In the multiplication expression as a whole, this amount is multiplied @@ -6032,23 +6303,22 @@ @smallexample @group (* @var{numeric-value-of-prefix-arg} - @var{number-of-characters-in-one-tenth-of-the-buffer}) + @var{number-of-characters-in-one-tenth-of-the-accessible-buffer}) @end group @end smallexample @noindent If, for example, the prefix argument is @samp{7}, the one-tenth value -will be multiplied by 7 to give a position 70% of the way through the -buffer. - -@need 1200 -The result of all this is that if the buffer is large, the -@code{goto-char} expression reads like this: +will be multiplied by 7 to give a position 70% of the way through. + +@need 1200 +The result of all this is that if the accessible portion of the buffer +is large, the @code{goto-char} expression reads like this: @smallexample @group (goto-char (* (prefix-numeric-value arg) - (/ (buffer-size) 10))) + (/ size 10))) @end group @end smallexample @@ -6069,7 +6339,7 @@ @c Keep this on one line. @smallexample -(/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10)) +(/ (+ 10 (* size (prefix-numeric-value arg))) 10)) @end smallexample @need 1200 @@ -6084,7 +6354,7 @@ (/ (+ 10 (* - (buffer-size) + size (prefix-numeric-value arg))) 10)) @end group @@ -6093,12 +6363,12 @@ @need 1200 @noindent Looking at parentheses, we see that the innermost operation is -@code{(prefix-numeric-value arg)}, which converts the raw argument to a -number. This number is multiplied by the buffer size in the following -expression: - -@smallexample -(* (buffer-size) (prefix-numeric-value arg)) +@code{(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: + +@smallexample +(* size (prefix-numeric-value arg)) @end smallexample @noindent @@ -6120,6 +6390,47 @@ Here is the complete text of the @code{beginning-of-buffer} function: @sp 1 +@c In GNU Emacs 22 +@smallexample +@group +(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. +@end group + +@group +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)) +@end group +@group + (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))) +@end group +@end smallexample + +@ignore +From before GNU Emacs 22 @smallexample @group (defun beginning-of-buffer (&optional arg) @@ -6151,6 +6462,7 @@ (if arg (forward-line 1))) @end group @end smallexample +@end ignore @noindent Except for two small points, the previous discussion shows how this @@ -6162,18 +6474,21 @@ In the documentation string, there is reference to an expression: @smallexample -\(goto-char (point-min)) -@end smallexample - -@noindent -A @samp{\} is used before the first parenthesis of this expression. -This @samp{\} tells the Lisp interpreter that the expression should be -printed as shown in the documentation rather than evaluated as a -symbolic expression, which is what it looks like. - -@need 1200 -Finally, the last line of the @code{beginning-of-buffer} command says to -move point to the beginning of the next line if the command is +\\[universal-argument] +@end smallexample + +@noindent +A @samp{\\} is used before the first square bracket of this +expression. This @samp{\\} tells the Lisp interpreter to substitute +whatever key is currently bound to the @samp{[@dots{}]}. In the case +of @code{universal-argument}, that is usually @kbd{C-u}, but it might +be different. (@xref{Documentation Tips, , Tips for Documentation +Strings, elisp, The GNU Emacs Lisp Reference Manual}, for more +information.) + +@need 1200 +Finally, the last line of the @code{beginning-of-buffer} command says +to move point to the beginning of the next line if the command is invoked with an argument: @smallexample @@ -6185,8 +6500,15 @@ appropriate tenths position in the buffer. This is a flourish that means that the cursor is always located @emph{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. +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 @kbd{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 @dots{} I don't know whether this is +intended or whether no one has dealt with the code to avoid this +happening. @node Second Buffer Related Review, optional Exercise, beginning-of-buffer, More Complex @comment node-name, next, previous, up @@ -6200,7 +6522,7 @@ argument that is not @code{nil}; if none return a value that is not @code{nil}, return @code{nil}. In brief, return the first true value of the arguments; return a true value if one @emph{or} any of the -other are true. +others are true. @item and Evaluate each argument in sequence, and if any are @code{nil}, return @@ -6254,9 +6576,9 @@ novices. @menu -* Narrowing advantages:: The advantages of narrowing -* save-restriction:: The @code{save-restriction} special form. -* what-line:: The number of the line that point is on. +* Narrowing advantages:: +* save-restriction:: +* what-line:: * narrow Exercise:: @end menu @@ -6359,6 +6681,60 @@ @end group @end smallexample +@ignore +Emacs 22 +/usr/local/src/emacs/lisp/simple.el + +(defun what-line () + "Print the current buffer line number and narrowed line number of point." + (interactive) + (let ((start (point-min)) + (n (line-number-at-pos))) + (if (= start 1) + (message "Line %d" n) + (save-excursion + (save-restriction + (widen) + (message "line %d (narrowed line %d)" + (+ n (line-number-at-pos start) -1) n)))))) + +(defun line-number-at-pos (&optional pos) + "Return (narrowed) buffer line number at position POS. +If POS is nil, use current buffer location. +Counting starts at (point-min), so the value refers +to the contents of the accessible portion of the buffer." + (let ((opoint (or pos (point))) start) + (save-excursion + (goto-char (point-min)) + (setq start (point)) + (goto-char opoint) + (forward-line 0) + (1+ (count-lines start (point)))))) + +(defun count-lines (start end) + "Return number of lines between START and END. +This is usually the number of newlines between them, +but can be one more if START is not equal to END +and the greater of them is not at the start of a line." + (save-excursion + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (if (eq selective-display t) + (save-match-data + (let ((done 0)) + (while (re-search-forward "[\n\C-m]" nil t 40) + (setq done (+ 40 done))) + (while (re-search-forward "[\n\C-m]" nil t 1) + (setq done (+ 1 done))) + (goto-char (point-max)) + (if (and (/= start end) + (not (bolp))) + (1+ done) + done))) + (- (buffer-size) (forward-line (buffer-size))))))) +@end ignore + @node what-line, narrow Exercise, save-restriction, Narrowing & Widening @comment node-name, next, previous, up @section @code{what-line} @@ -6389,13 +6765,17 @@ 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. The newer version uses a conditional to determine whether the -buffer has been narrowed, and rather than use @code{beginning-of-line} -to move point to the beginning of the current line, if need be, the -function uses @code{(forward-line 0)}.) - -The function as shown here has a documentation line and is -interactive, as you would expect. The next two lines use the +works. You will probably need to use @kbd{C-h f} +(@code{describe-function}). The newer version uses a conditional to +determine whether the buffer has been narrowed. + +(Also, it uses @code{line-number-at-pos}, which among other simple +expressions, such as @code{(goto-char (point-min))}, moves point to +the beginning of the current line with @code{(forward-line 0)} rather +than @code{beginning-of-line}.) + +The @code{what-line} function as shown here has a documentation line +and is interactive, as you would expect. The next two lines use the functions @code{save-restriction} and @code{widen}. The @code{save-restriction} special form notes whatever narrowing is in @@ -6434,15 +6814,14 @@ @end group @end smallexample -The @code{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 @samp{%d}, -@samp{%s}, or @samp{%c} to print arguments that follow the string. -@samp{%d} prints the argument as a decimal, so the message will say -something such as @samp{Line 243}. - -@need 1200 - +The @code{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 +@samp{%d} expression to print a following argument. @samp{%d} prints +the argument as a decimal, so the message will say something such as +@samp{Line 243}. + +@need 1200 The number that is printed in place of the @samp{%d} is computed by the last line of the function: @@ -6450,6 +6829,33 @@ (1+ (count-lines 1 (point))) @end smallexample +@ignore +GNU Emacs 22 + +(defun count-lines (start end) + "Return number of lines between START and END. +This is usually the number of newlines between them, +but can be one more if START is not equal to END +and the greater of them is not at the start of a line." + (save-excursion + (save-restriction + (narrow-to-region start end) + (goto-char (point-min)) + (if (eq selective-display t) + (save-match-data + (let ((done 0)) + (while (re-search-forward "[\n\C-m]" nil t 40) + (setq done (+ 40 done))) + (while (re-search-forward "[\n\C-m]" nil t 1) + (setq done (+ 1 done))) + (goto-char (point-max)) + (if (and (/= start end) + (not (bolp))) + (1+ done) + done))) + (- (buffer-size) (forward-line (buffer-size))))))) +@end ignore + @noindent What this does is count the lines from the first position of the buffer, indicated by the @code{1}, up to @code{(point)}, and then add @@ -6477,12 +6883,14 @@ @cindex Properties, mention of @code{buffer-substring-no-properties} (@code{buffer-substring} is a previously unmentioned function you will have to investigate yourself; or perhaps you will have to use -@code{buffer-substring-no-properties} @dots{}, yet another function -and one that introduces text properties, a feature otherwise not -discussed here. @xref{Text Properties, , Text Properties, elisp, The -GNU Emacs Lisp Reference Manual}. Additionally, do you really need -@code{goto-char} or @code{point-min}? Or can you write the function -without them?) +@code{buffer-substring-no-properties} or +@code{filter-buffer-substring} @dots{}, yet other functions. Text +properties are a feature otherwise not discussed here. @xref{Text +Properties, , Text Properties, elisp, The GNU Emacs Lisp Reference +Manual}. + +Additionally, do you really need @code{goto-char} or @code{point-min}? +Or can you write the function without them?) @node car cdr & cons, Cutting & Storing Text, Narrowing & Widening, Top @comment node-name, next, previous, up @@ -6499,13 +6907,13 @@ namely, @code{setcdr} and @code{nthcdr}. (@xref{copy-region-as-kill}.) @menu -* Strange Names:: An historical aside: why the strange names? -* car & cdr:: Functions for extracting part of a list. -* cons:: Constructing a list. -* nthcdr:: Calling @code{cdr} repeatedly. +* Strange Names:: +* car & cdr:: +* cons:: +* nthcdr:: * nth:: -* setcar:: Changing the first element of a list. -* setcdr:: Changing the rest of a list. +* setcar:: +* setcdr:: * cons Exercise:: @end menu @@ -6687,7 +7095,7 @@ @menu * Build a list:: -* length:: How to find the length of a list. +* length:: @end menu @node Build a list, length, cons, cons @@ -6798,7 +7206,7 @@ What you see, if you evaluate this, is the error message @smallexample -Wrong number of arguments: #<subr length>, 0 +Lisp error: (wrong-number-of-arguments length 0) @end smallexample @noindent @@ -6808,13 +7216,20 @@ length the function is measuring. (Note that @emph{one} list is @emph{one} argument, even if the list has many elements inside it.) -The part of the error message that says @samp{#<subr length>} is the -name of the function. This is written with a special notation, -@samp{#<subr}, that indicates that the function @code{length} is one -of the primitive functions written in C rather than in Emacs Lisp. -(@samp{subr} is an abbreviation for `subroutine'.) @xref{What Is a -Function, , What Is a Function?, elisp , The GNU Emacs Lisp Reference -Manual}, for more about subroutines. +The part of the error message that says @samp{length} is the name of +the function. + +@ignore +@code{length} is still a subroutine, but you need C-h f to discover that. + +In an earlier version: + This is written with a special notation, @samp{#<subr}, + that indicates that the function @code{length} is one of the primitive + functions written in C rather than in Emacs Lisp. (@samp{subr} is an + abbreviation for `subroutine'.) @xref{What Is a Function, , What Is a + Function?, elisp , The GNU Emacs Lisp Reference Manual}, for more + about subroutines. +@end ignore @node nthcdr, nth, cons, car cdr & cons @comment node-name, next, previous, up @@ -7016,9 +7431,14 @@ @noindent 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 @kbd{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.) +the expression and typing @kbd{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. Incidently, 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.) @need 1200 When we evaluate the variable @code{animals}, we see that it is bound to @@ -7156,12 +7576,12 @@ sources with `clip' and all occurrences of `killed' with `clipped'.) @menu -* 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. -* Digression into C:: Minor note on C programming language macros. -* defvar:: How to give a variable an initial value. -* copy-region-as-kill:: A definition for copying text. +* Storing Text:: +* zap-to-char:: +* kill-region:: +* copy-region-as-kill:: +* Digression into C:: +* defvar:: * cons & search-fwd Review:: * search Exercises:: @end menu @@ -7181,9 +7601,9 @@ @need 1200 @noindent -The function @code{cons} can be used to to create a new list from a -piece of text (an `atom', to use the jargon) and an existing list, -like this: +The function @code{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: @smallexample @group @@ -7238,27 +7658,27 @@ @section @code{zap-to-char} @findex zap-to-char -The @code{zap-to-char} function barely changed between GNU Emacs -version 19 and GNU Emacs version 21. However, @code{zap-to-char} -calls another function, @code{kill-region}, which enjoyed a major rewrite -on the way to version 21. +The @code{zap-to-char} function changed a little between GNU Emacs +version 19 and GNU Emacs version 22. However, @code{zap-to-char} +calls another function, @code{kill-region}, which enjoyed a major +rewrite. The @code{kill-region} function in Emacs 19 is complex, but does not use code that is important at this time. We will skip it. -The @code{kill-region} function in Emacs 21 is easier to read than the +The @code{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 @code{zap-to-char} function. @menu -* 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 @code{progn} special form. -* Summing up zap-to-char:: Using @code{point} and @code{search-forward}. +* Complete zap-to-char:: +* zap-to-char interactive:: +* zap-to-char body:: +* search-forward:: +* progn:: +* Summing up zap-to-char:: @end menu @node Complete zap-to-char, zap-to-char interactive, zap-to-char, zap-to-char @@ -7288,12 +7708,8 @@ manipulates text, and we will focus attention on them as well as on the deletion command. -@need 800 -Here is the complete text of the version 19 implementation of the function: - -@c v 19 -@smallexample -@group +@ignore +@c GNU Emacs version 19 (defun zap-to-char (arg char) ; version 19 implementation "Kill up to and including ARG'th occurrence of CHAR. Goes backward if ARG is negative; error if CHAR not found." @@ -7303,6 +7719,24 @@ (search-forward (char-to-string char) nil nil arg) (point)))) +@end ignore + +@need 1250 +Here is the complete text of the version 22 implementation of the function: + +@c GNU Emacs 22 +@smallexample +@group +(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)))) @end group @end smallexample @@ -7315,44 +7749,11 @@ this: @smallexample -(interactive "*p\ncZap to char: ") -@end smallexample - -The part within quotation marks, @code{"*p\ncZap to char:@: "}, specifies -three different things. First, and most simply, the asterisk, @samp{*}, -causes an error to be signaled if the buffer is read-only. This means that -if you try @code{zap-to-char} in a read-only buffer you will not be able to -remove text, and you will receive a message that says ``Buffer is -read-only''; your terminal may beep at you as well. - -The version 21 implementation does not have the asterisk, @samp{*}. The -function works the same as in version 19: in both cases, it cannot -remove text from a read-only buffer but the function does copy the -text that would have been removed to the kill ring. Also, in both -cases, you see an error message. - -However, the version 19 implementation copies text from a read-only -buffer only because of a mistake in the implementation of -@code{interactive}. According to the documentation for -@code{interactive}, the asterisk, @samp{*}, should prevent the -@code{zap-to-char} function from doing anything at all when the buffer -is read only. In version 19, the function should not copy the text to -the kill ring. It is a bug that it does. - -In version 21, the function is designed to copy the text to the kill -ring; moreover, @code{interactive} is implemented correctly. So the -asterisk, @samp{*}, had to be removed from the interactive -specification. However, if you insert an @samp{*} yourself and -evaluate the function definition, then the next time you run the -@code{zap-to-char} function on a read-only buffer, you will not copy -any text. - -That change aside, and a change to the documentation, the two versions -of the @code{zap-to-char} function are identical. - -Let us continue with the interactive specification. - -The second part of @code{"*p\ncZap to char:@: "} is the @samp{p}. +(interactive "p\ncZap to char: ") +@end smallexample + +The part within quotation marks, @code{"p\ncZap to char:@: "}, specifies +two different things. First, and most simply, is the @samp{p}. This part is separated from the next part by a newline, @samp{\n}. The @samp{p} means that the first argument to the function will be passed the value of a `processed prefix'. The prefix argument is @@ -7360,15 +7761,23 @@ the function is called interactively without a prefix, 1 is passed to this argument. -The third part of @code{"*p\ncZap to char:@: "} is @samp{cZap to char:@: -}. In this part, the lower case @samp{c} indicates that -@code{interactive} expects a prompt and that the argument will be a -character. The prompt follows the @samp{c} and is the string @samp{Zap -to char:@: } (with a space after the colon to make it look good). +The second part of @code{"p\ncZap to char:@: "} is +@samp{cZap to char:@: }. In this part, the lower case @samp{c} +indicates that @code{interactive} expects a prompt and that the +argument will be a character. The prompt follows the @samp{c} and is +the string @samp{Zap to char:@: } (with a space after the colon to +make it look good). What all this does is prepare the arguments to @code{zap-to-char} so they are of the right type, and give the user a prompt. +In a read-only buffer, the @code{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-ly. Also, the terminal may +beep or blink at you. + +Let us continue with the interactive specification. + @node zap-to-char body, search-forward, zap-to-char interactive, zap-to-char @comment node-name, next, previous, up @subsection The Body of @code{zap-to-char} @@ -7376,11 +7785,29 @@ The body of the @code{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: @smallexample -(kill-region (point) @dots{} -@end smallexample +(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))) +@end smallexample + +@noindent +@code{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 @code{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 @code{aref} +function extracts an element from an array. It is an array-specific +function that is not described in this document. @xref{Arrays, , +Arrays, elisp, The GNU Emacs Lisp Reference Manual}.) @noindent @code{(point)} is the current position of the cursor. @@ -7402,10 +7829,13 @@ zapped-for-character in @code{zap-to-char}. If the search is successful, @code{search-forward} leaves point immediately after the last character in the target string. (In @code{zap-to-char}, the -target string is just one character long.) If the search is -backwards, @code{search-forward} leaves point just before the first -character in the target. Also, @code{search-forward} returns @code{t} -for true. (Moving point is therefore a `side effect'.) +target string is just one character long. @code{zap-to-char} uses the +function @code{char-to-string} to ensure that the computer treats that +character as a string.) If the search is backwards, +@code{search-forward} leaves point just before the first character in +the target. Also, @code{search-forward} returns @code{t} for true. +(Moving point is therefore a `side effect'.) + @need 1250 In @code{zap-to-char}, the @code{search-forward} function looks like this: @@ -7501,9 +7931,12 @@ The second and last argument to @code{progn} is the expression @code{(point)}. This expression returns the value of point, which in this case will be the location to which it has been moved by -@code{search-forward}. This value is returned by the @code{progn} -expression and is passed to @code{kill-region} as @code{kill-region}'s -second argument. +@code{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 @code{point} is +returned by the @code{progn} expression and is passed to +@code{kill-region} as @code{kill-region}'s second argument. @node Summing up zap-to-char, , progn, zap-to-char @comment node-name, next, previous, up @@ -7520,14 +7953,14 @@ 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 @code{progn} special form is necessary because the @code{kill-region} -command takes two arguments; and it would fail if @code{search-forward} -and @code{point} expressions were written in sequence as two -additional arguments. The @code{progn} expression is a single argument -to @code{kill-region} and returns the one value that @code{kill-region} -needs for its second argument. - -@node kill-region, Digression into C, zap-to-char, Cutting & Storing Text +The @code{progn} special form is necessary because the +@code{kill-region} command takes two arguments; and it would fail if +@code{search-forward} and @code{point} expressions were written in +sequence as two additional arguments. The @code{progn} expression is +a single argument to @code{kill-region} and returns the one value that +@code{kill-region} needs for its second argument. + +@node kill-region, copy-region-as-kill, zap-to-char, Cutting & Storing Text @comment node-name, next, previous, up @section @code{kill-region} @findex kill-region @@ -7536,7 +7969,125 @@ This function clips text from a region and copies that text to the kill ring, from which it may be retrieved. -The Emacs 21 version of that function uses @code{condition-case} and +@ignore +GNU Emacs 22: + +(defun kill-region (beg end &optional yank-handler) + "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. +\(If you want to kill and then yank immediately, use \\[kill-ring-save].) + +If you want to append the killed region to the last killed text, +use \\[append-next-kill] before \\[kill-region]. + +If the buffer is read-only, Emacs will beep and refrain from deleting +the text, but put the text in the kill ring anyway. This means that +you can use the killing commands to copy text from a read-only buffer. + +This is the primitive for programs to kill text (as opposed to deleting it). +Supply two arguments, character positions indicating the stretch of text + to be killed. +Any command that calls this function is a \"kill command\". +If the previous command was also a kill command, +the text killed this time appends to the text killed last time +to make one entry in the kill ring. + +In Lisp code, optional third arg YANK-HANDLER, if non-nil, +specifies the yank-handler text property to be set on the killed +text. See `insert-for-yank'." + ;; Pass point first, then mark, because the order matters + ;; when calling kill-append. + (interactive (list (point) (mark))) + (unless (and beg end) + (error "The mark is not set now, so there is no region")) + (condition-case nil + (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) + (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) + ((buffer-read-only text-read-only) + ;; The code above failed because the buffer, or some of the characters + ;; in the region, are read-only. + ;; We should beep, in case the user just isn't aware of this. + ;; However, there's no harm in putting + ;; the region's text in the kill ring, anyway. + (copy-region-as-kill beg end) + ;; Set this-command now, so it will be set even if we get an error. + (setq this-command 'kill-region) + ;; This should barf, if appropriate, and give us the correct error. + (if kill-read-only-ok + (progn (message "Read only text copied to kill ring") nil) + ;; Signal an error if the buffer is read-only. + (barf-if-buffer-read-only) + ;; If the buffer isn't read-only, the text is. + (signal 'text-read-only (list (current-buffer))))))) + + +kfstorm 18-Jan-03): (defun kill-region (beg end &optional yank-handler) +rms 11-Mar-06): "Kill (\"cut\") text between point and mark. +rms 11-Mar-06): This deletes the text from the buffer and saves it in the kill ring. +jimb 21-Dec-91): The command \\[yank] can retrieve it from there. +eliz 16-Feb-01): \(If you want to kill and then yank immediately, use \\[kill-ring-save].) +eliz 16-Feb-01): +eliz 16-Feb-01): If you want to append the killed region to the last killed text, +eliz 16-Feb-01): use \\[append-next-kill] before \\[kill-region]. +eliz 16-Feb-01): +jimb 01-Feb-93): If the buffer is read-only, Emacs will beep and refrain from deleting +jimb 01-Feb-93): the text, but put the text in the kill ring anyway. This means that +jimb 01-Feb-93): you can use the killing commands to copy text from a read-only buffer. +jimb 21-Dec-91): +jimb 21-Dec-91): This is the primitive for programs to kill text (as opposed to deleting it). +lektu 07-Jun-04): Supply two arguments, character positions indicating the stretch of text +jimb 21-Dec-91): to be killed. +jimb 21-Dec-91): Any command that calls this function is a \"kill command\". +jimb 21-Dec-91): If the previous command was also a kill command, +jimb 21-Dec-91): the text killed this time appends to the text killed last time +kfstorm 18-Jan-03): to make one entry in the kill ring. +kfstorm 18-Jan-03): +uid68472 18-Feb-04): In Lisp code, optional third arg YANK-HANDLER, if non-nil, +uid68472 18-Feb-04): specifies the yank-handler text property to be set on the killed +uid68472 18-Feb-04): text. See `insert-for-yank'." +rms 21-May-06): ;; Pass point first, then mark, because the order matters +rms 21-May-06): ;; when calling kill-append. +rms 21-May-06): (interactive (list (point) (mark))) +rms 04-Sep-06): (unless (and beg end) +rms 04-Sep-06): (error "The mark is not set now, so there is no region")) +kwzh 19-Nov-97): (condition-case nil +rms 29-Mar-05): (let ((string (filter-buffer-substring beg end t))) +monnier 07-Dec-99): (when string ;STRING is nil if BEG = END +monnier 07-Dec-99): ;; Add that string to the kill ring, one way or another. +monnier 07-Dec-99): (if (eq last-command 'kill-region) +kfstorm 18-Jan-03): (kill-append string (< end beg) yank-handler) +kfstorm 18-Jan-03): (kill-new string nil yank-handler))) +kai 28-May-03): (when (or string (eq last-command 'kill-region)) +uid68472 18-Feb-04): (setq this-command 'kill-region)) +uid68472 18-Feb-04): nil) +kwzh 19-Nov-97): ((buffer-read-only text-read-only) +kwzh 19-Nov-97): ;; The code above failed because the buffer, or some of the characters +kwzh 19-Nov-97): ;; in the region, are read-only. +kwzh 19-Nov-97): ;; We should beep, in case the user just isn't aware of this. +kwzh 19-Nov-97): ;; However, there's no harm in putting +kwzh 19-Nov-97): ;; the region's text in the kill ring, anyway. +kwzh 19-Nov-97): (copy-region-as-kill beg end) +rms 19-May-98): ;; Set this-command now, so it will be set even if we get an error. +rms 19-May-98): (setq this-command 'kill-region) +rms 19-May-98): ;; This should barf, if appropriate, and give us the correct error. +kwzh 19-Nov-97): (if kill-read-only-ok +uid68472 18-Feb-04): (progn (message "Read only text copied to kill ring") nil) +kwzh 19-Nov-97): ;; Signal an error if the buffer is read-only. +kwzh 19-Nov-97): (barf-if-buffer-read-only) +kwzh 19-Nov-97): ;; If the buffer isn't read-only, the text is. +kwzh 19-Nov-97): (signal 'text-read-only (list (current-buffer))))))) + +@end ignore + +The Emacs 22 version of that function uses @code{condition-case} and @code{copy-region-as-kill}, both of which we will explain. @code{condition-case} is an important special form. @@ -7547,9 +8098,9 @@ contains the code that is called in the event of an error. @menu -* Complete kill-region:: The function definition. -* condition-case:: Dealing with a problem. -* delete-and-extract-region:: Doing the work. +* Complete kill-region:: +* condition-case:: +* Lisp macro:: @end menu @node Complete kill-region, condition-case, kill-region, kill-region @@ -7559,10 +8110,115 @@ @need 1200 We will go through the @code{condition-case} code in a moment. First, -let us look at the original definition of @code{kill-region}, with -comments added (the newer definition has an optional third argument -and is more complex): - +let us look at the definition of @code{kill-region}, with comments +added: + +@c GNU Emacs 22: +@smallexample +@group +(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. @dots{} " +@end group + +@group + ;; @bullet{} Since order matters, pass point first. + (interactive (list (point) (mark))) + ;; @bullet{} 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")) +@end group + +@group + ;; @bullet{} `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 +@end group + +@group + ;; @bullet{} The second argument to `condition-case' tells the + ;; Lisp interpreter what to do when all goes well. +@end group + +@group + ;; 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. +@end group + +@group + ;; 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. +@end group + +@group + ;; `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'. +@end group +@group + (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) +@end group +@group + ;; @minus{} `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) +@end group + +@group + ;; @bullet{} The third argument to `condition-case' tells the interpreter + ;; what to do with an error. +@end group +@group + ;; 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. +@end group +@group + ;; The first part of the third argument is the following: + ((buffer-read-only text-read-only) ;; the if-part + ;; then @dots{} + (copy-region-as-kill beg end) +@end group +@group + ;; 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. +@end group +@group + (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))))) +@end group +@end smallexample + +@ignore @c v 21 @smallexample @group @@ -7615,7 +8271,7 @@ @group ;; The third argument has a conditions part and a body part. ;; If the conditions are met (in this case, - ;; if text or buffer is read-only) + ;; if text or buffer are read-only) ;; then the body is executed. @end group @group @@ -7632,8 +8288,9 @@ (signal 'text-read-only (list (current-buffer))))))) @end group @end smallexample - -@node condition-case, delete-and-extract-region, Complete kill-region, kill-region +@end ignore + +@node condition-case, Lisp macro, Complete kill-region, kill-region @comment node-name, next, previous, up @subsection @code{condition-case} @findex condition-case @@ -7707,62 +8364,36 @@ @end group @end smallexample -@node delete-and-extract-region, , condition-case, kill-region -@comment node-name, next, previous, up -@subsection @code{delete-and-extract-region} -@findex delete-and-extract-region - -A @code{condition-case} expression has two parts, a part that is -evaluated in the expectation that all will go well, but which may -generate an error; and a part that is evaluated when there is an -error. - -First, let us look at the code in @code{kill-region} that is run in -the expectation that all goes well. This is the core of the function. -The code looks like this: - -@smallexample -@group -(let ((string (delete-and-extract-region beg end))) - (when string - (if (eq last-command 'kill-region) - (kill-append string (< end beg)) - (kill-new string))) - (setq this-command 'kill-region)) -@end group -@end smallexample - -It looks complicated because we have the new functions -@code{delete-and-extract-region}, @code{kill-append}, and -@code{kill-new} as well as the new variables, -@code{last-command} and @code{this-command}. - -The @code{delete-and-extract-region} function is straightforward. It -is a built-in function that deletes the text in a region (a side -effect) and also returns that text. This is the function that -actually removes the text. (And if it cannot do that, it signals the -error.) - -In this @code{let} expression, the text that -@code{delete-and-extract-region} returns is placed in the local -variable called @samp{string}. This is the text that is removed from -the buffer. (To be more precise, the variable is set to point to the -address of the extracted text; to say it is `placed in' the variable -is simply a shorthand.) - -If the variable @samp{string} does point to text, that text is added -to the kill ring. The variable will have a @code{nil} value if no -text was removed. - -The code uses @code{when} to determine whether the variable -@samp{string} points to text. A @code{when} statement is simply a -programmers' convenience. A @code{when} statement is an @code{if} -statement without the possibility of an else clause. In your mind, you -can replace @code{when} with @code{if} and understand what goes on. -That is what the Lisp interpreter does. - + +@ignore +2006 Oct 24 +In Emacs 22, +copy-region-as-kill is short, 12 lines, and uses +filter-buffer-substring, which is longer, 39 lines +and has delete-and-extract-region in it. +delete-and-extract-region is written in C. + +see Initializing a Variable with @code{defvar} +this is line 8054 +Initializing a Variable with @code{defvar} includes line 8350 +@end ignore + +@node Lisp macro, , condition-case, kill-region +@comment node-name, next, previous, up +@subsection Lisp macro @cindex Macro, lisp @cindex Lisp macro + +The part of the @code{condition-case} expression that is evaluated in +the expectation that all goes well has a @code{when}. The code uses +@code{when} to determine whether the @code{string} variable points to +text that exists. + +A @code{when} expression is simply a programmers' convenience. It is +an @code{if} without the possibility of an else clause. In your mind, +you can replace @code{when} with @code{if} and understand what goes +on. That is what the Lisp interpreter does. + Technically speaking, @code{when} is a Lisp macro. A Lisp @dfn{macro} enables you to define new control constructs and other language features. It tells the interpreter how to compute another Lisp @@ -7770,8 +8401,12 @@ `other expression' is an @code{if} expression. For more about Lisp macros, see @ref{Macros, , Macros, elisp, The GNU Emacs Lisp Reference Manual}. The C programming language also provides macros. These are -different, but also useful. We will briefly look at C macros in +different, but also useful. + +@ignore +We will briefly look at C macros in @ref{Digression into C}. +@end ignore @need 1200 If the string has content, then another conditional expression is @@ -7780,14 +8415,18 @@ @smallexample @group (if (eq last-command 'kill-region) - (kill-append string (< end beg)) - (kill-new string))) + (kill-append string (< end beg) yank-handler) + (kill-new string nil yank-handler)) @end group @end smallexample The then-part is evaluated if the previous command was another call to @code{kill-region}; if not, the else-part is evaluated. +@code{yank-handler} is an optional argument to @code{kill-region} that +tells the @code{kill-append} and @code{kill-new} functions how deal +with properties added to the text, such as `bold' or `italics'. + @code{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 @code{last-command} to the previous command. @@ -7797,12 +8436,725 @@ whether the previous command was @code{kill-region}. If it was, @smallexample -(kill-append string (< end beg)) +(kill-append string (< end beg) yank-handler) @end smallexample @noindent concatenates a copy of the newly clipped text to the just previously -clipped text in the kill ring. (If the @w{@code{(< end beg))}} +clipped text in the kill ring. + +@node copy-region-as-kill, Digression into C, kill-region, Cutting & Storing Text +@comment node-name, next, previous, up +@section @code{copy-region-as-kill} +@findex copy-region-as-kill +@findex nthcdr + +The @code{copy-region-as-kill} function copies a region of text from a +buffer and (via either @code{kill-append} or @code{kill-new}) saves it +in the @code{kill-ring}. + +If you call @code{copy-region-as-kill} immediately after a +@code{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 @code{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:: +@end menu + +@node Complete copy-region-as-kill, copy-region-as-kill body, copy-region-as-kill, copy-region-as-kill +@ifnottex +@unnumberedsubsec The complete @code{copy-region-as-kill} function definition +@end ifnottex + +@need 1200 +Here is the complete text of the version 22 @code{copy-region-as-kill} +function: + +@smallexample +@group +(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") +@end group +@group + (if (eq last-command 'kill-region) + (kill-append (filter-buffer-substring beg end) (< end beg)) + (kill-new (filter-buffer-substring beg end))) +@end group +@group + (if transient-mark-mode + (setq deactivate-mark t)) + nil) +@end group +@end smallexample + +@need 800 +As usual, this function can be divided into its component parts: + +@smallexample +@group +(defun copy-region-as-kill (@var{argument-list}) + "@var{documentation}@dots{}" + (interactive "r") + @var{body}@dots{}) +@end group +@end smallexample + +The arguments are @code{beg} and @code{end} and the function is +interactive with @code{"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 @code{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 +@code{interprogram-cut-function} function is @code{x-select-text}, +which works with the windowing system's equivalent of the Emacs kill +ring. + +The body of the @code{copy-region-as-kill} function starts with an +@code{if} clause. What this clause does is distinguish between two +different situations: whether or not this command is executed +immediately after a previous @code{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 @code{copy-region-as-kill} merits discussion in detail. + +@node copy-region-as-kill body, , Complete copy-region-as-kill, copy-region-as-kill +@comment node-name, next, previous, up +@subsection The Body of @code{copy-region-as-kill} + +The @code{copy-region-as-kill} function works in much the same way as +the @code{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 @code{kill-region}, the @code{copy-region-as-kill} function makes +use of the @code{last-command} variable that keeps track of the +previous Emacs command. + +@menu +* last-command & this-command:: +* kill-append function:: +* kill-new function:: +@end menu + +@node last-command & this-command, kill-append function, copy-region-as-kill body, copy-region-as-kill body +@ifnottex +@unnumberedsubsubsec @code{last-command} and @code{this-command} +@end ifnottex + +Normally, whenever a function is executed, Emacs sets the value of +@code{this-command} to the function being executed (which in this case +would be @code{copy-region-as-kill}). At the same time, Emacs sets +the value of @code{last-command} to the previous value of +@code{this-command}. + +In the first part of the body of the @code{copy-region-as-kill} +function, an @code{if} expression determines whether the value of +@code{last-command} is @code{kill-region}. If so, the then-part of +the @code{if} expression is evaluated; it uses the @code{kill-append} +function to concatenate the text copied at this call to the function +with the text already in the first element (the @sc{car}) of the kill +ring. On the other hand, if the value of @code{last-command} is not +@code{kill-region}, then the @code{copy-region-as-kill} function +attaches a new element to the kill ring using the @code{kill-new} +function. + +@need 1250 +The @code{if} expression reads as follows; it uses @code{eq}, which is +a function we have not yet seen: + +@smallexample +@group + (if (eq last-command 'kill-region) + ;; @r{then-part} + (kill-append (filter-buffer-substring beg end) (< end beg)) + ;; @r{else-part} + (kill-new (filter-buffer-substring beg end))) +@end group +@end smallexample + +@findex filter-buffer-substring +(The @code{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 @code{buffer-substring} function, which came before text +properties were implemented.) + +@findex eq @r{(example of use)} +@noindent +The @code{eq} function tests whether its first argument is the same Lisp +object as its second argument. The @code{eq} function is similar to the +@code{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. +@code{equal} determines whether the structure and contents of two +expressions are the same. + +If the previous command was @code{kill-region}, then the Emacs Lisp +interpreter calls the @code{kill-append} function + +@node kill-append function, kill-new function, last-command & this-command, copy-region-as-kill body +@unnumberedsubsubsec The @code{kill-append} function +@findex kill-append + +@need 800 +The @code{kill-append} function looks like this: + +@c in GNU Emacs 22 +@smallexample +@group +(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. +@dots{} " + (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))) +@end group +@end smallexample + +@ignore +was: +(defun kill-append (string before-p) + "Append STRING to the end of the latest kill in the kill ring. +If BEFORE-P is non-nil, prepend STRING to the kill. +If `interprogram-cut-function' is set, pass the resulting kill to +it." + (kill-new (if before-p + (concat string (car kill-ring)) + (concat (car kill-ring) string)) + t)) +@end ignore + +@noindent +The @code{kill-append} function is fairly straightforward. It uses +the @code{kill-new} function, which we will discuss in more detail in +a moment. + +(Also, the function provides an optional argument called +@code{yank-handler}; when invoked, this argument tells the function +how to deal with properties added to the text, such as `bold' or +`italics'.) + +@c !!! bug in GNU Emacs 22 version of kill-append ? +It has a @code{let*} function to set the value of the first element of +the kill ring to @code{cur}. (I do not know why the function does not +use @code{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 +@code{kill-new}. It uses @code{concat} to concatenate the new text to +the @sc{car} of the kill ring. Whether it prepends or appends the +text depends on the results of an @code{if} expression: + +@smallexample +@group +(if before-p ; @r{if-part} + (concat string cur) ; @r{then-part} + (concat cur string)) ; @r{else-part} +@end group +@end smallexample + +@noindent +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 @code{if} expression depends on the predicate @code{before-p} to +decide whether the newly saved text should be put before or after the +previously saved text. + +The symbol @code{before-p} is the name of one of the arguments to +@code{kill-append}. When the @code{kill-append} function is +evaluated, it is bound to the value returned by evaluating the actual +argument. In this case, this is the expression @code{(< 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 +@code{end} is less than the value of the variable @code{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, @code{(< 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 @code{end} is greater than the value of the variable +@code{beg}, the text will be appended after the previous text. + +@need 800 +When the newly saved text will be prepended, then the string with the new +text will be concatenated before the old text: + +@smallexample +(concat string cur) +@end smallexample + +@need 1200 +@noindent +But if the text will be appended, it will be concatenated +after the old text: + +@smallexample +(concat cur string)) +@end smallexample + +To understand how this works, we first need to review the +@code{concat} function. The @code{concat} function links together or +unites two strings of text. The result is a string. For example: + +@smallexample +@group +(concat "abc" "def") + @result{} "abcdef" +@end group + +@group +(concat "new " + (car '("first element" "second element"))) + @result{} "new first element" + +(concat (car + '("first element" "second element")) " modified") + @result{} "first element modified" +@end group +@end smallexample + +We can now make sense of @code{kill-append}: it modifies the contents +of the kill ring. The kill ring is a list, each element of which is +saved text. The @code{kill-append} function uses the @code{kill-new} +function which in turn uses the @code{setcar} function. + +@node kill-new function, , kill-append function, copy-region-as-kill body +@unnumberedsubsubsec The @code{kill-new} function +@findex kill-new + +@c in GNU Emacs 22, additional documentation to kill-new: +@ignore +Optional third arguments YANK-HANDLER controls how the STRING is later +inserted into a buffer; see `insert-for-yank' for details. +When a yank handler is specified, STRING must be non-empty (the yank +handler, if non-nil, is stored as a `yank-handler' text property on STRING). + +When the yank handler has a non-nil PARAM element, the original STRING +argument is not used by `insert-for-yank'. However, since Lisp code +may access and use elements from the kill ring directly, the STRING +argument should still be a \"useful\" string for such uses." +@end ignore +@need 1200 +The @code{kill-new} function looks like this: + +@smallexample +@group +(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. +@dots{}" +@end group +@group + (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")))) +@end group +@group + (if (fboundp 'menu-bar-update-yank-menu) + (menu-bar-update-yank-menu string (and replace (car kill-ring)))) +@end group +@group + (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))) +@end group +@group + (setq kill-ring-yank-pointer kill-ring) + (if interprogram-cut-function + (funcall interprogram-cut-function string (not replace)))) +@end group +@end smallexample +@ignore +was: +(defun kill-new (string &optional replace) + "Make STRING the latest kill in the kill ring. +Set the 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." + (and (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) + (setq kill-ring (cons 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)))) +@end ignore + +@noindent +(Notice that the function is not interactive.) + +As usual, we can look at this function in parts. + +The function definition has an optional @code{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. + +@need 1200 +The first line of the documentation makes sense: + +@smallexample +Make STRING the latest kill in the kill ring. +@end smallexample + +@noindent +Let's skip over the rest of the documentation for the moment. + +Also, let's skip over the initial @code{if} expression and those lines +of code involving @code{menu-bar-update-yank-menu}. We will explain +them below. + +@need 1200 +The critical lines are these: + +@smallexample +@group + (if (and replace kill-ring) + ;; @r{then} + (setcar kill-ring string) +@end group +@group + ;; @r{else} + (push string kill-ring) +@end group +@group + (setq kill-ring (cons string kill-ring)) + (if (> (length kill-ring) kill-ring-max) + ;; @r{avoid overly long kill ring} + (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) +@end group +@group + (setq kill-ring-yank-pointer kill-ring) + (if interprogram-cut-function + (funcall interprogram-cut-function string (not replace)))) +@end group +@end smallexample + +The conditional test is @w{@code{(and replace kill-ring)}}. +This will be true when two conditions are met: the kill ring has +something in it, and the @code{replace} variable is true. + +@need 1250 +When the @code{kill-append} function sets @code{replace} to be true +and when the kill ring has at least one item in it, the @code{setcar} +expression is executed: + +@smallexample +(setcar kill-ring string) +@end smallexample + +The @code{setcar} function actually changes the first element of the +@code{kill-ring} list to the value of @code{string}. It replaces the +first element. + +@need 1250 +On the other hand, if the kill ring is empty, or replace is false, the +else-part of the condition is executed: + +@smallexample +(push string kill-ring) +@end smallexample + +@noindent +@need 1250 +@code{push} puts its first argument onto the second. It is the same +as the older + +@smallexample +(setq kill-ring (cons string kill-ring)) +@end smallexample + +@noindent +@need 1250 +or the newer + +@smallexample +(add-to-list kill-ring string) +@end smallexample + +@noindent +When it is false, the expression first constructs a new version of the +kill ring by prepending @code{string} to the existing kill ring as a +new element (that is what the @code{push} does). Then it executes a +second @code{if} clause. This second @code{if} clause keeps the kill +ring from growing too long. + +Let's look at these two expressions in order. + +The @code{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. + +@need 800 +First, + +@smallexample +(setq example-list '("here is a clause" "another clause")) +@end smallexample + +@need 1200 +@noindent +After evaluating this expression with @kbd{C-x C-e}, you can evaluate +@code{example-list} and see what it returns: + +@smallexample +@group +example-list + @result{} ("here is a clause" "another clause") +@end group +@end smallexample + +@need 1200 +@noindent +Now, we can add a new element on to this list by evaluating the +following expression: +@findex push, @r{example} + +@smallexample +(push "a third clause" example-list) +@end smallexample + +@need 800 +@noindent +When we evaluate @code{example-list}, we find its value is: + +@smallexample +@group +example-list + @result{} ("a third clause" "here is a clause" "another clause") +@end group +@end smallexample + +@noindent +Thus, the third clause is added to the list by @code{push}. + +@need 1200 +Now for the second part of the @code{if} clause. This expression +keeps the kill ring from growing too long. It looks like this: + +@smallexample +@group +(if (> (length kill-ring) kill-ring-max) + (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) +@end group +@end smallexample + +The code checks whether the length of the kill ring is greater than +the maximum permitted length. This is the value of +@code{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 @code{nil}. It does this by using two functions, +@code{nthcdr} and @code{setcdr}. + +We looked at @code{setcdr} earlier (@pxref{setcdr, , @code{setcdr}}). +It sets the @sc{cdr} of a list, just as @code{setcar} sets the +@sc{car} of a list. In this case, however, @code{setcdr} will not be +setting the @sc{cdr} of the whole kill ring; the @code{nthcdr} +function is used to cause it to set the @sc{cdr} of the next to last +element of the kill ring---this means that since the @sc{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. + +@findex nthcdr, @r{example} +The @code{nthcdr} function works by repeatedly taking the @sc{cdr} of a +list---it takes the @sc{cdr} of the @sc{cdr} of the @sc{cdr} +@dots{} It does this @var{N} times and returns the results. +(@xref{nthcdr, , @code{nthcdr}}.) + +@findex setcdr, @r{example} +Thus, if we had a four element list that was supposed to be three +elements long, we could set the @sc{cdr} of the next to last element +to @code{nil}, and thereby shorten the list. (If you sent the last +element to some other value than @code{nil}, which you could do, then +you would not have shortened the list. @xref{setcdr, , +@code{setcdr}}.) + +You can see shortening by evaluating the following three expressions +in turn. First set the value of @code{trees} to @code{(maple oak pine +birch)}, then set the @sc{cdr} of its second @sc{cdr} to @code{nil} +and then find the value of @code{trees}: + +@smallexample +@group +(setq trees '(maple oak pine birch)) + @result{} (maple oak pine birch) +@end group + +@group +(setcdr (nthcdr 2 trees) nil) + @result{} nil + +trees + @result{} (maple oak pine) +@end group +@end smallexample + +@noindent +(The value returned by the @code{setcdr} expression is @code{nil} since +that is what the @sc{cdr} is set to.) + +To repeat, in @code{kill-new}, the @code{nthcdr} function takes the +@sc{cdr} a number of times that is one less than the maximum permitted +size of the kill ring and @code{setcdr} sets the @sc{cdr} of that +element (which will be the rest of the elements in the kill ring) to +@code{nil}. This prevents the kill ring from growing too long. + +@need 800 +The next to last expression in the @code{kill-new} function is + +@smallexample +(setq kill-ring-yank-pointer kill-ring) +@end smallexample + +The @code{kill-ring-yank-pointer} is a global variable that is set to be +the @code{kill-ring}. + +Even though the @code{kill-ring-yank-pointer} is called a +@samp{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 @code{yank} and +@code{yank-pop} (@pxref{Yanking, , Yanking Text Back}). + +@need 1200 +Now, to return to an early expression in the body of the function: + +@smallexample +@group + (if (fboundp 'menu-bar-update-yank-menu) + (menu-bar-update-yank-menu string (and replace (car kill-ring)))) +@end group +@end smallexample + +@noindent +It starts with an @code{if} expression + +In this case, the expression tests first to see whether +@code{menu-bar-update-yank-menu} exists as a function, and if so, +calls it. The @code{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 (@pxref{Making +Errors, , Generate an Error Message}). + +@noindent +The then-part contains an expression whose first element is the +function @code{and}. + +@findex and +The @code{and} special form evaluates each of its arguments until one +of the arguments returns a value of @code{nil}, in which case the +@code{and} expression returns @code{nil}; however, if none of the +arguments returns a value of @code{nil}, the value resulting from +evaluating the last argument is returned. (Since such a value is not +@code{nil}, it is considered true in Emacs Lisp.) In other words, an +@code{and} expression returns a true value only if all its arguments +are true. (@xref{Second Buffer Related Review}.) + +The expression determines whether the second argument to +@code{menu-bar-update-yank-menu} is true or not. +@ignore + ;; If we're supposed to be extending an existing string, and that + ;; string really is at the front of the menu, then update it in place. +@end ignore + +@code{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 @code{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 @code{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. + +@need 1200 +The expression looks like this: + +@smallexample +@group + (if interprogram-cut-function + (funcall interprogram-cut-function string (not replace)))) +@end group +@end smallexample + +If an @code{interprogram-cut-function} exists, then Emacs executes +@code{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 @code{if} expression could be replaced by an @code{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'. + + +@ignore +@c is this true in Emacs 22? Does not seems to be + + (If the @w{@code{(< end beg))}} expression is true, @code{kill-append} prepends the string to the just previously clipped text. For a detailed discussion, see @ref{kill-append function, , The @code{kill-append} function}.) @@ -7817,29 +9169,46 @@ then the @code{kill-new} function is called, which adds the text to the kill ring as the latest item, and sets the @code{kill-ring-yank-pointer} variable to point to it. - -@node Digression into C, defvar, kill-region, Cutting & Storing Text +@end ignore +@ignore + +@c Evidently, changed for Emacs 22. The zap-to-char command does not +@c use the delete-and-extract-region function + +2006 Oct 26, the Digression into C is now OK but should come after +copy-region-as-kill and filter-buffer-substring + +2006 Oct 24 +In Emacs 22, +copy-region-as-kill is short, 12 lines, and uses +filter-buffer-substring, which is longer, 39 lines +and has delete-and-extract-region in it. +delete-and-extract-region is written in C. + +see Initializing a Variable with @code{defvar} +@end ignore + +@node Digression into C, defvar, copy-region-as-kill, Cutting & Storing Text @comment node-name, next, previous, up @section Digression into C @findex delete-and-extract-region @cindex C, a digression into @cindex Digression into C -The @code{zap-to-char} command uses the -@code{delete-and-extract-region} function, which in turn uses two -other functions, @code{copy-region-as-kill} and -@code{del_range_1}. The @code{copy-region-as-kill} function will be -described in a following section; it puts a copy of the region in the -kill ring so it can be yanked back. (@xref{copy-region-as-kill, , -@code{copy-region-as-kill}}.) - -The @code{delete-and-extract-region} function removes the contents of -a region and you cannot get them back. - -Unlike the other code discussed here, @code{delete-and-extract-region} -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. +The @code{copy-region-as-kill} function (@pxref{copy-region-as-kill, , +@code{copy-region-as-kill}}) uses the @code{filter-buffer-substring} +function, which in turn uses the @code{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 +@code{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. + +@c GNU Emacs 22 in /usr/local/src/emacs/src/editfns.c +@c the DEFUN for buffer-substring-no-properties @need 1500 Like many of the other Emacs primitives, @@ -7847,17 +9216,24 @@ macro, a macro being a template for code. The complete macro looks like this: -@c /usr/local/src/emacs/src/editfns.c -@smallexample -@group -DEFUN ("delete-and-extract-region", Fdelete_and_extract_region, - Sdelete_and_extract_region, 2, 2, 0, - "Delete the text between START and END and return it.") - (start, end) +@smallexample +@group +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); - return del_range_1 (XINT (start), XINT (end), 1, 1); + b = XINT (start); + e = XINT (end); + + return make_buffer_string (b, e, 0); @} @end group @end smallexample @@ -7865,8 +9241,11 @@ Without going into the details of the macro writing process, let me point out that this macro starts with the word @code{DEFUN}. The word @code{DEFUN} was chosen since the code serves the same purpose as -@code{defun} does in Lisp. The word @code{DEFUN} is followed by seven -parts inside of parentheses: +@code{defun} does in Lisp. (The @code{DEFUN} C macro is defined in +@file{emacs/src/lisp.h}.) + +The word @code{DEFUN} is followed by seven parts inside of +parentheses: @itemize @bullet @item @@ -7924,26 +9303,27 @@ 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 @code{delete-and-extract-region} the `body' -consists of the following two lines: +consists of the following four lines: @smallexample @group validate_region (&start, &end); +if (XINT (start) == XINT (end)) + return build_string (""); return del_range_1 (XINT (start), XINT (end), 1, 1); @end group @end smallexample -The first function, @code{validate_region} checks whether the values +The @code{validate_region} function checks whether the values passed as the beginning and end of the region are the proper type and -are within range. The second function, @code{del_range_1}, actually -deletes the text. - -@code{del_range_1} 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 -@code{del_range}. These are @w{@code{XINT (start)}} and @w{@code{XINT -(end)}}. +are within range. If the beginning and end positions are the same, +then return and empty string. + +The @code{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 @code{del_range}. These are @w{@code{XINT (start)}} and +@w{@code{XINT (end)}}. As far as the C language is concerned, @code{start} and @code{end} are two integers that mark the beginning and end of the region to be @@ -7954,11 +9334,10 @@ 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 and a fourth bit is used for handling the computer's -memory; the remaining bits are used as `content'. +information; the remaining bits are used as `content'. @samp{XINT} is a C macro that extracts the relevant number from the -longer collection of bits; the four other bits are discarded. +longer collection of bits; the three other bits are discarded. @need 800 The command in @code{delete-and-extract-region} looks like this: @@ -7975,15 +9354,26 @@ simple; but hidden underneath is a great deal of complexity to make it all work. -@node defvar, copy-region-as-kill, Digression into C, Cutting & Storing Text +@node defvar, cons & search-fwd Review, Digression into C, Cutting & Storing Text @comment node-name, next, previous, up @section Initializing a Variable with @code{defvar} @findex defvar @cindex Initializing a variable @cindex Variable initialization -Unlike the @code{delete-and-extract-region} function, the -@code{copy-region-as-kill} function is written in Emacs Lisp. Two +@ignore +2006 Oct 24 +In Emacs 22, +copy-region-as-kill is short, 12 lines, and uses +filter-buffer-substring, which is longer, 39 lines +and has delete-and-extract-region in it. +delete-and-extract-region is written in C. + +see Initializing a Variable with @code{defvar} + +@end ignore + +The @code{copy-region-as-kill} function is written in Emacs Lisp. Two functions within it, @code{kill-append} and @code{kill-new}, copy a region in a buffer and save it in a variable called the @code{kill-ring}. This section describes how the @code{kill-ring} @@ -8011,7 +9401,7 @@ @menu * See variable current value:: -* defvar and asterisk:: An old-time convention. +* defvar and asterisk:: @end menu @node See variable current value, defvar and asterisk, defvar, defvar @@ -8111,620 +9501,8 @@ (@xref{Examining, , Examining and Setting Variables, emacs, The GNU Emacs Manual}.) -@node copy-region-as-kill, cons & search-fwd Review, defvar, Cutting & Storing Text -@comment node-name, next, previous, up -@section @code{copy-region-as-kill} -@findex copy-region-as-kill -@findex nthcdr - -The @code{copy-region-as-kill} function copies a region of text from a -buffer and (via either @code{kill-append} or @code{kill-new}) saves it -in the @code{kill-ring}. - -If you call @code{copy-region-as-kill} immediately after a -@code{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 @code{copy-region-as-kill}, -the function copies the text into a separate entry in the kill ring. - -@menu -* Complete copy-region-as-kill:: The complete function definition. -* copy-region-as-kill body:: The body of @code{copy-region-as-kill}. -@end menu - -@node Complete copy-region-as-kill, copy-region-as-kill body, copy-region-as-kill, copy-region-as-kill -@ifnottex -@unnumberedsubsec The complete @code{copy-region-as-kill} function definition -@end ifnottex - -@need 1200 -Here is the complete text of the version 21 @code{copy-region-as-kill} -function: - -@c !!! for no text properties, use buffer-substring-no-properties - -@smallexample -@group -(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") -@end group -@group - (if (eq last-command 'kill-region) - (kill-append (buffer-substring beg end) (< end beg)) - (kill-new (buffer-substring beg end))) -@end group -@group - (if transient-mark-mode - (setq deactivate-mark t)) - nil) -@end group -@end smallexample - -@need 800 -As usual, this function can be divided into its component parts: - -@smallexample -@group -(defun copy-region-as-kill (@var{argument-list}) - "@var{documentation}@dots{}" - (interactive "r") - @var{body}@dots{}) -@end group -@end smallexample - -The arguments are @code{beg} and @code{end} and the function is -interactive with @code{"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 its usual meaning. The -`Transient Mark' and @code{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 -@code{interprogram-cut-function} function is @code{x-select-text}, -which works with the windowing system's equivalent of the Emacs kill -ring. - -The body of the @code{copy-region-as-kill} function starts with an -@code{if} clause. What this clause does is distinguish between two -different situations: whether or not this command is executed -immediately after a previous @code{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 @code{copy-region-as-kill} merits discussion in detail. - -@node copy-region-as-kill body, , Complete copy-region-as-kill, copy-region-as-kill -@comment node-name, next, previous, up -@subsection The Body of @code{copy-region-as-kill} - -The @code{copy-region-as-kill} function works in much the same way as -the @code{kill-region} function (@pxref{kill-region, -,@code{kill-region}}). 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 @code{kill-region}, the @code{copy-region-as-kill} function makes -use of the @code{last-command} variable that keeps track of the -previous Emacs command. - -@menu -* last-command & this-command:: -* kill-append function:: -* kill-new function:: -@end menu - -@node last-command & this-command, kill-append function, copy-region-as-kill body, copy-region-as-kill body -@ifnottex -@unnumberedsubsubsec @code{last-command} and @code{this-command} -@end ifnottex - -Normally, whenever a function is executed, Emacs sets the value of -@code{this-command} to the function being executed (which in this case -would be @code{copy-region-as-kill}). At the same time, Emacs sets -the value of @code{last-command} to the previous value of -@code{this-command}. - -In the first part of the body of the @code{copy-region-as-kill} -function, an @code{if} expression determines whether the value of -@code{last-command} is @code{kill-region}. If so, the then-part of -the @code{if} expression is evaluated; it uses the @code{kill-append} -function to concatenate the text copied at this call to the function -with the text already in the first element (the @sc{car}) of the kill -ring. On the other hand, if the value of @code{last-command} is not -@code{kill-region}, then the @code{copy-region-as-kill} function -attaches a new element to the kill ring using the @code{kill-new} -function. - -@need 1250 -The @code{if} expression reads as follows; it uses @code{eq}, which is -a function we have not yet seen: - -@smallexample -@group - (if (eq last-command 'kill-region) - ;; @r{then-part} - (kill-append (buffer-substring beg end) (< end beg)) - ;; @r{else-part} - (kill-new (buffer-substring beg end))) -@end group -@end smallexample - -@findex eq @r{(example of use)} -@noindent -The @code{eq} function tests whether its first argument is the same Lisp -object as its second argument. The @code{eq} function is similar to the -@code{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. -@code{equal} determines whether the structure and contents of two -expressions are the same. - -If the previous command was @code{kill-region}, then the Emacs Lisp -interpreter calls the @code{kill-append} function - -@node kill-append function, kill-new function, last-command & this-command, copy-region-as-kill body -@unnumberedsubsubsec The @code{kill-append} function -@findex kill-append - -@need 800 -The @code{kill-append} function looks like this: - -@smallexample -@group -(defun kill-append (string before-p) - "Append STRING to the end of the latest kill in the kill ring. -If BEFORE-P is non-nil, prepend STRING to the kill. -If `interprogram-cut-function' is set, pass the resulting kill to -it." - (kill-new (if before-p - (concat string (car kill-ring)) - (concat (car kill-ring) string)) - t)) -@end group -@end smallexample - -@noindent -The @code{kill-append} function is fairly straightforward. It uses -the @code{kill-new} function, which we will discuss in more detail in -a moment. - -First, let us look at the conditional that is one of the two arguments -to @code{kill-new}. It uses @code{concat} to concatenate the new text -to the @sc{car} of the kill ring. Whether it prepends or appends the -text depends on the results of an @code{if} expression: - -@smallexample -@group -(if before-p ; @r{if-part} - (concat string (car kill-ring)) ; @r{then-part} - (concat (car kill-ring) string)) ; @r{else-part} -@end group -@end smallexample - -@noindent -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 @code{if} expression depends on the predicate @code{before-p} to -decide whether the newly saved text should be put before or after the -previously saved text. - -The symbol @code{before-p} is the name of one of the arguments to -@code{kill-append}. When the @code{kill-append} function is -evaluated, it is bound to the value returned by evaluating the actual -argument. In this case, this is the expression @code{(< 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 -@code{end} is less than the value of the variable @code{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, @code{(< 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 @code{end} is greater than the value of the variable -@code{beg}, the text will be appended after the previous text. - -@need 800 -When the newly saved text will be prepended, then the string with the new -text will be concatenated before the old text: - -@smallexample -(concat string (car kill-ring)) -@end smallexample - -@need 1200 -@noindent -But if the text will be appended, it will be concatenated -after the old text: - -@smallexample -(concat (car kill-ring) string)) -@end smallexample - -To understand how this works, we first need to review the -@code{concat} function. The @code{concat} function links together or -unites two strings of text. The result is a string. For example: - -@smallexample -@group -(concat "abc" "def") - @result{} "abcdef" -@end group - -@group -(concat "new " - (car '("first element" "second element"))) - @result{} "new first element" - -(concat (car - '("first element" "second element")) " modified") - @result{} "first element modified" -@end group -@end smallexample - -We can now make sense of @code{kill-append}: it modifies the contents -of the kill ring. The kill ring is a list, each element of which is -saved text. The @code{kill-append} function uses the @code{kill-new} -function which in turn uses the @code{setcar} function. - -@node kill-new function, , kill-append function, copy-region-as-kill body -@unnumberedsubsubsec The @code{kill-new} function -@findex kill-new - -@need 1200 -The @code{kill-new} function looks like this: - -@smallexample -@group -(defun kill-new (string &optional replace) - "Make STRING the latest kill in the kill ring. -Set the 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." -@end group -@group - (and (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) -@end group -@group - (if (and replace kill-ring) - (setcar kill-ring string) - (setq kill-ring (cons string kill-ring)) - (if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) -@end group -@group - (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -@end group -@end smallexample - -As usual, we can look at this function in parts. - -@need 1200 -The first line of the documentation makes sense: - -@smallexample -Make STRING the latest kill in the kill ring. -@end smallexample - -@noindent -Let's skip over the rest of the documentation for the moment. - -Also, let's skip over the first two lines of code, those involving -@code{menu-bar-update-yank-menu}. We will explain them below. - -@need 1200 -The critical lines are these: - -@smallexample -@group - (if (and replace kill-ring) - ;; @r{then} - (setcar kill-ring string) -@end group -@group - ;; @r{else} - (setq kill-ring (cons string kill-ring)) - (if (> (length kill-ring) kill-ring-max) - ;; @r{avoid overly long kill ring} - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) -@end group -@group - (setq kill-ring-yank-pointer kill-ring) - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -@end group -@end smallexample - -The conditional test is @w{@code{(and replace kill-ring)}}. -This will be true when two conditions are met: the kill ring has -something in it, and the @code{replace} variable is true. - -@need 1250 -The @code{kill-append} function sets @code{replace} to be true; then, -when the kill ring has at least one item in it, the @code{setcar} -expression is executed: - -@smallexample -(setcar kill-ring string) -@end smallexample - -The @code{setcar} function actually changes the first element of the -@code{kill-ring} list to the value of @code{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: - -@smallexample -@group -(setq kill-ring (cons string kill-ring)) -(if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) -@end group -@end smallexample - -@noindent -This expression first constructs a new version of the kill ring by -prepending @code{string} to the existing kill ring as a new element. -Then it executes a second @code{if} clause. This second @code{if} -clause keeps the kill ring from growing too long. - -Let's look at these two expressions in order. - -The @code{setq} 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. - -@need 800 -We can see how this works with an example: - -@smallexample -(setq example-list '("here is a clause" "another clause")) -@end smallexample - -@need 1200 -@noindent -After evaluating this expression with @kbd{C-x C-e}, you can evaluate -@code{example-list} and see what it returns: - -@smallexample -@group -example-list - @result{} ("here is a clause" "another clause") -@end group -@end smallexample - -@need 1200 -@noindent -Now, we can add a new element on to this list by evaluating the -following expression: -@findex cons, @r{example} - -@smallexample -(setq example-list (cons "a third clause" example-list)) -@end smallexample - -@need 800 -@noindent -When we evaluate @code{example-list}, we find its value is: - -@smallexample -@group -example-list - @result{} ("a third clause" "here is a clause" "another clause") -@end group -@end smallexample - -@noindent -Thus, the third clause was added to the list by @code{cons}. - -@need 1200 -This is exactly similar to what the @code{setq} and @code{cons} do in -the function. Here is the line again: - -@smallexample -(setq kill-ring (cons string kill-ring)) -@end smallexample - -@need 1200 -Now for the second part of the @code{if} clause. This expression -keeps the kill ring from growing too long. It looks like this: - -@smallexample -@group -(if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) -@end group -@end smallexample - -The code checks whether the length of the kill ring is greater than -the maximum permitted length. This is the value of -@code{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 @code{nil}. It does this by using two functions, -@code{nthcdr} and @code{setcdr}. - -We looked at @code{setcdr} earlier (@pxref{setcdr, , @code{setcdr}}). -It sets the @sc{cdr} of a list, just as @code{setcar} sets the -@sc{car} of a list. In this case, however, @code{setcdr} will not be -setting the @sc{cdr} of the whole kill ring; the @code{nthcdr} -function is used to cause it to set the @sc{cdr} of the next to last -element of the kill ring---this means that since the @sc{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. - -@findex nthcdr, @r{example} -The @code{nthcdr} function works by repeatedly taking the @sc{cdr} of a -list---it takes the @sc{cdr} of the @sc{cdr} of the @sc{cdr} -@dots{} It does this @var{N} times and returns the results. - -@findex setcdr, @r{example} -Thus, if we had a four element list that was supposed to be three -elements long, we could set the @sc{cdr} of the next to last element -to @code{nil}, and thereby shorten the list. (If you sent the last -element to some other value than @code{nil}, which you could do, then -you would not have shortened the list.) - -You can see shortening by evaluating the following three expressions -in turn. First set the value of @code{trees} to @code{(maple oak pine -birch)}, then set the @sc{cdr} of its second @sc{cdr} to @code{nil} -and then find the value of @code{trees}: - -@smallexample -@group -(setq trees '(maple oak pine birch)) - @result{} (maple oak pine birch) -@end group - -@group -(setcdr (nthcdr 2 trees) nil) - @result{} nil - -trees - @result{} (maple oak pine) -@end group -@end smallexample - -@noindent -(The value returned by the @code{setcdr} expression is @code{nil} since -that is what the @sc{cdr} is set to.) - -To repeat, in @code{kill-new}, the @code{nthcdr} function takes the -@sc{cdr} a number of times that is one less than the maximum permitted -size of the kill ring and sets the @sc{cdr} of that element (which -will be the rest of the elements in the kill ring) to @code{nil}. -This prevents the kill ring from growing too long. - -@need 800 -The next to last expression in the @code{kill-new} function is - -@smallexample -(setq kill-ring-yank-pointer kill-ring) -@end smallexample - -The @code{kill-ring-yank-pointer} is a global variable that is set to be -the @code{kill-ring}. - -Even though the @code{kill-ring-yank-pointer} is called a -@samp{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 @code{yank} and -@code{yank-pop} (@pxref{Yanking, , Yanking Text Back}). - -@need 1200 -Now, to return to the first two lines in the body of the function: - -@smallexample -@group - (and (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) -@end group -@end smallexample - -@noindent -This is an expression whose first element is the function @code{and}. - -@findex and, @r{introduced} -The @code{and} special form evaluates each of its arguments until one of -the arguments returns a value of @code{nil}, in which case the -@code{and} expression returns @code{nil}; however, if none of the -arguments returns a value of @code{nil}, the value resulting from -evaluating the last argument is returned. (Since such a value is not -@code{nil}, it is considered true in Emacs Lisp.) In other words, an -@code{and} expression returns a true value only if all its arguments -are true. -@findex and - -In this case, the expression tests first to see whether -@code{menu-bar-update-yank-menu} exists as a function, and if so, -calls it. The @code{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 (@pxref{Making -Errors, , Generate an Error Message}). - -@need 1200 -Essentially, the @code{and} is an @code{if} expression that reads like -this: - -@smallexample -@group -if @var{the-menu-bar-function-exists} - then @var{execute-it} -@end group -@end smallexample - -@code{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. - -Finally, the last expression in the @code{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 @code{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. - -@need 1200 -The expression looks like this: - -@smallexample -@group - (if interprogram-cut-function - (funcall interprogram-cut-function string (not replace)))) -@end group -@end smallexample - -If an @code{interprogram-cut-function} exists, then Emacs executes -@code{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 @code{if} expression could be replaced by an @code{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'. - -@need 1250 -@node cons & search-fwd Review, search Exercises, copy-region-as-kill, Cutting & Storing Text +@need 1250 +@node cons & search-fwd Review, search Exercises, defvar, Cutting & Storing Text @comment node-name, next, previous, up @section Review @@ -8856,14 +9634,15 @@ buffer and stores that text in the kill ring, so you can get it back by yanking. -@code{delete-and-extract-region} removes the text between point and -mark from the buffer and throws it away. You cannot get it back. - @code{copy-region-as-kill} copies the text between point and mark into the kill ring, from which you can get it by yanking. The function does not cut or remove the text from the buffer. @end table +@code{delete-and-extract-region} removes the text between point and +mark from the buffer and throws it away. You cannot get it back. +(This is not an interactive command.) + @need 1500 @node search Exercises, , cons & search-fwd Review, Cutting & Storing Text @section Searching Exercises @@ -8904,7 +9683,7 @@ @menu * Lists diagrammed:: -* Symbols as Chest:: Exploring a powerful metaphor. +* Symbols as Chest:: * List Exercise:: @end menu @@ -9385,8 +10164,8 @@ list is handled as a ring.) @menu -* Kill Ring Overview:: The kill ring is a list. -* kill-ring-yank-pointer:: The @code{kill-ring-yank-pointer} variable. +* Kill Ring Overview:: +* kill-ring-yank-pointer:: * yank nthcdr Exercises:: @end menu @@ -9422,6 +10201,15 @@ (insert (car kill-ring-yank-pointer)) @end smallexample +@noindent +(Well, no more. In GNU Emacs 22, the function has been replaced by +@code{insert-for-yank} which calls @code{insert-for-yank-1} +repetitively for each @code{yank-handler} segment. In turn, +@code{insert-for-yank-1} strips text properties from the inserted text +according to @code{yank-excluded-properties}. Otherwise, it is just +like @code{insert}. We will stick with plain @code{insert} since it +is easier to understand.) + To begin to understand how @code{yank} and @code{yank-pop} work, it is first necessary to look at the @code{kill-ring-yank-pointer} variable and the @code{rotate-yank-pointer} function. @@ -9525,15 +10313,46 @@ of the kill ring of which the first element (the @sc{car}) will be inserted. -The @code{rotate-yank-pointer} function changes the element in the -kill ring to which the @code{kill-ring-yank-pointer} points; when the -pointer is set to point to the next element beyond the end of the kill -ring, it automatically sets it to point to the first element of the -kill ring. This is how the list is transformed into a ring. The -@code{rotate-yank-pointer} function itself is not difficult, but -contains many details. It and the much simpler @code{yank} and -@code{yank-pop} functions are described in an appendix. -@xref{Kill Ring, , Handling the Kill Ring}. + +@ignore +In GNU Emacs 22, the @code{kill-new} function calls + +@code{(setq kill-ring-yank-pointer kill-ring)} + +(defun rotate-yank-pointer (arg) + "Rotate the yanking point in the kill ring. +With argument, rotate that many kills forward (or backward, if negative)." + (interactive "p") + (current-kill arg)) + +(defun current-kill (n &optional do-not-move) + "Rotate the yanking point by N places, and then return that kill. +If N is zero, `interprogram-paste-function' is set, and calling it +returns a string, then that string is added to the front of the +kill ring and returned as the latest kill. +If optional arg DO-NOT-MOVE is non-nil, then don't actually move the +yanking point; just return the Nth kill forward." + (let ((interprogram-paste (and (= n 0) + interprogram-paste-function + (funcall interprogram-paste-function)))) + (if interprogram-paste + (progn + ;; Disable the interprogram cut function when we add the new + ;; text to the kill ring, so Emacs doesn't try to own the + ;; selection, with identical text. + (let ((interprogram-cut-function nil)) + (kill-new interprogram-paste)) + interprogram-paste) + (or kill-ring (error "Kill ring is empty")) + (let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (or do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element)) + (car ARGth-kill-element))))) + +@end ignore @need 1500 @node yank nthcdr Exercises, , kill-ring-yank-pointer, Yanking @@ -9584,9 +10403,9 @@ 15 and 30 times their default value.}. @menu -* while:: Causing a stretch of code to repeat. +* while:: * dolist dotimes:: -* Recursion:: Causing a function to call itself. +* Recursion:: * Looping exercise:: @end menu @@ -9621,11 +10440,11 @@ @end smallexample @menu -* Looping with while:: Repeat so long as test returns true. -* Loop Example:: A @code{while} loop that uses a list. -* print-elements-of-list:: Uses @code{while}, @code{car}, @code{cdr}. -* Incrementing Loop:: A loop with an incrementing counter. -* Decrementing Loop:: A loop with a decrementing counter. +* Looping with while:: +* Loop Example:: +* print-elements-of-list:: +* Incrementing Loop:: +* Decrementing Loop:: @end menu @node Looping with while, Loop Example, while, while @@ -9776,8 +10595,9 @@ @cindex @file{*scratch*} buffer The function requires several lines for its output. If you are -reading this in Emacs 21 or a later version, you can evaluate the -following expression inside of Info, as usual. +reading this in a recent instance of GNU Emacs, +@c GNU Emacs 21, GNU Emacs 22, or a later version, +you can evaluate the following expression inside of Info, as usual. If you are using an earlier version of Emacs, you need to copy the necessary expressions to your @file{*scratch*} buffer and evaluate @@ -9787,8 +10607,10 @@ You can copy the expressions by marking the beginning of the region with @kbd{C-@key{SPC}} (@code{set-mark-command}), moving the cursor to the end of the region and then copying the region using @kbd{M-w} -(@code{copy-region-as-kill}). In the @file{*scratch*} buffer, you can -yank the expressions back by typing @kbd{C-y} (@code{yank}). +(@code{kill-ring-save}, which calls @code{copy-region-as-kill} and +then provides visual feedback). In the @file{*scratch*} +buffer, you can yank the expressions back by typing @kbd{C-y} +(@code{yank}). After you have copied the expressions to the @file{*scratch*} buffer, evaluate each expression in turn. Be sure to evaluate the last @@ -9801,7 +10623,7 @@ each @samp{^J} stands for a `newline'.) @need 1500 -If you are using Emacs 21 or later, you can evaluate these expressions +In a recent instance of GNU Emacs, you can evaluate these expressions directly in the Info buffer, and the echo area will grow to show the results. @@ -9882,9 +10704,9 @@ is set to 1. @menu -* Incrementing Example:: Counting pebbles in a triangle. -* Inc Example parts:: The parts of the function definition. -* Inc Example altogether:: Putting the function definition together. +* Incrementing Example:: +* Inc Example parts:: +* Inc Example altogether:: @end menu @node Incrementing Example, Inc Example parts, Incrementing Loop, Incrementing Loop @@ -9967,9 +10789,9 @@ called @code{number-of-rows}. Finally, we need a variable to use as a counter. We could call this -variable @code{counter}, but a better name is @code{row-number}. -That is because what the counter does is count rows, and a program -should be written to be as understandable as possible. +variable @code{counter}, but a better name is @code{row-number}. That +is because what the counter does in this function is count rows, and a +program should be written to be as understandable as possible. When the Lisp interpreter first starts evaluating the expressions in the function, the value of @code{total} should be set to zero, since we have @@ -10092,7 +10914,7 @@ (let (@var{varlist}) (while (@var{true-or-false-test}) @var{body-of-while}@dots{} ) - @dots{} ) ; @r{Need final expression here.} + @dots{} )) ; @r{Need final expression here.} @end group @end smallexample @@ -10190,9 +11012,9 @@ @end smallexample @menu -* Decrementing Example:: More pebbles on the beach. -* Dec Example parts:: The parts of the function definition. -* Dec Example altogether:: Putting the function definition together. +* Decrementing Example:: +* Dec Example parts:: +* Dec Example altogether:: @end menu @node Decrementing Example, Dec Example parts, Decrementing Loop, Decrementing Loop @@ -10547,13 +11369,13 @@ arguments that the final instance will stop. @menu -* 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. +* Building Robots:: +* Recursive Definition Parts:: +* Recursion with list:: * Recursive triangle function:: * Recursion with cond:: -* Recursive Patterns:: Often used templates. -* No Deferment:: Don't store up work ... +* Recursive Patterns:: +* No Deferment:: * No deferment solution:: @end menu @@ -10668,8 +11490,8 @@ of numbers can be written recursively. Here is the code, including an expression to set the value of the variable @code{animals} to a list. -If you are using Emacs 20 or before, this example must be copied to -the @file{*scratch*} buffer and each expression must be evaluated +If you are using GNU Emacs 20 or before, this example must be copied +to the @file{*scratch*} buffer and each expression must be evaluated there. Use @kbd{C-u C-x C-e} to evaluate the @code{(print-elements-recursively animals)} expression so that the results are printed in the buffer; otherwise the Lisp interpreter will @@ -10679,8 +11501,8 @@ of the @code{print-elements-recursively} function, before the comment. Otherwise, the Lisp interpreter will try to evaluate the comment. -If you are using Emacs 21 or later, you can evaluate this expression -directly in Info. +If you are using a more recent version, you can evaluate this +expression directly in Info. @findex print-elements-recursively @smallexample @@ -11432,7 +12254,7 @@ @need 1200 @noindent and find that the result is false, so it will invoke -the then-part of the @code{if} clause: +the else-part of the @code{if} clause: @smallexample @group @@ -11548,7 +12370,7 @@ @ref{Indicating, , Indicating, texinfo, Texinfo Manual}, which goes to a Texinfo manual in the current directory. Or, if you are on the Internet, see -@uref{http://www.gnu.org/manual/texinfo-4.6/html_node/Indicating.html} +@uref{http://www.gnu.org/software/texinfo/manual/texinfo/} @end ifhtml @iftex ``Indicating Definitions, Commands, etc.'' in @cite{Texinfo, The GNU @@ -11594,11 +12416,11 @@ introduces several new features. @menu -* sentence-end:: The regular expression for @code{sentence-end}. -* re-search-forward:: Very similar to @code{search-forward}. -* forward-sentence:: A straightforward example of regexp search. -* forward-paragraph:: A somewhat complex example. -* etags:: How to create your own @file{TAGS} table. +* sentence-end:: +* re-search-forward:: +* forward-sentence:: +* forward-paragraph:: +* etags:: * Regexp Review:: * re-search Exercises:: @end menu @@ -11697,8 +12519,20 @@ @end group @end smallexample -@ignore - +@noindent +(Well, not in GNU Emacs 22; that is because of an effort to make the +process simpler. When its value is @code{nil}, then use the value +defined by the function @code{sentence-end}, and that returns a value +constructed from the variables @code{sentence-end-base}, +@code{sentence-end-double-space}, @code{sentence-end-without-period}, +and @code{sentence-end-without-space}. The critical variable is +@code{sentence-end-base}; its global value is similar to the one +described above but it also contains two additional quotation marks. +These have differing degrees of curliness. The +@code{sentence-end-without-period} variable, when true, tells Emacs +that a sentence may end without a period, such as text in Thai.) + +@ignore @noindent (Note that here the @key{TAB}, two spaces, and @key{RET} are shown literally in the pattern.) @@ -11739,7 +12573,6 @@ the pattern, the carriage return is inserted as an actual carriage return between square brackets but here it is shown as @key{RET}. @end table - @end ignore @node re-search-forward, forward-sentence, sentence-end, Regexp Search @@ -11802,7 +12635,7 @@ @need 1200 In the @code{forward-sentence} function, the regular expression will be -the value of the variable @code{sentence-end}, namely: +the value of the variable @code{sentence-end}. In simple form, that is: @smallexample @group @@ -11831,8 +12664,8 @@ @menu * Complete forward-sentence:: -* fwd-sentence while loops:: Two @code{while} loops. -* fwd-sentence re-search:: A regular expression search. +* fwd-sentence while loops:: +* fwd-sentence re-search:: @end menu @node Complete forward-sentence, fwd-sentence while loops, forward-sentence, forward-sentence @@ -11843,6 +12676,44 @@ @need 1250 Here is the code for @code{forward-sentence}: +@c in GNU Emacs 22 +@smallexample +@group +(defun forward-sentence (&optional arg) + "Move forward to next `sentence-end'. With argument, repeat. +With negative argument, move backward repeatedly to `sentence-beginning'. + +The variable `sentence-end' is a regular expression that matches ends of +sentences. Also, every paragraph boundary terminates sentences as well." +@end group +@group + (interactive "p") + (or arg (setq arg 1)) + (let ((opoint (point)) + (sentence-end (sentence-end))) + (while (< arg 0) + (let ((pos (point)) + (par-beg (save-excursion (start-of-paragraph-text) (point)))) + (if (and (re-search-backward sentence-end par-beg t) + (or (< (match-end 0) pos) + (re-search-backward sentence-end par-beg t))) + (goto-char (match-end 0)) + (goto-char par-beg))) + (setq arg (1+ arg))) +@end group +@group + (while (> arg 0) + (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) + (if (re-search-forward sentence-end par-end t) + (skip-chars-backward " \t\n") + (goto-char par-end))) + (setq arg (1- arg))) + (constrain-to-field nil opoint t))) +@end group +@end smallexample + +@ignore +GNU Emacs 21 @smallexample @group (defun forward-sentence (&optional arg) @@ -11872,6 +12743,7 @@ (setq arg (1- arg)))) @end group @end smallexample +@end ignore The function looks long at first sight and it is best to look at its skeleton first, and then its muscle. The way to see the skeleton is to @@ -11883,16 +12755,21 @@ "@var{documentation}@dots{}" (interactive "p") (or arg (setq arg 1)) - (while (< arg 0) - @var{body-of-while-loop} - (while (> arg 0) - @var{body-of-while-loop} + (let ((opoint (point)) (sentence-end (sentence-end))) + (while (< arg 0) + (let ((pos (point)) + (par-beg (save-excursion (start-of-paragraph-text) (point)))) + @var{rest-of-body-of-while-loop-when-going-backwards} + (while (> arg 0) + (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) + @var{rest-of-body-of-while-loop-when-going-forwards} + @var{handle-forms-and-equivalent} @end group @end smallexample This looks much simpler! The function definition consists of documentation, an @code{interactive} expression, an @code{or} -expression, and @code{while} loops. +expression, a @code{let} expression, and @code{while} loops. Let's look at each of these parts in turn. @@ -11902,24 +12779,31 @@ that the processed prefix argument, if any, is passed to the function as its argument. (This will be a number.) If the function is not passed an argument (it is optional) then the argument -@code{arg} will be bound to 1. When @code{forward-sentence} is called -non-interactively without an argument, @code{arg} is bound to +@code{arg} will be bound to 1. + +When @code{forward-sentence} is called non-interactively without an +argument, @code{arg} is bound to @code{nil}. The @code{or} expression +handles this. What it does is either leave the value of @code{arg} as +it is, but only if @code{arg} is bound to a value; or it sets the +value of @code{arg} to 1, in the case when @code{arg} is bound to @code{nil}. -The @code{or} expression handles the prefix argument. What it does is -either leave the value of @code{arg} as it is, but only if @code{arg} -is bound to a value; or it sets the value of @code{arg} to 1, in the -case when @code{arg} is bound to @code{nil}. +Next is a @code{let}. That specifies the values of two local +variables, @code{point} and @code{sentence-end}. The local value of +point, from before the search, is used in the +@code{constrain-to-field} function which handles forms and +equivalents. The @code{sentence-end} variable is set by the +@code{sentence-end} function. @node fwd-sentence while loops, fwd-sentence re-search, Complete forward-sentence, forward-sentence @unnumberedsubsec The @code{while} loops -Two @code{while} loops follow the @code{or} expression. The first -@code{while} has a true-or-false-test that tests true if the prefix -argument for @code{forward-sentence} is a negative number. This is for -going backwards. The body of this loop is similar to the body of the -second @code{while} clause, but it is not exactly the same. We will -skip this @code{while} loop and concentrate on the second @code{while} +Two @code{while} loops follow. The first @code{while} has a +true-or-false-test that tests true if the prefix argument for +@code{forward-sentence} is a negative number. This is for going +backwards. The body of this loop is similar to the body of the second +@code{while} clause, but it is not exactly the same. We will skip +this @code{while} loop and concentrate on the second @code{while} loop. @need 1500 @@ -12052,6 +12936,9 @@ argument, which is @code{(goto-char par-end)}: it moves point to the end of the paragraph. +(And if the text is in a form or equivalent, and point may not move +fully, then the @code{constrain-to-field} function comes into play.) + Regular expression searches are exceptionally useful and the pattern illustrated by @code{re-search-forward}, in which the search is the test of an @code{if} expression, is handy. You will see or write code @@ -12062,6 +12949,151 @@ @section @code{forward-paragraph}: a Goldmine of Functions @findex forward-paragraph +@ignore +@c in GNU Emacs 22 +(defun forward-paragraph (&optional arg) + "Move forward to end of paragraph. +With argument ARG, do it ARG times; +a negative argument ARG = -N means move backward N paragraphs. + +A line which `paragraph-start' matches either separates paragraphs +\(if `paragraph-separate' matches it also) or is the first line of a paragraph. +A paragraph end is the beginning of a line which is not part of the paragraph +to which the end of the previous line belongs, or the end of the buffer. +Returns the count of paragraphs left to move." + (interactive "p") + (or arg (setq arg 1)) + (let* ((opoint (point)) + (fill-prefix-regexp + (and fill-prefix (not (equal fill-prefix "")) + (not paragraph-ignore-fill-prefix) + (regexp-quote fill-prefix))) + ;; Remove ^ from paragraph-start and paragraph-sep if they are there. + ;; These regexps shouldn't be anchored, because we look for them + ;; starting at the left-margin. This allows paragraph commands to + ;; work normally with indented text. + ;; This hack will not find problem cases like "whatever\\|^something". + (parstart (if (and (not (equal "" paragraph-start)) + (equal ?^ (aref paragraph-start 0))) + (substring paragraph-start 1) + paragraph-start)) + (parsep (if (and (not (equal "" paragraph-separate)) + (equal ?^ (aref paragraph-separate 0))) + (substring paragraph-separate 1) + paragraph-separate)) + (parsep + (if fill-prefix-regexp + (concat parsep "\\|" + fill-prefix-regexp "[ \t]*$") + parsep)) + ;; This is used for searching. + (sp-parstart (concat "^[ \t]*\\(?:" parstart "\\|" parsep "\\)")) + start found-start) + (while (and (< arg 0) (not (bobp))) + (if (and (not (looking-at parsep)) + (re-search-backward "^\n" (max (1- (point)) (point-min)) t) + (looking-at parsep)) + (setq arg (1+ arg)) + (setq start (point)) + ;; Move back over paragraph-separating lines. + (forward-char -1) (beginning-of-line) + (while (and (not (bobp)) + (progn (move-to-left-margin) + (looking-at parsep))) + (forward-line -1)) + (if (bobp) + nil + (setq arg (1+ arg)) + ;; Go to end of the previous (non-separating) line. + (end-of-line) + ;; Search back for line that starts or separates paragraphs. + (if (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart. + (let (multiple-lines) + (while (and (progn (beginning-of-line) (not (bobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (looking-at fill-prefix-regexp)) + (unless (= (point) start) + (setq multiple-lines t)) + (forward-line -1)) + (move-to-left-margin) + ;; This deleted code caused a long hanging-indent line + ;; not to be filled together with the following lines. + ;; ;; Don't move back over a line before the paragraph + ;; ;; which doesn't start with fill-prefix + ;; ;; unless that is the only line we've moved over. + ;; (and (not (looking-at fill-prefix-regexp)) + ;; multiple-lines + ;; (forward-line 1)) + (not (bobp))) + (while (and (re-search-backward sp-parstart nil 1) + (setq found-start t) + ;; Found a candidate, but need to check if it is a + ;; REAL parstart. + (progn (setq start (point)) + (move-to-left-margin) + (not (looking-at parsep))) + (not (and (looking-at parstart) + (or (not use-hard-newlines) + (bobp) + (get-text-property + (1- start) 'hard))))) + (setq found-start nil) + (goto-char start)) + found-start) + ;; Found one. + (progn + ;; Move forward over paragraph separators. + ;; We know this cannot reach the place we started + ;; because we know we moved back over a non-separator. + (while (and (not (eobp)) + (progn (move-to-left-margin) + (looking-at parsep))) + (forward-line 1)) + ;; If line before paragraph is just margin, back up to there. + (end-of-line 0) + (if (> (current-column) (current-left-margin)) + (forward-char 1) + (skip-chars-backward " \t") + (if (not (bolp)) + (forward-line 1)))) + ;; No starter or separator line => use buffer beg. + (goto-char (point-min)))))) + + (while (and (> arg 0) (not (eobp))) + ;; Move forward over separator lines... + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (looking-at parsep)) + (forward-line 1)) + (unless (eobp) (setq arg (1- arg))) + ;; ... and one more line. + (forward-line 1) + (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart. + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) + (looking-at fill-prefix-regexp)) + (forward-line 1)) + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) + (if (< (point) (point-max)) + (goto-char start)))) + (constrain-to-field nil opoint t) + ;; Return the number of steps that could not be done. + arg)) +@end ignore + The @code{forward-paragraph} function moves point forward to the end of the paragraph. It is usually bound to @kbd{M-@}} and makes use of a number of functions that are important in themselves, including @@ -12091,14 +13123,9 @@ This is an added complication. @menu -* forward-paragraph in brief:: Key parts of the function definition. -* fwd-para let:: The @code{let*} expression. -* fwd-para while:: The forward motion @code{while} loop. -* fwd-para between paragraphs:: Movement between paragraphs. -* fwd-para within paragraph:: Movement within paragraphs. -* fwd-para no fill prefix:: When there is no fill prefix. -* fwd-para with fill prefix:: When there is a fill prefix. -* fwd-para summary:: Summary of @code{forward-paragraph} code. +* forward-paragraph in brief:: +* fwd-para let:: +* fwd-para while:: @end menu @node forward-paragraph in brief, fwd-para let, forward-paragraph, forward-paragraph @@ -12121,12 +13148,10 @@ (or arg (setq arg 1)) (let* @var{varlist} - (while (< arg 0) ; @r{backward-moving-code} + (while (and (< arg 0) (not (bobp))) ; @r{backward-moving-code} @dots{} - (setq arg (1+ arg))) - (while (> arg 0) ; @r{forward-moving-code} + (while (and (> arg 0) (not (eobp))) ; @r{forward-moving-code} @dots{} - (setq arg (1- arg))))) @end group @end smallexample @@ -12147,22 +13172,34 @@ @unnumberedsubsec The @code{let*} expression The next line of the @code{forward-paragraph} function begins a -@code{let*} expression. This is a different kind of expression than -we have seen so far. The symbol is @code{let*} not @code{let}. +@code{let*} expression. This is a different than @code{let}. The +symbol is @code{let*} not @code{let}. The @code{let*} special form is like @code{let} except that Emacs sets each variable in sequence, one after another, and variables in the latter part of the varlist can make use of the values to which Emacs set variables in the earlier part of the varlist. -In the @code{let*} expression in this function, Emacs binds two -variables: @code{fill-prefix-regexp} and @code{paragraph-separate}. -The value to which @code{paragraph-separate} is bound depends on the -value of @code{fill-prefix-regexp}. - -@need 1200 -Let's look at each in turn. The symbol @code{fill-prefix-regexp} is -set to the value returned by evaluating the following list: +@ignore +( refappend save-excursion, , code save-excursion in code append-to-buffer .) +@end ignore + +(@ref{append save-excursion, , @code{save-excursion} in @code{append-to-buffer}}.) + +In the @code{let*} expression in this function, Emacs binds a total of +seven variables: @code{opoint}, @code{fill-prefix-regexp}, +@code{parstart}, @code{parsep}, @code{sp-parstart}, @code{start}, and +@code{found-start}. + +The variable @code{parsep} appears twice, first, to remove instances +of @samp{^}, and second, to handle fill prefixes. + +The variable @code{opoint} is just the value of @code{point}. As you +can guess, it is used in a @code{constrain-to-field} expression, just +as in @code{forward-sentence}. + +The variable @code{fill-prefix-regexp} is set to the value returned by +evaluating the following list: @smallexample @group @@ -12226,49 +13263,44 @@ will exactly match the fill prefix if the fill prefix exists. Otherwise, the variable will be set to @code{nil}. -The second local variable in the @code{let*} expression is -@code{paragraph-separate}. It is bound to the value returned by -evaluating the expression: - -@smallexample -@group -(if fill-prefix-regexp - (concat paragraph-separate - "\\|^" fill-prefix-regexp "[ \t]*$") - paragraph-separate))) -@end group -@end smallexample - -This expression shows why @code{let*} rather than @code{let} was used. -The true-or-false-test for the @code{if} depends on whether the variable -@code{fill-prefix-regexp} evaluates to @code{nil} or some other value. +The next two local variables in the @code{let*} expression are +designed to remove instances of @samp{^} from @code{parstart} and +@code{parsep}, the local variables indicate the paragraph start and +the paragraph separator. The next expression sets @code{parsep} +again. That is to handle fill prefixes. + +This is the setting that requires the definition call @code{let*} +rather than @code{let}. The true-or-false-test for the @code{if} +depends on whether the variable @code{fill-prefix-regexp} evaluates to +@code{nil} or some other value. If @code{fill-prefix-regexp} does not have a value, Emacs evaluates -the else-part of the @code{if} expression and binds -@code{paragraph-separate} to its local value. -(@code{paragraph-separate} is a regular expression that matches what -separates paragraphs.) +the else-part of the @code{if} expression and binds @code{parsep} to +its local value. (@code{parsep} is a regular expression that matches +what separates paragraphs.) But if @code{fill-prefix-regexp} does have a value, Emacs evaluates -the then-part of the @code{if} expression and binds -@code{paragraph-separate} to a regular expression that includes the -@code{fill-prefix-regexp} as part of the pattern. - -Specifically, @code{paragraph-separate} is set to the original value -of the paragraph separate regular expression concatenated with an -alternative expression that consists of the @code{fill-prefix-regexp} -followed by a blank line. The @samp{^} indicates that the -@code{fill-prefix-regexp} must begin a line, and the optional -whitespace to the end of the line is defined by @w{@code{"[ \t]*$"}}.) -The @samp{\\|} defines this portion of the regexp as an alternative to -@code{paragraph-separate}. +the then-part of the @code{if} expression and binds @code{parsep} to a +regular expression that includes the @code{fill-prefix-regexp} as part +of the pattern. + +Specifically, @code{parsep} is set to the original value of the +paragraph separate regular expression concatenated with an alternative +expression that consists of the @code{fill-prefix-regexp} followed by +optional whitespace to the end of the line. The whitespace is defined +by @w{@code{"[ \t]*$"}}.) The @samp{\\|} defines this portion of the +regexp as an alternative to @code{parsep}. + +According to a comment in the code, the next local variable, +@code{sp-parstart}, is used for searching, and then the final two, +@code{start} and @code{found-start}, are set to @code{nil}. Now we get into the body of the @code{let*}. The first part of the body of the @code{let*} deals with the case when the function is given a negative argument and is therefore moving backwards. We will skip this section. -@node fwd-para while, fwd-para between paragraphs, fwd-para let, forward-paragraph +@node fwd-para while, , fwd-para let, forward-paragraph @unnumberedsubsec The forward motion @code{while} loop The second part of the body of the @code{let*} deals with forward @@ -12278,243 +13310,162 @@ @code{while} loop is evaluated exactly once, and the cursor moves forward one paragraph. +@ignore +(while (and (> arg 0) (not (eobp))) + + ;; Move forward over separator lines... + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (looking-at parsep)) + (forward-line 1)) + (unless (eobp) (setq arg (1- arg))) + ;; ... and one more line. + (forward-line 1) + + (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart. + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) + (looking-at fill-prefix-regexp)) + (forward-line 1)) + + + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) + + (if (< (point) (point-max)) + (goto-char start)))) +@end ignore + This part handles three situations: when point is between paragraphs, -when point is within a paragraph and there is a fill prefix, and -when point is within a paragraph and there is no fill prefix. +when there is a fill prefix and when there is no fill prefix. @need 800 The @code{while} loop looks like this: @smallexample @group -(while (> arg 0) - (beginning-of-line) +;; @r{going forwards and not at the end of the buffer} +(while (and (> arg 0) (not (eobp))) ;; @r{between paragraphs} - (while (prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1))) -@end group - -@group - ;; @r{within paragraphs, with a fill prefix} + ;; Move forward over separator lines... + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (looking-at parsep)) + (forward-line 1)) + ;; @r{This decrements the loop} + (unless (eobp) (setq arg (1- arg))) + ;; ... and one more line. + (forward-line 1) +@end group + +@group (if fill-prefix-regexp - ;; @r{There is a fill prefix; it overrides paragraph-start.} + ;; There is a fill prefix; it overrides parstart; + ;; we go forward line by line (while (and (not (eobp)) - (not (looking-at paragraph-separate)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) (looking-at fill-prefix-regexp)) (forward-line 1)) @end group @group - ;; @r{within paragraphs, no fill prefix} - (if (re-search-forward paragraph-start nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max)))) - - (setq arg (1- arg))) -@end group -@end smallexample - -We can see immediately that this is a decrementing counter @code{while} -loop, using the expression @code{(setq arg (1- arg))} as the decrementer. - -@need 800 -The body of the loop consists of three expressions: - -@smallexample -@group -;; @r{between paragraphs} -(beginning-of-line) -(while - @var{body-of-while}) -@end group - -@group -;; @r{within paragraphs, with fill prefix} -(if @var{true-or-false-test} - @var{then-part} -@end group - -@group -;; @r{within paragraphs, no fill prefix} - @var{else-part} -@end group -@end smallexample - -@noindent -When the Emacs Lisp interpreter evaluates the body of the -@code{while} loop, the first thing it does is evaluate the -@code{(beginning-of-line)} expression and move point to the beginning -of the line. Then there is an inner @code{while} loop. This -@code{while} loop is designed to move the cursor out of the blank -space between paragraphs, if it should happen to be there. Finally, -there is an @code{if} expression that actually moves point to the end -of the paragraph. - -@node fwd-para between paragraphs, fwd-para within paragraph, fwd-para while, forward-paragraph -@unnumberedsubsec Between paragraphs - -First, let us look at the inner @code{while} loop. This loop handles -the case when point is between paragraphs; it uses three functions -that are new to us: @code{prog1}, @code{eobp} and @code{looking-at}. -@findex prog1 + ;; There is no fill prefix; + ;; we go forward character by character + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) +@end group + +@group + ;; and if there is no fill prefix and if we are not at the end, + ;; go to whatever was found in the regular expression search + ;; for sp-parstart + (if (< (point) (point-max)) + (goto-char start)))) +@end group +@end smallexample + @findex eobp +We can see that this is a decrementing counter @code{while} loop, +using the expression @code{(setq arg (1- arg))} as the decrementer. +That expression is not far from the @code{while}, but is hidden in +another Lisp macro, an @code{unless} macro. Unless we are at the end +of the buffer --- that is what the @code{eobp} function determines; it +is an abbreviation of @samp{End Of Buffer P} --- we decrease the value +of @code{arg} by one. + +(If we are at the end of the buffer, we cannot go forward any more and +the next loop of the @code{while} expression will test false since the +test is an @code{and} with @code{(not (eobp))}. The @code{not} +function means exactly as you expect; it is another name for +@code{null}, a function that returns true when its argument is false.) + +Interestingly, the loop count is not decremented until we leave the +space between paragraphs, unless we come to the end of buffer or stop +seeing the local value of the paragraph separator. + +That second @code{while} also has a @code{(move-to-left-margin)} +expression. The function is self-explanatory. It is inside a +@code{progn} expression and not the last element of its body, so it is +only invoked for its side effect, which is to move point to the left +margin of the current line. + @findex looking-at - -@itemize @bullet -@item -@code{prog1} is similar to the @code{progn} special form, -except that @code{prog1} evaluates its arguments in sequence and then -returns the value of its first argument as the value of the whole -expression. (@code{progn} returns the value of its last argument as the -value of the expression.) The second and subsequent arguments to -@code{prog1} are evaluated only for their side effects. - -@item -@code{eobp} is an abbreviation of @samp{End Of Buffer P} and is a -function that returns true if point is at the end of the buffer. - -@item -@code{looking-at} is a function that returns true if the text following -point matches the regular expression passed @code{looking-at} as its -argument. -@end itemize - -@need 800 -The @code{while} loop we are studying looks like this: - -@smallexample -@group -(while (prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1))) -@end group -@end smallexample - -@need 1200 -@noindent -This is a @code{while} loop with no body! The true-or-false-test of the -loop is the expression: - -@smallexample -@group -(prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1)) -@end group -@end smallexample - -@noindent -The first argument to the @code{prog1} is the @code{and} expression. It -has within in it a test of whether point is at the end of the buffer and -also a test of whether the pattern following point matches the regular -expression for separating paragraphs. - -If the cursor is not at the end of the buffer and if the characters -following the cursor mark the separation between two paragraphs, then -the @code{and} expression is true. After evaluating the @code{and} -expression, the Lisp interpreter evaluates the second argument to -@code{prog1}, which is @code{forward-line}. This moves point forward -one line. The value returned by the @code{prog1} however, is the -value of its first argument, so the @code{while} loop continues so -long as point is not at the end of the buffer and is between -paragraphs. When, finally, point is moved to a paragraph, the -@code{and} expression tests false. Note however, that the -@code{forward-line} command is carried out anyhow. This means that -when point is moved from between paragraphs to a paragraph, it is left -at the beginning of the second line of the paragraph. - -@node fwd-para within paragraph, fwd-para no fill prefix, fwd-para between paragraphs, forward-paragraph -@unnumberedsubsec Within paragraphs - -The next expression in the outer @code{while} loop is an @code{if} -expression. The Lisp interpreter evaluates the then-part of the -@code{if} when the @code{fill-prefix-regexp} variable has a value other -than @code{nil}, and it evaluates the else-part when the value of -@code{if fill-prefix-regexp} is @code{nil}, that is, when there is no -fill prefix. - -@node fwd-para no fill prefix, fwd-para with fill prefix, fwd-para within paragraph, forward-paragraph -@unnumberedsubsec No fill prefix - -It is simplest to look at the code for the case when there is no fill -prefix first. This code consists of yet another inner @code{if} -expression, and reads as follows: - -@smallexample -@group -(if (re-search-forward paragraph-start nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max))) -@end group -@end smallexample - -@noindent -This expression actually does the work that most people think of as -the primary purpose of the @code{forward-paragraph} command: it causes -a regular expression search to occur that searches forward to the -start of the next paragraph and if it is found, moves point there; but -if the start of another paragraph if not found, it moves point to the -end of the accessible region of the buffer. - -The only unfamiliar part of this is the use of @code{match-beginning}. -This is another function that is new to us. The -@code{match-beginning} function returns a number specifying the -location of the start of the text that was matched by the last regular -expression search. - -The @code{match-beginning} function is used here because of a -characteristic of a forward search: a successful forward search, -regardless of whether it is a plain search or a regular expression -search, will move point to the end of the text that is found. In this -case, a successful search will move point to the end of the pattern for -@code{paragraph-start}, which will be the beginning of the next -paragraph rather than the end of the current one. - -However, we want to put point at the end of the current paragraph, not at -the beginning of the next one. The two positions may be different, -because there may be several blank lines between paragraphs. - -@findex match-beginning -When given an argument of 0, @code{match-beginning} returns the position -that is the start of the text that the most recent regular -expression search matched. In this case, the most recent regular -expression search is the one looking for @code{paragraph-start}, so -@code{match-beginning} returns the beginning position of the pattern, -rather than the end of the pattern. The beginning position is the end -of the paragraph. - -(Incidentally, when passed a positive number as an argument, the -@code{match-beginning} function will place point at that parenthesized -expression in the last regular expression. It is a useful function.) - -@node fwd-para with fill prefix, fwd-para summary, fwd-para no fill prefix, forward-paragraph -@unnumberedsubsec With a fill prefix - -The inner @code{if} expression just discussed is the else-part of an enclosing -@code{if} expression which tests whether there is a fill prefix. If -there is a fill prefix, the then-part of this @code{if} is evaluated. -It looks like this: - -@smallexample -@group -(while (and (not (eobp)) - (not (looking-at paragraph-separate)) - (looking-at fill-prefix-regexp)) - (forward-line 1)) -@end group -@end smallexample - -@noindent -What this expression does is move point forward line by line so long -as three conditions are true: +The @code{looking-at} function is also self-explanatory; it returns +true if the text after point matches the regular expression given as +its argument. + +The rest of the body of the loop looks difficult at first, but makes +sense as you come to understand it. + +@need 800 +First consider what happens if there is a fill prefix: + +@smallexample +@group + (if fill-prefix-regexp + ;; There is a fill prefix; it overrides parstart; + ;; we go forward line by line + (while (and (not (eobp)) + (progn (move-to-left-margin) (not (eobp))) + (not (looking-at parsep)) + (looking-at fill-prefix-regexp)) + (forward-line 1)) +@end group +@end smallexample + +@noindent +This expression moves point forward line by line so long +as four conditions are true: @enumerate @item Point is not at the end of the buffer. @item +We can move to the left margin of the text and are +not at the end of the buffer. + +@item The text following point does not separate paragraphs. @item @@ -12526,101 +13477,93 @@ function. This means that if the text has a fill prefix, the @code{looking-at} function will see it. -@node fwd-para summary, , fwd-para with fill prefix, forward-paragraph -@unnumberedsubsec Summary - -In summary, when moving forward, the @code{forward-paragraph} function -does the following: - -@itemize @bullet -@item -Move point to the beginning of the line. - -@item -Skip over lines between paragraphs. - -@item -Check whether there is a fill prefix, and if there is: - -@itemize --- - -@item -Go forward line by line so long as the line is not a paragraph -separating line. -@end itemize - -@item -But if there is no fill prefix, - -@itemize --- - -@item -Search for the next paragraph start pattern. - -@item -Go to the beginning of the paragraph start pattern, which will be the -end of the previous paragraph. - -@item -Or else go to the end of the accessible portion of the buffer. -@end itemize -@end itemize - -@need 1200 -For review, here is the code we have just been discussing, formatted -for clarity: - -@smallexample -@group -(interactive "p") -(or arg (setq arg 1)) -(let* ( - (fill-prefix-regexp - (and fill-prefix (not (equal fill-prefix "")) - (not paragraph-ignore-fill-prefix) - (regexp-quote fill-prefix))) -@end group - -@group - (paragraph-separate - (if fill-prefix-regexp - (concat paragraph-separate - "\\|^" - fill-prefix-regexp - "[ \t]*$") - paragraph-separate))) - - @var{omitted-backward-moving-code} @dots{} -@end group - -@group - (while (> arg 0) ; @r{forward-moving-code} - (beginning-of-line) - - (while (prog1 (and (not (eobp)) - (looking-at paragraph-separate)) - (forward-line 1))) -@end group - -@group - (if fill-prefix-regexp - (while (and (not (eobp)) ; @r{then-part} - (not (looking-at paragraph-separate)) - (looking-at fill-prefix-regexp)) - (forward-line 1)) -@end group -@group - ; @r{else-part: the inner-if} - (if (re-search-forward paragraph-start nil t) - (goto-char (match-beginning 0)) - (goto-char (point-max)))) - - (setq arg (1- arg))))) ; @r{decrementer} -@end group -@end smallexample +@need 1250 +Consider what happens when there is no fill prefix. + +@smallexample +@group + (while (and (re-search-forward sp-parstart nil 1) + (progn (setq start (match-beginning 0)) + (goto-char start) + (not (eobp))) + (progn (move-to-left-margin) + (not (looking-at parsep))) + (or (not (looking-at parstart)) + (and use-hard-newlines + (not (get-text-property (1- start) 'hard))))) + (forward-char 1)) +@end group +@end smallexample + +@noindent +This @code{while} loop has us searching forward for +@code{sp-parstart}, which is the combination of possible whitespace +with a the local value of the start of a paragraph or of a paragraph +separator. (The latter two are within an expression starting +@code{\(?:} so that they are not referenced by the +@code{match-beginning} function.) + +@need 800 +The two expressions, + +@smallexample +@group +(setq start (match-beginning 0)) +(goto-char start) +@end group +@end smallexample + +@noindent +mean go to the start of the text matched by the regular expression +search. + +The @code{(match-beginning 0)} expression is new. It returns a number +specifying the location of the start of the text that was matched by +the last search. + +The @code{match-beginning} function is used here because of a +characteristic of a forward search: a successful forward search, +regardless of whether it is a plain search or a regular expression +search, moves point to the end of the text that is found. In this +case, a successful search moves point to the end of the pattern for +@code{sp-parstart}. + +However, we want to put point at the end of the current paragraph, not +somewhere else. Indeed, since the search possibly includes the +paragraph separator, point may end up at the beginning of the next one +unless we use an expression that includes @code{match-beginning}. + +@findex match-beginning +When given an argument of 0, @code{match-beginning} returns the +position that is the start of the text matched by the most recent +search. In this case, the most recent search looks for +@code{sp-parstart}. The @code{(match-beginning 0)} expression returns +the beginning position of that pattern, rather than the end position +of that pattern. + +(Incidentally, when passed a positive number as an argument, the +@code{match-beginning} function returns the location of point at that +parenthesized expression in the last search unless that parenthesized +expression begins with @code{\(?:}. I don't know why @code{\(?:} +appears here since the argument is 0.) + +@need 1250 +The last expression when there is no fill prefix is + +@smallexample +@group +(if (< (point) (point-max)) + (goto-char start)))) +@end group +@end smallexample + +@noindent +This says that if there is no fill prefix and if we are not at the +end, point should move to the beginning of whatever was found by the +regular expression search for @code{sp-parstart}. The full definition for the @code{forward-paragraph} function not only -includes this code for going forwards, but also code for going backwards. +includes code for going forwards, but also code for going backwards. If you are reading this inside of GNU Emacs and you want to see the whole function, you can type @kbd{C-h f} (@code{describe-function}) @@ -12631,26 +13574,25 @@ your sources! Without them, you are like a person who tries to drive a car with his eyes shut!) -@c !!! again, 21.0.100 tags table location in this paragraph -Or -- a good habit to get into -- you can type @kbd{M-.} -(@code{find-tag}) and the name of the function when prompted for it. -This will take you directly to the source. If the @code{find-tag} -function first asks you for the name of a @file{TAGS} table, give it -the name of the @file{TAGS} file such as -@file{/usr/local/share/emacs/21.0.100/lisp/TAGS}. (The exact path to your -@file{TAGS} file depends on how your copy of Emacs was installed.) - -You can also create your own @file{TAGS} file for directories that -lack one. -@ifnottex -@xref{etags, , Create Your Own @file{TAGS} File}. -@end ifnottex - @node etags, Regexp Review, forward-paragraph, Regexp Search @section Create Your Own @file{TAGS} File @findex etags @cindex @file{TAGS} file, create own +Besides @kbd{C-h f} (@code{describe-function}), another way to see the +source of a function is to type @kbd{M-.} (@code{find-tag}) and the +name of the function when prompted for it. This is a good habit to +get into. This will take you directly to the source. If the +@code{find-tag} function first asks you for the name of a @file{TAGS} +table, give it the name of a @file{TAGS} file such as +@file{/usr/local/src/emacs/src/TAGS}. (The exact path to your +@file{TAGS} file depends on how your copy of Emacs was installed. I +just told you the location that provides both my C and my Emacs Lisp +sources.) + +You can also create your own @file{TAGS} file for directories that +lack one. + The @kbd{M-.} (@code{find-tag}) command takes you directly to the source for a function, variable, node, or other source. The function depends on tags tables to tell it where to go. @@ -12720,11 +13662,11 @@ you want, but do not know where it is, you can use the @code{locate} program to attempt to find it. -Type @w{@kbd{M-x locate RET TAGS RET}} and Emacs will list for you the -full path names of all your @file{TAGS} files. On my system, this -command lists 34 @file{TAGS} files. On the other hand, a `plain -vanilla' system I recently installed did not contain any @file{TAGS} -files. +Type @w{@kbd{M-x locate @key{RET} TAGS @key{RET}}} and Emacs will list +for you the full path names of all your @file{TAGS} files. On my +system, this command lists 34 @file{TAGS} files. On the other hand, a +`plain vanilla' system I recently installed did not contain any +@file{TAGS} files. If the tags table you want has been created, you can use the @code{M-x visit-tags-table} command to specify it. Otherwise, you will need to @@ -12784,6 +13726,7 @@ nil @end group @end smallexample + @noindent (The @code{insert} function inserts its arguments at point; the @code{format} function returns a string formatted from its arguments @@ -12800,6 +13743,7 @@ @enumerate @item A regular expression that specifies the pattern to search for. +(Remember to put quotation marks around this argument!) @item Optionally, the limit of the search. @@ -12844,20 +13788,6 @@ of a buffer. The end of the accessible part is the end of the buffer if the buffer is not narrowed; it is the end of the narrowed part if the buffer is narrowed. - -@item prog1 -Evaluate each argument in sequence and then return the value of the -@emph{first}. - -@need 1250 -For example: - -@smallexample -@group -(prog1 1 2 3 4) - @result{} 1 -@end group -@end smallexample @end table @need 1500 @@ -12891,8 +13821,8 @@ @menu * Why Count Words:: -* count-words-region:: Use a regexp, but find a problem. -* recursive-count-words:: Start with case of no words in region. +* count-words-region:: +* recursive-count-words:: * Counting Exercise:: @end menu @@ -12928,8 +13858,8 @@ words in just a section, rather than all of a buffer. So it makes more sense to design the command to count the number of words in a region. Once you have a @code{count-words-region} command, you can, -if you wish, count words in a whole buffer by marking it with @kbd{C-x -h} (@code{mark-whole-buffer}). +if you wish, count words in a whole buffer by marking it with +@w{@kbd{C-x h}} (@code{mark-whole-buffer}). Clearly, counting words is a repetitive act: starting from the beginning of the region, you count the first word, then the second @@ -12938,8 +13868,8 @@ or to a @code{while} loop. @menu -* Design count-words-region:: The definition using a @code{while} loop. -* Whitespace Bug:: The Whitespace Bug in @code{count-words-region}. +* Design count-words-region:: +* Whitespace Bug:: @end menu @node Design count-words-region, Whitespace Bug, count-words-region, count-words-region @@ -13043,11 +13973,13 @@ @noindent (Note that paired backslashes precede the @samp{w} and @samp{W}. A -single backslash has special meaning to the Emacs Lisp interpreter. It -indicates that the following character is interpreted differently than -usual. For example, the two characters, @samp{\n}, stand for +single backslash has special meaning to the Emacs Lisp interpreter. +It indicates that the following character is interpreted differently +than usual. For example, the two characters, @samp{\n}, stand for @samp{newline}, rather than for a backslash followed by @samp{n}. Two -backslashes in a row stand for an ordinary, `unspecial' backslash.) +backslashes in a row stand for an ordinary, `unspecial' backslash, +which in this case is followed by a letter, the combination of which +is important to @code{re-search-forward}.) We need a counter to count how many words there are; this variable must first be set to 0 and then incremented each time Emacs goes @@ -13312,21 +14244,21 @@ @iftex @noindent (For information about @code{and}, see -@ref{forward-paragraph, , @code{forward-paragraph}: a Goldmine of -Functions}.) +@ref{kill-new function, , The @code{kill-new} function}.) @end iftex @ifinfo @noindent -(@xref{forward-paragraph}, for information about @code{and}.) +(@xref{kill-new function, , The @code{kill-new} function}, for +information about @code{and}.) @end ifinfo The @code{re-search-forward} expression returns @code{t} if the search succeeds and as a side effect moves point. Consequently, as words are -found, point is moved through the region. When the search -expression fails to find another word, or when point reaches the end -of the region, the true-or-false-test tests false, the @code{while} -loop exists, and the @code{count-words-region} function displays one -or other of its messages. +found, point is moved through the region. When the search expression +fails to find another word, or when point reaches the end of the +region, the true-or-false-test tests false, the @code{while} loop +exits, and the @code{count-words-region} function displays one or +other of its messages. After incorporating these final changes, the @code{count-words-region} works without bugs (or at least, without bugs that I have found!). @@ -13590,6 +14522,7 @@ each word, the counting mechanism must be an expression that adds one to the value returned by a call to @code{recursive-count-words}. +@need 800 Consider several cases: @itemize @bullet @@ -13776,15 +14709,15 @@ @menu * Divide and Conquer:: -* Words and Symbols:: What to count? -* Syntax:: What constitutes a word or symbol? -* count-words-in-defun:: Very like @code{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. +* Words and Symbols:: +* Syntax:: +* count-words-in-defun:: +* Several defuns:: +* Find a File:: +* lengths-list-file:: +* Several files:: +* Several files recursively:: +* Prepare the data:: @end menu @node Divide and Conquer, Words and Symbols, Words in a defun, Words in a defun @@ -14161,7 +15094,7 @@ @node Several defuns, Find a File, count-words-in-defun, Words in a defun @section Count Several @code{defuns} Within a File -A file such as @file{simple.el} may have 80 or more function +A file such as @file{simple.el} may have a hundred or more function definitions within it. Our long term goal is to collect statistics on many files, but as a first step, our immediate goal is to collect statistics on one file. @@ -14223,9 +15156,7 @@ problem. @need 1200 -Let's look at the source for @code{find-file} (you can use the -@code{find-tag} command or @kbd{C-h f} (@code{describe-function}) to -find the source of a function): +Let's look at the source for @code{find-file}: @smallexample @group @@ -14238,18 +15169,54 @@ @end group @end smallexample -The definition possesses short but complete documentation and an -interactive specification that prompts you for a file name when you -use the command interactively. The body of the definition contains -two functions, @code{find-file-noselect} and @code{switch-to-buffer}. +@noindent +(The most recent version of the @code{find-file} function definition +permits you to specify optional wildcards visit multiple files; that +makes the definition more complex and we will not discuss it here, +since it is not relevant. You can see its source using either +@kbd{M-.} (@code{find-tag}) or @kbd{C-h f} (@code{describe-function}).) + +@ignore +In Emacs 22 +(defun find-file (filename &optional wildcards) + "Edit file FILENAME. +Switch to a buffer visiting file FILENAME, +creating one if none already exists. +Interactively, the default if you just type RET is the current directory, +but the visited file name is available through the minibuffer history: +type M-n to pull it into the minibuffer. + +Interactively, or if WILDCARDS is non-nil in a call from Lisp, +expand wildcards (if any) and visit multiple files. You can +suppress wildcard expansion by setting `find-file-wildcards' to nil. + +To visit a file without any kind of conversion and without +automatically choosing a major mode, use \\[find-file-literally]." + (interactive (find-file-read-args "Find file: " nil)) + (let ((value (find-file-noselect filename nil nil wildcards))) + (if (listp value) + (mapcar 'switch-to-buffer (nreverse value)) + (switch-to-buffer value)))) +@end ignore + +The definition I am showing possesses short but complete documentation +and an interactive specification that prompts you for a file name when +you use the command interactively. The body of the definition +contains two functions, @code{find-file-noselect} and +@code{switch-to-buffer}. According to its documentation as shown by @kbd{C-h f} (the @code{describe-function} command), the @code{find-file-noselect} function reads the named file into a buffer and returns the buffer. -However, the buffer is not selected. Emacs does not switch its -attention (or yours if you are using @code{find-file-noselect}) to the -named buffer. That is what @code{switch-to-buffer} does: it switches -the buffer to which Emacs attention is directed; and it switches the +(Its most recent version includes an optional wildcards argument, +too, as well as another to read a file literally and an other you +suppress warning messages. These optional arguments are irrelevant.) + +However, the @code{find-file-noselect} function does not select the +buffer in which it puts the file. Emacs does not switch its attention +(or yours if you are using @code{find-file-noselect}) to the named +buffer. That is what @code{switch-to-buffer} does: it switches the +buffer to which Emacs attention is directed; and it switches the buffer displayed in the window to the new buffer. We have discussed buffer switching elsewhere. (@xref{Switching Buffers}.) @@ -14261,7 +15228,7 @@ So instead of calling on @code{find-file} to do the job, we must write our own expression. -The task is easy: use @code{find-file-noselect} and @code{set-buffer}. +The task is easy: use @code{find-file-noselect} and @code{set-buffer}. @node lengths-list-file, Several files, Find a File, Words in a defun @section @code{lengths-list-file} in Detail @@ -14345,10 +15312,10 @@ definition and constructs a lengths' list containing the information. Emacs kills the buffer after working through it. This is to save -space inside of Emacs. My version of Emacs 19 contained over 300 -source files of interest; Emacs 21 contains over 800 source files. -Another function will apply @code{lengths-list-file} to each of the -files. +space inside of Emacs. My version of GNU Emacs 19 contained over 300 +source files of interest; GNU Emacs 22 contains over a thousand source +files. Another function will apply @code{lengths-list-file} to each +of the files. Finally, the last expression within the @code{let} expression is the @code{lengths-list} variable; its value is returned as the value of @@ -14358,20 +15325,29 @@ place your cursor after the following expression and type @kbd{C-x C-e} (@code{eval-last-sexp}). -@c !!! 21.0.100 lisp sources location here +@c !!! 22.0.100 lisp sources location here @smallexample (lengths-list-file - "/usr/local/share/emacs/21.0.100/lisp/emacs-lisp/debug.el") + "/usr/local/share/emacs/22.0.100/lisp/emacs-lisp/debug.el") @end smallexample @c was: (lengths-list-file "../lisp/debug.el") -@c !!! as of 21, Info file is in -@c /usr/share/info/emacs-lisp-intro.info.gz -@c but debug.el is in /usr/local/share/emacs/21.0.100/lisp/emacs-lisp/debug.el - -@noindent -(You may need to change the pathname of the file; the one here worked -with GNU Emacs version 21.0.100. To change the expression, copy it to +@ignore +2006 Oct 29 +For Bob, as root, + gunzip /usr/local/share/emacs/22.0.50/lisp/emacs-lisp/debug.el.gz +In GNU Emacs 22, in *info* eval + count-words-in-defun +in The `count-words-in-defun' Function + count-words-in-defun +in `lengths-list-file' in Detail +then eval + (lengths-list-file "/usr/local/share/emacs/22.0.50/lisp/emacs-lisp/debug.el") +@end ignore + +@noindent +(You may need to change the pathname of the file; the one here is for +GNU Emacs version 22.0.100. To change the expression, copy it to the @file{*scratch*} buffer and edit it. @need 1200 @@ -14389,10 +15365,10 @@ @need 1200 The lengths' list for @file{debug.el} takes less than a second to -produce and looks like this: - -@smallexample -(77 95 85 87 131 89 50 25 44 44 68 35 64 45 17 34 167 457) +produce and looks like this in GNY Emacs 22: + +@smallexample +(83 113 105 144 289 22 30 97 48 89 25 52 52 88 28 29 77 49 43 290 232 587) @end smallexample @need 1500 @@ -14403,7 +15379,7 @@ (75 41 80 62 20 45 44 68 45 12 34 235) @end smallexample -(The newer version of @file{debug.el} contains more defuns than the +(The newer version of @file{debug.el} contains more defuns than the earlier one; and my new machine is much faster than the old one.) Note that the length of the last definition in the file is first in @@ -14421,8 +15397,8 @@ either a @code{while} loop or recursion. @menu -* lengths-list-many-files:: Return a list of the lengths of defuns. -* append:: Attach one list to another. +* lengths-list-many-files:: +* append:: @end menu @node lengths-list-many-files, append, Several files, Several files @@ -14499,11 +15475,19 @@ name to the absolute, long, path name form of the directory in which the function is called. -@c !!! 21.0.100 lisp sources location here +@ignore +2006 Oct 29 +For Bob, as root, + gunzip /usr/local/share/emacs/22.0.50/lisp/emacs-lisp/debug.el.gz +In GNU Emacs 22, eval +(expand-file-name "/usr/local/share/emacs/22.0.50/lisp/emacs-lisp/debug.el") +@end ignore + +@c !!! 22.0.100 lisp sources location here @need 1500 Thus, if @code{expand-file-name} is called on @code{debug.el} when Emacs is visiting the -@file{/usr/local/share/emacs/21.0.100/lisp/emacs-lisp/} directory, +@file{/usr/local/share/emacs/22.0.100/lisp/emacs-lisp/} directory, @smallexample debug.el @@ -14513,9 +15497,9 @@ @noindent becomes -@c !!! 21.0.100 lisp sources location here -@smallexample -/usr/local/share/emacs/21.0.100/lisp/emacs-lisp/debug.el +@c !!! 22.0.100 lisp sources location here +@smallexample +/usr/local/share/emacs/22.0.100/lisp/emacs-lisp/debug.el @end smallexample The only other new element of this function definition is the as yet @@ -14604,34 +15588,69 @@ the @file{*scratch*} buffer, edit them, and then evaluate them. The results are shown after the @samp{@result{}}. (These results are -for files from Emacs Version 21.0.100; files from other versions of +for files from Emacs Version 22.0.100; files from other versions of Emacs may produce different results.) -@c !!! 21.0.100 lisp sources location here -@smallexample -@group -(cd "/usr/local/share/emacs/21.0.100/") +@ignore +2006 Oct 29 +For Bob, as root, + gunzip /usr/local/share/emacs/22.0.50/lisp/macros.el.gz +In GNU Emacs 22, eval + (lengths-list-file "/usr/local/share/emacs/22.0.50/lisp/macros.el") +@end ignore + +@c !!! 22.0.100 lisp sources location here +@smallexample +@group +(cd "/usr/local/share/emacs/22.0.100/") (lengths-list-file "./lisp/macros.el") - @result{} (273 263 456 90) -@end group + @result{} (283 263 480 90) +@end group + +@ignore +2006 Oct 29 +For Bob, as root, + gunzip /usr/local/share/emacs/22.0.50/lisp/mail/mailalias.el.gz +In GNU Emacs 22, eval + (lengths-list-file "/usr/local/share/emacs/22.0.50/lisp/mail/mailalias.el") +@end ignore @group (lengths-list-file "./lisp/mail/mailalias.el") - @result{} (38 32 26 77 174 180 321 198 324) -@end group + @result{} (38 32 29 95 178 180 321 218 324) +@end group + +@ignore +2006 Oct 29 +For Bob, as root, + gunzip /usr/local/share/emacs/22.0.50/lisp/makesum.el +In GNU Emacs 22, eval + (lengths-list-file "/usr/local/share/emacs/22.0.50/lisp/makesum.el") +@end ignore @group (lengths-list-file "./lisp/makesum.el") @result{} (85 181) @end group -@group -(recursive-lengths-list-many-files - '("./lisp/macros.el" - "./lisp/mail/mailalias.el" - "./lisp/makesum.el")) - @result{} (273 263 456 90 38 32 26 77 174 180 321 198 324 85 181) +@ignore +2006 Oct 29 +In GNU Emacs 22, eval +(progn + (cd "/usr/local/share/emacs/22.0.50/") + (recursive-lengths-list-many-files + '("./lisp/macros.el" + "./lisp/mail/mailalias.el" + "./lisp/makesum.el"))) +@end ignore + +@group + (recursive-lengths-list-many-files + '("./lisp/macros.el" + "./lisp/mail/mailalias.el" + "./lisp/makesum.el")) + @result{} (283 263 480 90 38 32 29 95 178 180 321 218 324 85 181) @end group @end smallexample @@ -14671,8 +15690,8 @@ that we will need. @menu -* Sorting:: Sorting lists. -* Files List:: Making a list of files. +* Sorting:: +* Files List:: * Counting function definitions:: @end menu @@ -14717,13 +15736,27 @@ @code{recursive-lengths-list-many-files} function is straightforward; it uses the @code{<} function: +@ignore +2006 Oct 29 +In GNU Emacs 22, eval +(progn + (cd "/usr/local/share/emacs/22.0.50/") + (sort + (recursive-lengths-list-many-files + '("./lisp/macros.el" + "./lisp/mail/mailalias.el" + "./lisp/makesum.el")) + '<)) + +@end ignore + @smallexample @group (sort (recursive-lengths-list-many-files - '("../lisp/macros.el" - "../lisp/mailalias.el" - "../lisp/makesum.el")) + '("./lisp/macros.el" + "./lisp/mailalias.el" + "./lisp/makesum.el")) '<) @end group @end smallexample @@ -14733,7 +15766,7 @@ which produces: @smallexample -(85 86 116 122 154 176 179 265) +(29 32 38 85 90 95 178 180 181 218 263 283 321 324 480) @end smallexample @noindent @@ -14779,9 +15812,9 @@ @smallexample @group -("../lisp/macros.el" - "../lisp/mail/rmail.el" - "../lisp/makesum.el") +("./lisp/macros.el" + "./lisp/mail/rmail.el" + "./lisp/makesum.el") @end group @end smallexample @@ -14793,36 +15826,58 @@ element of the list is @code{t} for a directory, a string for symbolic link (the string is the name linked to), or @code{nil}. +@ignore +(directory-files-and-attributes "/usr/local/src/emacs") --> +(... ("lisp" t 21 1000 100 (17733 259) (17732 36064) (17732 36064) 12288 +"drwxr-xr-x" nil 2971606 773)) +@end ignore + + For example, the first @samp{.el} file in the @file{lisp/} directory is @file{abbrev.el}. Its name is -@file{/usr/local/share/emacs/21.0.100/lisp/abbrev.el} and it is not a +@file{/usr/local/share/emacs/22.0.100/lisp/abbrev.el} and it is not a directory or a symbolic link. @need 1000 This is how @code{directory-files-and-attributes} lists that file and its attributes: -@smallexample -@group -("/usr/local/share/emacs/21.0.100/lisp/abbrev.el" +@ignore +(directory-files-and-attributes "/usr/local/src/emacs/lisp") --> +(... ("abbrev.el" nil 1 1000 100 (17733 259) (17491 28834) (17596 62124) +13157 "-rw-r--r--" nil 2971624 773) ...) +@end ignore + +@smallexample +@group +("abbrev.el" nil 1 1000 100 @end group @group -(15019 32380) -(14883 48041) -(15214 49336) -11583 +(17733 259) +(17491 28834) +(17596 62124) +13157 "-rw-rw-r--" @end group @group -t -341385 -776) -@end group -@end smallexample +nil +2971624 +773) +@end group +@end smallexample + +@ignore +(directory-files-and-attributes "/usr/local/src/emacs/lisp/mail/") --> +(("." t 3 1000 100 (17733 1296) (17718 8756) (17718 8756) 4096 "drwxr-xr-x" nil 1273504 773)) + +(directory-files-and-attributes "/usr/local/src/emacs/lisp/") --> +(... ("mail" t 3 1000 100 (17733 1296) (17718 8756) (17718 8756) 4096 +"drwxr-xr-x" nil 1273504 773) ...) +@end ignore @need 1200 On the other hand, @file{mail/} is a directory within the @file{lisp/} @@ -14830,18 +15885,17 @@ @smallexample @group -("/usr/local/share/emacs/21.0.100/lisp/mail" +("mail" t @dots{} ) @end group @end smallexample -(Look at the documentation of @code{file-attributes} to learn about -the different attributes. Bear in mind that the -@code{file-attributes} function does not list the filename, so its -first element is @code{directory-files-and-attributes}'s second -element.) +(To learn about the different attributes, look at the documentation of +@code{file-attributes}. Bear in mind that the @code{file-attributes} +function does not list the filename, so its first element is +@code{directory-files-and-attributes}'s second element.) We will want our new function, @code{files-in-below-directory}, to list the @samp{.el} files in the directory it is told to check, and in @@ -14893,11 +15947,14 @@ using @code{append} as the combiner. @ignore -(directory-files "/usr/local/share/emacs/21.0.100/lisp/" t "\\.el$") -(shell-command "find /usr/local/share/emacs/21.0.100/lisp/ -name '*.el'") -@end ignore - -@c /usr/local/share/emacs/21.0.100/lisp/ +(directory-files "/usr/local/src/emacs/lisp/" t "\\.el$") +(shell-command "find /usr/local/src/emacs/lisp/ -name '*.el'") + +(directory-files "/usr/local/share/emacs/22.0.100/lisp/" t "\\.el$") +(shell-command "find /usr/local/share/emacs/22.0.100/lisp/ -name '*.el'") +@end ignore + +@c /usr/local/share/emacs/22.0.100/lisp/ @need 800 Here is the function: @@ -14909,7 +15966,7 @@ ;; Although the function will be used non-interactively, ;; it will be easier to test if we make it interactive. ;; The directory will have a name such as - ;; "/usr/local/share/emacs/21.0.100/lisp/" + ;; "/usr/local/share/emacs/22.0.100/lisp/" (interactive "DDirectory name: ") @end group @group @@ -14953,7 +16010,8 @@ @end group @end smallexample -@c (files-in-below-directory "/usr/local/share/emacs/21.0.100/lisp/") +@c (files-in-below-directory "/usr/local/src/emacs/lisp/") +@c (files-in-below-directory "/usr/local/share/emacs/22.0.100/lisp/") The @code{files-in-below-directory} @code{directory-files} function takes one argument, the name of a directory. @@ -14961,17 +16019,19 @@ @need 1250 Thus, on my system, -@c !!! 21.0.100 lisp sources location here +@c (length (files-in-below-directory "/usr/local/src/emacs/lisp/")) + +@c !!! 22.0.100 lisp sources location here @smallexample @group (length - (files-in-below-directory "/usr/local/share/emacs/21.0.100/lisp/")) -@end group -@end smallexample - -@noindent -tells me that my version 21.0.100 Lisp sources directory contains 754 -@samp{.el} files. + (files-in-below-directory "/usr/local/share/emacs/22.0.100/lisp/")) +@end group +@end smallexample + +@noindent +tells me that my Lisp sources directory contains 1031 @samp{.el} +files. @code{files-in-below-directory} returns a list in reverse alphabetical order. An expression to sort the list in alphabetical order looks @@ -14980,24 +16040,21 @@ @smallexample @group (sort - (files-in-below-directory "/usr/local/share/emacs/21.0.100/lisp/") + (files-in-below-directory "/usr/local/share/emacs/22.0.100/lisp/") 'string-lessp) @end group @end smallexample @ignore (defun test () - "Test how long it takes to find lengths of all elisp defuns." + "Test how long it takes to find lengths of all sorted elisp defuns." (insert "\n" (current-time-string) "\n") (sit-for 0) (sort (recursive-lengths-list-many-files - '("../lisp/macros.el" - "../lisp/mailalias.el" - "../lisp/makesum.el")) + (files-in-below-directory "/usr/local/src/emacs/lisp/")) '<) (insert (format "%s" (current-time-string)))) - @end ignore @node Counting function definitions, , Files List, Prepare the data @@ -15259,11 +16316,14 @@ @c colon in printed section title causes problem in Info cross reference This way, we avoid an error. @iftex -@xref{forward-paragraph, , @code{forward-paragraph}: a Goldmine of -Functions}, for more information about @code{and}. +@noindent +(For information about @code{and}, see +@ref{kill-new function, , The @code{kill-new} function}.) @end iftex @ifinfo -@xref{forward-paragraph}, for more information about @code{and}. +@noindent +(@xref{kill-new function, , The @code{kill-new} function}, for +information about @code{and}.) @end ifinfo Here is a short test of the @code{defuns-per-range} function. First, @@ -15301,7 +16361,6 @@ of 200 or larger. @c The next step is to turn this numbers' list into a graph. - @node Readying a Graph, Emacs Initialization, Words in a defun, Top @chapter Readying a Graph @cindex Readying a graph @@ -15328,7 +16387,7 @@ @menu * Columns of a graph:: -* graph-body-print:: How to print the body of a graph. +* graph-body-print:: * recursive-graph-body-print:: * Printed Axes:: * Line Graph Exercise:: @@ -15363,7 +16422,7 @@ own column-insertion function or discover whether one exists in Emacs. To see whether there is one in Emacs, we can use the @kbd{M-x apropos} -command. This command is like the @kbd{C-h a} (command-apropos) +command. This command is like the @kbd{C-h a} (@code{command-apropos}) command, except that the latter finds only those functions that are commands. The @kbd{M-x apropos} command lists all symbols that match a regular expression, including functions that are not interactive. @@ -15374,9 +16433,11 @@ the word `print' or the word `insert' or the word `column'. Therefore, we can simply type @kbd{M-x apropos RET print\|insert\|column RET} and look at the result. On my system, this -command takes quite some time, and then produces a list of 79 -functions and variables. Scanning down the list, the only function -that looks as if it might do the job is @code{insert-rectangle}. +command once too takes quite some time, and then produced a list of 79 +functions and variables. Now it does not take much time at all and +produces a list of 211 functions and variables. Scanning down the +list, the only function that looks as if it might do the job is +@code{insert-rectangle}. @need 1200 Indeed, this is the function we want; its documentation says: @@ -15388,6 +16449,8 @@ RECTANGLE's first line is inserted at point, its second line is inserted at a point vertically under point, etc. RECTANGLE should be a list of strings. +After this command, the mark is at the upper left corner +and point is at the lower right corner. @end group @end smallexample @@ -15403,8 +16466,7 @@ @group (insert-rectangle '("first" "second" "third"))first second - third -nil + thirdnil @end group @end smallexample @@ -15418,12 +16480,14 @@ If you are reading this in Info, you can see how this works by switching to another buffer, such as the @file{*scratch*} buffer, -placing point somewhere in the buffer, typing @kbd{M-:}, -typing the @code{insert-rectangle} expression into the minibuffer at -the prompt, and then typing @key{RET}. This causes Emacs to evaluate -the expression in the minibuffer, but to use as the value of point the -position of point in the @file{*scratch*} buffer. (@kbd{M-:} -is the keybinding for @code{eval-expression}.) +placing point somewhere in the buffer, typing @kbd{M-:}, typing the +@code{insert-rectangle} expression into the minibuffer at the prompt, +and then typing @key{RET}. This causes Emacs to evaluate the +expression in the minibuffer, but to use as the value of point the +position of point in the @file{*scratch*} buffer. (@kbd{M-:} is the +keybinding for @code{eval-expression}. Also, @code{nil} does not +appear in the @file{*scratch*} buffer since the expression is +evaluated in the minibuffer.) We find when we do this that point ends up at the end of the last inserted line---that is to say, this function moves point as a @@ -15983,20 +17047,20 @@ @menu * 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 @code{.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 version 19 in X. +* Site-wide Init:: +* defcustom:: +* Beginning a .emacs File:: +* Text and Auto-fill:: +* Mail Aliases:: +* Indent Tabs Mode:: +* Keybindings:: +* Keymaps:: +* Loading Files:: +* Autoload:: +* Simple Extension:: +* X11 Colors:: * Miscellaneous:: -* Mode Line:: How to customize your mode line. +* Mode Line:: @end menu @node Default Configuration, Site-wide Init, Emacs Initialization, Emacs Initialization @@ -16011,7 +17075,11 @@ sense, if you do not know who is going to use Emacs. Who knows what a person hopes to do with an unadorned file? Fundamental mode is the right default for such a file, just as C mode is the right default for -editing C code. But when you do know who is going to use Emacs---you, +editing C code. (Enough programming languages have syntaxes +that enable them to share or nearly share features, so C mode is +now provided by by CC mode, the `C Collection'.) + +But when you do know who is going to use Emacs---you, yourself---then it makes sense to customize Emacs. For example, I seldom want Fundamental mode when I edit an @@ -16169,8 +17237,8 @@ @noindent and find that the group for editing files of data is called `data'. Enter that group. Text Mode Hook is the first member. You can click -on its various options to set the values. After you click on the -button to +on its various options, such as @code{turn-on-auto-fill}, to set the +values. After you click on the button to @smallexample Save for Future Sessions @@ -16183,24 +17251,22 @@ @smallexample @group (custom-set-variables - ;; custom-set-variables was added by Custom -- - ;; don't edit or cut/paste it! + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify)))) @end group @end smallexample @noindent (The @code{text-mode-hook-identify} function tells -@code{toggle-text-mode-auto-fill} which buffers are in Text mode.) - -In spite of the warning, you certainly may edit, cut, and paste the -expression! I do all time. The purpose of the warning is to scare -those who do not know what they are doing, so they do not -inadvertently generate an error. +@code{toggle-text-mode-auto-fill} which buffers are in Text mode. +It comes on automatically. +) The @code{custom-set-variables} function works somewhat differently -than a @code{setq}. While I have never learned the differences, I do +than a @code{setq}. While I have never learned the differences, I modify the @code{custom-set-variables} expressions in my @file{.emacs} file by hand: I make the changes in what appears to me to be a reasonable manner and have not had any problems. Others prefer to use @@ -16221,7 +17287,7 @@ message that says @smallexample -this option has been changed outside the customize buffer. +CHANGED outside Customize; operating on it here may be unreliable. @end smallexample @need 800 @@ -16338,12 +17404,11 @@ @smallexample @group ;;; Text mode and Auto Fill mode -; The next three lines put Emacs into Text mode +; The next two lines put Emacs into Text mode ; and Auto Fill mode, and are for writers who ; want to start writing prose rather than code. (setq default-major-mode 'text-mode) -(add-hook 'text-mode-hook 'text-mode-hook-identify) (add-hook 'text-mode-hook 'turn-on-auto-fill) @end group @end smallexample @@ -16404,33 +17469,28 @@ else in Emacs. @need 800 -Here are the next two lines: +Here is the next line: @cindex Auto Fill mode turned on @findex add-hook @smallexample -(add-hook 'text-mode-hook 'text-mode-hook-identify) (add-hook 'text-mode-hook 'turn-on-auto-fill) @end smallexample @noindent -In these two lines, the @code{add-hook} command first adds -@code{text-mode-hook-identify} to the variable called -@code{text-mode-hook} and then adds @code{turn-on-auto-fill} to the -variable. +In this line, the @code{add-hook} command adds +@code{turn-on-auto-fill} to the variable. @code{turn-on-auto-fill} is the name of a program, that, you guessed -it!, turns on Auto Fill mode. @code{text-mode-hook-identify} is a -function that tells @code{toggle-text-mode-auto-fill} which buffers -are in Text mode. +it!, turns on Auto Fill mode. Every time Emacs turns on Text mode, Emacs runs the commands `hooked' onto Text mode. So every time Emacs turns on Text mode, Emacs also turns on Auto Fill mode. -In brief, the first line causes Emacs to enter Text mode when you edit -a file, unless the file name extension, first non-blank line, or local -variables tell Emacs otherwise. +In brief, the first line causes Emacs to enter Text mode when you edit a +file, unless the file name extension, a first non-blank line, or local +variables to tell Emacs otherwise. Text mode among other actions, sets the syntax table to work conveniently for writers. In Text mode, Emacs considers an apostrophe @@ -16439,11 +17499,10 @@ @samp{it's}. On the other hand, in C mode, @kbd{M-f} stops just after the @samp{t} of @samp{it's}. -The second and third lines causes Emacs to turn on Auto Fill mode when -it turns on Text mode. In Auto Fill mode, Emacs automatically breaks -a line that is too wide and brings the excessively wide part of the -line down to the next line. Emacs breaks lines between words, not -within them. +The second line causes Emacs to turn on Auto Fill mode when it turns +on Text mode. In Auto Fill mode, Emacs automatically breaks a line +that is too wide and brings the excessively wide part of the line down +to the next line. Emacs breaks lines between words, not within them. When Auto Fill mode is turned off, lines continue to the right as you type them. Depending on how you set the value of @@ -16785,7 +17844,10 @@ (defun load-library (library) "Load the library named LIBRARY. This is an interface to the function `load'." - (interactive "sLoad library: ") + (interactive + (list (completing-read "Load library: " + 'locate-file-completion + (cons load-path (get-load-suffixes))))) (load library)) @end group @end smallexample @@ -16822,12 +17884,12 @@ load that function's file with a @code{load} expression in your @file{.emacs} file. -In my @file{.emacs} file for Emacs version 21, I load 12 libraries +In my @file{.emacs} file for Emacs version 22, I load 14 libraries that contain functions that would otherwise be autoloaded. (Actually, -it would have been better to include these files in my `dumped' Emacs -when I built it, but I forgot. @xref{Building Emacs, , Building -Emacs, elisp, The GNU Emacs Lisp Reference Manual}, and the @file{INSTALL} -file for more about dumping.) +it would have been better to include these files in my `dumped' Emacs, +but I forgot. @xref{Building Emacs, , Building Emacs, elisp, The GNU +Emacs Lisp Reference Manual}, and the @file{INSTALL} file for more +about dumping.) You may also want to include autoloaded expressions in your @file{.emacs} file. @code{autoload} is a built-in function that takes up to five @@ -16916,18 +17978,18 @@ @cindex Conditional 'twixt two versions of Emacs @cindex Version of Emacs, choosing @cindex Emacs version, choosing -If you run two versions of GNU Emacs, such as versions 20 and 21, and +If you run two versions of GNU Emacs, such as versions 21 and 22, and use one @file{.emacs} file, you can select which code to evaluate with the following conditional: @smallexample @group (cond - ((string-equal (number-to-string 20) (substring (emacs-version) 10 12)) - ;; evaluate version 20 code - ( @dots{} )) ((string-equal (number-to-string 21) (substring (emacs-version) 10 12)) ;; evaluate version 21 code + ( @dots{} )) + ((string-equal (number-to-string 22) (substring (emacs-version) 10 12)) + ;; evaluate version 22 code ( @dots{} ))) @end group @end smallexample @@ -16940,6 +18002,10 @@ @smallexample emacs -q --no-site-file -eval '(blink-cursor-mode nil)' + +@exdent Or nowadays, using an even more sophisticated set of options, + +emacs -Q - D @end smallexample }: @@ -17055,16 +18121,12 @@ @end smallexample In any event, since it is not part of Emacs, I set the root color of -my X window in my @file{~/.xinitrc} file, like this@footnote{I -occasionally run more modern window managers, such as Sawfish with -GNOME, Enlightenment, SCWM, or KDE; in those cases, I often specify an -image rather than a plain color.}: - -@smallexample -@group -# I use TWM for window manager. +my X window in my @file{~/.xinitrc} file, like this@footnote{I also +run more modern window managers, such as Enlightenment, Gnome, or KDE; +in those cases, I often specify an image rather than a plain color.}: + +@smallexample xsetroot -solid Navy -fg white & -@end group @end smallexample @node Miscellaneous, Mode Line, X11 Colors, Emacs Initialization @@ -17076,6 +18138,7 @@ @itemize @minus @item Set the shape and color of the mouse cursor: + @smallexample @group ; Cursor shapes are defined in @@ -17099,6 +18162,32 @@ @end smallexample @item +Or you can set the values of a variety of features in an alist, like +this: + +@smallexample +@group +(setq-default + default-frame-alist + '((cursor-color . "white") + (mouse-color . "white") + (foreground-color . "white") + (background-color . "DodgerBlue4") + ;; (cursor-type . bar) + (cursor-type . box) +@end group +@group + (tool-bar-lines . 0) + (menu-bar-lines . 1) + (width . 80) + (height . 58) + (font . + "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1") + )) +@end group +@end smallexample + +@item Convert @kbd{@key{CTL}-h} into @key{DEL} and @key{DEL} into @kbd{@key{CTL}-h}.@* (Some older keyboards needed this, although I have not seen the @@ -17123,6 +18212,9 @@ @end group @end smallexample +@noindent +or start GNU Emacs with the command @code{emacs -nbc}. + @item Ignore case when using `grep'@* @samp{-n}@w{ } Prefix each line of output with line number@* @samp{-i}@w{ } Ignore case distinctions@* @@ -17132,11 +18224,16 @@ (setq grep-command "grep -n -i -e ") @end smallexample -@item Automatically uncompress compressed files when visiting them - -@smallexample +@ignore +@c Evidently, no longer needed in GNU Emacs 22 + +item Automatically uncompress compressed files when visiting them + +smallexample (load "uncompress") -@end smallexample +end smallexample + +@end ignore @item Find an existing buffer, even if it has a different name@* This avoids problems with symbolic links. @@ -17305,8 +18402,8 @@ nowadays, Emacs can add properties to a string, such as highlighting or, as in this case, a help feature. If you place your mouse cursor over the hyphen, some help information appears (By default, you must -wait one second before the information appears. You can change that -timing by changing the value of @code{tooltip-delay}.) +wait seven-tenths of a second before the information appears. You can +change that timing by changing the value of @code{tooltip-delay}.) @need 1000 The new string format has a special syntax: @@ -17344,7 +18441,7 @@ characters; this length works well in a typical 80 column wide window.) -@code{:eval} is a new feature in GNU Emacs version 21. It says to +@code{:eval} was a new feature in GNU Emacs version 21. It says to evaluate the following form and use the result as a string to display. In this case, the expression displays the first component of the full system name. The end of the first component is a @samp{.} (`period'), @@ -17399,10 +18496,10 @@ In this chapter, I will walk through a short example of each. @menu -* 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 @kbd{C-g}. -* edebug:: How to use Edebug, a source level debugger. +* debug:: +* debug-on-entry:: +* debug-on-quit:: +* edebug:: * Debugging Exercises:: @end menu @@ -17479,6 +18576,7 @@ tell you what you need to know to correct the definition. The function @code{1=} is `void'. +@ignore @need 800 In GNU Emacs 20 and before, you will see: @@ -17489,11 +18587,12 @@ @noindent which has the same meaning as the @file{*Backtrace*} buffer line in version 21. +@end ignore However, suppose you are not quite certain what is going on? You can read the complete backtrace. -In this case, you need to run GNU Emacs 21, which automatically starts +In this case, you need to run GNU Emacs 22, which automatically starts the debugger that puts you in the @file{*Backtrace*} buffer; or else, you need to start the debugger manually as described below. @@ -17535,14 +18634,18 @@ @section @code{debug-on-entry} @findex debug-on-entry -GNU Emacs 21 starts the debugger automatically when your function has -an error. GNU Emacs version 20 and before did not; it simply +GNU Emacs 22 starts the debugger automatically when your function has +an error. + +@ignore +GNU Emacs version 20 and before did not; it simply presented you with an error message. You had to start the debugger manually. - -You can start the debugger manually for all versions of Emacs; the -advantage is that the debugger runs even if you do not have a bug in -your code. Sometimes your code will be free of bugs! +@end ignore + +Incidently, you can start the debugger manually for all versions of +Emacs; the advantage is that the debugger runs even if you do not have +a bug in your code. Sometimes your code will be free of bugs! You can enter the debugger when you call the function by calling @code{debug-on-entry}. @@ -17796,13 +18899,13 @@ move point past @code{number}, you will see the following: @smallexample -Result: 3 = C-c -@end smallexample - -@noindent -This means the value of @code{number} is 3, which is @sc{ascii} -`control-c' (the third letter of the alphabet, in case you need to -know this information). +Result: 3 (#o3, #x3, ?\C-c) +@end smallexample + +@noindent +This means the value of @code{number} is 3, which is octal three, +hexadecimal three, and @sc{ascii} `control-c' (the third letter of the +alphabet, in case you need to know this information). You can continue moving through the code until you reach the line with the error. Before evaluation, that line looks like this: @@ -17872,7 +18975,7 @@ @code{count-words-region} is working. @item -Move point to some spot further down function and then type the +Move point to some spot further down the function and then type the @kbd{h} (@code{edebug-goto-here}) command to jump to that location. @item @@ -17922,8 +19025,8 @@ on-line and as a typeset, printed book.) Go to the other on-line help that is part of GNU Emacs: the on-line -documentation for all functions, and @code{find-tags}, the program -that takes you to sources. +documentation for all functions and variables, and @code{find-tags}, +the program that takes you to sources. Here is an example of how I explore the sources. Because of its name, @file{simple.el} is the file I looked at first, a long time ago. As @@ -17932,21 +19035,16 @@ function, for example, looks complicated. You may want to walk through this function slowly, as we did with the -@code{forward-sentence} function. -@ifnottex -(@xref{forward-sentence}.) -@end ifnottex -@iftex -(@xref{forward-sentence, , @code{forward-sentence}}.) -@end iftex -Or you may want to skip that function and look at another, such as -@code{split-line}. You don't need to read all the functions. -According to @code{count-words-in-defun}, the @code{split-line} -function contains 27 words and symbols. - -Even though it is short, @code{split-line} contains four expressions +@code{forward-sentence} function. (@xref{forward-sentence, The +@code{forward-sentence} function}.) Or you may want to skip that +function and look at another, such as @code{split-line}. You don't +need to read all the functions. According to +@code{count-words-in-defun}, the @code{split-line} function contains +102 words and symbols. + +Even though it is short, @code{split-line} contains expressions we have not studied: @code{skip-chars-forward}, @code{indent-to}, -@code{current-column} and @samp{?\n}. +@code{current-column} and @code{insert-and-inherit}. Consider the @code{skip-chars-forward} function. (It is part of the function definition for @code{back-to-indentation}, which is shown in @@ -17974,25 +19072,17 @@ character codes; and it shows how to create a temporary buffer. (The @code{indent-to} function is written in C rather than Emacs Lisp; -it is a `built-in' function. @code{help-follow} only provides you -with the documentation of a built-in function; it does not take you to -the source. But @code{find-tag} will take you to the source, if -properly set up.) +it is a `built-in' function. @code{help-follow} takes you to its +source as does @code{find-tag}, when properly set up.) You can look at a function's source using @code{find-tag}, which is bound to @kbd{M-.} Finally, you can find out what the Reference Manual has to say by visiting the manual in Info, and typing @kbd{i} -(@code{Info-index}) and the name of the function, or by looking up -@code{skip-chars-forward} in the index to a printed copy of the -manual. - -Similarly, you can find out what is meant by @samp{?\n}. You can try -using @code{Info-index} with @samp{?\n}. It turns out that this -action won't help; but don't give up. If you search the index for -@samp{\n} without the @samp{?}, you will be taken directly to the -relevant section of the manual. (@xref{Character Type, , Character -Type, elisp, The GNU Emacs Lisp Reference Manual}. @samp{?\n} stands -for the newline character.) +(@code{Info-index}) and the name of the function, or by looking up the +function in the index to a printed copy of the manual. + +Similarly, you can find out what is meant by +@code{insert-and-inherit}. Other interesting source files include @file{paragraphs.el}, @file{loaddefs.el}, and @file{loadup.el}. The @file{paragraphs.el} @@ -18115,53 +19205,82 @@ You can substitute the other regular expressions shown above in the function definition and try each of them on this list. -@node Kill Ring, Full Graph, the-the, Top -@appendix Handling the Kill Ring -@cindex Kill ring handling -@cindex Handling the kill ring -@cindex Ring, making a list like a - -The kill ring is a list that is transformed into a ring by the -workings of the @code{rotate-yank-pointer} function. The @code{yank} -and @code{yank-pop} commands use the @code{rotate-yank-pointer} -function. This appendix describes the @code{rotate-yank-pointer} -function as well as both the @code{yank} and the @code{yank-pop} -commands. - -@menu -* rotate-yank-pointer:: Move a pointer along a list and around. -* yank:: Paste a copy of a clipped element. -* yank-pop:: Insert first element pointed to. -* ring file:: -@end menu - -@node rotate-yank-pointer, yank, Kill Ring, Kill Ring -@comment node-name, next, previous, up -@appendixsec The @code{rotate-yank-pointer} Function -@findex rotate-yank-pointer - -The @code{rotate-yank-pointer} function changes the element in the kill -ring to which @code{kill-ring-yank-pointer} points. For example, it can -change @code{kill-ring-yank-pointer} from pointing to the second -element to point to the third element. - -@need 800 -Here is the code for @code{rotate-yank-pointer}: - -@smallexample -@group -(defun rotate-yank-pointer (arg) - "Rotate the yanking point in the kill ring." - (interactive "p") - (let ((length (length kill-ring))) -@end group -@group - (if (zerop length) - ;; @r{then-part} - (error "Kill ring is empty") -@end group -@group - ;; @r{else-part} +@c done til here 2006 Oct 29 + +@ignore + + + +@end ignore + + +@ignore +as of GNU Emacs 22, this no longer seems to be the case +with yank yank-pop + +guts of rotate-yank-pointer moved to current-kill +in simple.el + +(defun current-kill (n &optional do-not-move) + "Rotate the yanking point by N places, and then return that kill. + +critical part is: + + (let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (or do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element)) + (car ARGth-kill-element)) + + + + (mod X Y) + Return X modulo Y. + + (% X Y) + Return remainder of X divided by Y. + + (mod 12 3) 0 (#o0, #x0, ?\C-@) + (mod 4 3) 1 + (mod 13 3) 1 + + (% 12 3) 0 + (% 4 3) 1 + (% 13 3) 1 + + mod returns the value of DIVIDEND modulo DIVISOR; in + other words, the remainder after division of DIVIDEND by DIVISOR, + but with the same sign as DIVISOR. The arguments must be numbers + or markers. + + Unlike `%', `mod' returns a well-defined result for negative + arguments. It also permits floating point arguments; it rounds the + quotient downward (towards minus infinity) to an integer, and uses + that quotient to compute the remainder. + + % returns the integer remainder after division of + DIVIDEND by DIVISOR. The arguments must be integers or markers. + + For negative arguments, the remainder is in principle + machine-dependent since the quotient is; but in practice, all + known machines behave alike. + + + +rotate-yank-pointer has + +reformatted: + (let ((length (length kill-ring))) + ... + (setq kill-ring-yank-pointer + (nthcdr (% (+ arg + (- length (length kill-ring-yank-pointer))) + length) + kill-ring))))) + +originally (setq kill-ring-yank-pointer (nthcdr (% (+ arg (- length @@ -18169,108 +19288,292 @@ kill-ring-yank-pointer))) length) kill-ring))))) -@end group -@end smallexample - -@menu -* Understanding rotate-yk-ptr:: -* rotate-yk-ptr body:: The body of @code{rotate-yank-pointer}. -@end menu - -@node Understanding rotate-yk-ptr, rotate-yk-ptr body, rotate-yank-pointer, rotate-yank-pointer -@ifnottex -@unnumberedsubsec @code{rotate-yank-pointer} in Outline -@end ifnottex - -The @code{rotate-yank-pointer} function looks complex, but as usual, -it can be understood by taking it apart piece by piece. First look at -it in skeletal form: - -@smallexample -@group -(defun rotate-yank-pointer (arg) - "Rotate the yanking point in the kill ring." - (interactive "p") + + + + + + +/usr/local/src/emacs/lisp/ChangeLog.3 +1992-05-21 Jim Blandy (jimb@pogo.cs.oberlin.edu) +simple.el + (yank-pop): Use current-kill, rather than assuming that + kill-ring-yank-pointer points to the text you should use. + (yank): Use current-kill, instead of calling rotate-yank-pointer + and then fetching through the kill-ring-yank-pointer. + +@end ignore + +@node Kill Ring, Full Graph, the-the, Top +@appendix Handling the Kill Ring +@cindex Kill ring handling +@cindex Handling the kill ring +@cindex Ring, making a list like a + +The kill ring is a list that is transformed into a ring by the +workings of the @code{current-kill} function. The @code{yank} and +@code{yank-pop} commands use the @code{current-kill} function. + +This appendix describes the @code{current-kill} function as well as +both the @code{yank} and the @code{yank-pop} commands, but first, +consider the workings of the kill ring. + +@need 1250 +The kill ring has a default maximum length of sixty items; this number +is too large for an explanation. Instead, set it to four. Please +evaluate the following: + +@smallexample +@group +(setq old-kill-ring-max kill-ring-max) +(setq kill-ring-max 4) +@end group +@end smallexample + +@noindent +Then, please copy each line of the following indented example into the +kill ring. You may kill each line with @kbd{C-k} or mark it and copy +it with @kbd{M-w}. + +@noindent +(In a read-only buffer, such as the @file{*info*} buffer, the kill +command, @kbd{C-k} (@code{kill-line}), will not remove the text, +merely copy it to the kill ring. However, your machine may beep at +you. Alternatively, for silence, you may copy the region of each line +with the @kbd{M-w} (@code{kill-ring-save}) command. You must mark +each line for this command to succeed, but it does not matter at which +end you put point or mark.) + +@need 1250 +@noindent +Please invoke the calls in order, so that five elements attempt to +fill the kill ring: + +@smallexample +@group +first some text +second piece of text +third line +fourth line of text +fifth bit of text +@end group +@end smallexample + +@need 1250 +@noindent +Then find the value of @code{kill-ring} by evaluating + +@smallexample +kill-ring +@end smallexample + +@need 800 +@noindent +It is: + +@smallexample +@group +("fifth bit of text" "fourth line of text" +"third line" "second piece of text") +@end group +@end smallexample + +@noindent +The first element, @samp{first some text}, was dropped. + +@need 1250 +To return to the old value for the length of the kill ring, evaluate: + +@smallexample +(setq kill-ring-max old-kill-ring-max) +@end smallexample + +@menu +* current-kill:: +* yank:: +* yank-pop:: +* ring file:: +@end menu + +@node current-kill, yank, Kill Ring, Kill Ring +@comment node-name, next, previous, up +@appendixsec The @code{current-kill} Function +@findex current-kill + +The @code{current-kill} function changes the element in the kill ring +to which @code{kill-ring-yank-pointer} points. (Also, the +@code{kill-new} function sets @code{kill-ring-yank-pointer} to point +to the latest element of the the kill ring.) + +@need 1500 +The @code{current-kill} function is used by @code{yank} and by +@code{yank-pop}. Here is the code for @code{current-kill}: + +@smallexample +@group +(defun current-kill (n &optional do-not-move) + "Rotate the yanking point by N places, and then return that kill. +If N is zero, `interprogram-paste-function' is set, and calling it +returns a string, then that string is added to the front of the +kill ring and returned as the latest kill. +@end group +@group +If optional arg DO-NOT-MOVE is non-nil, then don't actually move the +yanking point; just return the Nth kill forward." + (let ((interprogram-paste (and (= n 0) + interprogram-paste-function + (funcall interprogram-paste-function)))) +@end group +@group + (if interprogram-paste + (progn + ;; Disable the interprogram cut function when we add the new + ;; text to the kill ring, so Emacs doesn't try to own the + ;; selection, with identical text. + (let ((interprogram-cut-function nil)) + (kill-new interprogram-paste)) + interprogram-paste) +@end group +@group + (or kill-ring (error "Kill ring is empty")) + (let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (or do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element)) + (car ARGth-kill-element))))) +@end group +@end smallexample + +In addition, the @code{kill-new} function sets +@code{kill-ring-yank-pointer} to the latest element of the the kill +ring. And indirectly so does @code{kill-append}, since it calls +@code{kill-new}. In addition, @code{kill-region} and @code{kill-line} +call the @code{kill-new} function. + +@need 1500 +Here is the line in @code{kill-new}, which is explained in +@ref{kill-new function, , The @code{kill-new} function}. + +@smallexample +(setq kill-ring-yank-pointer kill-ring) +@end smallexample + +@menu +* Understanding current-kill:: +@end menu + +@node Understanding current-kill, , current-kill, current-kill +@ifnottex +@unnumberedsubsec @code{current-kill} in Outline +@end ifnottex + +The @code{current-kill} function looks complex, but as usual, it can +be understood by taking it apart piece by piece. First look at it in +skeletal form: + +@smallexample +@group +(defun current-kill (n &optional do-not-move) + "Rotate the yanking point by N places, and then return that kill. (let @var{varlist} @var{body}@dots{}) @end group @end smallexample -This function takes one argument, called @code{arg}. It has a brief -documentation string; and it is interactive with a small @samp{p}, which -means that the argument must be a processed prefix passed to the -function as a number. +This function takes two arguments, one of which is optional. It has a +documentation string. It is @emph{not} interactive. The body of the function definition is a @code{let} expression, which itself has a body as well as a @var{varlist}. The @code{let} expression declares a variable that will be only usable within the bounds of this function. This variable is called -@code{length} and is bound to a value that is equal to the number of -items in the kill ring. This is done by using the function called -@code{length}. (Note that this function has the same name as the -variable called @code{length}; but one use of the word is to name the -function and the other is to name the variable. The two are quite -distinct. Similarly, an English speaker will distinguish between the -meanings of the word @samp{ship} when he says: "I must ship this package -immediately." and "I must get aboard the ship immediately.") - -The function @code{length} tells the number of items there are in a list, -so @code{(length kill-ring)} returns the number of items there are in the -kill ring. - -@node rotate-yk-ptr body, , Understanding rotate-yk-ptr, rotate-yank-pointer -@comment node-name, next, previous, up -@appendixsubsec The Body of @code{rotate-yank-pointer} - -The body of @code{rotate-yank-pointer} is a @code{let} expression and -the body of the @code{let} expression is an @code{if} expression. - -The purpose of the @code{if} expression is to find out whether there is -anything in the kill ring. If the kill ring is empty, the @code{error} -function stops evaluation of the function and prints a message in the -echo area. On the other hand, if the kill ring has something in it, the -work of the function is done. - -Here is the if-part and then-part of the @code{if} expression: +@code{interprogram-paste} and is for copying to another program. It +is not for copying within this instance of GNU Emacs. Most window +systems provide a facility for interprogram pasting. Sadly, that +facility usually provides only for the lasted element. Most windowing +systems have not adopted a ring of many possiblities, even though +Emacs has provided it for decades. + +The @code{if} expression has two parts, one if there exists +@code{interprogram-paste} and one if not. + +@need 2000 +Let us consider the `if not' or else-part of the @code{current-kill} +function. (The then-part uses the the @code{kill-new} function, which +we have already described. (@xref{kill-new function, , The +@code{kill-new} function}.) + +@smallexample +@group +(or kill-ring (error "Kill ring is empty")) +(let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (or do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element)) + (car ARGth-kill-element)) +@end group +@end smallexample + +@noindent +The code first checks whether the kill ring has content; otherwise it +signals an error. + +@need 1000 +Note that the @code{or} expression is very similar to writing @findex zerop @findex error @smallexample @group -(if (zerop length) ; @r{if-part} - (error "Kill ring is empty") ; @r{then-part} - @dots{} +(if (zerop (length kill-ring)) ; @r{if-part} + (error "Kill ring is empty")) ; @r{then-part} + ;; No else-part @end group @end smallexample @noindent If there is not anything in the kill ring, its length must be zero and an error message sent to the user: @samp{Kill ring is empty}. The -@code{if} expression uses the function @code{zerop} which returns true -if the value it is testing is zero. When @code{zerop} tests true, the -then-part of the @code{if} is evaluated. The then-part is a list -starting with the function @code{error}, which is a function that is -similar to the @code{message} function (@pxref{message}), in that it -prints a one-line message in the echo area. However, in addition to -printing a message, @code{error} also stops evaluation of the function -within which it is embedded. This means that the rest of the function -will not be evaluated if the length of the kill ring is zero. - -@menu -* Digression concerning error:: How to mislead humans, but not computers. -* rotate-yk-ptr else-part:: The else-part of the @code{if} expression. -* Remainder Function:: The remainder, @code{%}, function. -* rotate-yk-ptr remainder:: Using @code{%} in @code{rotate-yank-pointer}. -* kill-rng-yk-ptr last elt:: Pointing to the last element. -@end menu - -@node Digression concerning error, rotate-yk-ptr else-part, rotate-yk-ptr body, rotate-yk-ptr body +@code{current-kill} function uses an @code{or} expression which is +simpler. But an @code{if} expression reminds us what goes on. + +This @code{if} expression uses the function @code{zerop} which returns +true if the value it is testing is zero. When @code{zerop} tests +true, the then-part of the @code{if} is evaluated. The then-part is a +list starting with the function @code{error}, which is a function that +is similar to the @code{message} function +(@pxref{message, , The @code{message} Function}), in that +it prints a one-line message in the echo area. However, in addition +to printing a message, @code{error} also stops evaluation of the +function within which it is embedded. This means that the rest of the +function will not be evaluated if the length of the kill ring is zero. + +Then the @code{current-kill} function selects the element to return. +The selection depends on the number of places that @code{current-kill} +rotates and on where @code{kill-ring-yank-pointer} points. + +Next, either the optional @code{do-not-move} argument is true or the +current value of @code{kill-ring-yank-pointer} is set to point to the +list, the first element of which is returned even if the +@code{do-not-move} argument is true. + + +@menu +* Digression concerning error:: +* Determining the Element :: +@end menu + +@node Digression concerning error, Determining the Element , Understanding current-kill, Understanding current-kill @ifnottex @unnumberedsubsubsec Digression about the word `error' @end ifnottex -(In my opinion, it is slightly misleading, at least to humans, to use +In my opinion, it is slightly misleading, at least to humans, to use the term `error' as the name of the @code{error} function. A better term would be `cancel'. Strictly speaking, of course, you cannot point to, much less rotate a pointer to a list that has no length, so @@ -18285,86 +19588,38 @@ that a human who is acting virtuously, by exploring his or her environment, is making an error. This is bad. Even though the computer takes the same steps as it does when there is an `error', a term such as -`cancel' would have a clearer connotation.) - -@node rotate-yk-ptr else-part, Remainder Function, Digression concerning error, rotate-yk-ptr body -@unnumberedsubsubsec The else-part of the @code{if} expression - -The else-part of the @code{if} expression is dedicated to setting the -value of @code{kill-ring-yank-pointer} when the kill ring has something -in it. The code looks like this: - -@smallexample -@group -(setq kill-ring-yank-pointer - (nthcdr (% (+ arg - (- length - (length kill-ring-yank-pointer))) - length) - kill-ring))))) -@end group -@end smallexample - -This needs some examination. Clearly, @code{kill-ring-yank-pointer} -is being set to be equal to some @sc{cdr} of the kill ring, using the +`cancel' would have a clearer connotation. + +@node Determining the Element , , Digression concerning error, Understanding current-kill +@ifnottex +@unnumberedsubsubsec Determining the Element +@end ifnottex + +Among other actions, the else-part of the @code{if} expression sets +the value of @code{kill-ring-yank-pointer} to +@code{ARGth-kill-element} when the kill ring has something in it and +the value of @code{do-not-move} is @code{nil}. + +@need 800 +The code looks like this: + +@smallexample +@group +(nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) +@end group +@end smallexample + +This needs some examination. Unless it is not supposed to move the +pointer, the @code{current-kill} function changes where +@code{kill-ring-yank-pointer} points. +That is what the +@w{@code{(setq kill-ring-yank-pointer ARGth-kill-element))}} +expression does. Also, clearly, @code{ARGth-kill-element} is being +set to be equal to some @sc{cdr} of the kill ring, using the @code{nthcdr} function that is described in an earlier section. -(@xref{copy-region-as-kill}.) But exactly how does it do this? - -Before looking at the details of the code let's first consider the -purpose of the @code{rotate-yank-pointer} function. - -The @code{rotate-yank-pointer} function changes what -@code{kill-ring-yank-pointer} points to. If -@code{kill-ring-yank-pointer} starts by pointing to the first element -of a list, a call to @code{rotate-yank-pointer} causes it to point to -the second element; and if @code{kill-ring-yank-pointer} points to the -second element, a call to @code{rotate-yank-pointer} causes it to -point to the third element. (And if @code{rotate-yank-pointer} is -given an argument greater than 1, it jumps the pointer that many -elements.) - -The @code{rotate-yank-pointer} function uses @code{setq} to reset what -the @code{kill-ring-yank-pointer} points to. If -@code{kill-ring-yank-pointer} points to the first element of the kill -ring, then, in the simplest case, the @code{rotate-yank-pointer} -function must cause it to point to the second element. Put another -way, @code{kill-ring-yank-pointer} must be reset to have a value equal -to the @sc{cdr} of the kill ring. - -@need 1250 -That is, under these circumstances, - -@smallexample -@group -(setq kill-ring-yank-pointer - ("some text" "a different piece of text" "yet more text")) - -(setq kill-ring - ("some text" "a different piece of text" "yet more text")) -@end group -@end smallexample - -@need 800 -@noindent -the code should do this: - -@smallexample -(setq kill-ring-yank-pointer (cdr kill-ring)) -@end smallexample - -@need 1000 -@noindent -As a result, the @code{kill-ring-yank-pointer} will look like this: - -@smallexample -@group -kill-ring-yank-pointer - @result{} ("a different piece of text" "yet more text")) -@end group -@end smallexample - -The actual @code{setq} expression uses the @code{nthcdr} function to do -the job. +(@xref{copy-region-as-kill}.) How does it do this? As we have seen before (@pxref{nthcdr}), the @code{nthcdr} function works by repeatedly taking the @sc{cdr} of a list---it takes the @@ -18381,477 +19636,222 @@ @end group @end smallexample -In the @code{rotate-yank-pointer} function, however, the first -argument to @code{nthcdr} is a rather complex looking expression with -lots of arithmetic inside of it: - -@smallexample -@group -(% (+ arg - (- length - (length kill-ring-yank-pointer))) - length) -@end group -@end smallexample - -As usual, we need to look at the most deeply embedded expression first -and then work our way towards the light. - -The most deeply embedded expression is @code{(length -kill-ring-yank-pointer)}. This finds the length of the current value of -the @code{kill-ring-yank-pointer}. (Remember that the -@code{kill-ring-yank-pointer} is the name of a variable whose value is a -list.) - -@need 800 -The measurement of the length is inside the expression: - -@smallexample -(- length (length kill-ring-yank-pointer)) -@end smallexample - -@noindent -In this expression, the first @code{length} is the variable that was -assigned the length of the kill ring in the @code{let} statement at the -beginning of the function. (One might think this function would be -clearer if the variable @code{length} were named -@code{length-of-kill-ring} instead; but if you look at the text of the -whole function, you will see that it is so short that naming this -variable @code{length} is not a bother, unless you are pulling the -function apart into very tiny pieces as we are doing here.) - -So the line @code{(- length (length kill-ring-yank-pointer))} tells the -difference between the length of the kill ring and the length of the list -whose name is @code{kill-ring-yank-pointer}. - -To see how all this fits into the @code{rotate-yank-pointer} -function, let's begin by analyzing the case where -@code{kill-ring-yank-pointer} points to the first element of the kill -ring, just as @code{kill-ring} does, and see what happens when -@code{rotate-yank-pointer} is called with an argument of 1. - -The variable @code{length} and the value of the expression -@code{(length kill-ring-yank-pointer)} will be the same since the -variable @code{length} is the length of the kill ring and the -@code{kill-ring-yank-pointer} is pointing to the whole kill ring. -Consequently, the value of - -@smallexample -(- length (length kill-ring-yank-pointer)) -@end smallexample - -@noindent -will be zero. Since the value of @code{arg} will be 1, this will mean -that the value of the whole expression - -@smallexample -(+ arg (- length (length kill-ring-yank-pointer))) -@end smallexample - -@noindent -will be 1. - -@need 1200 -Consequently, the argument to @code{nthcdr} will be found as the result of -the expression - -@smallexample -(% 1 length) -@end smallexample - -@node Remainder Function, rotate-yk-ptr remainder, rotate-yk-ptr else-part, rotate-yk-ptr body -@unnumberedsubsubsec The @code{%} remainder function - -To understand @code{(% 1 length)}, we need to understand @code{%}. -According to its documentation (which I just found by typing @kbd{C-h -f @kbd{%} @key{RET}}), the @code{%} function returns the remainder of -its first argument divided by its second argument. For example, the -remainder of 5 divided by 2 is 1. (2 goes into 5 twice with a -remainder of 1.) - -What surprises people who don't often do arithmetic is that a smaller -number can be divided by a larger number and have a remainder. In the -example we just used, 5 was divided by 2. We can reverse that and ask, -what is the result of dividing 2 by 5? If you can use fractions, the -answer is obviously 2/5 or .4; but if, as here, you can only use whole -numbers, the result has to be something different. Clearly, 5 can go into -2 zero times, but what of the remainder? To see what the answer is, -consider a case that has to be familiar from childhood: - -@itemize @bullet -@item -5 divided by 5 is 1 with a remainder of 0; - -@item -6 divided by 5 is 1 with a remainder of 1; - -@item -7 divided by 5 is 1 with a remainder of 2. - -@item -Similarly, 10 divided by 5 is 2 with a remainder of 0; - -@item -11 divided by 5 is 2 with a remainder of 1; - -@item -12 divided by 5 is 1 with a remainder of 2. -@end itemize - -@need 1250 -@noindent -By considering the cases as parallel, we can see that - -@itemize @bullet -@item -zero divided by 5 must be zero with a remainder of zero; - -@item -1 divided by 5 must be zero with a remainder of 1; - -@item -2 divided by 5 must be zero with a remainder of 2; -@end itemize - -@noindent -and so on. - -@need 1250 -So, in this code, if the value of @code{length} is 5, then the result of -evaluating - -@smallexample -(% 1 5) -@end smallexample - -@noindent -is 1. (I just checked this by placing the cursor after the expression -and typing @kbd{C-x C-e}. Indeed, 1 is printed in the echo area.) - -@need 2000 -@node rotate-yk-ptr remainder, kill-rng-yk-ptr last elt, Remainder Function, rotate-yk-ptr body -@unnumberedsubsubsec Using @code{%} in @code{rotate-yank-pointer} - -When the @code{kill-ring-yank-pointer} points to the -beginning of the kill ring, and the argument passed to -@code{rotate-yank-pointer} is 1, the @code{%} expression returns 1: - -@smallexample -@group -(- length (length kill-ring-yank-pointer)) - @result{} 0 -@end group -@end smallexample - -@need 1250 -@noindent -therefore, - -@smallexample -@group -(+ arg (- length (length kill-ring-yank-pointer))) - @result{} 1 -@end group -@end smallexample - -@need 1250 -@noindent -and consequently: - -@smallexample -@group -(% (+ arg (- length (length kill-ring-yank-pointer))) - length) - @result{} 1 -@end group -@end smallexample - -@noindent -regardless of the value of @code{length}. - -@need 1250 -@noindent -As a result of this, the @code{setq kill-ring-yank-pointer} expression -simplifies to: - -@smallexample -(setq kill-ring-yank-pointer (nthcdr 1 kill-ring)) -@end smallexample - -@noindent -What it does is now easy to understand. Instead of pointing as it did -to the first element of the kill ring, the -@code{kill-ring-yank-pointer} is set to point to the second element. - -Clearly, if the argument passed to @code{rotate-yank-pointer} is two, then -the @code{kill-ring-yank-pointer} is set to @code{(nthcdr 2 kill-ring)}; -and so on for different values of the argument. - -Similarly, if the @code{kill-ring-yank-pointer} starts out pointing to -the second element of the kill ring, its length is shorter than the -length of the kill ring by 1, so the computation of the remainder is -based on the expression @code{(% (+ arg 1) length)}. This means that -the @code{kill-ring-yank-pointer} is moved from the second element of -the kill ring to the third element if the argument passed to -@code{rotate-yank-pointer} is 1. - -@node kill-rng-yk-ptr last elt, , rotate-yk-ptr remainder, rotate-yk-ptr body -@unnumberedsubsubsec Pointing to the last element - -The final question is, what happens if the @code{kill-ring-yank-pointer} -is set to the @emph{last} element of the kill ring? Will a call to -@code{rotate-yank-pointer} mean that nothing more can be taken from the -kill ring? The answer is no. What happens is different and useful. -The @code{kill-ring-yank-pointer} is set to point to the beginning of -the kill ring instead. - -Let's see how this works by looking at the code, assuming the length of the -kill ring is 5 and the argument passed to @code{rotate-yank-pointer} is 1. -When the @code{kill-ring-yank-pointer} points to the last element of -the kill ring, its length is 1. The code looks like this: - -@smallexample -(% (+ arg (- length (length kill-ring-yank-pointer))) length) -@end smallexample - -@need 1250 -When the variables are replaced by their numeric values, the expression -looks like this: - -@smallexample -(% (+ 1 (- 5 1)) 5) -@end smallexample - -@noindent -This expression can be evaluated by looking at the most embedded inner -expression first and working outwards: The value of @code{(- 5 1)} is 4; -the sum of @code{(+ 1 4)} is 5; and the remainder of dividing 5 by 5 is -zero. So what @code{rotate-yank-pointer} will do is - -@smallexample -(setq kill-ring-yank-pointer (nthcdr 0 kill-ring)) -@end smallexample - -@noindent -which will set the @code{kill-ring-yank-pointer} to point to the beginning -of the kill ring. - -So what happens with successive calls to @code{rotate-yank-pointer} is that -it moves the @code{kill-ring-yank-pointer} from element to element in the -kill ring until it reaches the end; then it jumps back to the beginning. -And this is why the kill ring is called a ring, since by jumping back to -the beginning, it is as if the list has no end! (And what is a ring, but -an entity with no end?) - -@node yank, yank-pop, rotate-yank-pointer, Kill Ring +However, the @code{nthcdr} expression is more complicated. It uses +the @code{mod} function to determine which @sc{cdr} to select. + +(You will remember to look at inner functions first; indeed, we will +have to go inside the @code{mod}.) + +The @code{mod} function returns the value of its first argument modulo +the second; that is to say, it returns the remainder after dividing +the first argument by the second. The value returned has the same +sign as the second argument. + +@need 800 +Thus, + +@smallexample +@group +(mod 12 4) + @result{} 0 ;; @r{because there is no remainder} +(mod 13 4) + @result{} 1 +@end group +@end smallexample + +@need 1250 +In this case, the first argument is often smaller than the second. +That is fine. + +@smallexample +@group +(mod 0 4) + @result{} 0 +(mod 1 4) + @result{} 1 +@end group +@end smallexample + +We can guess what the @code{-} function does. It is like @code{+} but +substracts instead of adds; the @code{-} function subtracts its second +argument from its first. Also, we already know what the @code{length} +function does (@pxref{length}). It returns the length of a list. + +And @code{n} is the name of the required argument to the +@code{current-kill} function. + +@need 1250 +So when the first argument to @code{nthcdr} is zero, the @code{nthcdr} +expression returns the whole list, as you can see by evaluating the +following: + +@smallexample +@group +;; kill-ring-yank-pointer @r{and} kill-ring @r{have a length of four} +(nthcdr (mod (- 0 4) 4) ; (mod -4 4) @result{} 0 + '("fourth line of text" + "third line" + "second piece of text" + "first some text")) +@end group +@end smallexample + +@need 1250 +When the first argument to the @code{current-kill} function is one, +the @code{nthcdr} expression returns the list without its first +element. + +@smallexample +@group +(nthcdr (mod (- 1 4) 4) + '("fourth line of text" + "third line" + "second piece of text" + "first some text")) +@end group +@end smallexample + +@cindex @samp{global variable} defined +@cindex @samp{variable, global}, defined +Incidently, both @code{kill-ring} and @code{kill-ring-yank-pointer} +are @dfn{global variables}. That means that any expression in Emacs +Lisp can access them. They are not like the local variables set by +@code{let} (@pxref{Prevent confusion}) or like the symbols in an +argument list (@pxref{defun, , The @code{defun} Special Form}). Local +variables can only be accessed within the @code{let} that defines them +or the function that specifies them in an argument list (and within +expressions called by them). + +@node yank, yank-pop, current-kill, Kill Ring @comment node-name, next, previous, up @appendixsec @code{yank} @findex yank -After learning about @code{rotate-yank-pointer}, the code for the +After learning about @code{current-kill}, the code for the @code{yank} function is almost easy. It has only one tricky part, which is the computation of the argument to be passed to @code{rotate-yank-pointer}. @need 1250 The code looks like this: +@c in GNU Emacs 22 @smallexample @group (defun yank (&optional arg) - "Reinsert the last stretch of killed text. -More precisely, reinsert the stretch of killed text most -recently killed OR yanked. -With just C-U as argument, same but put point in front -(and mark at end). With argument n, reinsert the nth -most recently killed stretch of killed text. + "Reinsert (\"paste\") the last stretch of killed text. +More precisely, reinsert the stretch of killed text most recently +killed OR yanked. Put point at end, and set mark at beginning. +With just \\[universal-argument] as argument, same but put point at +beginning (and mark at end). With argument N, reinsert the Nth most +recently killed stretch of killed text. + +When this command inserts killed text into the buffer, it honors +`yank-excluded-properties' and `yank-handler' as described in the +doc string for `insert-for-yank-1', which see. + See also the command \\[yank-pop]." @end group @group - (interactive "*P") - (rotate-yank-pointer (if (listp arg) 0 - (if (eq arg '-) -1 - (1- arg)))) + (setq yank-window-start (window-start)) + ;; If we don't get all the way thru, make last-command indicate that + ;; for the following command. + (setq this-command t) (push-mark (point)) - (insert (car kill-ring-yank-pointer)) +@end group +@group + (insert-for-yank (current-kill (cond + ((listp arg) 0) + ((eq arg '-) -2) + (t (1- arg))))) (if (consp arg) - (exchange-point-and-mark))) -@end group -@end smallexample - -Glancing over this code, we can understand the last few lines readily -enough. The mark is pushed, that is, remembered; then the first element -(the @sc{car}) of what the @code{kill-ring-yank-pointer} points to is -inserted; and then, if the argument passed the function is a -@code{cons}, point and mark are exchanged so the point is put in the -front of the inserted text rather than at the end. This option is -explained in the documentation. The function itself is interactive with -@code{"*P"}. This means it will not work on a read-only buffer, and that -the unprocessed prefix argument is passed to the function. - -@menu -* rotate-yk-ptr arg:: Pass the argument to @code{rotate-yank-pointer}. -* rotate-yk-ptr negative arg:: Pass a negative argument. -@end menu - -@node rotate-yk-ptr arg, rotate-yk-ptr negative arg, yank, yank -@unnumberedsubsubsec Passing the argument - -The hard part of @code{yank} is understanding the computation that -determines the value of the argument passed to -@code{rotate-yank-pointer}. Fortunately, it is not so difficult as it -looks at first sight. - -What happens is that the result of evaluating one or both of the -@code{if} expressions will be a number and that number will be the -argument passed to @code{rotate-yank-pointer}. - -@need 1250 -Laid out with comments, the code looks like this: - -@smallexample -@group -(if (listp arg) ; @r{if-part} - 0 ; @r{then-part} - (if (eq arg '-) ; @r{else-part, inner if} - -1 ; @r{inner if's then-part} - (1- arg)))) ; @r{inner if's else-part} -@end group -@end smallexample - -@noindent -This code consists of two @code{if} expression, one the else-part of -the other. - -The first or outer @code{if} expression tests whether the argument -passed to @code{yank} is a list. Oddly enough, this will be true if -@code{yank} is called without an argument---because then it will be -passed the value of @code{nil} for the optional argument and an -evaluation of @code{(listp nil)} returns true! So, if no argument is -passed to @code{yank}, the argument passed to -@code{rotate-yank-pointer} inside of @code{yank} is zero. This means -the pointer is not moved and the first element to which -@code{kill-ring-yank-pointer} points is inserted, as we expect. -Similarly, if the argument for @code{yank} is @kbd{C-u}, this will be -read as a list, so again, a zero will be passed to -@code{rotate-yank-pointer}. (@kbd{C-u} produces an unprocessed prefix -argument of @code{(4)}, which is a list of one element.) At the same -time, later in the function, this argument will be read as a -@code{cons} so point will be put in the front and mark at the end of -the insertion. (The @code{P} argument to @code{interactive} is -designed to provide these values for the case when an optional -argument is not provided or when it is @kbd{C-u}.) - -The then-part of the outer @code{if} expression handles the case when -there is no argument or when it is @kbd{C-u}. The else-part handles the -other situations. The else-part is itself another @code{if} expression. - -The inner @code{if} expression tests whether the argument is a minus -sign. (This is done by pressing the @key{META} and @kbd{-} keys at the -same time, or the @key{ESC} key and then the @kbd{-} key). In this -case, the @code{rotate-yank-pointer} function is passed @kbd{-1} as an -argument. This moves the @code{kill-ring-yank-pointer} backwards, which -is what is desired. - -If the true-or-false-test of the inner @code{if} expression is false -(that is, if the argument is not a minus sign), the else-part of the -expression is evaluated. This is the expression @code{(1- arg)}. -Because of the two @code{if} expressions, it will only occur when the -argument is a positive number or when it is a negative number (not -just a minus sign on its own). What @code{(1- arg)} does is decrement -the number and return it. (The @code{1-} function subtracts one from -its argument.) This means that if the argument to -@code{rotate-yank-pointer} is 1, it is reduced to zero, which means -the first element to which @code{kill-ring-yank-pointer} points is -yanked back, as you would expect. - -@node rotate-yk-ptr negative arg, , rotate-yk-ptr arg, yank -@unnumberedsubsubsec Passing a negative argument - -Finally, the question arises, what happens if either the remainder -function, @code{%}, or the @code{nthcdr} function is passed a negative -argument, as they quite well may? - -The answers can be found by a quick test. When @code{(% -1 5)} is -evaluated, a negative number is returned; and if @code{nthcdr} is -called with a negative number, it returns the same value as if it were -called with a first argument of zero. This can be seen by evaluating -the following code. - -Here the @samp{@result{}} points to the result of evaluating the code -preceding it. This was done by positioning the cursor after the code -and typing @kbd{C-x C-e} (@code{eval-last-sexp}) in the usual fashion. -You can do this if you are reading this in Info inside of GNU Emacs. - -@smallexample -@group -(% -1 5) - @result{} -1 -@end group - -@group -(setq animals '(cats dogs elephants)) - @result{} (cats dogs elephants) -@end group - -@group -(nthcdr 1 animals) - @result{} (dogs elephants) -@end group - -@group -(nthcdr 0 animals) - @result{} (cats dogs elephants) -@end group - -@group -(nthcdr -1 animals) - @result{} (cats dogs elephants) -@end group -@end smallexample - -So, if a minus sign or a negative number is passed to @code{yank}, the -@code{kill-ring-yank-point} is rotated backwards until it reaches the -beginning of the list. Then it stays there. Unlike the other case, -when it jumps from the end of the list to the beginning of the list, -making a ring, it stops. This makes sense. You often want to get back -to the most recently clipped out piece of text, but you don't usually -want to insert text from as many as thirty kill commands ago. So you -need to work through the ring to get to the end, but won't cycle around -it inadvertently if you are trying to come back to the beginning. - -Incidentally, any number passed to @code{yank} with a minus sign -preceding it will be treated as @minus{}1. This is evidently a -simplification for writing the program. You don't need to jump back -towards the beginning of the kill ring more than one place at a time -and doing this is easier than writing a function to determine the -magnitude of the number that follows the minus sign. + ;; This is like exchange-point-and-mark, + ;; but doesn't activate the mark. + ;; It is cleaner to avoid activation, even though the command + ;; loop would deactivate the mark because we inserted text. + (goto-char (prog1 (mark t) + (set-marker (mark-marker) (point) (current-buffer))))) +@end group +@group + ;; If we do get all the way thru, make this-command indicate that. + (if (eq this-command t) + (setq this-command 'yank)) + nil) +@end group +@end smallexample + +The key expression is @code{insert-for-yank}, which inserts the string +returned by @code{current-kill}, but removes some text properties from +it. + +However, before getting to that expression, the function set the value +of @code{yank-window-start} to the position returned by the +@code{(window-start)} expression, the position at which the display +currently starts. It also set @code{this-command} and pushed the +mark. + +After it yanks the appropriate element, if the optional argument is a +@sc{cons} rather than a number or nothing, put point at beginning of +the yanked text and mark at its end. (The @code{prog1} function is +like @code{progn} but returns the value of its first argument rather +than the value of its last argument. Its first argument is forced to +return the buffer's mark as an integer. You can see the documentation +for these functions by placing point over them in this buffer and then +typing @kbd{C-h f} (@code{describe-function}) followed by a @kbd{RET}; +the default is the function.) + +The last part of the function tells what to do when it succeeds. + + @node yank-pop, ring file, yank, Kill Ring @comment node-name, next, previous, up @appendixsec @code{yank-pop} @findex yank-pop -After understanding @code{yank}, the @code{yank-pop} function is easy. -Leaving out the documentation to save space, it looks like this: - -@smallexample -@group -(defun yank-pop (arg) +After understanding @code{yank} and @code{current-kill}, you know how +to approach the @code{yank-pop} function Leaving out the documentation +to save space, it looks like this: + +@c GNU Emacs 22 +@smallexample +@group +(defun yank-pop (&optional arg) + "@dots{}" (interactive "*p") (if (not (eq last-command 'yank)) (error "Previous command was not a yank")) @end group @group (setq this-command 'yank) - (let ((before (< (point) (mark)))) - (delete-region (point) (mark)) - (rotate-yank-pointer arg) -@end group -@group - (set-mark (point)) - (insert (car kill-ring-yank-pointer)) - (if before (exchange-point-and-mark)))) + (unless arg (setq arg 1)) + (let ((inhibit-read-only t) + (before (< (point) (mark t)))) +@end group +@group + (if before + (funcall (or yank-undo-function 'delete-region) (point) (mark t)) + (funcall (or yank-undo-function 'delete-region) (mark t) (point))) + (setq yank-undo-function nil) +@end group +@group + (set-marker (mark-marker) (point) (current-buffer)) + (insert-for-yank (current-kill arg)) + ;; Set the window start back where it was in the yank command, + ;; if possible. + (set-window-start (selected-window) yank-window-start t) +@end group +@group + (if before + ;; This is like exchange-point-and-mark, + ;; but doesn't activate the mark. + ;; It is cleaner to avoid activation, even though the command + ;; loop would deactivate the mark because we inserted text. + (goto-char (prog1 (mark t) + (set-marker (mark-marker) + (point) + (current-buffer)))))) + nil) @end group @end smallexample @@ -18859,20 +19859,20 @@ argument is processed and passed to the function. The command can only be used after a previous yank; otherwise an error message is sent. This check uses the variable @code{last-command} which is -discussed elsewhere. (@xref{copy-region-as-kill}.) +set by @code{yank} and is discussed elsewhere. (@xref{copy-region-as-kill}.) The @code{let} clause sets the variable @code{before} to true or false depending whether point is before or after mark and then the region between point and mark is deleted. This is the region that was just inserted by the previous yank and it is this text that will be -replaced. Next the @code{kill-ring-yank-pointer} is rotated so that -the previously inserted text is not reinserted yet again. Mark is set -at the beginning of the place the new text will be inserted and then -the first element to which @code{kill-ring-yank-pointer} points is -inserted. This leaves point after the new text. If in the previous -yank, point was left before the inserted text, point and mark are now -exchanged so point is again left in front of the newly inserted text. -That is all there is to it! +replaced. + +@code{funcall} calls its first argument as a function, passing +remaining arguments to it. The first argument is whatever the +@code{or} expression returns. The two remaining arguments are the +positions of point and mark set by the preceding @code{yank} command. + +There is more, but that is the hardest part. @node ring file, , yank-pop, Kill Ring @comment node-name, next, previous, up @@ -18895,10 +19895,10 @@ @menu * Labelled Example:: -* print-graph Varlist:: @code{let} expression in @code{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. +* print-graph Varlist:: +* print-Y-axis:: +* print-X-axis:: +* Print Whole Graph:: @end menu @node Labelled Example, print-graph Varlist, Full Graph, Full Graph @@ -19073,11 +20073,11 @@ five. @menu -* 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. +* Height of label:: +* Compute a Remainder:: +* Y Axis Element:: +* Y-axis-column:: +* print-Y-axis Penultimate:: @end menu @node Height of label, Compute a Remainder, print-Y-axis, print-Y-axis @@ -19129,10 +20129,7 @@ that you cannot discover using @code{apropos}: you find nothing if you type @kbd{M-x apropos @key{RET} remainder @key{RET}}. The only way to learn of the existence of @code{%} is to read about it in a book such -as this or in the Emacs Lisp sources. The @code{%} function is used -in the code for @code{rotate-yank-pointer}, which is described in an -appendix. (@xref{rotate-yk-ptr body, , The Body of -@code{rotate-yank-pointer}}.) +as this or in the Emacs Lisp sources. You can try the @code{%} function by evaluating the following two expressions: @@ -19515,8 +20512,8 @@ graph without changing the ways the graph is labelled. @menu -* Similarities differences:: Much like @code{print-Y-axis}, but not exactly. -* X Axis Tic Marks:: Create tic marks for the horizontal axis. +* Similarities differences:: +* X Axis Tic Marks:: @end menu @node Similarities differences, X Axis Tic Marks, print-X-axis, print-X-axis @@ -19864,13 +20861,13 @@ @end smallexample @menu -* 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 @dots{} most insidious. -* Final printed graph:: The graph itself! +* The final version:: +* Test print-graph:: +* Graphing words in defuns:: +* lambda:: +* mapcar:: +* Another Bug:: +* Final printed graph:: @end menu @node The final version, Test print-graph, Print Whole Graph, Print Whole Graph