home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2001 May / SGI Freeware 2001 May - Disc 3.iso / dist / fw_elisp-intro.idb / usr / freeware / info / emacs-lisp-intro.info-10.z / emacs-lisp-intro.info-10
Encoding:
GNU Info File  |  1998-10-28  |  47.3 KB  |  1,164 lines

  1. This is Info file emacs-lisp-intro.info, produced by Makeinfo version
  2. 1.67 from the input file emacs-lisp-intro.texi.
  3.  
  4.    This is an introduction to `Programming in Emacs Lisp', for people
  5. who are not programmers.
  6.  
  7.    Edition 1.05, 21 October 1997
  8.  
  9.    Copyright (C) 1990, '91, '92, '93, '94, '95, '97 Free Software
  10. Foundation, Inc.
  11.  
  12.    Permission is granted to make and distribute verbatim copies of this
  13. manual provided the copyright notice and this permission notice are
  14. preserved on all copies.
  15.  
  16.    Permission is granted to copy and distribute modified versions of
  17. this manual under the conditions for verbatim copying, provided also
  18. that the sections entitled "Copying" and "GNU General Public License"
  19. are included exactly as in the original, and provided that the entire
  20. resulting derived work is distributed under the terms of a permission
  21. notice identical to this one.
  22.  
  23.    Permission is granted to copy and distribute translations of this
  24. manual into another language, under the above conditions for modified
  25. versions, except that this permission notice may be stated in a
  26. translation approved by the Free Software Foundation.
  27.  
  28. 
  29. File: emacs-lisp-intro.info,  Node: Several files recursively,  Next: Prepare the data,  Prev: Several files,  Up: Words in a defun
  30.  
  31. Recursively Count Words in Different Files
  32. ==========================================
  33.  
  34.    Besides a `while' loop, you can work on each of a list of files with
  35. recursion.  A recursive version of `lengths-list-many-files' is short
  36. and simple.
  37.  
  38.    The recursive function has the usual parts: the `do-again-test', the
  39. `next-step-expression', and the recursive call.  The `do-again-test'
  40. determines whether the function should call itself again, which it will
  41. do if the `list-of-files' contains any remaining elements; the
  42. `next-step-expression' resets the `list-of-files' to the CDR of itself,
  43. so eventually the list will be empty; and the recursive call calls
  44. itself on the shorter list.  The complete function is shorter than this
  45. description!
  46.  
  47.      (defun recursive-lengths-list-many-files (list-of-files)
  48.        "Return list of lengths of each defun in LIST-OF-FILES."
  49.        (if list-of-files                     ; do-again-test
  50.            (append
  51.             (lengths-list-file
  52.              (expand-file-name (car list-of-files)))
  53.             (recursive-lengths-list-many-files
  54.              (cdr list-of-files)))))
  55.  
  56. In a sentence, the function returns the lengths' list for the first of
  57. the `list-of-files' appended to the result of calling itself on the
  58. rest of the `list-of-files'.
  59.  
  60.    Here is a test of `recursive-lengths-list-many-files', along with
  61. the results of running `lengths-list-file' on each of the files
  62. individually.
  63.  
  64.    Install `recursive-lengths-list-many-files' and `lengths-list-file',
  65. if necessary, and then evaluate the following expressions.  You may
  66. need to change the files' pathnames; those here work when this Info
  67. file and the Emacs sources are located in their customary places.  To
  68. change the expressions, copy them to the `*scratch*' buffer, edit them,
  69. and then evaluate them.
  70.  
  71.    The results are shown after the `=>'.  (These results are for files
  72. from Emacs Version 18.57; files from other versions of Emacs may
  73. produce different results.)
  74.  
  75.      (lengths-list-file
  76.       "../lisp/macros.el")
  77.           => (176 154 86)
  78.      
  79.      (lengths-list-file
  80.       "../lisp/mailalias.el")
  81.           => (116 122 265)
  82.      
  83.      (lengths-list-file
  84.       "../lisp/makesum.el")
  85.           => (85 179)
  86.      
  87.      (recursive-lengths-list-many-files
  88.       '("../lisp/macros.el"
  89.         "../lisp/mailalias.el"
  90.         "../lisp/makesum.el"))
  91.             => (176 154 86 116 122 265 85 179)
  92.  
  93.    The `recursive-lengths-list-many-files' function produces the output
  94. we want.
  95.  
  96.    The next step is to prepare the data in the list for display in a
  97. graph.
  98.  
  99. 
  100. File: emacs-lisp-intro.info,  Node: Prepare the data,  Prev: Several files recursively,  Up: Words in a defun
  101.  
  102. Prepare the Data for Display in a Graph
  103. =======================================
  104.  
  105.    The `recursive-lengths-list-many-files' function returns a list of
  106. numbers.  Each number records the length of a function definition.
  107. What we need to do now is transform this data into a list of numbers
  108. suitable for generating a graph.  The new list will tell how many
  109. functions definitions contain less than 10 words and symbols, how many
  110. contain between 10 and 19 words and symbols, how many contain between
  111. 20 and 29 words and symbols, and so on.
  112.  
  113.    In brief, we need to go through the lengths' list produced by the
  114. `recursive-lengths-list-many-files' function and count the number of
  115. defuns within each range of lengths, and produce a list of those
  116. numbers.
  117.  
  118.    Based on what we have done before, we can readily foresee that it
  119. should not be too hard to write a function that `CDRs' down the
  120. lengths' list, looks at each element, determines which length range it
  121. is in, and increments a counter for that range.
  122.  
  123.    However, before beginning to write such a function, we should
  124. consider the advantages of sorting the lengths' list first, so the
  125. numbers are ordered from smallest to largest.  First, sorting will make
  126. it easier to count the numbers in each range, since two adjacent
  127. numbers will either be in the same length range or in adjacent ranges.
  128. Second, by inspecting a sorted list, we can discover the highest and
  129. lowest number, and thereby determine the largest and smallest length
  130. range that we will need.
  131.  
  132. * Menu:
  133.  
  134. * Sorting::                     Sorting lists.
  135. * Files List::                  Making a list of files.
  136.  
  137. 
  138. File: emacs-lisp-intro.info,  Node: Sorting,  Next: Files List,  Prev: Prepare the data,  Up: Prepare the data
  139.  
  140. Sorting Lists
  141. -------------
  142.  
  143.    Emacs contains a function to sort lists, called (as you might guess)
  144. `sort'.  The `sort' function takes two arguments, the list to be
  145. sorted, and a predicate that determines whether the first of two list
  146. elements is "less" than the second.
  147.  
  148.    As we saw earlier (*note Using the Wrong Type Object as an Argument:
  149. Wrong Type of Argument.), a predicate is a function that determines
  150. whether some property is true or false.  The `sort' function will
  151. reorder a list according to whatever property the predicate uses; this
  152. means that `sort' can be used to sort non-numeric lists by non-numeric
  153. criteria--it can, for example, alphabetize a list.
  154.  
  155.    The `<' function is used when sorting a numeric list.  For example,
  156.  
  157.      (sort '(4 8 21 17 33 7 21 7) '<)
  158.  
  159. produces this:
  160.  
  161.      (4 7 7 8 17 21 21 33)
  162.  
  163. (Note that in this example, both the arguments are quoted so that the
  164. symbols are not evaluated before being passed to `sort' as arguments.)
  165.  
  166.    Sorting the list returned by the `recursive-lengths-list-many-files'
  167. function is straightforward:
  168.  
  169.      (sort
  170.       (recursive-lengths-list-many-files
  171.        '("../lisp/macros.el"
  172.          "../lisp/mailalias.el"
  173.          "../lisp/makesum.el"))
  174.       '<)
  175.  
  176. which produces:
  177.  
  178.      (85 86 116 122 154 176 179 265)
  179.  
  180. (Note that in this example, the first argument to `sort' is not quoted,
  181. since the expression must be evaluated so as to produce the list that
  182. is passed to `sort'.)
  183.  
  184. 
  185. File: emacs-lisp-intro.info,  Node: Files List,  Prev: Sorting,  Up: Prepare the data
  186.  
  187. Making a List of Files
  188. ----------------------
  189.  
  190.    The `recursive-lengths-list-many-files' function requires a list of
  191. files as its argument.  For our test examples, we constructed such a
  192. list by hand; but the Emacs Lisp source directory is too large for us
  193. to do for that.  Instead, we need to use the `directory-files' function
  194. to construct a list for us.
  195.  
  196.    The `directory-files' function takes three arguments: the first
  197. argument is the name of a directory, a string; a non-`nil' second
  198. argument causes the function to return the files' absolute pathnames;
  199. and the third argument is a selector.  If it contains a regular
  200. expression (rather than `nil'), only pathnames that match that regular
  201. expression are returned.
  202.  
  203.    Thus, on my system,
  204.  
  205.      (length
  206.       (directory-files "../lisp" t "\\.el$"))
  207.  
  208. tells me that my version 19.25 Lisp sources directory contains 307
  209. `.el' files.
  210.  
  211.    An expression to sort the list returned by
  212. `recursive-lengths-list-many-files' looks like this:
  213.  
  214.      (sort
  215.       (recursive-lengths-list-many-files
  216.        (directory-files "../lisp" t "\\.el$"))
  217.       '<)
  218.  
  219.    Our immediate goal is to generate a list that tells us how many
  220. function definitions contain fewer than 10 words and symbols, how many
  221. contain between 10 and 19 words and symbols, how many contain between
  222. 20 and 29 words and symbols, and so on.  With a sorted list of numbers,
  223. this is easy: count how many elements of the list are smaller than 10,
  224. then, after moving past the numbers just counted, count how many are
  225. smaller than 20, then, after moving past the numbers just counted,
  226. count how many are smaller than 30, and so on.  Each of the numbers,
  227. 10, 20, 30, 40, and the like, is one larger than the top of that range.
  228. We can call the list of such numbers the `top-of-ranges' list.
  229.  
  230.    If we wanted to, we could generate this list automatically, but it is
  231. simpler to write a list manually.  Here it is:
  232.  
  233.      (defvar top-of-ranges
  234.       '(10  20  30  40  50
  235.         60  70  80  90 100
  236.        110 120 130 140 150
  237.        160 170 180 190 200
  238.        210 220 230 240 250
  239.        260 270 280 290 300)
  240.       "List specifying ranges for `defuns-per-range'.")
  241.  
  242.    To change the ranges, we edit this list.
  243.  
  244.    Next, we need to write the function that creates the list of the
  245. number of definitions within each range.  Clearly, this function must
  246. take the `sorted-lengths' and the `top-of-ranges' lists as arguments.
  247.  
  248.    The `defuns-per-range' function must do two things again and again:
  249. it must count the number of definitions within a range specified by the
  250. current top-of-range value; and it must shift to the next higher value
  251. in the `top-of-ranges' list after counting the number of definitions in
  252. the current range.  Since each of these actions is repetitive, we can
  253. use `while' loops for the job.  One loop counts the number of
  254. definitions in the range defined by the current top-of-range value, and
  255. the other loop selects each of the top-of-range values in turn.
  256.  
  257.    Several entries of the `sorted-lengths' list are counted for each
  258. range; this means that the loop for the `sorted-lengths' list will be
  259. inside the loop for the `top-of-ranges' list, like a small gear inside
  260. a big gear.
  261.  
  262.    The inner loop counts the number of definitions within the range.  It
  263. is a simple counting loop of the type we have seen before.  (*Note A
  264. loop with an incrementing counter: Incrementing Loop.) The
  265. true-or-false test of the loop tests whether the value from the
  266. `sorted-lengths' list is smaller than the current value of the top of
  267. the range.  If it is, the function increments the counter and tests the
  268. next value from the `sorted-lengths' list.
  269.  
  270.    The inner loop looks like this:
  271.  
  272.      (while LENGTH-ELEMENT-SMALLER-THAN-TOP-OF-RANGE
  273.        (setq number-within-range (1+ number-within-range))
  274.        (setq sorted-lengths (cdr sorted-lengths)))
  275.  
  276.    The outer loop must start with the lowest value of the
  277. `top-of-ranges' list, and then be set to each of the succeeding higher
  278. values in turn.  This can be done with a loop like this:
  279.  
  280.      (while top-of-ranges
  281.        BODY-OF-LOOP...
  282.        (setq top-of-ranges (cdr top-of-ranges)))
  283.  
  284.    Put together, the two loops look like this:
  285.  
  286.      (while top-of-ranges
  287.      
  288.        ;; Count the number of elements within the current range.
  289.        (while LENGTH-ELEMENT-SMALLER-THAN-TOP-OF-RANGE
  290.          (setq number-within-range (1+ number-within-range))
  291.          (setq sorted-lengths (cdr sorted-lengths)))
  292.      
  293.        ;; Move to next range.
  294.        (setq top-of-ranges (cdr top-of-ranges)))
  295.  
  296.    In addition, in each circuit of the outer loop, Emacs should record
  297. the number of definitions within that range (the value of
  298. `number-within-range') in a list.  We can use `cons' for this purpose.
  299. (*Note `cons': cons.)
  300.  
  301.    The `cons' function works fine, except that the list it constructs
  302. will contain the number of definitions for the highest range at its
  303. beginning and the number of definitions for the lowest range at its
  304. end.  This is because `cons' attaches new elements of the list to the
  305. beginning of the list, and since the two loops are working their way
  306. through the lengths' list from the lower end first, the
  307. `defuns-per-range-list' will end up largest number first.  But we will
  308. want to print our graph with smallest values first and the larger
  309. later.  The solution is to reverse the order of the
  310. `defuns-per-range-list'.  We can do this using the `nreverse' function,
  311. which reverses the order of a list.
  312.  
  313.    For example,
  314.  
  315.      (nreverse '(1 2 3 4))
  316.  
  317. produces:
  318.  
  319.      (4 3 2 1)
  320.  
  321.    Note that the `nreverse' function is "destructive"--that is, it
  322. changes the list to which it is applied; this contrasts with the `car'
  323. and `cdr' functions, which are non-destructive.  In this case, we do
  324. not want the original `defuns-per-range-list', so it does not matter
  325. that it is destroyed.  (The `reverse' function provides a reversed copy
  326. of a list, leaving the original list as is.)
  327.  
  328.    Put all together, the `defuns-per-range' looks like this:
  329.  
  330.      (defun defuns-per-range (sorted-lengths top-of-ranges)
  331.        "SORTED-LENGTHS defuns in each TOP-OF-RANGES range."
  332.        (let ((top-of-range (car top-of-ranges))
  333.              (number-within-range 0)
  334.              defuns-per-range-list)
  335.      
  336.          ;; Outer loop.
  337.          (while top-of-ranges
  338.      
  339.            ;; Inner loop.
  340.            (while (and
  341.                    ;; Need number for numeric test.
  342.                    (car sorted-lengths)
  343.                    (< (car sorted-lengths) top-of-range))
  344.      
  345.              ;; Count number of definitions within current range.
  346.              (setq number-within-range (1+ number-within-range))
  347.              (setq sorted-lengths (cdr sorted-lengths)))
  348.      
  349.            ;; Exit inner loop but remain within outer loop.
  350.      
  351.            (setq defuns-per-range-list
  352.                  (cons number-within-range defuns-per-range-list))
  353.            (setq number-within-range 0)      ; Reset count to zero.
  354.      
  355.            ;; Move to next range.
  356.            (setq top-of-ranges (cdr top-of-ranges))
  357.            ;; Specify next top of range value.
  358.            (setq top-of-range (car top-of-ranges)))
  359.      
  360.          ;; Exit outer loop and count the number of defuns larger than
  361.          ;;   the largest top-of-range value.
  362.          (setq defuns-per-range-list
  363.                (cons
  364.                 (length sorted-lengths)
  365.                 defuns-per-range-list))
  366.      
  367.          ;; Return a list of the number of definitions within each range,
  368.          ;;   smallest to largest.
  369.          (nreverse defuns-per-range-list)))
  370.  
  371. The function is straightforward except for one subtle feature.  The
  372. true-or-false test of the inner loop looks like this:
  373.  
  374.      (and (car sorted-lengths)
  375.           (< (car sorted-lengths) top-of-range))
  376.  
  377. instead of like this:
  378.  
  379.      (< (car sorted-lengths) top-of-range)
  380.  
  381.    The purpose of the test is to determine whether the first item in the
  382. `sorted-lengths' list is less than the value of the top of the range.
  383.  
  384.    The simple version of the test works fine unless the
  385. `sorted-lengths' list has a `nil' value.  In that case, the `(car
  386. sorted-lengths)' expression function returns `nil'.  The `<' function
  387. cannot compare a number to `nil', which is an empty list, so Emacs
  388. signals an error and stops the function from attempting to continue to
  389. execute.
  390.  
  391.    The `sorted-lengths' list always becomes `nil' when the counter
  392. reaches the end of the list.  This means that any attempt to use the
  393. `defuns-per-range' function with the simple version of the test will
  394. fail.
  395.  
  396.    We solve the problem by using the `(car sorted-lengths)' expression
  397. in conjunction with the `and' expression.  The `(car sorted-lengths)'
  398. expression returns a non-`nil' value so long as the list has at least
  399. one number within it, but returns `nil' if the list is empty.  The
  400. `and' expression first evaluates the `(car sorted-lengths)' expression,
  401. and if it is `nil', returns false *without* evaluating the `<'
  402. expression.  But if the `(car sorted-lengths)' expression returns a
  403. non-`nil' value, the `and' expression evaluates the `<' expression, and
  404. returns that value as the value of the `and' expression.
  405.  
  406.    This way, we avoid an error.  *Note forward-paragraph::, for more
  407. information about `and'.
  408.  
  409.    Here is a short test of the `defuns-per-range' function.  First,
  410. evaluate the expression that binds (a shortened) `top-of-ranges' list
  411. to the list of values, then evaluate the expression for binding the
  412. `sorted-lengths' list, and then evaluate the `defuns-per-range'
  413. function.
  414.  
  415.      ;; (Shorter list than we will use later.)
  416.      (setq top-of-ranges
  417.       '(110 120 130 140 150
  418.         160 170 180 190 200))
  419.      
  420.      (setq sorted-lengths
  421.            '(85 86 110 116 122 129 154 176 179 200 265 300 300))
  422.      
  423.      (defuns-per-range sorted-lengths top-of-ranges)
  424.  
  425. The list returned looks like this:
  426.  
  427.      (2 2 2 0 0 1 0 2 0 0 4)
  428.  
  429. Indeed, there are two elements of the `sorted-lengths' list smaller
  430. than 110, two elements between 110 and 119, two elements between 120
  431. and 129, and so on.  There are four elements with a value of 200 or
  432. larger.
  433.  
  434. 
  435. File: emacs-lisp-intro.info,  Node: Readying a Graph,  Next: Emacs Initialization,  Prev: Words in a defun,  Up: Top
  436.  
  437. Readying a Graph
  438. ****************
  439.  
  440.    Our goal is to construct a graph showing the numbers of function
  441. definitions of various lengths in the Emacs lisp sources.
  442.  
  443.    As a practical matter, if you were creating a graph, you would
  444. probably use a program such as `gnuplot' to do the job.  (`gnuplot' is
  445. nicely integrated into GNU Emacs.)  In this case, however, we create
  446. one from scratch, and in the process we will reaquaint ourselves with
  447. some of what we learned before and learn more.
  448.  
  449.    In this chapter, we will first write a simple graph printing
  450. function.  This first definition will be a "prototype", a rapidly
  451. written function that enables us to reconnoiter this unknown
  452. graph-making territory.  We will discover dragons, or find that they
  453. are myth.  After scouting the terrain, we will feel more confident and
  454. enhance the function to label the axes automatically.
  455.  
  456. * Menu:
  457.  
  458. * Columns of a graph::          How to print individual columns.
  459. * graph-body-print::            How to print the body of a graph.
  460. * recursive-graph-body-print::
  461. * Printed Axes::
  462. * Line Graph Exercise::
  463.  
  464. 
  465. File: emacs-lisp-intro.info,  Node: Columns of a graph,  Next: graph-body-print,  Prev: Readying a Graph,  Up: Readying a Graph
  466.  
  467. Printing the Columns of a Graph
  468. ===============================
  469.  
  470.    Since Emacs is designed to be flexible and work with all kinds of
  471. terminals, including character-only terminals, the graph will need to
  472. be made from one of the `typewriter' symbols.  An asterisk will do; as
  473. we enhance the graph-printing function, we can make the choice of
  474. symbol a user option.
  475.  
  476.    We can call this function `graph-body-print'; it will take a
  477. `numbers-list' as its only argument.  At this stage, we will not label
  478. the graph, but only print its body.
  479.  
  480.    The `graph-body-print' function inserts a vertical column of
  481. asterisks for each element in the `numbers-list'.  The height of each
  482. line is determined by the value of that element of the `numbers-list'.
  483.  
  484.    Inserting columns is a repetitive act; that means that this function
  485. can be written either with a `while' loop or recursively.
  486.  
  487.    Our first challenge is to discover how to print a column of
  488. asterisks.  Usually, in Emacs, we print characters onto a screen
  489. horizontally, line by line, by typing.  We have two routes we can
  490. follow: write our own column-insertion function or discover whether one
  491. exists in Emacs.
  492.  
  493.    To see whether there is one in Emacs, we can use the `M-x apropos'
  494. command.  This command is like the `C-h a' (command-apropos) command,
  495. except that the latter finds only those functions that are commands.
  496. The `M-x apropos' command lists all symbols that match a regular
  497. expression, including functions that are not interactive.
  498.  
  499.    What we want to look for is some command that prints or inserts
  500. columns.  Very likely, the name of the function will contain either the
  501. word `print' or the word `insert' or the word `column'.  Therefore, we
  502. can simply type `M-x apropos RET print\|insert\|column RET' and look at
  503. the result.  On my system, this command takes quite some time, and then
  504. produces a list of 79 functions and variables.  Scanning down the list,
  505. the only function that looks as if it might do the job is
  506. `insert-rectangle'.  Indeed, this is the function we want; its
  507. documentation says:
  508.  
  509.      insert-rectangle:
  510.      Insert text of RECTANGLE with upper left corner at point.
  511.      RECTANGLE's first line is inserted at point,
  512.      its second line is inserted at a point vertically under point, etc.
  513.      RECTANGLE should be a list of strings.
  514.  
  515.    We can run a quick test, to make sure it does what we expect of it.
  516.  
  517.    Here is the result of placing the cursor after the
  518. `insert-rectangle' expression and typing `C-u C-x C-e'
  519. (`eval-last-sexp').  The function inserts the strings `"first"',
  520. `"second"', and `"third"' at and below point.  Also the function
  521. returns `nil'.
  522.  
  523.      (insert-rectangle '("first" "second" "third"))first
  524.                                                    second
  525.                                                    third
  526.      nil
  527.  
  528. Of course, we won't be inserting the text of the `insert-rectangle'
  529. expression itself into the buffer in which we are making the graph, but
  530. will call the function from our program.  We shall, however, have to
  531. make sure that point is in the buffer at the place where the
  532. `insert-rectangle' function will insert its column of strings.
  533.  
  534.    If you are reading this in Info, you can see how this works by
  535. switching to another buffer, such as the `*scratch*' buffer, placing
  536. point somewhere in the buffer, typing `M-:', typing the
  537. `insert-rectangle' expression into the minibuffer at the prompt, and
  538. then typing <RET>.  This causes Emacs to evaluate the expression in the
  539. minibuffer, but to use as the value of point the position of point in
  540. the `*scratch*' buffer.  (`M-:' is the keybinding for
  541. `eval-expression'.)
  542.  
  543.    We find when we do this that point ends up at the end of the last
  544. inserted line--that is to say, this function moves point as a
  545. side-effect.  If we were to repeat the command, with point at this
  546. position, the next insertion would be below and to the right of the
  547. previous insertion.  We don't want this!  If we are going to make a bar
  548. graph, the columns need to be beside each other.
  549.  
  550.    So we discover that each cycle of the column-inserting `while' loop
  551. must reposition point to the place we want it, and that place will be
  552. at the top, not the bottom, of the column.  Moreover, we remember that
  553. when we print a graph, we do not expect all the columns to be the same
  554. height.  This means that the top of each column may be at a different
  555. height from the previous one.  We cannot simply reposition point to the
  556. same line each time, but moved over to the right--or perhaps we can...
  557.  
  558.    We are planning to make the columns of the bar graph out of
  559. asterisks.  The number of asterisks in the column is the number
  560. specified by the current element of the `numbers-list'.  We need to
  561. construct a list of asterisks of the right length for each call to
  562. `insert-rectangle'.  If this list consists solely of the requisit
  563. number of asterisks, then we will have position point the right number
  564. of lines above the base for the graph to print correctly.  This could
  565. be difficult.
  566.  
  567.    Alternatively, if we can figure out some way to pass
  568. `insert-rectangle' a list of the same length each time, then we can
  569. place point on the same line each time, but move it over one column to
  570. the right for each new column.  If we do this, however, some of the
  571. entries in the list passed to `insert-rectangle' must be blanks rather
  572. than asterisks.  For example, if the maximum height of the graph is 5,
  573. but the height of the column is 3, then `insert-rectangle' requires an
  574. argument that looks like this:
  575.  
  576.      (" " " " "*" "*" "*")
  577.  
  578.    This last proposal is not so difficult, so long as we can determine
  579. the column height.  There are two ways for us to specify the column
  580. height: we can arbitrarily state what it will be, which would work fine
  581. for graphs of that height; or we can search through the list of numbers
  582. and use the maximum height of the list as the maximum height of the
  583. graph.  If the latter operation were difficult, then the former
  584. procedure would be easiest, but there is a function built into Emacs
  585. that determines the maximum of its arguments.  We can use that
  586. function.  The function is called `max' and it returns the largest of
  587. all its arguments, which must be numbers.  Thus, for example,
  588.  
  589.      (max  3 4 6 5 7 3)
  590.  
  591. returns 7.  (A corresponding function called `min' returns the smallest
  592. of all its arguments.)
  593.  
  594.    However, we cannot simply call `max' on the `numbers-list'; the
  595. `max' function expects numbers as its argument, not a list of numbers.
  596. Thus, the following expression,
  597.  
  598.      (max  '(3 4 6 5 7 3))
  599.  
  600. produces the following error message;
  601.  
  602.      Wrong type of argument:  integer-or-marker-p, (3 4 6 5 7 3)
  603.  
  604.    We need a function that passes a list of arguments to a function.
  605. This function is `apply'.  This function `applies' its first argument
  606. (a function) to its remaining arguments, the last of which may be a
  607. list.
  608.  
  609.    For example,
  610.  
  611.      (apply 'max 3 4 7 3 '(4 8 5))
  612.  
  613. returns 8.
  614.  
  615.    (Incidentally, I don't know how you would learn of this function
  616. without a book such as this.  It is possible to discover other
  617. functions, like `search-forward' or `insert-rectangle', by guessing at
  618. a part of their names and then using `apropos'.  Even though its base
  619. in metaphor is clear--`apply' its first argument to the rest--I doubt a
  620. novice would come up with that particular word when using `apropos' or
  621. other aid.  Of course, I could be wrong; after all, the function was
  622. first named by someone who had to invent it.)
  623.  
  624.    The second and subsequent arguments to `apply' are optional, so we
  625. can use `apply' to call a function and pass the elements of a list to
  626. it, like this, which also returns 8:
  627.  
  628.      (apply 'max '(4 8 5))
  629.  
  630.    This latter way is how we will use `apply'.  The
  631. `recursive-lengths-list-many-files' function returns a numbers' list to
  632. which we can apply `max' (we could also apply `max' to the sorted
  633. numbers' list; it does not matter whether the list is sorted or not.)
  634.  
  635.    Hence, the operation for finding the maximum height of the graph is
  636. this:
  637.  
  638.      (setq max-graph-height (apply 'max numbers-list))
  639.  
  640.    Now we can return to the question of how to create a list of strings
  641. for a column of the graph.  Told the maximum height of the graph and
  642. the number of asterisks that should appear in the column, the function
  643. should return a list of strings for the `insert-rectangle' command to
  644. insert.
  645.  
  646.    Each column is made up of asterisks or blanks.  Since the function is
  647. passed the value of the height of the column and the number of
  648. asterisks in the column, the number of blanks can be found by
  649. subtracting the number of asterisks from the height of the column.
  650. Given the number of blanks and the number of asterisks, two `while'
  651. loops can be used to construct the list:
  652.  
  653.      ;;; First version.
  654.      (defun column-of-graph (max-graph-height actual-height)
  655.        "Return list of strings that is one column of a graph."
  656.        (let ((insert-list nil)
  657.              (number-of-top-blanks
  658.               (- max-graph-height actual-height)))
  659.      
  660.          ;; Fill in asterisks.
  661.          (while (> actual-height 0)
  662.            (setq insert-list (cons "*" insert-list))
  663.            (setq actual-height (1- actual-height)))
  664.      
  665.          ;; Fill in blanks.
  666.          (while (> number-of-top-blanks 0)
  667.            (setq insert-list (cons " " insert-list))
  668.            (setq number-of-top-blanks
  669.                  (1- number-of-top-blanks)))
  670.      
  671.          ;; Return whole list.
  672.          insert-list))
  673.  
  674.    If you install this function and then evaluate the following
  675. expression you will see that it returns the list as desired:
  676.  
  677.      (column-of-graph 5 3)
  678.  
  679. returns
  680.  
  681.      (" " " " "*" "*" "*")
  682.  
  683.    As written, `column-of-graph' contains a major flaw: the symbols
  684. used for the blank and for the marked entries in the column are
  685. `hard-coded' as a space and asterisk.  This is fine for a prototype,
  686. but you, or another user, may wish to use other symbols.  For example,
  687. in testing the graph function, you many want to use a period in place
  688. of the space, to make sure the point is being repositioned properly
  689. each time the `insert-rectangle' function is called; or you might want
  690. to substitute a `+' sign or other symbol for the asterisk.  You might
  691. even want to make a graph-column that is more than one display column
  692. wide.  The program should be more flexible.  The way to do that is to
  693. replace the blank and the asterisk with two variables that we can call
  694. `graph-blank' and `graph-symbol' and define those variables separately.
  695.  
  696.    Also, the documentation is not well written.  These considerations
  697. lead us to the second version of the function:
  698.  
  699.      (defvar graph-symbol "*"
  700.        "String used as symbol in graph, usually an asterisk.")
  701.      
  702.      (defvar graph-blank " "
  703.        "String used as blank in graph, usually a blank space.
  704.      graph-blank must be the same number of columns wide
  705.      as graph-symbol.")
  706.  
  707. (For an explanation of `defvar', see *Note Initializing a Variable with
  708. `defvar': defvar.)
  709.  
  710.      ;;; Second version.
  711.      (defun column-of-graph (max-graph-height actual-height)
  712.        "Return list of MAX-GRAPH-HEIGHT strings;
  713.      ACTUAL-HEIGHT are graph-symbols.
  714.      The graph-symbols are contiguous entries at the end
  715.      of the list.
  716.      The list will be inserted as one column of a graph.
  717.      The strings are either graph-blank or graph-symbol."
  718.      
  719.        (let ((insert-list nil)
  720.              (number-of-top-blanks
  721.               (- max-graph-height actual-height)))
  722.      
  723.          ;; Fill in `graph-symbols'.
  724.          (while (> actual-height 0)
  725.            (setq insert-list (cons graph-symbol insert-list))
  726.            (setq actual-height (1- actual-height)))
  727.      
  728.          ;; Fill in `graph-blanks'.
  729.          (while (> number-of-top-blanks 0)
  730.            (setq insert-list (cons graph-blank insert-list))
  731.            (setq number-of-top-blanks
  732.                  (1- number-of-top-blanks)))
  733.      
  734.          ;; Return whole list.
  735.          insert-list))
  736.  
  737.    If we wished, we could rewrite `column-of-graph' a third time to
  738. provide optionally for a line graph as well as for a bar graph.  This
  739. would not be hard to do.  One way to think of a line graph is that it
  740. is no more than a bar graph in which the part of each bar that is below
  741. the top is blank.  To construct a column for a line graph, the function
  742. first constructs a list of blanks that is one shorter than the value,
  743. then it uses `cons' to attach a graph symbol to the list; then it uses
  744. `cons' again to attach the `top blanks' to the list.
  745.  
  746.    It is easy to see how to write such a function, but since we don't
  747. need it, we will not do it.  But the job could be done, and if it were
  748. done, it would be done with `column-of-graph'.  Even more important, it
  749. is worth noting that few changes would have to be made anywhere else.
  750. The enhancement, if we ever wish to make it, is simple.
  751.  
  752.    Now, finally, we come to our first actual graph printing function.
  753. This prints the body of a graph, not the labels for the vertical and
  754. horizontal axes, so we can call this `graph-body-print'.
  755.  
  756. 
  757. File: emacs-lisp-intro.info,  Node: graph-body-print,  Next: recursive-graph-body-print,  Prev: Columns of a graph,  Up: Readying a Graph
  758.  
  759. The `graph-body-print' Function
  760. ===============================
  761.  
  762.    After our preparation in the preceding section, the
  763. `graph-body-print' function is straightforward.  The function will
  764. print column after column of asterisks and blanks, using the elements
  765. of a numbers' list to specify the number of asterisks in each column.
  766. This is a repetitive act, which means we can use a decrementing `while'
  767. loop or recursive function for the job.  In this section, we will write
  768. the definition using a `while' loop.
  769.  
  770.    The `column-of-graph' function requires the height of the graph as
  771. an argument, so we should determine and record that as a local variable.
  772.  
  773.    This leads us to the following template for the `while' loop version
  774. of this function:
  775.  
  776.      (defun graph-body-print (numbers-list)
  777.        "DOCUMENTATION..."
  778.        (let ((height  ...
  779.               ...))
  780.      
  781.          (while numbers-list
  782.            INSERT-COLUMNS-AND-REPOSITION-POINT
  783.            (setq numbers-list (cdr numbers-list)))))
  784.  
  785. We need to fill in the slots of the template.
  786.  
  787.    Clearly, we can use the `(apply 'max numbers-list)' expression to
  788. determine the height of the graph.
  789.  
  790.    The `while' loop will cycle through the `numbers-list' one element
  791. at a time.  As it is shortened by the `(setq numbers-list (cdr
  792. numbers-list))' expression, the CAR of each instance of the list is the
  793. value of the argument for `column-of-graph'.
  794.  
  795.    At each cycle of the `while' loop, the `insert-rectangle' function
  796. inserts the list returned by `column-of-graph'.  Since the
  797. `insert-rectangle' function moves point to the lower right of the
  798. inserted rectangle, we need to save the location of point at the time
  799. the rectangle is inserted, move back to that position after the
  800. rectangle is inserted, and then move horizontally to the next place
  801. from which `insert-rectangle' is called.
  802.  
  803.    If the inserted columns are one character wide, as they will be if
  804. single blanks and asterisks are used, the repositioning command is
  805. simply `(forward-char 1)'; however, the width of a column may be
  806. greater than one.  This means that the repositioning command should be
  807. written `(forward-char symbol-width)'.  The `symbol-width' itself is
  808. the length of a `graph-blank' and can be found using the expression
  809. `(length graph-blank)'.  The best place to bind the `symbol-width'
  810. variable to the value of the width of graph column is in the varlist of
  811. the `let' expression.
  812.  
  813.    These considerations lead to the following function definition:
  814.  
  815.      (defun graph-body-print (numbers-list)
  816.        "Print a bar graph of the NUMBERS-LIST.
  817.      The numbers-list consists of the Y-axis values."
  818.      
  819.        (let ((height (apply 'max numbers-list))
  820.              (symbol-width (length graph-blank))
  821.              from-position)
  822.      
  823.          (while numbers-list
  824.            (setq from-position (point))
  825.            (insert-rectangle
  826.             (column-of-graph height (car numbers-list)))
  827.            (goto-char from-position)
  828.            (forward-char symbol-width)
  829.            ;; Draw graph column by column.
  830.            (sit-for 0)
  831.            (setq numbers-list (cdr numbers-list)))
  832.          ;; Place point for X axis labels.
  833.          (forward-line height)
  834.          (insert "\n")
  835.      ))
  836.  
  837. The one unexpected expression in this function is the `(sit-for 0)'
  838. expression in the `while' loop.  This expression makes the graph
  839. printing operation more interesting to watch than it would be
  840. otherwise.  The expression causes Emacs to `sit' or do nothing for a
  841. zero length of time and then redraw the screen.  Placed here, it causes
  842. Emacs to redraw the screen column by column.  Without it, Emacs would
  843. not redraw the screen until the function exits.
  844.  
  845.    We can test `graph-body-print' with a short list of numbers.
  846.  
  847.   1. Install `graph-symbol', `graph-blank', `column-of-graph' and
  848.      `graph-body-print'.
  849.  
  850.   2. Copy the following expression:
  851.  
  852.           (graph-body-print '(1 2 3 4 6 4 3 5 7 6 5 2 3))
  853.  
  854.   3. Switch to the `*scratch*' buffer and place the cursor where you
  855.      want the graph to start.
  856.  
  857.   4. Type `M-:' (`eval-expression').
  858.  
  859.   5. Yank the `graph-body-print' expression into the minibuffer with
  860.      `C-y' (`yank)'.
  861.  
  862.   6. Press <RET> to evaluate the `graph-body-print' expression.
  863.  
  864.    Emacs will print a graph like this:
  865.  
  866.                          *
  867.                      *   **
  868.                      *  ****
  869.                     *** ****
  870.                    ********* *
  871.                   ************
  872.                  *************
  873.  
  874. 
  875. File: emacs-lisp-intro.info,  Node: recursive-graph-body-print,  Next: Printed Axes,  Prev: graph-body-print,  Up: Readying a Graph
  876.  
  877. The `recursive-graph-body-print' Function
  878. =========================================
  879.  
  880.    The `graph-body-print' function may also be written recursively.  In
  881. this case, it is divided into two parts: an outside `wrapper' that uses
  882. a `let' expression to determine the values of several variables that
  883. need only be found once, such as the maximum height of the graph, and
  884. an inside function that is called recursively to print the graph.
  885.  
  886.    The `wrapper' is uncomplicated:
  887.  
  888.      (defun recursive-graph-body-print (numbers-list)
  889.        "Print a bar graph of the NUMBERS-LIST.
  890.      The numbers-list consists of the Y-axis values."
  891.        (let ((height (apply 'max numbers-list))
  892.              (symbol-width (length graph-blank))
  893.              from-position)
  894.          (recursive-graph-body-print-internal
  895.           numbers-list
  896.           height
  897.           symbol-width)))
  898.  
  899.    The recursive function is a little more difficult.  It has four
  900. parts: the `do-again-test', the printing code, the recursive call, and
  901. the `next-step-expression'.  The `do-again-test' is an `if' expression
  902. that determines whether the `numbers-list' contains any remaining
  903. elements; if it does, the function prints one column of the graph using
  904. the printing code and calls itself again.  The function calls itself
  905. again according to the value produced by the `next-step-expression'
  906. which causes the call to act on a shorter version of the `numbers-list'.
  907.  
  908.      (defun recursive-graph-body-print-internal
  909.        (numbers-list height symbol-width)
  910.        "Print a bar graph.
  911.      Used within recursive-graph-body-print function."
  912.      
  913.        (if numbers-list
  914.            (progn
  915.              (setq from-position (point))
  916.              (insert-rectangle
  917.               (column-of-graph height (car numbers-list)))
  918.              (goto-char from-position)
  919.              (forward-char symbol-width)
  920.              (sit-for 0)     ; Draw graph column by column.
  921.              (recursive-graph-body-print-internal
  922.               (cdr numbers-list) height symbol-width))))
  923.  
  924.    After installation, this expression can be tested; here is a sample:
  925.  
  926.      (recursive-graph-body-print '(3 2 5 6 7 5 3 4 6 4 3 2 1))
  927.  
  928.    Here is what `recursive-graph-body-print' produces:
  929.  
  930.                      *
  931.                     **   *
  932.                    ****  *
  933.                    **** ***
  934.                  * *********
  935.                  ************
  936.                  *************
  937.  
  938.    Either of these two functions, `graph-body-print' or
  939. `recursive-graph-body-print', create the body of a graph.
  940.  
  941. 
  942. File: emacs-lisp-intro.info,  Node: Printed Axes,  Next: Line Graph Exercise,  Prev: recursive-graph-body-print,  Up: Readying a Graph
  943.  
  944. Need for Printed Axes
  945. =====================
  946.  
  947.    A graph needs printed axes, so you can orient yourself.  For a
  948. do-once project, it may be reasonable to draw the axes by hand using
  949. Emacs's Picture mode; but a graph drawing function may be used more
  950. than once.
  951.  
  952.    For this reason, I have written enhancements to the basic
  953. `print-graph-body' function that automatically print labels for the
  954. horizontal and vertical axes.  Since the label printing functions do
  955. not contain much new material, I have placed their description in an
  956. appendix.  *Note A Graph with Labelled Axes: Full Graph.
  957.  
  958. 
  959. File: emacs-lisp-intro.info,  Node: Line Graph Exercise,  Prev: Printed Axes,  Up: Readying a Graph
  960.  
  961. Exercise
  962. ========
  963.  
  964.    Write a line graph version of the graph printing functions.
  965.  
  966. 
  967. File: emacs-lisp-intro.info,  Node: Emacs Initialization,  Next: Debugging,  Prev: Readying a Graph,  Up: Top
  968.  
  969. Your `.emacs' File
  970. ******************
  971.  
  972.    "You don't have to like Emacs to like it" - this seemingly
  973. paradoxical statement is the secret of GNU Emacs.  The plain, `out of
  974. the box' Emacs is a generic tool.  Most people who use it, customize it
  975. to suit themselves.
  976.  
  977.    GNU Emacs is mostly written in Emacs Lisp; this means that by writing
  978. expressions in Emacs Lisp you can change or extend Emacs.
  979.  
  980. * Menu:
  981.  
  982. * Default Configuration::       Emacs has sensible defaults.
  983. * Site-wide Init::              You can write site-wide init files.
  984. * edit-options::                How to set some variables for a session.
  985. * Beginning a .emacs File::     How to write a `.emacs file'.
  986. * Text and Auto-fill::          Automatically wrap lines.
  987. * Mail Aliases::                Use abbreviations for email addresses.
  988. * Indent Tabs Mode::            Don't use tabs with TeX
  989. * Keybindings::                 Create some personal keybindings.
  990. * Loading Files::               Load (i.e. evaluate) files automatically.
  991. * Autoload::                    Make functions available.
  992. * Simple Extension::            Define a function; bind it to a key.
  993. * Keymaps::                     More about key binding.
  994. * X11 Colors::                  Colors in version 19 in X.
  995. * V19 Miscellaneous::           Automatically resize minibuffer, and more.
  996. * Mode Line::                   How to customize your mode line.
  997.  
  998. 
  999. File: emacs-lisp-intro.info,  Node: Default Configuration,  Next: Site-wide Init,  Prev: Emacs Initialization,  Up: Emacs Initialization
  1000.  
  1001. Emacs's Default Configuration
  1002. =============================
  1003.  
  1004.    There are those who appreciate Emacs's default configuration.  After
  1005. all, Emacs starts you in C mode when you edit a C file, starts you in
  1006. Fortran mode when you edit a Fortran file, and starts you in
  1007. Fundamental mode when you edit an unadorned file.  This all makes
  1008. sense, if you do not know who is going to use Emacs.  Who knows what a
  1009. person hopes to do with an unadorned file?  Fundamental mode is the
  1010. right default for such a file, just as C mode is the right default for
  1011. editing C code.  But when you do know who is going to use Emacs--you,
  1012. yourself--then it makes sense to customize Emacs.
  1013.  
  1014.    For example, I seldom want Fundamental mode when I edit an otherwise
  1015. undistinguished file; I want Text mode.  This is why I customize Emacs:
  1016. so it suits me.
  1017.  
  1018.    You can customize and extend Emacs by writing or adapting a
  1019. `~/.emacs' file.  This is your personal initialization file; its
  1020. contents, written in Emacs Lisp, tell Emacs what to do.
  1021.  
  1022.    This chapter describes a simple `.emacs' file; for more information,
  1023. see *Note The Init File: (emacs)Init File, and *Note The Init File:
  1024. (elisp)Init File.
  1025.  
  1026. 
  1027. File: emacs-lisp-intro.info,  Node: Site-wide Init,  Next: edit-options,  Prev: Default Configuration,  Up: Emacs Initialization
  1028.  
  1029. Site-wide Initialization Files
  1030. ==============================
  1031.  
  1032.    In addition to your personal initialization file, Emacs automatically
  1033. loads various site-wide initialization files, if they exist.  These
  1034. have the same form as your `.emacs' file, but are loaded by everyone.
  1035.  
  1036.    Two site-wide initialization files, `site-load.el' and
  1037. `site-init.el', are loaded into Emacs and then `dumped' if a `dumped'
  1038. version of Emacs is created, as is most common.  (Dumped copies of
  1039. Emacs load more quickly.  However, once a file is loaded and dumped, a
  1040. change to it does not lead to a change in Emacs unless you load it
  1041. yourself or re-dump Emacs.  *Note Building Emacs: (elisp)Building
  1042. Emacs, and the `INSTALL' file.)
  1043.  
  1044.    Three other site-wide initialization files are loaded automatically
  1045. each time you start Emacs, if they exist.  These are `site-start.el',
  1046. which is loaded *before* your `.emacs' file, and `default.el', and the
  1047. terminal type file, which are both loaded *after* your `.emacs' file.
  1048.  
  1049.    Settings and definitions in your `.emacs' file will overwrite
  1050. conflicting settings and definitions in a `site-start.el' file, if it
  1051. exists; but the settings and definitions in a `default.el' or terminal
  1052. type file will overwrite those in your `.emacs' file.  (You can prevent
  1053. interference from a terminal type file by setting `term-file-prefix' to
  1054. `nil'.  *Note A Simple Extension: Simple Extension.)
  1055.  
  1056.    The `INSTALL' file that comes in the distribution contains
  1057. descriptions of the `site-init.el' and `site-load.el' files.
  1058.  
  1059.    The `loadup.el', `startup.el', and `loaddefs.el' files control
  1060. loading.  These files are in the `lisp' directory of the Emacs
  1061. distribution and are worth perusing.
  1062.  
  1063.    The `loaddefs.el' file contains a good many suggestions as to what
  1064. to put into your own `.emacs' file, or into a site-wide initialization
  1065. file.
  1066.  
  1067. 
  1068. File: emacs-lisp-intro.info,  Node: edit-options,  Next: Beginning a .emacs File,  Prev: Site-wide Init,  Up: Emacs Initialization
  1069.  
  1070. Setting Variables for One Session
  1071. =================================
  1072.  
  1073.    My copy of Emacs version 19.23 has 392 options that you can set with
  1074. the `edit-options' command.  These `options' are no more than variables
  1075. such as we have seen earlier and defined using `defvar'.
  1076.  
  1077.    Emacs determines whether a variable is intended to be easily settable
  1078. by looking at the first character in its documentation string; if the
  1079. first character is an asterisk, `*', the variable is a user-settable
  1080. option.  (*Note Initializing a Variable with `defvar': defvar.)
  1081.  
  1082.    The `edit-options' command lists all the variables in Emacs that the
  1083. people who wrote the Emacs Lisp libraries think ought to be readily
  1084. settable.  It provides an easy-to-use interface for resetting these
  1085. variables.
  1086.  
  1087.    On the other hand, options set using `edit-options' are set only for
  1088. the duration of your editing session.  The new values are not saved
  1089. between sessions.  Each time Emacs starts, it reads the original
  1090. `defvar' value in its source code.  To carry a changed setting from one
  1091. session to the next, you need to use a `setq' expression within a
  1092. `.emacs' file or other file that you load every time you start a
  1093. session.
  1094.  
  1095.    For me, the major use of the `edit-options' command is to suggest
  1096. variables I might want to set in my `.emacs' file.  I urge you to look
  1097. through the list.
  1098.  
  1099.    *Note Editing Variable Values: (emacs)Edit Options, for more
  1100. information.
  1101.  
  1102. 
  1103. File: emacs-lisp-intro.info,  Node: Beginning a .emacs File,  Next: Text and Auto-fill,  Prev: edit-options,  Up: Emacs Initialization
  1104.  
  1105. Beginning a `.emacs' File
  1106. =========================
  1107.  
  1108.    When you start Emacs, it loads your `.emacs' file unless you tell it
  1109. not to by specifying `-q' on the command line.  (The `emacs -q' command
  1110. gives you a plain, out-of-the-box Emacs.)
  1111.  
  1112.    A `.emacs' file contains Lisp expressions.  Often, these are no more
  1113. than expressions to set values; sometimes they are function definitions.
  1114.  
  1115.    *Note The Init File `~/.emacs': (emacs)Init File, for a short
  1116. description of initialization files.
  1117.  
  1118.    This chapter goes over some of the same ground, but is a walk among
  1119. extracts from a complete, long-used `.emacs' file--my own.
  1120.  
  1121.    The first part of the file consists of comments: reminders to myself.
  1122. By now, of course, I remember these things, but when I started, I did
  1123. not.
  1124.  
  1125.      ;;;; Bob's .emacs file
  1126.      ; Robert J. Chassell
  1127.      ; 26 September 1985
  1128.  
  1129. Look at that date!  I started this file a long time ago.  I have been
  1130. adding to it ever since.
  1131.  
  1132.      ; Each section in this file is introduced by a
  1133.      ; line beginning with four semicolons; and each
  1134.      ; entry is introduced by a line beginning with
  1135.      ; three semicolons.
  1136.  
  1137. This describes the usual conventions for comments in Emacs Lisp.
  1138. Everything on a line that follows a semicolon is a comment.  Two,
  1139. three, and four semicolons are used as section and subsection markers.
  1140. (*Note Comments: (elisp)Comments, for more about comments.)
  1141.  
  1142.      ;;;; The Help Key
  1143.      ; Control-h is the help key;
  1144.      ; after typing control-h, type a letter to
  1145.      ; indicate the subject about which you want help.
  1146.      ; For an explanation of the help facility,
  1147.      ; type control-h three times in a row.
  1148.  
  1149. Just remember: type `C-h' three times for help.
  1150.  
  1151.      ; To find out about any mode, type control-h m
  1152.      ; while in that mode.  For example, to find out
  1153.      ; about mail mode, enter mail mode and then type
  1154.      ; control-h m.
  1155.  
  1156. `Mode help', as I call this, is very helpful.  Usually, it tells you
  1157. all you need to know.
  1158.  
  1159.    Of course, you don't need to include comments like these in your
  1160. `.emacs' file.  I included them in mine because I kept forgetting about
  1161. Mode help or the conventions for comments--but I was able to remember
  1162. to look here to remind myself.
  1163.  
  1164.