From: ······@gmail.com
Subject: basic emacs lisp idioms
Date: 
Message-ID: <ab3047dd-8846-4e47-ad4e-4d6adf33b7d0@j33g2000pri.googlegroups.com>
Here's a short tutorial i wrote up today that is a basic collection of
Emacs Lisp Idioms.

The HTML version with links, syntax coloring, is at:
 http://xahlee.org/emacs/elisp_idioms.html

The text version follows. Comments, corrections, suggestions welcome.

-----------------------------
This page collects some basic emacs lisp programing patterns related
to text processing.

This page is grouped into 2 sections: Interactive and Batch. The
Interactive section focuses on idioms of writing the type of commands
you call when actively editing. For example, looking up the word under
cursor in google search, replace certain words in current region,
insert XML template, rename a given function in the current programing
project, etc. The Batch section focuses on batch style text
processing, typically the type of tasks one would do in unix shell
tools or Perl. For example, find and replace on a list of given files
or dir, run XML validation on a bunch of files.

The idioms on this page contains only very basic ones, suitable for
beginning elisp programer.

You should first be familiar with basic emacs functions that get
cursor position, move cursor, search text, inserting and deleting
text. See Elisp Common Functions Reference.

------------------------------
Interactive Command Idioms

Grabbing Text

Grab the text of given beginning position and ending position.

; get the string from buffer
(setq myStr (buffer-substring myStartPos myEndPos))
(setq myStr (buffer-substring-no-properties myStartPos myEndPos))

Emacs's string can have properties for the purposes of syntax
coloring, active button, hypertext, etc. The “buffer-substring-no-
properties” function just return a plain string without these
properties. However, most functions that takes string as argument can
also accept strings that has properties.

Reference: Elisp Manual: Buffer-Contents.

------------------------------

Grabbing the current word, line, sentence, url, file name etc.

; grab a thing at point. The “thing” is a semantic unit. It can be a
; word, symbol, line, sentence, filename, url and others.
(setq myStr (thing-at-point 'word)) ; grab the current word
(setq myStr (thing-at-point 'symbol)) ; grab the current word with
hyphens or underscore
(setq line (thing-at-point 'line)) ; grab the current line

; grab the start and end positions of a line (or any other thing)
(setq myBoundaries (bounds-of-thing-at-point 'line))
Note that, when the thing is a “symbol”, it usually means any
alphanumeric sequence with dash “-” or underscore “_” characters. For
example, if you are writing php reference lookup command, and the
cursor is on p in “ print_r($y);”, you want to grab the whole
“print_r” not just “print”. The exact meaning of symbol depends on the
mode's Syntax Table.

Reference: Elisp Manual: Syntax-Tables.

------------------------------
Here's a example of php reference lookup command that grabs by
“symbol”.

(defun php-lookup ()
  "Look up current word in PHP ref site in a browser.\n
  If a region is active (a phrase), lookup that phrase."
  (interactive)
  (let (myword myurl)
    (setq myword
          (if (and transient-mark-mode mark-active)
              (buffer-substring-no-properties (region-beginning)
(region-end))
            (thing-at-point 'symbol)))
    (setq myurl
          (concat "http://us.php.net/" myword))
    (browse-url myurl)))
Reference: Elisp Manual: Buffer-Contents.

------------------------------
Grab Between Matching Pairs

Grab the current text between delimiters such as between angle
brackets “<>”, parens “()”, double quotes “""”, etc.

(defun select-inside-quotes ()
  "Select text between double straight quotes
on each side of cursor."
  (interactive)
  (let (p1 p2)
    (skip-chars-backward "^\"")
    (setq p1 (point))
    (skip-chars-forward "^\"")
    (setq p2 (point))

    (goto-char p1)
    (push-mark p2)
    (setq mark-active t)
  )
)

------------------------------
Acting on Region

Idiom for a command that works on the current region.

Let your function have 2 parameters, such as “start” and “end”, then
use “(interactive "r")”, then the parameters will be filled with
beginning and ending positions of the region. Example:

(defun remove-hard-wrap-region (start end)
  "Replace newline chars in region by single spaces."
  (interactive "r")
  (let ((fill-column 90002000))
    (fill-region start end)))

------------------------------
Idiom for acting on the region, if there's one, else, on the current
word or thing.

(defun down-case-word-or-region ()
  "Make current word or region into lower case."
(interactive)
(let (pos1 pos2)
  (if (and transient-mark-mode mark-active)
      (setq pos1 (region-beginning)
            pos2 (region-end))
    (setq pos1 (car (bounds-of-thing-at-point 'word))
          pos2 (cdr (bounds-of-thing-at-point 'word))))
  (downcase-region pos1 pos2)
  )
)

------------------------------
Prompting and Getting Input

Idiom for promping user for input as the argument to your command.

Use this code “(interactive "‹code›‹promp string›")”. Example:

(defun query-friends-phone (name)
  "..."
  (interactive "sEnter friend's name: ")
  (message "Name: %s" name)
)

What the “(interactive "sEnter friend's name:")” does is that it will
ask user to input something, taken as string, and becomes the value of
your command's parameter.

The “interactive” can be used to get other types of input. Here are
some basic examples of using “interactive”.

“(interactive)” makes the function available thru interactive use,
where user can call it with execute-extended-command (M-x).

“(interactive "s")” will prompt the user to enter a argument, taken as
string, as argument to the function.

“(interactive "n")” will prompt the user to enter a argument, taken as
number, as argument to the function.

The prompt text can follow the single-letter code string.

If your function takes multiple inputs, you can promp user multiple
times, using a single call “interactive”, by joining the promp code
string with “\n” in between, like this:

(defun query-friends-phone (name age)
  "..."
  (interactive "sEnter friend's name: \nnEnter friend's age: ")
  (message "Name: %s, Age: %d" name age)
)

Reference: Elisp Manual: Defining-Commands.


------------------------------
Batch Style Text Processing Idioms

Open a file, process it, save, close it

; open a file, process it, save, close it
(defun my-process-file (fpath)
  "process the file at fullpath fpath ..."
  (let (mybuffer)
    (setq mybuffer (find-file fpath))
    (goto-char (point-min)) ;; in case buffer already open
    ;; do something
    (save-buffer)
    (kill-buffer mybuffer)))

For processing hundreds of files, you don't need emacs to keep undo
info or fontification. This is more efficient:

(defun my-process-file (fpath)
  "process the file at fullpath fpath ..."
  (let ()
    ;; create temp buffer without undo record. first space is
necessary
    (set-buffer (get-buffer-create " myTemp"))
    (insert-file-contents filePath nil nil nil t)
    ;; process it ...
    (kill-buffer " myTemp")))

------------------------------
Find Replace strings:

; idiom for string replacement in current buffer;
; use search-forward-regexp if you need regexp
  (goto-char (point-min))
  (while (search-forward "myStr1" nil t) (replace-match
"myReplaceStr2"))
  (goto-char (point-min))
  (while (search-forward "myStr2" nil t) (replace-match
"myReplaceStr2"))
  ;; repeat for other strings ...

Calling a shell command.

; idiom for calling a shell command
(shell-command "cp /somepath/myfile.txt  /somepath")

; idiom for calling a shell command and get its output
(shell-command-to-string "ls")
Both shell-command and shell-command-to-string will wait for the shell
process to finish before continuing. To not wait, use start-process or
start-process-shell-command.

Reference: Elisp Manual: Asynchronous-Processes.

------------------------------
Traverse a directory recursively.

In the following, my-process-file is a function that takes a file full
path as input. The find-lisp-find-files will generate a list of full
paths, using a regex on file name. The “mapc” will apply the function
to elements in a list.

; idiom for traversing a directory
(require 'find-lisp)
(mapc 'my-process-file (find-lisp-find-files "~/web/emacs/" "\\.html
$"))

------------------------------

  Xah
∑ http://xahlee.org/

☄

From: ············@gmail.com
Subject: Re: basic emacs lisp idioms
Date: 
Message-ID: <5844e3db-31e5-4e19-848e-583161b8da27@m36g2000hse.googlegroups.com>
On 14 juin, 15:35, ·······@gmail.com" <······@gmail.com> wrote:
> Here's a short tutorial i wrote up today that is a basic collection of
> Emacs Lisp Idioms.
>
> The HTML version with links, syntax coloring, is at:
>  http://xahlee.org/emacs/elisp_idioms.html
>
> The text version follows. Comments, corrections, suggestions welcome.
>
> -----------------------------
> This page collects some basic emacs lisp programing patterns related
> to text processing.
>
> This page is grouped into 2 sections: Interactive and Batch. The
> Interactive section focuses on idioms of writing the type of commands
> you call when actively editing. For example, looking up the word under
> cursor in google search, replace certain words in current region,
> insert XML template, rename a given function in the current programing
> project, etc. The Batch section focuses on batch style text
> processing, typically the type of tasks one would do in unix shell
> tools or Perl. For example, find and replace on a list of given files
> or dir, run XML validation on a bunch of files.
>
> The idioms on this page contains only very basic ones, suitable for
> beginning elisp programer.
>
> You should first be familiar with basic emacs functions that get
> cursor position, move cursor, search text, inserting and deleting
> text. See Elisp Common Functions Reference.
>
> ------------------------------
> Interactive Command Idioms
>
> Grabbing Text
>
> Grab the text of given beginning position and ending position.
>
> ; get the string from buffer
> (setq myStr (buffer-substring myStartPos myEndPos))
> (setq myStr (buffer-substring-no-properties myStartPos myEndPos))
>
> Emacs's string can have properties for the purposes of syntax
> coloring, active button, hypertext, etc. The “buffer-substring-no-
> properties” function just return a plain string without these
> properties. However, most functions that takes string as argument can
> also accept strings that has properties.
>
> Reference: Elisp Manual: Buffer-Contents.
>
> ------------------------------
>
> Grabbing the current word, line, sentence, url, file name etc.
>
> ; grab a thing at point. The “thing” is a semantic unit. It can be a
> ; word, symbol, line, sentence, filename, url and others.
> (setq myStr (thing-at-point 'word)) ; grab the current word
> (setq myStr (thing-at-point 'symbol)) ; grab the current word with
> hyphens or underscore
> (setq line (thing-at-point 'line)) ; grab the current line
>
> ; grab the start and end positions of a line (or any other thing)
> (setq myBoundaries (bounds-of-thing-at-point 'line))
> Note that, when the thing is a “symbol”, it usually means any
> alphanumeric sequence with dash “-” or underscore “_” characters. For
> example, if you are writing php reference lookup command, and the
> cursor is on p in “ print_r($y);”, you want to grab the whole
> “print_r” not just “print”. The exact meaning of symbol depends on the
> mode's Syntax Table.
>
> Reference: Elisp Manual: Syntax-Tables.
>
> ------------------------------
> Here's a example of php reference lookup command that grabs by
> “symbol”.
>
> (defun php-lookup ()
>   "Look up current word in PHP ref site in a browser.\n
>   If a region is active (a phrase), lookup that phrase."
>   (interactive)
>   (let (myword myurl)
>     (setq myword
>           (if (and transient-mark-mode mark-active)
>               (buffer-substring-no-properties (region-beginning)
> (region-end))
>             (thing-at-point 'symbol)))
>     (setq myurl
>           (concat "http://us.php.net/" myword))
>     (browse-url myurl)))
> Reference: Elisp Manual: Buffer-Contents.
>
> ------------------------------
> Grab Between Matching Pairs
>
> Grab the current text between delimiters such as between angle
> brackets “<>”, parens “()”, double quotes “""”, etc.
>
> (defun select-inside-quotes ()
>   "Select text between double straight quotes
> on each side of cursor."
>   (interactive)
>   (let (p1 p2)
>     (skip-chars-backward "^\"")
>     (setq p1 (point))
>     (skip-chars-forward "^\"")
>     (setq p2 (point))
>
>     (goto-char p1)
>     (push-mark p2)
>     (setq mark-active t)
>   )
> )
>
> ------------------------------
> Acting on Region
>
> Idiom for a command that works on the current region.
>
> Let your function have 2 parameters, such as “start” and “end”, then
> use “(interactive "r")”, then the parameters will be filled with
> beginning and ending positions of the region. Example:
>
> (defun remove-hard-wrap-region (start end)
>   "Replace newline chars in region by single spaces."
>   (interactive "r")
>   (let ((fill-column 90002000))
>     (fill-region start end)))
>
> ------------------------------
> Idiom for acting on the region, if there's one, else, on the current
> word or thing.
>
> (defun down-case-word-or-region ()
>   "Make current word or region into lower case."
> (interactive)
> (let (pos1 pos2)
>   (if (and transient-mark-mode mark-active)
>       (setq pos1 (region-beginning)
>             pos2 (region-end))
>     (setq pos1 (car (bounds-of-thing-at-point 'word))
>           pos2 (cdr (bounds-of-thing-at-point 'word))))
>   (downcase-region pos1 pos2)
>   )
> )
>
> ------------------------------
> Prompting and Getting Input
>
> Idiom for promping user for input as the argument to your command.
>
> Use this code “(interactive "‹code›‹promp string›")”. Example:
>
> (defun query-friends-phone (name)
>   "..."
>   (interactive "sEnter friend's name: ")
>   (message "Name: %s" name)
> )
>
> What the “(interactive "sEnter friend's name:")” does is that it will
> ask user to input something, taken as string, and becomes the value of
> your command's parameter.
>
> The “interactive” can be used to get other types of input. Here are
> some basic examples of using “interactive”.
>
> “(interactive)” makes the function available thru interactive use,
> where user can call it with execute-extended-command (M-x).
>
> “(interactive "s")” will prompt the user to enter a argument, taken as
> string, as argument to the function.
>
> “(interactive "n")” will prompt the user to enter a argument, taken as
> number, as argument to the function.
>
> The prompt text can follow the single-letter code string.
>
> If your function takes multiple inputs, you can promp user multiple
> times, using a single call “interactive”, by joining the promp code
> string with “\n” in between, like this:
>
> (defun query-friends-phone (name age)
>   "..."
>   (interactive "sEnter friend's name: \nnEnter friend's age: ")
>   (message "Name: %s, Age: %d" name age)
> )
>
> Reference: Elisp Manual: Defining-Commands.
>
> ------------------------------
> Batch Style Text Processing Idioms
>
> Open a file, process it, save, close it
>
> ; open a file, process it, save, close it
> (defun my-process-file (fpath)
>   "process the file at fullpath fpath ..."
>   (let (mybuffer)
>     (setq mybuffer (find-file fpath))
>     (goto-char (point-min)) ;; in case buffer already open
>     ;; do something
>     (save-buffer)
>     (kill-buffer mybuffer)))
>
> For processing hundreds of files, you don't need emacs to keep undo
> info or fontification. This is more efficient:
>
> (defun my-process-file (fpath)
>   "process the file at fullpath fpath ..."
>   (let ()
>     ;; create temp buffer without undo record. first space is
> necessary
>     (set-buffer (get-buffer-create " myTemp"))
>     (insert-file-contents filePath nil nil nil t)
>     ;; process it ...
>     (kill-buffer " myTemp")))
>
> ------------------------------
> Find Replace strings:
>
> ; idiom for string replacement in current buffer;
> ; use search-forward-regexp if you need regexp
>   (goto-char (point-min))
>   (while (search-forward "myStr1" nil t) (replace-match
> "myReplaceStr2"))
>   (goto-char (point-min))
>   (while (search-forward "myStr2" nil t) (replace-match
> "myReplaceStr2"))
>   ;; repeat for other strings ...
>
> Calling a shell command.
>
> ; idiom for calling a shell command
> (shell-command "cp /somepath/myfile.txt  /somepath")
>
> ; idiom for calling a shell command and get its output
> (shell-command-to-string "ls")
> Both shell-command and shell-command-to-string will wait for the shell
> process to finish before continuing. To not wait, use start-process or
> start-process-shell-command.
>
> Reference: Elisp Manual: Asynchronous-Processes.
>
> ------------------------------
> Traverse a directory recursively.
>
> In the following, my-process-file is a function that takes a file full
> path as input. The find-lisp-find-files will generate a list of full
> paths, using a regex on file name. The “mapc” will apply the function
> to elements in a list.
>
> ; idiom for traversing a directory
> (require 'find-lisp)
> (mapc 'my-process-file (find-lisp-find-files "~/web/emacs/" "\\.html
> $"))
>
> ------------------------------
>
>   Xah
> ∑http://xahlee.org/
>
> ☄

Oh, you should have written this a week ago and let me save a lot of
time grabbing such tips ;)
By the way, let me just add a simple way to use this in shell script.
I needed a way to indent a lot of files and i wanted it to be done the
emacs way. I'm not a shell guru, please forgive any bad practice.
Skipping the file selection, the 'indent' scipt looks like this:

-------- 8< ----------
#!/bin/sh

if [ $# -eq 0 ]
    then
    echo "Usage: $0 [-u <user>] [--] <filenames>">&2
    exit 1
fi

for arg
  do
  case $arg in
      -u) shift; user=$arg; shift; continue;;
      --) shift; break;;
      *) continue;;
  esac
done

for file
  do
  files="$files \"$file\""
done

if [ -z $files ]; then exit 0; fi

batch="
(let (buffer)
  (dolist (filename '($files))
    (setq buffer (find-file filename))
    (indent-region (point-min) (point-max) nil)
    (save-buffer)
    (kill-buffer buffer)))
"

if [ -n $user ];
    then
    user=`whoami`
fi
if [ -n $user ]; then user="-u $user"; fi
emacs -batch $user --eval "$batch"

-------- 8< ----------

Thanks Mr Lee, such tutorials are really helpfull.

-Nicolas
From: ······@gmail.com
Subject: Re: basic emacs lisp idioms
Date: 
Message-ID: <62610317-1345-4df2-bf5a-d4c812b9b18d@a32g2000prf.googlegroups.com>
Xah wrote:
«Here's a short tutorial i wrote up today that is a basic collection
of Emacs Lisp Idioms.  http://xahlee.org/emacs/elisp_idioms.html»

Nicolas ············@gmail.com wrote:

> Oh, you should have written this a week ago and let me save a lot of
> time grabbing such tips ;)
> By the way, let me just add a simple way to use this in shell script.
> I needed a way to indent a lot of files and i wanted it to be done the
> emacs way. I'm not a shell guru, please forgive any bad practice.
> Skipping the file selection, the 'indent' scipt looks like this:
>
> #!/bin/sh
>
> ...
>
> for file
>   do
>   files="$files \"$file\""
> done
>
> if [ -z $files ]; then exit 0; fi
>
> batch="
> (let (buffer)
>   (dolist (filename '($files))
>     (setq buffer (find-file filename))
>     (indent-region (point-min) (point-max) nil)
>     (save-buffer)
>     (kill-buffer buffer)))
> "
>
> ...
>
> emacs -batch $user --eval "$batch"

Thanks. Very interesting example.

This inspired me to look at running elisp from command line which i've
been wanting to look at. I cleaned up my own elisp script and added a
section about running elisp from command line like a perl, python
script.

Here's the addition:
---------------

Running Elisp in Batch mode

You can run a elisp program in the the Operating System's command line
interfare (shell), using the “--script” option. For example:

emacs --script ~/emacs/my_scripts/process_log.el

Emacs has few other options and variations to control how you run a
elisp script. Here's a table of main options:

full option name     |   meaning

--no-site-file      |    Do not load the site wide “site-start.el”

--no-init-file   |   Do not load your init files “~/.emacs” or
“default.el”.

--batch       |    Run emacs in batch mode, use it together with “--
load” to specify a lisp file. This implies “--no-init-file” but not “--
no-site-file”.

--script ‹file path›  |     Run emacs like “--batch” with “--load” set
to “‹file path›”.

--load="‹elispFilePath›"   |   Execute the elisp file at
“‹elispFilePath›”.

--user=‹user name›   |   Load user ‹user name›'s emacs init file (the
“.emacs”).

When you write a elisp script to run in batch, make sure your elisp
file is self-contained, doesn't call functions in your emacs init
file, call to load all libraries it needs (using “require” or “load”),
has necessary load path set in the script (e.g. “(add-to-list 'load-
path ‹lib path›)”), just like you would with a Perl or Python script.

If you've done a clean job in your elisp script, then, all you need to
use is “emacs --script ‹elisp file path›”.

If your elisp program requires functions that you've defined in your
emacs init file (the “.emacs”), then you should explicitly load it in
your script by “(load ‹emacs init file path›)”, or, you can add the
option to load it, like this: “--user=xah”. (best to actually pull out
the function you need)

If you are on a Mac with Carbon Emacs or Aquamacs, your emacs program
will be be like this “/Applications/Emacs.app/Contents/MacOS/Emacs”
instead of just “emacs”. The following is a example of a variation

/Applications/Emacs.app/Contents/MacOS/Emacs --no-site-file --batch --
load="~/process_log.el"

Reference: (info "(emacs)Option Index").

  Xah
∑ http://xahlee.org/

☄
From: Blake McBride
Subject: Re: basic emacs lisp idioms
Date: 
Message-ID: <48587250.9020104@mcbride.name>
With a few very minor tweaks, emacs could be pretty useful as a command 
line lisp system.  I've encountered the following problems (although 
given my experience, it is highly likely someone knows a solution.)

1.  If you do a (read t) to get keyboard input emacs always prompts with 
"Lisp expression:".  I would prefer the ability to specify my own prompt 
via (princ "....")

2.  I'd like to see a (read-string) function that reads to the eol

3.  If you do:  emacs --batch -Q -l file.el
Emacs runs the file in the current directory just fine, however, if you 
compile the file and have a "file.el" and "file.elc" and want file.elc 
to run unless file.el has a later date you have to do:

emacs --batch -Q -eval '(progn (setq load-path (list nil)) (load "file" 
nil t))'

You should just be able to do:  emacs --batch -Q -l file

4.  The ability to read & write strings and s-exps to a file (directly) 
would be great too.

With these few additions, emacs could be used as a really good command file.

Blake McBride
From: Pascal J. Bourguignon
Subject: Re: basic emacs lisp idioms
Date: 
Message-ID: <87k5gnb7e5.fsf@hubble.informatimago.com>
Blake McBride <·····@mcbride.name> writes:

> With a few very minor tweaks, emacs could be pretty useful as a
> command line lisp system.  I've encountered the following problems
> (although given my experience, it is highly likely someone knows a
> solution.)
>
> 1.  If you do a (read t) to get keyboard input emacs always prompts
> with "Lisp expression:".  I would prefer the ability to specify my own
> prompt via (princ "....")
>
> 2.  I'd like to see a (read-string) function that reads to the eol
>
> 3.  If you do:  emacs --batch -Q -l file.el
> Emacs runs the file in the current directory just fine, however, if
> you compile the file and have a "file.el" and "file.elc" and want
> file.elc to run unless file.el has a later date you have to do:
>
> emacs --batch -Q -eval '(progn (setq load-path (list nil)) (load
> "file" nil t))'
>
> You should just be able to do:  emacs --batch -Q -l file
>
> 4.  The ability to read & write strings and s-exps to a file
> (directly) would be great too.
>
> With these few additions, emacs could be used as a really good command file.

I used to think the same, and what function you miss hear can rather
trivially be written in emacs lisp.  However, there's no point in it,
given than there are good Common Lisp implementations that you can use
as shell or script (#!) interpreters.  Try clisp ; have a look at 
http://clisp.cons.org/clash.html

Also, I've noticed that CL primitives and libraries, while not
specifically designed to _edit_ text, are quite powerfull to _process_
text: in general you won't be missing emacs text editing functions.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

THIS IS A 100% MATTER PRODUCT: In the unlikely event that this
merchandise should contact antimatter in any form, a catastrophic
explosion will result.
From: Rob Warnock
Subject: Re: basic emacs lisp idioms
Date: 
Message-ID: <rMednSn6rKlFcsXVnZ2dnUVZ_sbinZ2d@speakeasy.net>
Pascal J. Bourguignon <···@informatimago.com> wrote:
+---------------
| Blake McBride <·····@mcbride.name> writes:
| > ... emacs could be used as a really good command file.
| 
| I used to think the same, and what function you miss hear can rather
| trivially be written in emacs lisp.  However, there's no point in it,
| given than there are good Common Lisp implementations that you can use
| as shell or script (#!) interpreters.  Try clisp ...
+---------------

Or, CMUCL, assuming you've added my #! hack
<http://rpw3.org/hacks/lisp/site-switch-script.lisp>
or equivalent.

+---------------
| ...have a look at http://clisp.cons.org/clash.html
+---------------

I've not tried going *that* far, but my "cmu" script, which is the
usual way I fire up a CMUCL REPL, when given command-line args simply
evaluates them (instead of starting a REPL). Combine that with a
symlink from "~/bin/=" to "~/bin/cmu", and you get a neat little
command-line "CL calculator":

    $ = + 1 2
    3
    $ = expt 2 100
    1267650600228229401496703205376
    $ = \* \* 1e6
    1.2676506002282294e36
    $ 

Yes, it saves the last value in a file and restores it to "*"!  ;-}

    $ = floor 28376542876534 82736
    342976973
    38406
    $ = get-decoded-time
    54
    57
    3
    18
    6
    2008
    2
    T
    8
    $ = loop for i to 25 when '(oddp i)' collect '(expt 2 i)'
    (2 8 32 128 512 2048 8192 32768 131072 524288 2097152 8388608 33554432)
    $ = format t '"2^100 = ~d~%"' '(expt 2 100)'
    2^100 = 1267650600228229401496703205376
    NIL
    $ 

O.k., so quoting starts getting messy when you need strings or sub-exprs.
But you can always just single-quote the whole mess and be done with it:

    $ = '(let ((x "A String.")) (format t "Now print ~(~a~)~%" x) (values))'
    Now print a string.
    $ 

Where it works *really* well is if you have a whole bunch of
pre-defined functions for things you commonly do, which I typically
do in a script called "hwtool" (hardware debugging tool), e.g.:

    $ hwtool dump32 '"Show CMUCL\'s string layout."'
    0x48956a28: 0x0000002a 0x0000006c 0x776f6853 0x554d4320
    0x48956a38: 0x73274c43 0x72747320 0x20676e69 0x6f79616c
    0x48956a48: 0x002e7475 0x00000000 0x48956a2f 0x28f0000b
    0x48956a58: 0x48956a1b 0x28f0000b 0x48956a2f 0x28f0000b
    $ 


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: David Kastrup
Subject: Re: basic emacs lisp idioms
Date: 
Message-ID: <86tzfrgox2.fsf@lola.quinscape.zz>
Blake McBride <·····@mcbride.name> writes:

> With a few very minor tweaks, emacs could be pretty useful as a
> command line lisp system.  I've encountered the following problems
> (although given my experience, it is highly likely someone knows a
> solution.)

Well, you could just use librep.

-- 
David Kastrup