Lispy functions


fsbot: (privmsg (foo (bar…))) will privmsg, to you, the results of the calculation of the inner loop. For example, fsbot: (privmsg (say (concat “hi” “hey”)) or (privmsg “bar”)

Note that, more generally, a call to privmsg anywhere in the body will cause the resulting message to be a privmsg. For example, fsbot: (progn (privmsg) (+ 2 3))

Emacs Documentation: df, dv, dk, wi

Each of these names is just a shortcut to the full emacs name, which is also available.


    <kensanata> , df ignore
    <fsbot> ignore is an interactive compiled Lisp function in
        `subr'.  (ignore &rest IGNORE)
    <fsbot> Do nothing and return nil.  This function accepts
        any number of arguments, but ignores them.

The above could also be achieved by:

    <deego> ,(describe-function 'ignore)
    <deego> ,describe-function ignore
    <kensanata> , dk C-x 2
    <fsbot> split-window-vertically
    <kensanata> , wi split-window-horizontally
    <fsbot> M-x split-window-horizontally RET
    <kensanata> , wi split-window-vertically
    <fsbot> C-x 2, <menu-bar> <files> <split-window>
    <kensanata> dv tab-width
    <fsbot> *Distance between tab stops (for display of tab
        characters), in columns.  Automatically becomes
        buffer-local when set in any fashion.
    <fsbot> You can customize this variable.

Find function : ff

ff prints the function definition, a runs apropos.

   <deego> ,ff ignore
   *fsbot* (defun ignore (&rest ignore)
   *fsbot*   (interactive)
   *fsbot*   nil)

Notice that find-function strips any documentation. For documentation, see df above.

Apropos and Commands

    <deego> , (apropos "^ac")
    <fsbot> 11 matches.  (acapulco accept-process-output access-file
        accessible-keymaps ache aching acid acons acos
        activate-input-method active-minibuffer-window)

To restrict the apropos to the commands erbot provides in IRC, you can add the prefix “fs-”

    <deego> , a "^fs-.*wiki"
    *fsbot* 4 matches.  (fs-google-emacswiki fs-google-hurdwiki
        fs-google-twiki fs-google-wikipedia)

Adding the prefix fs- being specially relevant to fsbot, this can also be done by

     <deego> , commands "wiki"
     *fsbot* 4 matches.  (google-emacswiki google-hurdwiki google-twiki

And “commands” has a further abbrevitation “c”.

An increasing number of emacs functions and variables are accessible to bot users. Common emacs variables are typically available as functions rather than variables, for example:

 <deego> (car (auto-mode-alist))
 *fsbot* ("\\.s?html?\\.e\\'" . html-mode)
 <deego> (lengthg (channel-members))
 *fsbot* 75

Notice the parens around auto-mode-alist and channel-members.

Persistent Data

Users defining new bot functions

(defun) works. Any new functions you define via (defun) will get stored to a file (which for fsbot, is at With appropriate entries in the bot’s .emacs, this file gets reloaded every session, so that your functions are persistent across sessions.

In the defuns, keywords like &optional and &rest now work.

Also, if you want a bot function to be executed upon bot starting up, (defun) a (fs-user-init) and the bots, with appropriate entries in .emacs, will read it.


Any variables you setq in the bot (and all other fs- variables) are also written out to a file periodically, and also persist across sessions, with appropriate entries to the bots’ .emacs. This file for fsbot is at

While many of these variables are just defined by users playing with the bots, some of these variables affect how the bots work! So, please be careful when modifying such variables. Most bot-affecting variables are marked with an “internal-”, such as ‘fs-internal-google-time’. PS: We prefixed these variables with fs- because we do want to allow users to be able to change them.

Common Errors

The most common source of confusion is confusing of TERMS with VARIABLES:

     <Riastradh> , rr-bullet
     <fsbot> hmm, rr-bullet is 0
     <Riastradh> , (setq fs-rr-bullet rr-bullet)
     <fsbot> oops, error.  Symbol's value as variable is void: fs-rr-bullet
     <Riastradh> , (defvar fs-rr-bullet rr-bullet)
     <fsbot> :(   Symbol's function definition is void: fs-defvar
     <Riastradh> Grumbl.[10:56]     
     <deego> ,(setq rr-bullet 0)
     <fsbot> 0
     <Riastradh> , RR
     <deego> nah, one is "TERM", one is variable


 <deego> ,info "foo"
 <fsbot> Press C-x C-e after: (info  "(efaq)Basic keys")

 <deego> ,info-file "ediff" "foo"
 <fsbot> Press C-x C-e after: (info  "(ediff)Quick Help Commands")

fsbot has special functions info-efaq, info-emacs, info-eintr and info-elisp defined for EmacsManual, EmacsLispReference, Emacs FAQ and Elisp intro respectively.

<deego> ,info-efaq "foo"						
<fsbot> Press C-x C-e after: (info  "(efaq)Basic keys")

(info) calls the above 4 functions in succession looking for a match. The ideal order would be efaq,emacs,eintr and elisp, but we choose emacs, elisp, efaq and eintr because the last two, specially the last one are require to install and are not as likely to be installed on people’s computers as the former two.

For each invocation of info on an info file, erbot first tries a “node topic match”, else Searches for it throughout the file.


 <deego> singbot: (progn a)
 <singbot>  (1 2 (33 4))
 <deego> singbot: (setf (caar (cddr a)) 3)
 <singbot> 3
 <deego> singbot: (progn a)
 <singbot>  (1 2 (3 4))

Developer Section

Some Developer guidelines :-) / If you are an ErBot developer

Going deeper:

The nicks used: nick, fs-nick, erbot-nick, erbnoc-nick

;;; 2005-01-06 T10:10:20-0500 (Thursday)    D. Goel
<petekaz> whats the diff between 'nick and 'fs-nick.  I don't understand the
          comment in erbot.el						[10:02]
<petekaz> They are both bound in a let, but the comment implies something that
          I am not understanding.					[10:03]
<deego> petekaz: there are several issues here:				[10:04]

<deego> [1] we want to *temporarily* bind fs-nick to caller's nickname, 
        using a let, so that 2 or more
        concurrent calls to fsbot don't get the nicks mixed up
<deego> [2] we normally want to rely on erbnoc-nick rather than fs-nick 
        for important things, since fs-nick is available to endusers..	
<deego> [3] for some things we rather want to provide fs-nick, if we want
        people to allow minor tricks like: (let ((nick foo)) (tell me about
<deego> [4] all this should not be confused with erbot-nick, which is fsbot's
        own nick							[10:06]
<petekaz> ok. more questions based on that.				[10:07]
<deego> [5] historically, at some places, we simply call nick instead of
        erbnoc-nick... we should really convert all of such calls to
        erbnoc-nick... the former isn't even namespace-compliant.. Similarly, we should move away from tgt... to erbnoc-tgt
<deego> done
<deego> ..i should store this conversation and document that..
<deego> sure								
[10:08]<petekaz> so 'nick and 'fs-nick are not same ... in my
          erbjavadoc-learn-javadocs I at one point used 'nick to refer to the
          person that invoked the command.				[10:09]
<petekaz> 'nick did not refer to the bot's nick iirc
<deego> nick, erbnoc-nick and fs-nick start out the same, the only difference
        is that fs-nick can be changed by the sophisticated irc user... which
        can be an exploit as well as a feature..			[10:11]
<petekaz> ok.
<deego> so, depending on what you want to do, at some places in the code, you
        want to rely on fs-nick, and in others, on erbnoc-nick..
<petekaz> but why not just plain nick?					[10:12]
<petekaz> that is effectively the same as nick no?
<deego> i am trying to eliminate plain nick in favor of erbnoc-nick.. for
        namespace reasons..
<deego> erbnoc-nick is something we can properly (defvar..)		

To reiterate, Users can change fs-nick, but not erbnoc-nick. 

If petekaz calls fsbot, 

(defun fs-test (&rest args) (format "%s %s %s %s" nick erbnoc-nick
        fs-nick erbot-nick)) --> petekaz petekaz petekaz fsbot.

Notes on Erbot natural language translation and locales

<indio> deego: Have in mind that libtranslate needs its text input and output
	in utf-8, so I had to change my `LANG' env var to a utf-8 variant
	because that code uses `shell-command'.
<indio> deego: It can work w/o multi-byte, but it won't translate multi-byte
<indio> deego: In any case you have to set `LANG' environment var so the
	program knows how to do character conversions. Just an utf-8 variant
	if you want multi-byte translations....				

<indio> Since the tty console doesn't support utf-8 character sets, it's quite
	funny how it looks, since text gets weird from time to time, but
	hitting C-l fixes it again.					[14:17]

For example, the english-spanish bot, borg, has this in its .bashrc: export LANG=“es_AR.utf8” You will also most likely need something like: (set-buffer-file-coding-system ‘utf-8) in the bot’s .emacs.

<some-guy> you're going to need to set LC_ALL in [erbot's commandline invocation script].
<some-guy> it defaults to POSIX and libtranslate won't do utf-8 right under
<some-guy> bit of duff design on libtranslate's part.
<some-guy> it always tries to encode the return value based on your locale,
	     even though it inststs on being fed utf-8			
<some-guy> regardless of whether such encoding is possible.

<some-guy> I set it to en_GB.UTF-8, but any UTF-8 setting should suffice.

fsbot uses: export LANG=en_GB.UTF-8