Document id

        This page contains manual pages from each Emacs tiny*.el module in
        alphabetical order. The tools initially started around 1994 and
        they include many Emacs related utilities ranging from Emadvicedacs
        configuration, email, Gnus spam reply, diffing, patching, URL
        jumping, eating text and many more. Installation, Mailing list and
        other information is available at the main WWW page at
        http://tiny-tools.sourceforge.net/

          _NOTE:_ This documentation page is out of date. Do not use any of
          the variables of functions mentioned here. All the identifier
          names has changed since this page was created. To get help, run
          M-x PACKAGE-version, where PACKAGE is the file name. Be sure that
          you have loaded the file first before call M-x tinygnus-version.

        .$Id: emacs-tiny-tools.txt,v 2.11 2003/05/19 12:19:19 jaalto Exp $
        .$Keywords: Emacs, elisp, tiny tools, documentation $

    Generated documentation

        This document is automatically generated from the Emacs lisp files
        with 2 small perl scripts
        http://cpan.perl.org/modules/by-authors/id/J/JA/JARIAALTO/ in the
        following manner:

            % ripdoc.pl `ls ti*.el|sort` | t2html.pl > emacs-tiny-tools.html

        The perl program assume that the documentation sections have been
        written in Technical Text Format (you are looking at TF layout in
        this file). An Emacs minor mode for writing TF files is available in
        package *tinytf.el*.

    Brief overview

        There are plenty of packages to choose from and almost nobody uses
        them all in one emacs session, so here are some recommendations.
        The setup examples for many of these packages are available in the
        unpacked kit under *rc/emacs-rc-tiny.el*. Start with the top ten
        and add other packages that you find useful. The order of
        appearance is also the recommended installation order: "install
        this, see the docs, and go to next one..."

        Top ten or so

        o   _TinyPath_ -- Find your your whole load path hierarchy.
            No more manual updating of `load-path' or other Emacs system
            variables. Transparent compressed lisp file support.
        o   _Tinyeat_ -- More easier text deletion. eg. C-backspace and
            Alt-backspace do all your text delete operations.
        o   _TinyTab_ -- Set your tab to 2 4 8 and keep text and code
            nicely formatted in any mode, like in `mail-mode',
            `message-mode', `cc-mode', `lisp-mode', `perl-mode' ...
        o   _TinyUrl_ -- Jump to http url at point (C++, Perl, lisp support
            too) This minor mode can be permanently on and it marks links
            all links under current line. Press M-RET or mouse-2 to jump
            to link. Centralized url handling, no need to configure VM, Gnus or
            browse-url separately.
        o   _TinyMail_ -- TAB completes your defined aliases, BBDB entries
            and /etc/password file. *REPORTS* *INCOMING* *MAIL* in X frame or
            echo area.
        o   _TinyMy_ -- Grabbag of utilities. Automatic window change when
            pointing it with mouse. Make dos files readable with C-c m D
            display minor mode etc. Automatic save of your most important
            files.
        o   _TinyHotlist_ -- Keep hotlist of most important buffers in X-popup
            and jump to buffer in the list. The selection can be existing
            buffer, pointer to file (ange-ftp file) or directory. This
            is the "Most important work files: permanent list"
        o   _TinySearch_ -- more faster "search word" than cumbersome C-s C-w..
            At current point hit F2/S-F2 to search the word forward/backward.
        o   _TinyReplace_ -- More convenient replace than M-%. Can replace
            over multiple files (run M-x grep to and hit % in compile buffer)
            RCS file support (checkout before replace)
        o   _TinyEf_ -- C-x C-f file path manipulation in minibuffer.
            Electric file composing minor mode: $ / ~ keys are special.
        o   _TinyCb_ -- Change Buffers in one window. useful only if you have
            small amount of buffers in Emacs session. Use `C-.' and `C-,' to
            circulate buffer list in window.
        o   _TinyLoad_ -- Delayed loading of lisp packages.

        Other packages

        o   _TinyTf_ -- Write text documents easily and convert them to html.
            Eg. this document uses TF format (Technical Format)
        o   _TinyLoad_ -- Speed up your Emacs Load up time dramatically.
        o   _TinyIgrep_ -- Grepping files; directories? Get this and igrep.el
        o   _TinyPerl_ -- Perl utilities, eg. viewing and browsing POD pages.
        o   _TinyLisp_ -- Full of utilities for Emacs Lisp programming.
        o   _TinyDired_ -- Run Ange-ftp get/put request at background
        o   _TinyPgp_ -- 2nd generation PGP/remailer interface; BBDB, TM mime ...
        o   _TinyAd_ -- Advice collection, make Emacs a bit more intuitive.
        o   _TinyScroll_ -- Make any buffer to scroll: *Messages* *Compile*
        o   _TinyLock_ -- Lock your Emacs session
        o   _TinyMbx_ -- Browse Unix mailbox files a bit more easily.
        o   _TinyRlog_ -- RCS revision log minor mode. (hooks itself to vc)
        o   _TinyLpr_ -- Managing multiple printers and print styles
        o   _TinyDiff_ -- Taking diffs and applying patches easily. RCS too.
        o   _TinyDesk_ -- Simple emacs sessiosn saver (files used are recorded)
        o   _TinyProcmail_ -- procmail mode Lint parser for procmail code
            Procmail is "mail processing tool" to kill spam, classify your
            mail and creating autoresponders. See http://www.procmail.org/
        o   _TinyNbr_ - oct/bin/hex/dec number conversion minor mode.

        And more...which are not listed in these

Tinyad.el -- Collection of (ad)viced functions

    Preface, apr 1996

        What you see here is a selection of adviced functions
        that I have found extremely useful. Some are written by me
        (if there is not author written) and some of them I have seen in
        the emacs newsgroups.

        I also have also included extra advices which I think, are not so
        essential, but which may interest user of this package.

        Those advices are put to the end of file and they are all disabled
        by default. You have to manually enable them if you want to use those.
        These advices are put under package name "my" and not to "tiad".

        This file does not include all the advices that I'm currently
        using, many of them are not included, because I considered them
        too personal; their benefit to someone else was questionable.

    Note: XEmacs

        These advices are for Emacs and I'd be surprised if they work in
        XEmacs. Use at your own risk. Send me fixed XEmacs compatible
        advices if you have the guts to try them there :/)

    Can these advices be included with emacs -- Mail RMS

        Many of these enhancements could have shipped with the Emacs itself.
        And I have suggested many of them to be added to the next
        Emacs release, with no luck.

        If you think some feature here is useful, Please, please,
        mail <rms@gnu.mit.ai.edu> and say,

            "I would like to have this XXX feature, as described in tinyad.el,
            to be included in next Emacs release."

        This because, RMS isn't convinced that a feature should be added to
        Emacs if only I ask for it. We need group power. The more mail RMS
        gets, the more likely feature will is added. I'd rather not have
        these adviced functions, but for now it's the only way to get
        these extensions with Emacs.

    How to use this package

        I would suggest just loading this package right away and then
        printing out the whole file and reading the comments about
        individual functions and how they have changed.

    File advice note:

        If you set variable tiad-:file-compress-support to no-nil
        then you can compress files on disk at wish and emacs packages
        that read/save data from/to files doesn't even notice that
        you have compressed them.

        This is very valuable feature if you're low of quota, eg.
        you can now compress GNUS 5 .newsrc.eld and gnus will read
        the .newsrc.eld.gz trasparently. It also saves to
        .newsrc.eld.gz too.

        See write-file's and find-file's fucntion documentation
        for full explanation of this feature.

    Overview of features -- only some features have been mentioned

        Enhancements to existing emacs functions. Advices that make your
        day in emacs more easier. Includes best advices found from the net
        or written by the Author.

        o   `gud' highlights full line
        o   no dialogs in X for `y-or-n-p' styled questions.
        o   mouse window delete confrmation (pointing on the mode line)
        o   `dired', diables dired mouse properties --> dired runs faster.

        o   `debugger-eval-expression',  Backtrace buffer's
                            "e" offers current word for prompt
        o   `dired-man'       , make sure variables are initialized.
        o   `dired-do-rename' , you can edit the old filename
        o   `find-file'       , can load .gz and .Z file
        o   `goto-line' and `imenu' now widens automatically before executing
        o   `rename-buffer'   , offers old buffer name for editing
        o   `recover-file'    , offers buffer filename by default
        o   `switch-to-buffer-other-frame' , selects some non existig frame
        o   `setenv'          , getenv offers completion
        o   `write-file'      , confirmation upon overwrite, VAX support too
        o   `write-region'    , confirmation upon ovwrt, VAX support

        o   `C-x' `;'  , `indent-for-comment' negative arg deletes comment.
        o   `C-x' `='  , `what-cursor-position' shows the line number too
        o   `C-x' `i'  , insert buffer offers other window
        o   `C-x' `C-c' , `save-buffers-kill-emacs' asks confirmation
                          to prevent accidents
        o   `C-x' `b'  , `swich-to-buffer' ask confirmation
                          for non-existing buffers.
        o   `C-x' `C-b' , list-buffers puts you to "*Buffer List*"

        o   compilation: buffer auto scroll (disabled, see 'handling advices')
        o   compilation: smart save feature (only .cc .h files, not
            all emacs files)
        o   compilation: find-file is done in non dedicated frame

        o   completion:  case sensitive filename completion

        o   ediff:  list only files that have diff over directories.

        o   grep:   filename completion via TAB key!

        o   vc:     `vc-print-log' ,put cursor on the buffer's revision number.
        o   vc:     smarter `vc-mode-line' , shows "b" if ver is in the middle.
        o   vc:     vc-register creates RCS directory if does not exist
        o   vc:     user to set the initial comment when doing 1st CI.

    Handling advices

        If you have some other emacs version that is not supported in the
        `tiad-:advice-table' you can modify the regexps in the list and try
        if the advice works in your emacs. If it does, please drop me a
        mail immediately and I update the regexp. If some advice annoys
        you, there is simple method how you disable advice(s).

            (setq tiad-load-hook '(tiad-install my-tiad-load-hook))

            (defun my-tiad-load-hook ()
              "Configure 'tiny tool's advices' to my taste."
              (interactive)                      ;; For user call
              ;; This diables two advices
              (tiad-advice 'disable
                 '(switch-to-buffer mouse-delete-other-windows)))
            (require 'tinyad)

    Disabling disturbing advice by hand

        If some piece of advice disturbs or causes trouble in your current
        emacs session. You can deactivate it immediately. First you have to
        know the function name that generates problems. Say you used `C-x'
        `C-b' `switch-to-buffer' and you don't like the confirmation for
        non-existent buffers. You can disable this behavior immediately by
        calling:

            C-u M-x tiad-advice

        and giving the function name switch-to-buffer to it. To permanently
        turn it off in your emacs sessions, see previous section's lisp code.

    About functions and variables

        Mostly this package has only standard emacs functions that are
        adviced in some way. However it may be necessary that particular
        advice needs some other function's help or uses some other external
        variables. These extra functions, outside of advide, are named
        starting with the prefix "tiad-" for functions and "tiad-:" for
        variables.

    Code note

        You see this in the code:

            (when (tiad-activate-p)
                (defadvice ..

        If emacs version is wrong, the advice is _never_ actually assembled.
        You can't activate or deactivate this function with tiad-advice.

    Many thanks to, in no particular order:

        Vladimir Alexiev        <vladimir@cs.ualberta.ca>
        Kevin    Rodgers        <kevinr@ihs.com>
        Ilya     Zakharevich    <ilya@math.ohio-state.edu>
        Peter                   <pbreton@i-kinetics.com>
        T. V. Raman             <raman@adobe.com>


Tinyappend.el -- A simple text gathering to buffer utility.

    Preface, March 1094

        This package does nothing fancy, it gathers text from buffers with
        few key bindings. Later you can then peek on that buffer, arrange
        text etc. `C-x' `a' is handy when appending data to buffer, but
        it's annoying that you have to give "buffer name" all the time This
        one adds to buffer "*append*" automatically, creating one if it
        doesn't exist.

        I'd strongly recommend you to keep `transient-mark-mode' (Emacs) on
        all the time, so that you can see if you're adding a selected
        region into the *append* buffer. If the region is not active, these
        functions normally add the current line to the *append* buffer.

    Default bindings

        My keyboard (HP-UX / X window) just happens to access
        these keys easily, so I chose them. Change the `tia-:load-hook'
        if you want to use other key bindings.

            C-c =       Append to the end
            C-c -       Append to the beginning
            C-c _       underscore, Kill (empty) *append* buffer



Tinybm.el -- (B)ook(m)ark package, keep your file in organized sections

    Preface, feb 1995

        Long ago I used little function I wrote for myself that inserted
        section breaks, those that I call `bookmarks'. I also used
        `folding.el' to keep the code in separate sections. Findings things
        was easy when you just searched either bookmarks or jumped between
        folds.

        Next I found imenu.el which provided X-popup for my bookmarks
        and I immediately started writing this .el

    Overview of features

        o   Provides some 'setting bookmarks' functions: adding
            repeated characters and sequences up till end of line with
            named identifier. (like breaks in this file)
        o   Automatically parses bookmarks from file, if it contains
            RCS identifier `bookMarkRegexp' which defines bookmark syntax for
            the file. Uses X-popup [imenu] for showing those bookmarks and
            moving between them.

    Read.me -- how to keep your files organized

        There are several tools to keep your code organized and they are at
        their best if you think how they can co-operate. For example I have
        chosen to use folding.el and tinybm.el, which might seem to do
        double job, since they both divide code into more easily manageable
        sections.

        The key point is that when I use folding, I work _within_ some
        special section and I want to hide all the rest of the code. But
        when I want to jump easily back and forth on the buffer, I usually
        `unfold' all and use `TinyBm to find bookmarks.

        Now, to confuse you more, there is also `imenu.el' which I use too
        for jumping inside code. I have configured it so that it will pick
        all function names inside list, and when I want to go to specific
        function, I just pick one from imenu.

        To summarize:

        o   folding.el     -- for hiding unneeded code,
                              clear view on the structure
        o   tinybm.el      -- Jumping between/finding  _large_ code sections
        o   imenu.el       -- finding specific funtion, more detailed control.
        o   tinyhotlist.el -- Add/remove files from permanent X-popup list

    How to use this package

        There is following function that inserts bookmark on the current line

            tibm-insert

        There is also normal repeat function, that fills line with your
        pattern:

            tibm-repeat

        Normally the most usual bookmark separator is the "." <dot> , which
        isn't so 'noisy' as continuous '-' line. Normally I add some unused
        ID character, like '&' at front of real bookmark, like this:

            (defun test ()
             (progn
              ..
              (goto-char ..
              ;; ^^^^^^^^^^^^^^^^^^^^^^^ sepratorInsideCode ^^^

        The `How-to-use' is bookmark, because it has `&' on it, whilst the
        latter isn't -- it is used inside code to make it more readable and
        I don't want to include it into imenu.


    About the bookmark identifier naming

        When you name the breaks, keep in mind that when identifiers are
        sorted, the ones that start with big letters A-Z show up first, and
        a-z next. Allthougt it would be convenient to have all subwords in
        capital, it is usually better to start with lowercase letter,
        because it's easily unintentinally mix up/down case letters.
        Besides you have to reah out for shift to have uppercase.

            ............. breakName ...         ;prefered, starting low
            ............. BreakName ...         ;watch out for mixed case!

        it is also adviced that you choose some common beginning for the
        identifier, so that they get sorted nicely. If you define variables
        at the beginning of file it might be good idea to attach beginning
        letter like `v-' for varibles before the real identifier name
        begins, like:

            ............. v-globals ...
            ............... v-hooks ...

        Of course, we can now use the uppercase letter trick to have them
        sorted fist in the list :-/, just change `v-' with `V-'. Generally
        you should think which ones do you use most, do you leave the
        variables alone when you have defined them and mostly work with new
        functions ? Then the variables can stay at the end of list and
        there is no need for `V-' trick. but if you need to access
        variables often, then you might want to see variables first in the
        list. It's up to your decision how you name the variables and how
        you want to see them listed.

    Breaks and sub-break naming

        If you have very large file, you'll propably need major breaks,
        level one breaks and possibly level 2 breaks too. To keep the list
        well sorted, put the functions into bigger groups and name the
        sub-level breaks so that they have some common beginning in respect
        to the major break they belong to. Let's see an example where
        you're dealing with mail handling. Notice the CAPITAL letter.

            ;; ################################# &h-Header ###
            ;;  this is beginning block of header handling

            ;;  Some special function here to handle CC
            ;;  field, killing all recipients, or only
            ;;  some of them

            ;;  More detailled functions under h-cc, Not
            ;;  named, because there is only 2 small funcs
            ;;  easily found.

        Again there is couple of point's to follow here. All the tricks are
        discussed already: the `Big' letter trick put's major break to the
        top of imenu list, common beginning keeps the subsections together.

    Example breaks

        Some bokmark breaks are proposed here, but you can use whatever you
        like. Thumb of rule: be consistent, always use same convention in
        your files and consider the 'noisy level' of your breaks, so that
        they build up nicely and the code is easy to read. Too many
        _different_ breaks is not good idea, because they clutter the view
        fast, instead use variations on a theme: same break character but
        varying spaces and continuous character lengths.

        Thumb rule: select 1-3 break chars, and never change them in you
        files; your files look alike. Vary the spacing, not the break
        chars.

        These are 'noisy breaks' , Major section separators, pick only one
        and use it in your files, do not use all three!

            ##############################################################
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

        less noisy breaks

            .`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`

            .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^

            .:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:
            .~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~


        This is subSection break

            ................................................................


        This is even lighter subsection break (varying spacing)

            ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...

        'Draw one's attention' break: something special in this section


            --++-- --++-- --++-- --++-- --++-- --++-- --++-- --++-- --++--

        Internal break 1, inside function, long C++-'switch' begin etc.

            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        Internal break 2, to separate long case elements etc.


            ^^^  ^^^  ^^^  ^^^  ^^^  ^^^  ^^^  ^^^  ^^^  ^^^  ^^^  ^^^  ^^^

        Bookmark cache

        So that imenu works fast, it is not desirable that the breaks are
        always parsed from scratch, because it takes time to scan the file
        for possible bookmarks. That's why the information is cached. If
        the break cache is empty, the breaks are gathered from buffer and
        stored to the cache and when you call the imenu, the cache is
        offered to it --> fast response time.

        When you add new breaks to the buffer [especially at the beginning
        of code development], you may want to call function

            tibm-parse

        which will empty the cache and re-read all bookmarks.

        If you write lot of code the points that were cached do no longer
        represent exact points of bookmarks, because they have been sliding
        off their places.

        If you want *always* have updated bookmark points, there is variable

            tibm-cache-update

        which you can set to 'always, if you want the cqache to be updated
        always prior showing X-menu. In large buffer this remarkably slows
        down the menu appering. See variable for more choices.

    Automatic bookmark detection

        In order bookmarks to be detected in file, you may define following
        RCS identifier [see ident(1)] preferably at the beginning of your
        file:

            $BookMarkRegexp:<space>'REGEXP'<space>$

        Be careful so that the identifier is _exactly_ in this form: pay
        attention to spaces and (') around the REGEXP. The regular
        expression tells what line can be considered as bookmark and the
        bookmark name is indicated in subexpression 1 [\\(.*\\)] , look at
        this file, how it is constructed.

        In order to find all bookmarks and build up the cache, it needs to
        widen the buffer in case the file is narrowed with some folding or
        outline editor. When the cache has been built the buffer's
        narrowing is restored, so you shouldn't even notice this. Of course
        you don't want to find bookmarks from your RMAIL file.

        One word about the regexp contruction, let's see my regexp that
        matches the identifier:

            &+\\([^ ]+\\)

        Pay attention to using exclusive regexp, not just '.*'
        construction. When you use folding or outline editor the '.*' form
        is very ill behaving, because if the line being scanned is
        currently folded, IT WILL MATCH WHOLE folded section --> your
        identifier surely isn't that one. We can't unfold the sections
        during scanning, because if there are subfolds, what editor is on
        use .. it's too complex/slow to handle such situations. But using
        the exclusive list [^ ] will surely match the identifier, because
        it stops when it can find first space. This means that you can't
        use _spaces_ inside the identifiers. Cat the words together.

    If the BookMarkRegexp isn't defined in file

        Then the programs tries to search for the default bookmarks.
        See function tibm-re-default for more.

    Message: Empty cache. Building...

        Do you wonder why you get this message displayed, while you were
        sure that you the buffer had cache already? Don't be suprised. This
        is totally normal behaviour: whenever you switch mode for the
        buffer the new mode _kills_ all local variables, including this
        cache information. Obviously the information must be restored when
        you call the hotlist again.

        I could have programmed the cache to be intern variable with buffer
        name added to it, but what happens when you kill the buffer? The
        variable lies around in emacs with no use. [oh yeah, there is
        buffer kill hooks to take care of that... but let's be simple
        here]. Keeping track of the interned variables is not what I had in
        mind: the more simpler, the better and the easier to maintain. You
        just have to live with those messages :-/

    About imenu

        You definitely want to look at the documentation of imenu
        to find many more usages for it. It makes your day shine in
        X-display. You should also configure few variables for it, like:

            (setq imenu-max-items 20)

    Test run

        Load this file and set those keybindings mentioned. Hit the mouse
        bindings and you're running bookmark package.

        Since the break marks are used in commentary also, the list of
        bookmarks are not in their most informative form,
        I use following convention to name bookmarks;

            'v-'     variable topic
            't-'     text topic

    Design thoughts

        Sooner or later someone wonder's: "Can't we have sub-breaks listed
        nicely with indentation in front lines in X-popup?"

        My answer is "No", since it would require keeping track of the
        'Main break' and then seeing if there exist sub-breaks. Immediately
        this leads to question "What is the main break?", and if we say
        main breaks start with "#|/%" charset we limit the use of breaks.
        Besides deciding what are sub-breaks, main-breaks with regexp may
        be too slow.

        I wanted to have a somple *overview* of the buffer. Please put
        imenu to find single functions if you don't feel like tapping
        couple of pgUp/pgDown afer you have jumped to bookmark section.



Tinycache.el -- Maintain a cache of visited files [compile,dired]

    Preface, overview of features

        This package is meant to be uqsed with dired and compilation
        buffers. When you load file from either one, the file is
        cached. This way you can view files easily and when you
        have finished you can flush the cache and get rid of all
        vieved files.

    Dired description

        When you load file from dired for viewing (dired-view-file), the
        file is cached. You can load several files for viewing and when you
        have finished, you can call `tica-flush' (Defaults to `C-c' `k' in
        dired) to remove all the cached files from emacs.

        This way you don't end up having files that you're not interested
        in any more. Using the cache makes browsing buch of files very
        easy. Each dired buffer has it's own cache. The cache is also
        flushed if you kill the dired buffer.

    Compilation cache description

        Maintain also a cache of buffers visiting files via the
        `next-error' and `compile-goto-error' commands; each compile/grep
        buffer has its own cache.  To kill the cached buffers manually, use
        `C-c' `C-d' (compile-flush-cache) in the compile/grep buffer;
        deleting the compile/grep buffer automatically kills the cached
        buffers.  To disable the cache, set `compilation-find-file-cache'
        to a non-list value (e.g. 'disable).

        After loading this file, every file that is loaded by calling some
        compile function, ie. `compile-goto-error', is cached if it is not
        in emacs already. Ie. when you fix some small errors in other
        files, you may not want to keep those files in emacs after you've
        done; remember, those got loaded during the calls to
        compile-goto-error. The easiest way to get rid of these extra
        files, that were not originally in emacs, is to:

            A. kill compilation buffer, C-x k *compilation*
            B. Call M-x tica-flush directly

        See *igrep.el* also how you can browse(grep) files easily and when
        you've done, you can call this package top get rid of those browsed
        files.

    Cache minor mode indication --  Controlling the cache flag

        Modeline indication shows for loaded buffer

            "+C"    if file is loaded as cached.
            "+c"    If you have manually turned off the cache

        And for root buffer where the file were loaded, normally
        compilation or dired buffer, the modeline shows

            "+CN"  where N is number of files currently in the cache

        Sometimes you want to keep some file that belongs to the cache
        and you don't want to loose it when you execute `M-x' `tica-flush'
        or when you kill the root buffer.

        For that purpose there is function `tica-mode' to turn off the cache
        for current buffer. When the cache mark says "+c" in the
        modeline, it tells you that the file will not be killed when you
        `tica-flush' is called.

        Note: the root buffer's xx count is not updated when you kill
        buffer that was cached. So if the count says 10, and you kill 3
        files that, the count will still still say 10. The count is
        updated only when you load some *new* file from the root buffer.
        At his tim all the buffers cached are checked and the ones that
        do not exist any more are removed.

    Buffer list commands [C-x C-b]

        There are some additional commands added to buffer list which
        helps you to keep track of the cached files better. The "c"
        prefix is chosen for (c)ache related commands.

            C-c c m     mark all cached files
            C-c c d     mark as deleted
            C-c c u     unmark cached files.

    Dired mode commands

        Similar to buffer list, there is some dired commands too

            C-c c k     tica-flush, remove all cached files from this dired
            C-c c m     tica-dired-mark
            C-c c u     tica-dired-unmark

    Thanks

        Kevin Rodgers, his igrep.el gave me an idea for this. The
        original cache code from where this pacakge evolved was
        written by Kevin under name *compile-cache.el*

Tinycb.el -- (C)hange (b)uffers in current window.

    Preface, May 1996

        With this small package you can switch to next or previous buffer
        in a current window. If you only have small amount of buffers in
        `buffer-list', this may be the fastest way to select a working
        buffer. In the other hand, if you have more than 20 working
        buffers, I'd recommend that you use exellent substring buffer
        switching utility instead.

            iswitch-buffer.el <stephene@cogs.susx.ac.uk>
            http://www.cogs.susx.ac.uk/users/stephene/emacs

        And one bonus more; if you have X and want to have hotlist of your
        permanent buffers available, use following package. Then you can
        select RMAIL; GNUS; VM; *scratch* buffers instantly. It is part of
        the tiny tools distribution.

             tinyhotlist.el -- Hotlist of buffers in X, easy add, easy remove

    Description

        If you don't want default bindings, clear the installation with
        following. This must be prior the 'require command.

            (setq ticb-:load-hook nil)

        To change buffers forward/backward easily, this file installs
        following keybindings to windowed envinronment.  For non-windowed
        emacs (in tty) the default bindings are for HP numeric keypad keys
        1 2 3.

            C-, previous buffer         (Think this as < back)
            C-. Next buffer             (Think this as > fwd)
            A-. sort order on/off       (Think this as > sorted)

            C-< iswitch mode, select buffer with RET, move with <,> and <.>
                This mode is special, it shows the buffer name
                ,in echo area while you go backward and forward.

                This is usefull if you have many buffers and just want to
                skip 2-5 buffers fast. Eg. if the buffers are font-lock
                conrolled, swithing to them with the C-, and C-, keys would
                be slow due to fontification which happens every time you
                ,switch over a buffer.

                The command prompt looks like following. The mode name is
                shown only if buffer has no associated file name [mode name
                ,has been left out so that full path fits there]

                "Iswitch buffer: my-lisp.el     ~/elisp/my-lisp.el"
                "Iswitch buffer: test           <dired> ~/tmp/test"
                "Iswitch buffer: *Messages*     <fundamental-mode>"

        You should also configure `ticb-:ignore-regex' to your taste.

    Thanks

        Original idea for this package comes from yic-buffer.el
        by choo@cs.yale.edu (young-il choo), 7 Aug 90.


Tinychist.el -- (c)ommand (h)istory save/restore utility

    Preface, apr 1996

        In newsgroup post to gnu.emacs.help there was discussion about
        saving and restoring emacs command history between session. Fred G.
        Athearn <fga@maple.sover.net>, gnu.emacs.help Send a help message
        to a person asking for it describing how to print out
        command-history and saving it into a file with `C-x' `C-w'. This
        little package tries to automate everythig, so that when you load
        it, it will automatically load command history for the right emacs
        and when yu exit emacs, the command history is saved to disk.

    Overview of features

        o   Saving and restoring emacs command history
        o   Suports simultaneous emacs sessions, different history for
            each one. Eg. "-name Mail" is associated with "mail" emacs history,
            "-name News" is associated with "news" history. This trick works
            on non-windowed tty too, since the switch is evaluated and cached
            internally in those cases.

    Default save file from -name parameter

        The default save name of command history file is extracted from
        the frame parameter. It is quite customary that people have
        several emacs open in their X display, each one dedicated to
        specific task.

        The key here is, that you should make a habbit of naming your
        emacs by task when you start it:

            % emacs -name Mail &        # My mail emacs
            % emacs -name C++1 &        # My C++ project 1
            % emacs -name News          # for news reading

        This effectively sets the frame's name to "-name" parameter's value.

        But old emacs  is a  little picky about the order of command line
        options, please loak at the info pages in which order you must specify
        additional arguments. (info pages, Node:Initial Options)

        For non-windowed environment, this trick doesn't quite work out of
        the box, because emacs doesn't accept the name option at all.
        Let's try to start fresh emacs to an xterm, not to separate frame
        and see what happens. Order of the options is important here.

            % emacs -nw -q -name Mail  &

        What happens, is that you get two new buffers: "-name" and "Mail", and
        this is not what we intended. If we ask the frame name in this
        emacs, it says "terminal" or something similar.

        What we do instead, is ,that we install our own command line handler
        in non-windowed emacs and then we're able to intercept the "-name"
        option and it's parameter. When the emacs is killed, we then again
        look at the cached "-name" option to derive the save file postfix.

        If you're interested in adding your own command line option,
        see function add-command-line-arg in tinylibm.el

    How it works

        Your emacs must support `kill-emacs-hook', so that the command history
        can be saved automatically when you exit emacs. If you have older
        than 19.xx, or other emacs that doesn't support the variable,
        there is alternative example which replaces you emacs exit.

        See at the end of file for examples.

        When emacs loads, the `tich-load' is runs (see installation) and
        correct `command-history' file is loaded.

    File saving/loading

        If you want to save/load the history session manually, you can call
        function

            M-x tich-command-history-save

    About using the frame name

        I know it's a bit risky to rely on the frame name's first word, that
        it designates the purpose of your emacs. After all you _can_ change
        the frame name to whatever you want in side emacs.

        But in general, the name labels your emacs and gives visible
        clue in X where the particular emacs is used to. (in non-X you can't
        see the name parameter at all, but I don't think that's a problem.)

    See also

        See file chistory.el in your emacs distribution, how to configure
        some parameters. Eg:

            M-x command-history-mode
            (setq list-command-history-max 50)


Tinycom.el -- Smart comment setting utility

    Preface, sep 1994

        In 18 Oct 94 Era Eriksson asked for help in gnu.emacs.help.
        He hated 'modes' because they redefined his tab key strangely.
        What he wanted was tab 8 in _every possible case_. *huh*,
        I thought when reading his post: "..but if the mode screws with my
        tab key, I don't want it.". Whatever the language, he was going
        to use _hard_ tabs...we'll I don't think he had met Lisp yet :-/

        Anyway, he also wanted his comments always to be positioned in
        column 56 (tab #7), And I started thinking how could he add
        comments if the mode, which _knows_ comment syntax, wasn't
        turned on? (He always programmed in fundamental-mode, what a
        cool dude...)

        As a result this packet was eventually born. It really became
        part of my daily life use! I couldn't live do without it anymore.
        The original .el to Era was posted under name 'general-comment.el'.

    What's this all about, short introduction

        Let see...I'm in C/C++ mode, and I want to switch to better mode
        before I start adjusting my comments nicely. But wait, the new mode
        doesn't know about C++-comments! Or I'm editing my ~/.Xdefauls,
        there is no mode for it, no-one to know the comment syntax. Boom
        :-( Now it's time for giving this packet a run.  It hooks itself
        directly to "\M-;" replacing any previous function.

        It defines comment syntax and position on the fly when it can identify
        the file name. If the file isn't known then it passes control
        to 'mode' to handle the commenting-> very handy in temporary buffers
        that has no filename, eg. *scratch* buffer.
        Repetitive calls to M-; convert comment between *classes*, they
        adjust comment according to previous one, or move it on the line.

    Overview of features

        o   Replaces M-; commenting key. Suitable for any major mode
        o   Determines comment variables on the fly, no matter where you
            are or what mode you are.
        o   There is no-list that tells not to touch this mode's commenting.
            This is for modes that has comment-end. TIC can't handle those.
        o   Repetitive M-; converts single comments into 'bigger classes'
        o   Positions new comment on empty line by looking at previous
            comment.
        o   You can define column position for those comments that are not
            allowed to move This handy for long lines or special comments.
        o   If there are multiple 'comments' , like $#var # comment
            in perl-mode, TIC picks the last # char and treats
            it as a comment. Emacs commention cope similar situations.

    Limitations

        This isn't designed for modes that have comment-end, you get
        only ready '/* */' string eg. in C-mode ie. ready comment string,
        the comment classes don't apply.

    Examples

        At the end of file there is my favorite 'general editing mode' :-)
        setup. I use it for perl, shells, awk, C++ [sometimes]


Tinycompile.el -- Compile buffer additions. Minor mode.

    Preface, mar 1997

        When I was doing grepping over multiple files with igrep.el the
        results that were inserted into buffer were too long: There were
        2-6 directory paths which occupied 40 characters and the actual
        grep hits were continued with \ character to the right.

        That was awfull to read. I couldn't get clear look at the grep
        results. I decided that there must be a way to clarify the results
        somehow, so I started doing this package.

    Overview of features

        o   Shortening directory paths
        o   Killing non-interesting files from the buffer
        o   Hiding commented lines


Tinydesk.el -- Saves/restores files in Emacs between sessions

    Preface, feb 1995

        I have had these function for ages and I just decided to remove
        them from my own lisp library of various useful functions and
        put them into separate package.

        I'm usually working with X at my work, which I left open day to
        day. In fact I seldom even logout, so my Emacs files just sits nicely,
        so I haven't had a need for sophisticated session saver yet.

        What I do need, is, that sometimes I have to go to the lab next
        floor to see what's troubling my C++ program. I must have some way
        to transfer the list of files that I was just editing and bring
        them into lab where I may need to replicate my setup.

        These functions save my configuration into file, which can later
        be opened again in Emacs somewhere else.

        Hope someone finds use for this also, although there exist much more
        better desktop savers, which saves points, marks and modes.

    Overview of features

        o   Simple desktop: only filenames and directories are read/saved.

            Unlike the other desktop savers, this one can also UNLOAD files
            from Emacs. You just tell it to remove 'these files listed in
            state file state.XXX', and those files will be removed from
            your Emacs buffers. You can collect 'projects' and switch
            between them easily: after project1, It can can be unload and
            load project3 instead.

        o   Parse any file that includes filenames and comments

        o   If there were any invalid entries in the state file,
            the state file contents is shown to user and the entries which
            had problems are marked.

        o   State file editing (tid-mode):

            --  load single file on the line
            --  clear face properties from buffer, so that they don't
                disturb your view.
            --  parse files for loading.
            --  Show files that cannot be loaded.

        o   In regular intervals save the state of Emacs (files loaded)
            If Emacs crashes you can recover the previous session.
            See function `tid-auto-save' for more. Similar functionality
            is in new Emacs releases, but this package was originally
            written fo 19.28

        o   CRASH RECOVERY: If Emacs crashes, or you have to kill it
            with `-HUP' if it hang, it leaved autosaved files around.
            When you boot up again, you need to reload the existing files
            AND recover any autosaved files. The best way to get your
            Emacs back where it was, is that you load the state file for
            editing: `M-x' `tid-edit-state-file' And from the StateFileEdit
            mode hit command `tid-find-file-whole-buffer' which is bound to
            C-c b and `tid-recover-file-whole-buffer' which is bound to C-c B.
            And you'll be up again with your latest files.

    Quick start

        If you're just eager to use the package, here are the basics.
        I suppose you have copied the installation setup as is.

        o   You have Emacs session open with bunch of files. Now you
            believe that it's time to save this session. You do
            C-x 4 s and give some name "state.c" if you edited c project.

        Now, it all depends what you want to do after that. If you find more
        files to Emacs; or kill some unwanted buffers, you can re-execute
        C-x 4 s whenever you like. You can even edit the state file with
        C-x 4 e to remove some files that you don't want to include to
        that "project".

        o   Next time you open Emacs you can load any state file with
            C-x 4 r "state.c"

        If you want to switch between projects; unload first the current
        project with C-x 4 u "state.c" and reload some other project
        with C-x 4 r, eg your current C++ project "state.cc"

    Automatic one time session saver

        Some people just want to save the session on exit and reopen it
        when Emacs starts again. I must say that this is not necessarily
        the best, because when you start Emacs for some quick job, you
        don't necessarily want it to load the saved session (loading all
        files take time considerably). Loading Emacs with -q is not the
        choice, if you still like to have your other Emacs goodies active.

        Here is semi-automatic save and restore, put all these lines
        near the end of your .Emacs. It saves the file info when
        Emacs exists and asks if you want to return to saved session
        on Emacs startup.

            (defconst tid-:dir-default "~/projects/")
            (defconst my-tid-session
              (concat tid-:dir-default "state.last-session"))

            (add-hook 'kill-Emacs-hook 'my-save-session)

            (defun my-save-session ()
              "Save loaded file information."
              ;;  Or (tid-save-state my-tid-session '(4))
              ;;  if you want to save dired buffers too.
              (tid-save-state my-tid-session) nil)

            (if (y-or-n-p "Recover session ")
                (tid-recover-state my-tid-session))

    Face setup

        This program uses some faces to catch your attention when you're
        working with the state files. I you restore state from a file and
        some file reference cannot be loaded, the state file will be shown
        to you and the problematic lines are highlighted.

        If you open the state file for editing, you can selectively load
        files. The mouse pointer will change and the text is again
        highlighted.  To make the highlight work for you, you must set some
        colors like this

           (set-face-foreground 'italic "LightBlue")

    About saving the files

        While you may save your session files with any name I suggest here
        one convention that you could use. Name every filename so,
        that they have common prefix:

            M-x tid-save-state   ;; or any hotkey you have bound this
            state.XXX

        where the XXX describes the name of the state file you just saved.

        Later on it's easier to use Emacs file name cmpletion capability
        to load the file you want. If you don't exactly remember what files
        you saved, or which sessions you have in dir, you just type

            state.[TAB]

        when `tid-recover-state' ask for filename.
        Prefix arg to `tid-save-state saves' say to load directories too.

    Automatic state file saving

        Has it ever happened to you that Emacs crashed mystically when you
        were in the middle of your daily routines. You had several C++
        files open, perl code, text files, RMAIL, ...

        Note that 19.29+ also has feature that makes possible to
        recover your session. See bunch of `auto-save-list-' variables.

        This package installs `tid-auto-save' function to
        `write-file-hooks' and in regular intervals all your Emacs session
        files are stored into the state file. After a crash you can easily
        recover your session by reading the saved state file information
        with `tid-recover-state' <FILE>. The name of the fil is your
        current Emacs's frame name (title). In non-windowed Emacs this
        is `state.saved', because frame name is not available.

    Development note

        No, I won't duplicate `desktop.el' functionality to save points
        and modes and so on. This is for simple state restoring only.


Tinydiff.el -- Diff output minor mode. Browsing, patching.

    Preface, jan 1996

        Long ago I made simple function that would generate instant diff
        for the file I was editing before I would check it in RCS. I didn't
        use vc.el, since it was not in the emacs distribution back then I
        started wondering why I used "goto-line" command in other buffer
        every time I wanted to jump to diff point... and it gave me idea to
        make separate diff mode: it would handle jumping for me. The project
        turned out to be a bit bigger than just taking simple diff...

    Overview of features

        Taking diff

        o   Buffer based simple diff/rcsdiff/patch package.
        o   You can diff current buffer against last saved backup copy.
        o   Give and manipulate diff command in echo-area: file name
            completion; switching between rcsdiff/diff, guess rcs version
            for buffer, various diff switches...

        Browsing diff

        o   Supported: normal diff, context diff, gnu diff -u, gnu diff -n
        o   When you have diff output in buffer, turning on `tdi-mode'
            allows you to browse source buffer by jumping diff blocks fwd/back
            and showing the source location.
        o   You can kill single diff block with `tdi-block-kill'
        o   You can apply only the current diff block (patch) with
            `tdi-block-apply-patch'


        Sending or saving diff

        o   In diff buffer, you can save the diff to a file with "W"; write
        o   In diff buffer, you can attach the content as MIME diff to
            the open mail buffer. Or if you don't have MIME-edit active,
            the diff is added without MIME tags. Command "M" for Mime.

        Patch

        o   Easy patching. Finds file to patch (along user defined paths)
            and applies the diff. You can receive patches by email
            and apply them with one or two keystrokes.
        o   Finds the file to patch through pre defined paths.
        o   Can also patch compresses .gz file.
        o   loads patch rejection file, if patch didn't succeed 100%
        o   Re-evaluates patched lisp file if the file was used by Emacs
        o   If you don't want to apply whole diff, use `tdi-block-apply-patch'
            for individual sections.

    Genrating diff -- parsing diff

        Be in buffer where you have diff file and just turn on the

            M-x tdi-mode

        Then take a look at the bindings you have available:

            C-x b

        If you want to generate [rcs]diff for current buffer, call function

            M-x tdi-diff-show   (I have bound this to C-z C-d)

        And it generates diff and puts you on `tdi-mode'. X window users and
        those that have the highlighting capabitities can enjoy more about
        this mode, because it marks line numbers in buffer with
        `mouse-face'. You just click the point to jump to diff position

    Taking diffs

        The main purpose of this module is to help you taking "diff shots",
        inside emacs. This means that the file must be loaded into
        emacs and your cursor must be in the buffers, before you execute

            M-x tdi-diff-show

        o   If the file is not rcs controlled you're offered regular diff
        o   if file is rcs controlled, your're offered rcsdiff prompt
        o   if the buffer has changed, you're offered to diff against
            last saved file to see recent changes you have done since you
            saved the buffer.

    Command prompt

        The help key is on `?', press it to get summary of command while
        you're in minibuffer prompt. The command prompt in minibuffer looks
        like this for rcs controlled file.

            > cd /users/foo/dir1/dir2; rcsdiff -c -r1.21 test.txt

        You can edit this command as much as you like, but please leave `cd'
        `XXX' alone because the minibuffer commands expect it it be
        present. The hotkey command won't work without it.

    Command prompt: rcsdiff and diff toggle

        To conveniently construct diff command against another file, say
        test2.txt, you can hit key `C-z' to chage the prompt immediately to

            > cd /users/foo/dir1/dir2; diff -c test.txt

        And add the `test2.txt' to the end of line. If you want to restore
        the previous rcsdiff form, just hit `C-z' again. This `C-z'
        facility works only if the initial command was rcsdiff. There is no
        point of converting initial diff command to rcsdiff command though.

    Command prompt: tab completes file name

        While your're editing the command you can also use the TAB key to
        complete filename in the 'cd' command directory. If you specify any
        directories for the file, the directory's files are completed.
        That feature should allow you to get filenames into the prompt
        easily.

    Command prompt: diffing between two Rcs revisions

        There is also more commands, like `C-x' which changes

            > cd /users/foo/dir1/dir2; rcsdiff -c -r1.21 test.txt

        prompt so that it has now two -r commands. You can take diffs
        between two versions easily with it. The `C-x' key is a toggle.

            > cd /users/foo/dir1/dir2; rcsdiff -c -r1.21 -r1.21 test.txt

         Case study:

        You see nice package on the net. You download it ;; and notice that
        it needs some fixes. You put the original version ;; to your
        private rcstree with the same version number as what ;; the package
        had; say 2.2. Then you CheckOut the original, make ;; changes, and
        put it back to tree with version 2.2.1.1. You dont't ;; put it back
        with 2.3, because that's not your file. You made the ;; correction
        to 2.2, so you must make a branch.

        Okay. You have the original 2.2 and you have the fixed version
        2.2.1.1 and you want to send the diff to the author. Here is how
        you do it

        o   Be on the file buffer 2.2.1.1 and hit M-x tdi-dif
        o   Hit `C-x' and edit the line to look "-r2.2 -r2.2.1.1". You are
            comparing _old_ and _new_ versions.
        o   Hit `C-s' to toggle between `-u' or `-c'. You normally want
            to send `-u' gnu unified diff, because it is more readable.
            Provided that the receiver has gnu patch to understand it.
        o   Hit `C-f' to add option `tdi-:cl-user-option' which by
            default is `-kk'. From the rcsdiff(1) man pages you will
            see that it roughly means: "When you take diff between versions,
            ignore the rcs tag differencies". Confused? It means that
            the keywords that changed, like version, author, log ..
            when you deposited 2.2 and 2.2.1.1 are ignored.

        And hit enter. Then you get clean diff that you can send to author.
        And when he responds back or sends you new version, say 2.5,
        you repeat the whole process again if you intend to make more
        changes 8put original 2.5 on ice and make branch 2.5.1.1 for your
        changes)

    Command prompt: autosave and backup file diff

        Other helpfull commands insert he #autosaved# and backup~ filenames
        into the current point. Remember to put the # or ~ file to the left
        and not to the right. you do want to diff current file against the
        saved one; right? The first one is original prompt. That second is
        after `C-x' and latter after `C-v'

            > cd /users/foo/dir1/dir2; diff -c test.txt
                                              * point here

            > cd /users/foo/dir1/dir2; diff -c #test.txt# test.txt
            > cd /users/foo/dir1/dir2; diff -c ~/backup/test.txt~ test.txt

        Notice that your backup file may not reside int he same directory.
        The backupfilename is returned by function `make-backup-file'.

    Generated diff: the Prereq tag

        It is important that when you send diff, it is diff between two
        rcs versions if possible (if you're author of program). In those
        cases where revision information can be found, the diff data
        is preceeded with this line:

            Prereq: N.NN        eg. Prereq: 1.76

        If the receiving end has GNU patch, the patch program first checks
        if the version that person has is exactly N.NN and aborts if
        he had some other version. This prevent applying diffs that
        are meant to other versions. Regular Unix *patch* program
        does not notice the *Prereq:* tag, so consider getting more
        safer GNU version as soon as possible.

    Patching

        There is also included little patching function.

            M-x tdi-patch          non verbose
            C-u M-x tdi-patch      verbose

        For elisp (.el) files the `load-path' is automatically searched
        for possible destination of the patch. You can set variable

            tdi-:patch-list

        To match files and their associated patch directories if you
        receive patches for other files regularly. This function is most
        usefull for RCS diffs, because they can be easily detected and the
        file information is also included in the diff.

    Patch: general notes

        Note: normally when `patch' program is called it always makes
        backup with the suffix .orig. So if you have applied a patch,
        then there is two file in the directory.

            FILE.txt        -- patched file
            FILE.txt.orig   -- original file, before the patch

        It also creates rejections file if all dind't go as planned.

            FILE.txt.rej

    Patch: success or failure

        When the patch has been applied, This package checks if all went
        well. If rejection file was created; then the patch process's
        output is shown and the rejection file is loaded so that you can
        see what possibly went wrong and if you should be concerned.

        If you get this rejection file, then there propably is potential
        trouble. Please contact the sender of patch immediately and tell
        about your troubles. There are few common reasons why patch failure
        happened.

        o   Sender forgot `-kk' switch when he run rcsdiff to the file
            that was not owned by him (See RCS for details about `-kk')
        o   Too few context, Sender should try increasing context with
            `-C' switch (like `-C7')
        o   The patch were modified during email transit. Ask
            to send the patch with some encoded format: uuencode, base64,
            PGP encrypted or PGP base64 signed (clearsig off) format.

    Patch: what happens after success

        When the patch succeeds, there is a bit special handling for Emacs
        elisp packages. Say we recieve correction to the following module
        and you have it loaded in emacs: (feature 'foo) returns true.

            foo.el

        After patch is applied, you're asked if you want to reload the
        new release of *foo* module (just patched). You should answer
        `Yes' to get the newest one running in your Emacs immediately.

    Patch: after success, returning to original version

        If the patched version, which is usually new version of the progrmam
        doesn't work as it is supposed to, you can go back to the original
        version by appluing the same patch again. You should report what
        problems you had to the maintainer and inform that you wnet back
        to previous version.

        *IMPORTANT* If you did get the rejection file, you can't use that
        patch to go back to original!! See next chapter how to go to
        original version in that case

    Patch: rejection file created -- what to do?

        If you want to go back to original version, apply the same diff
        again; this reverses just applied patch. Just call `M-x'
        `tdi-patch' in the buffer where you have the diff.

        When you do that, the function detects that there is already a
        .orig file and prompts you to choose an appropriate action.
        Here is the explanation what they do and what should you choose

        _*o*_

        Go back to (o)riginal. This copies the FILE.txt.orig over the
        FILE.txt and deletes FILE.txt.orig and doesn't do _anything_
        else (stops the patching process). You're back to starting
        point as if you never patched anything.

        _*r*_

        (R)etry means that the FILE.txt.orig is copied over FILE.txt and the
        pach is tried again for FILE.txt. You may have asked the author to
        send more context with using the -C10 switch and after you received
        this new patch you want to try if it now goes ok. The FILE.txt.orig
        still remains as a backup

        _*g*_

        (G)o says that we should apply the diff again to FILE.txt. Do this
        _ONLY_ if you did not get rejections last time. The intention
        is that you apply the patch again, and this reverses the situation.
        I mean 1) you patch; you get new version 2) you patch again: you
        degrade to the version before patch (original file before patch)

    Development note

        I know about `ediff.el', which is much more complete package than
        this is. My aim was to develop a simple but handy package for
        everyday diff'ing and easy package patching.

    Bugs

        The "f" key, which shows the function identifier in diff browse
        mode `tdi-mode', can handle buffers which are narrowed, but if the
        buffer is using folding.el or similar package where goto-line does
        not work properly, the returned message shown to user is not
        correct.

        Please unfold the buffer and you get the correct result.

    Sending good bug reports

        If you find anything funny happening in the command line prompt
        while you use the tdi minibuffer commands. Immediately do
        following.

        o   Turn on debug: `M-x' `tdi-debug-toggle'
        o   Turn on emacs debug: (setq debug-on-error t)
        o   Clear the debug buffer *tdi-debug* if it exists
        o   Start from original situation
        o   Do what you did and when the weird condition is met
            immediately go to *tdi-debug* buffer and save the
            content and send it to the maintainer.


Tinydired.el -- Dired enchancements. Backgroud Ange ftp support

    Preface, Jan 1996

        This package started evolving, when I wanted something more from
        ange-ftp, like background file loading. And i dind't want to get
        popped to .zip or .tar.gz buffer after loading remote gz/zip file.
        I just wanted to download the files somewhere other than inside
        emacs. I also wanted to *mark* files for download and get them all
        at once. With standard `ange-ftp' you would have to load them one
        by one. Sometimes I also wanted to go associated `ange-ftp' buffer
        and give commands directly there. Thre should be a command to
        switch between ange-ftp and dired buffers.

        Now you can do this with standard `ange-ftp' and Emacs dired.
        Hope you enjoy your ange ftp as much as I do now.

        Note: This paskage is just extension to `ange-ftp', consider
        getting next generation ange-ftp, the `EFS', if you want
        overall better and more complete interface. Use this package if
        you only need features like batch put/get at backround.

    Overview of features

        o   Connecting to VAX host minimally supported. You can navigate
            in vax dired buffer and load files. Nothing more.
        o   Few enchancements to dired mode. Eg. keep only one
            dired buffer when ascending to directory. Shorten symlinks.
        o   User can mark and put files into STORE and start a backgroud
            ange-ftp session to get STORED files into download directory
        o   Easy switching between ange-ftp session buffer and dired buffer
        o   Dealing with ange ftp buffers in general
            (x)  killing all ange buffers at once
            (x)  killing all ange + dired ange buffers at once.
            (x)  switching to ange buffers with completion
        o   Run "!" on ange ftp dired buffer (operate on local copy)
        o   customizable backup file flagging.
        o   other handy dired commands, like "pop to this file in emacs."
            "find all marked files"...

    Vax dired listing note

        When you connect to a VAX host; you may get some error message
        and you don't see the dired listing; don't panic. Just repeat the
        `C-xC-f' command with

            C-x ESC ESC

        And it should succeed second time. There are quirks in the VAX handling
        and if you run into it; the usual cure is:

            Kill the VAX ange-ftp process buffer

    XEmacs note

        The dired and ange-ftp implementation (nowadays efs) is
        completely differen than in Emacs

        ** THIS PACKAGE IS FOR Emacs ONLY **

    General dired additions

        In simplest form. This module installs some functions in your
        dired hooks. Their purpose is

        o   To keep your dired buffer sorted so that directories are
            always put first.
        o   Delete unwanted files from dired buffer automatically.
        o   Shorten the symlink references, so that they don't spread
            multiple lines and ruin your view.

        It also changes one dired function with `defadvice', so that you
        can control if you want to have only one dired buffer when
        ascending to another directory. See variable:

            tdd-:use-only-one-buffer-flag

    Dired and ange-ftp additions

        In general, when you want to start ftp session in emacs you just do

            C-x C-f /login@site:/dir/dir/file

        Let's take an example: To see what new things has arrived
        to GNU site, you'd do this:

            C-x C-f /ftp@prep.ai.mit.edu:/pub/gnu/

        After that you are put into the dired listing, where you
        can mark files with dired-mark command

            "m"

        Now you have files ready. Next put files into batch STORAGE.
        There is "a" prefix for ange-ftp related commands.

            "a" "S"     big S put selected files into storage
            "a" "q"     to check what files you have batched
            "a" "c"     to clear the batch storage

        Now start ftp'ding the files in background. You're prompted
        for the download directory.

            "a" "g"     "get" files

        If you want to operate on the associated ftp buffer
        directly, there is command

            "a" "b"     b for "buffer change"

        that puts you into ftp, where the dired buffer refers. When
        you're in the ftp buffer you have some keybinding available.

            C-c f       insert stored files on the line
            C-c d       insert directory name
            C-c b       back to dired window

        It's sometimes handy that you can give direct ftp commands.

    Setting up ange ftp

        Here is my settings, which you can use as a reference so that you
        get the ange running. For more details, see the ange-ftp.el's
        source code. These settings include firewall "ftpgw.poboxes.com"

 ;; (setq ange-ftp-generate-anonymous-password t)
 (setq ange-ftp-dumb-unix-host-regexp  "tntpc") ;PC hosts
 (setq ange-ftp-gateway-host "ftpgw.poboxes.com")
 (setq ange-ftp-smart-gateway t)
 (setq ange-ftp-local-host-regexp "\\.myhost\\.\\(com|fi\\)|^[^.]*$")
 ;;  Always use binary
 (setq ange-ftp-binary-file-name-regexp ".")
 (autoload 'ange-ftp-set-passwd "ange-ftp" t t)
 (setq ange-ftp-generate-anonymous-password "jari.aalto@poboxes.com")

    How to use this modeule 3 -- special vc

        There are some extra commands that you may take a look at.
        See source code of bind function

            tdd-default-other-bindings

        What additional commands you get when loading this module.

        The VC special commands were programmed, because I felt that the
        C-x v v in dired mode didn't quite do what I wanted. I wanted
        simple ci/co/revert commands for files that were in VC control.
        And I wanted to handle them individually, expecially when ci'ing.
        (written for Emacs 19.28).

        This VC part of the package is highly experimental.
        I'm not sure if I support it in further releases.

    Important ange-ftp interface note

        The ange ftp batch interface used here may cause unpredictable
        problems. Sometimes the `get' or `put' process doesn't start at all
        although you see message saying it started the job. I have had
        several occurrances where `lcd' cmd succeeded, but then nothing
        happened. Repeating the `put' or `get' command cleared the problem
        whatever it was.

        So, never trust the message `completed', unless you saw that the
        download percentage count started running. If you're downloading
        important file, double check the real ftp buffer for correct response.
        Try again if ftp wasn't started. Another way to clear the problem: kill
        the ange ftp buffer and try the command from dired again. It
        automatically opens session to the site.

    Advertise -- other usefull packages

        There are exellent dired extensions around, please consider getting
        these packages:

        o   dired-sort.el (requires date-parse.el)
        o   dired-tar.el

    Note: Slow autoload

        When you have added the autoloads into your .emacs, the first time
        you bring up dired buffer may be quite slow. This is normal, Emacs
        just need to load some additional files that this package uses.

    Note: Refreshing the view takes long time / point isn't exatly the same

        This is normal, dired is just slow and program has to do lot of
        work to maintain the "view". Eg. save view, save marks, delete
        marks, revert, sort, restore marks... Only the current line
        position is preserved where user was, not point.

    Note: Code

        Emacs ships with package `dired-x.el', which seems to offer some
        more goodies to dired. Currently, if the `dired-x' is detected the
        appropriate functions in this package are diabled, to prevent
        overlapping behavior. However, if the function behaves differently
        than the one in some dired extension package, then the function
        isn't disabled. Eg. see `tdd-load-all-marked-files', which can turn
        off marks.

    Note: limited vax directory support

        You can connect to VAX host with `find-file' and this package
        provides modified functions to allow you to use `f' in dired
        and load file into Emacs. Any other TinyDired commands are
        disabled in dired vax buffer.  Don't try anything fancy there,
        you know that it isn't unix ls buffer.

        See function `tdd-remove-bindings'. You must add your own
        keyboard disable function if you have added tdd functions to
        other bindings than the default to disable this package in
        VAX buffers. Add your disable funcion to

            tdd-:readin-hook

    Note: limited dos directory support

        You can connect PC hosts that print 'dir' into the dired buffer.
        Your only command available is `f, just like in vax dired, so
        please don't even try any other choices.

        The PC support is experimental and is based on unix --> lan
        connected PC which is running `pctcp' software: win 3.11
        (workgroup) `ctlapp.exe' ftp server. Do not mail me about PC
        support, since I won't fix it if it doesn't work. Get `efs'
        distribution if you need PC ftp support.


Tinyeat.el -- Eating blocks of text forward, backward

    Preface, overview of features

        o   Determine how much text should be eaten around current cursor
            position. Eat extra spaces, extra newlines, next word
            next statement, next comment ... whatever is appropriate
        o   When you grow accustomed to this, it probably replace your
            old deleting habbits.
        o   Can also eat inside mixed case word: WordsThatAreLikeThis
        o   you can yank "overwrite" text under cursor with Meta mouse-2 or
            Meta C-y. (Std Emacs in overwrite mode doesn't allow you to
            yank/overwrite)

    Non-windowed and Windowed Emacs

        This package works _best_ in windowed Emacs, because in Windowed
        environment you can use the modifiers Control, Alt and Meta
        freely with another keys. The idea of this package is to overload
        your single key, `backspace', as much as possible with various
        delete functionalities.

        In non-windowed Emacs there is no key named `backspace', so we have to
        rebind standard Emacs bindings instead. Many of this packages features
        are also unused because there are no suitable keys to bind the
        commands to. In non-windowed Emacs the extra bindings have
        been marked with (*):

                            was                 now
            -------------------------------------------------------------
            Meta s          <none>              tie-backward-preserve (*)
            Meta d          kill-word           tie-forward-preserve  (*)
            Meta SPC        just-one-space      tie-delete-whole-word (*)
            Meta k          kill-sentence       tie-delete-paragraph  (*)
            Meta C-d        down-list           tie-kill-line-back    (*)
            Meta ESC        mark-defun          tie-erase-buffer
            Meta C-y        <none>              tie-yank-overwrite

    Story behind this package

        I got sick of moving cursor around the point and using del/backspace
        when writing C++ and LISP symbols. Say I have:

            (defun lisp-symbol-name-myname          ()
                                    *

        And I decide I want to change that 'myname' to something
        else. Normally I'd have to reach out for ESC-d for `kill-word' to
        delete `myname'. Then I'd type a new name:

            (defun lisp-symbol-name-mynew           ()
                                         *

        Now I notice that there are extra spaces involved, I don't want
        those before the '()' characters. I have to call `fixup-whitespace'
        for that ... damn it's not bound to any keys by default (in this
        particular Emacs I'm using), so I have to type it the long way
        round: `M-x' `fixup-whitespace'. Now I'm beginning to think: "Oh,
        why I didn't I bind it to some key...".  Next I notice that the
        'symbol-name-mynew' wasn't good name after all, So I decide to
        delete 3 words backward. Now, how do I do that?

            (defun lisp-symbol-name-mynew ()
                                         *

        Where is the command to delete backward ... (I start stimulating my
        brain cells). After spending valuable minutes to find the
        `delete-backward-word' command: "Rats again, there is no such
        command". I end up tapping backspace until I reach the correct
        point:

            (defun lisp- ()
                        *

        And start typing new name...

            (defun lisp-my-func ()

        Then I suddenly notice that there is too many newlines above my
        newly created function: "I really should delete those 5 extra ones
        above function".  "Now, how do I kill backward 5 emnpty lines ? The
        `kill-line' in C-k kills only forward" ...

    Lesson learned

        As you can notice, we often spend most of our time to position the
        cursor to the right spot and deleting text over there.. over here
        ..  typing more .. changing our mind ... etc.

        I thought it was time to do something creative, so that I wouldn't
        have to worry about the deleting of text so much. This package
        provides _smart_ deleting of text, whether you want to delete
        forward of backward. Naturally it isn't capable of miracles, it
        just does few guesses, and a guess may be wrong.

        If you end up in a situation where you suddenly notice that vast
        area of text have just vanished from you buffer, remember, there is
        no need to panic. Just send a bug report to me, and hit `undo'.

        I'd be surprised if you ever want to discard this package when you
        have tried it. Can I smile happily at this point?

    Default keybindings

        chunk delete: words, spaces, symbols ...

            <<              >>                  <<>> [Delete whole word]
            Alt-Backspace   Control-backspace   Shift-Backspace

        Line delete

            <<              >>                  <<>> [zap whole line]
            Alt-Backspace   Control-k (Alt-k)   Control-k
            + Shift                             + Alt

        Buffer delete

            \/              /\                  \//\             ZAP
            untill pmax     untill pmin         Paragraph delete Whole buffer
            C-A-backspace   C-A-Backspace       C-S-backspace    Esc-Backspace
                            + Shift


        Joining next line to the end of current line: Esc Control-backspace

        [Some minibuffer hotkeys]

            f1  = Kill whole line.
            f2  = Delete line backward (to the left)

        [Mouse binding]

            (Alt|meta)-Mouse-2 overwries text when pasting.


Tinyef.el -- (E)lectric (f)ile minor mode. Easy filename composing

    Preface, Apr 1995

        I saw a post in gnu.emacs.sources (what a source of inspirations),
        where one of my friend Anders Lindgren <andersl@csd.uu.se> posted
        the basic code that allowed electric ~ and electric / character to
        wipe out full (mini)buffer in certain cases.

        What you see here, is complete rewrite and enchancement of that
        code. This is a real must for any minibuffer file handling.

    Overview of features

        o   Easy filename editing. Deletes directories at time, delete line
            backward, electric tilde, electric slash, electric colon etc..
        o   This is a must for minibuffer's `C-x' `C-f' command
        o   Mouse-3 in minibuffers clears the input and with mouse-2
            you can paste from cutbuffer.

    Description

        Believe or not, but for years I didn't understood what an earth
        "electric" meant. I had heard many e-modes mentioned in the net,
        but never much payed attention to them... until now.  Well, this
        package isn't that *electric*, because it only defines some keys to
        be electric and it needs some other keys solely to its own use
        (you can't insert these chars to buffer without `C-q' `CHAR')

        If you're another non-english speaking, as I am, the electric means
        that the character you press behaves differently if the pressing
        happens around certain other charcters (anyway, some condition is
        met which triggers this other behavior). Other than that, the
        character behaves normally.

        Here is smple graph to give you an overview of what this mode does.
        In these presented cases cursor it at the end of line.
        Alternatively, just load this file, press C-x C-f and experiment
        with keys "[]\/~".

        o   b>> means what's on the line *before*
        o   a>> means what's there *after*
        o   ""  means what you just pressed
        o   []  means which action the character triggered

            b>> http:/www.site.com/~userFoo/dir1/dir2/dir3/ "/" [e-slash]
            a>> http:/
            The e-slash action wiped out the line, because writing
            two slashes normally indicates, that you want to give
            another path

            b>> ~/dir1/dir2/dir3/                       "~" [e-tilde]
            a>> ~
            The action wiped the line away, because it assumed
            you want to give "~userFoo" or another "~" relative path

            b>> ~/dir1/dir2/dir3/                       "[" [step-delete-back]
            a>> ~/dir1/dir2/
            The action wiped previous directory name or until
            special mark, See code, defaults are  ":/@" (ange-ftp things)

            b>> ~/dir1/dir2/                            "=" [undo]
            a>> ~/dir1/dir2/dir3/
            The action works like normal undo.

            b>> ~/dir1/dir2/                            "\" [chunk-delete]
            a>>
            The action deleted whole line. It deletes until special marks
            like "@:". If repeated, it deletes constantly backward

    Automatic Intallation

        This file includes function

            tief-install

        which hooks the mode to the appropriate places. Eg. to your
        minibuffer. If you're in trouble, you can always turn this mode off
        with the supplied hotkey, which is by default.

            C-c \

        You can't "see" whether mode is on or off in minibuffer, since it
        doesn't have its own mode line. But calling the hotkey will tell
        you the state change.

        You can also remove this mode completely from your emacs if you need
        to do that in emergencies. just call following function with
        some prefix argument like `C-u'.

            tief-install

    Mouse bindings in minibuffer

        When this package loads, it calls function `tief-install-mouse'
        which defined following bindings to your minibuffer

            <-- BIG erase backward from point Mouse-3 (because it's free)
            <-- Small delete backward C-mouse-1. Use C-mouse-3 to undo( -->)

        This should give your free hands to cut,paste and Delete, without
        lifting your hand off the mouse.




Tinygnus.el -- Gnus Plug-in. Additional functions. UBE fight etc.

    Preface, Sep 1997

        I haven't have a chance to try the new Gnus 5 for a long time
        because the envinronment didn't have Emacs 19.34. And when the
        sysadm installed it, I started slowly moving from my dear RMAIL
        (that I had configured to work very well) to the bold and beatiful
        Gnus. I had also started using procmail and subscribed to many
        mailing lists, so the only choice to manage all my mail was
        Gnus. Here you find some functions that I found usefull.

    Overview of features

        o   A sample .gnus startup file is available.
            Send email containing _subject_ 'send help' to [jari]
        o   Automatic reload of files when entring group with SPACE
            (mimic  Newsgroup behavior)
        o   You can have compresses .eld file. If you compress .gnus to
            .gnus.gz then the .eld files will be compressed too to .eld.gz
            This saves you disk space in low quota account.

        o   Fast read group by showing only unread (newly arrived)
            articles. Speeds up reading your mail groups by 10x.
        o   Show immediately dormants in non-nntp groups. some people
            use dormant mark ? in their private mail groups as `todo'
            and to be able to see those todo articles immediately saves
            you 5x time, when you don't have to separately limit to
            dormants.

        o   Ready %uX user function that you can use in the *-line-format
            strings.
        o   Group User format function: "expiry", Tell the expiry value
            for the group and varaious other values.
        o   Group User format function: "comment", Tell the group comment.
        o   Group User format function: "tick",    Tell if group has ticks.

        o   Send UBE complaint to all postmasters in Received headers.
            The ip addresses of postmasters are nslookup verified. You
            can select either individual article or process mark multiple
            articles.

    Url pointers

        o   Procmail information can be found from pm-tips.txt file.
            You get that by sending email with subject "send help" to
            [jari]
        o   Gnus can be found from http://www.gnus.org/

    Fighting against UBE messages

        Many of us receive UBE (Unsolicited Bulk Email) and if we don't do
        anything to stop them, then the practice comes approved de facto
        internet convention. It is important that you complaint about every
        piece of UBE you may receive, your vote counts and it will also
        give you satisfaction to know that most of the postmasters kick off
        the idiot in the other end of the wire. I have provided two functions
        in this module:

            tign-article-ube-send-to-postmasters    U      key, U = UBE
            tign-summary-ube-send-to-postmasters    C-c'u  key, send UBE

        The first function is fully interactive and it reads the current
        active article and composes `forward' message to all postmasters
        mentioned in the `received' header chain. Before sending you have
        a chance to reformat the article anyway you like.

        The latter function is usefull to batch send complaints: you
        process mark(#) articles in summary buffer, Hit C-c'u, and each
        article is processes and complaint send to postmasters. Before
        sending message, the function asks confirmation. You can suppress
        the confirmation with C-u prefix argument. _Note_: It may take some
        time to compose all complaints if you have marked many articles,
        because parsing Received headers and checking them with `nslookup'
        may be slow. If you use `procmail' or Gnus split methods to flter
        your UBE mail to one single newsgroup, say `junk.ube', Then you can
        mark all messages in the newsgroup and handle all the UBE you have
        received in a whip.

        Someone may ask why the complaint message is sent to *postmaster*
        address, while recently sites have set up an *abuse* addresses as
        well. That's simply because RC822 requires that each has an email
        address should have postmaster account and you should be able
        to count on delivery to that address.

          ...standard specifies a single, reserved  mailbox  address
          (local-part)  which  is  to  be valid at each site.  Mail sent to
          that address is to be routed to  a  person  responsible  for  the
          site's mail system or to a person with responsibility for general
          site operation.  The name of the reserved local-part address is:

                                  Postmaster

          so that "postmaster@domain" is required to be valid. Some domains
          have opened specific addresses where you can send these
          xomplains, eg abuse@aol.com, fraud@uu.net. If you know a specific
          address where to send the complaint, update
          `tign-:ube-abuse-account-table'

    Gathering information from articles (eg. URLs)

        If you read group that has very high traffic, and don't have to time
        to read all articles, but you're are still interested in seeing
        if there are any good urls mentioned, you can use function below.
        It will not record duplicate urls, only unique ones.

            C-c ' g u       tign-summary-gather-urls

        Function steps through all marked articles (Mark command in summary
        buffer is in M P submap), examines each message and puts the urls
        in `tign-:output-buffer'. You can clear and display with commands:

            C-c ' g d       tign-summary-gather-display
            C-c ' g c       tign-summary-gather-clear

    Configuring the user format functions

        Before you load this file, you should configure the variable
        `tign-:uff-table' so that it won't clash the definitions of your
        own gnus-user-format-function-X. If you load this file without
        modifying the table, it will replace all susch existing functions
        according to that table.

        In case you don't know what I'm talking about, Go to Emacs info
        pages C-h i, Go to GNUS, select 'g' and enter 'Summary Buffer
        Lines' RET. Look at the specifier %uX, where X is anything.

    Enhanced Gnus functions

         [Entering group in Topic mode with SPC]

        Function `gnus-topic-read-group' is enhanced to maximize speed of
        reading new articles. Normally when you enter Group, gnus shows
        unread and ticked articles, but if you have any previously ticked
        articles in group, making the summary buffer is slow. If we
        ignore the ticked articles and display only the newly arrived,
        unread, articles, the time to generate Summary buffer is 10x less.

        If you have many private mail,work, mailing list groups, this
        saves you from lot of time to be able to track new messages.

         [Showing dormants immediately in non-nntp groups]

        Function `gnus-summary-limit-children' is enhanced so that
        it will include dormant articles in Summary creation in non-nntp
        groups. Some people found out that the dormant mark ? is handy
        in mail groups to mean `todo' or `see this later' or `urgent'.
        Normally gnus treats all groups the same: nntp or private mail
        makes no difference. However the dormant mark can be used to mean
        different meaning in nntp group and non-nntp groups and this
        enchancement does just that.

        You get fast Summary with dormants now and you don't need to
        separately limit the buffer to show the dormants. To turn off
        this feature, set `tign-:show-dormants' to nil.

    Compressed Gnus newsrc files

        Having a unix account that has unlimited disk space is very rare
        and for that reason you should be able to keep files in compressed
        format as much as possible to save disk space so that you don't go
        over your Quota and see that annoying "Quota limit exceed,
        remove nnnK withing N days...".

        Gnus 19.34 has support for Group files, but not for the bloating
        .newsrc or .eld files. Gawk. They consume your disk real fast
        because they become real big in no time.

        For that reason I have included adviced Gnus code that
        automatically starts using compressed startup files if your
        `gnus-init-file' has extension `.gz'. Changing from normal init
        file to compressed one is easy:

        .   gzip your .newsrc and .eld files
        .   (setq tign-:z ".gz")
        .   M-x load-library RET tinygnus RET

        If you later want to restore this settings: Unzip, do (setq tign-:z
        nil), and reload the package. But if you're of low quota, you
        propably do the reverse operation.

        I don't know about newer Gnus versions, I do hope that the full
        file compression is avilable there.

    Gnus version note

        This file installs only features to Gnus 5.3 (Emacs 19.34) and
        if you're using newer gnus version the advice code is not activated.
        Using this package should be safe with any existing Gnus version
        later than 5.3.

    Line format example for *Group* buffer

        I have configured my Group buffer line as follows to Qgnus(1997-10)
        If you try this with older gnus, drop away that fancy ~(cut 6) and
        use plain %d. I use procmail to `process' my mail.

            (setq gnus-topic-line-format "%i%(%{%n%}%) %A -- %g %v\n")

            (add-hook 'gnus-select-group-hook   'gnus-group-set-timestamp)
            (defconst gnus-group-line-format
                "%M%S%p%3uZ[%L]%-4uE%uT %5y: %-40,40g %7,7~(cut 6)d %uC\n")

        Which looks like the following in the buffer, notice that the topic
        mode is on.

            Procmail 34 -- 9
              [2]3.g       0: nnml:list.ding        30T1810
              [2]3.        0: nnml:list.ntemacs     30T1819
            * [2]3.  !     0: nnml:list.procmail    30T1850
              [2]2.t      33: nnml:list.flamenco    30T1849
               | |   |                              %d
               | |   %uT
               | The whole "2.t" comes from %uE
               %L

        There you can see the benefit of the user functions. The [2] tells
        the group level, "2.t" says "2" day Expiry, "." means that the
        perior is explicitely defined as a group parameter and "t" means
        that total expiry in the group parameter list is also on. Do you
        see the extra `g' at the top line? It tells that the `gcc-self'
        group parameter is activated in group parameter list. If group has
        Ticked articles, the %uT will show it. The %ud says "Day 30 in the
        month, Time 18:10" when you read the group.

        All these additional functions that display these status informations
        canb be found from this package.

    Displaying the group parameter info

        As you saw above, the %uE function, or more precisely,
        `tign-uff-group-expiry' controls what information is returned by
        looking at `tign-:uff-table'. Please configure it to display
        whatever you want from group parameters.

    Article wash functions

        If you are interested, you can add following function(s) to the
        `gnus-article-display-hook'

        o   `tign-article-fix-msword-quotes'




Tinyhotlist.el -- Hotlist of important buffers, files(ange-ftp), dired

    Preface, may 1995

        I'm big fan of 'msb.el', but when it comes to having important
        files at hand, I really need some companion with it. When I'm
        having an emacs session, it's very common that when I have 20 C++
        files in emacs. I start reading news while the compile it going on
        its own buffer [normally I have 15min break], then I see some
        interesting article and I want to try some lisp code .. let's load
        couple of .emacs.XXXX configurable files. Then I realize that there
        is mail coming, because `dragbar-time.el' tells me that, I switch to
        rmail and start reading the latest messages... Within that 15
        minute my emacs if full of buffers and when I use MSB to navigate
        through them I get frustrated: "Where was that buffer again, do I
        need to step 3 panes before I can see that file..."

        The navigation is especially problem if I'm only working with
        handful of source files _actively_, while I still have 30+ files
        _loaded_.

        What I really need, is a simple hotlist for my most recent files,
        where I can put/remove items very easily, and which I can
        immediately call. No more searching like in msb.el.

        Don't get me wrong, I'd never give `msb' away, it's superb in class
        of its own, but I also need the hotlist, because the most recent
        files page in msb changes dynamically whenever I change buffers,
        but my hotlist stays the same, unless I remove item from it.

    Overview of features

        o   Provides X popup where you can add/remove current buffer.
            Kinda 'most important work file list'. In non-windowed system,
            you get completion menu instead of X-popup.
        o   You can keep any persistent files in hotlist: even ange-ftp files.
            Dired buffers can be saved to hotlist too.
        o   Hotlist can be saved and read on startup.
        o   This is not "last visited files" list, but persistent list of
            files. When you select item from hotlist the file is displayed
            if it is in Emacs, or loaded (by using ange-ftp if necessary)
            if it wasn't.

    How to use the hotlist

        When you load this package, it defines hotlist cache to store the
        items. Obviously the list will be empty at first, but after you
        have added entry to it, you'll get the hotlist visible. How entries
        are added or removed from hotlist, is explained in function:

            C-h f tiho-control

        If you use add/remove commands lot and you can spend some keybindings,
        you can define following bindings too. You don't necessarily need
        these, because you can always give the right prefix argument to
        `tiho-control' that does exactly the same.

            (global-set-key [(shift f3)]   'tiho-add)
            (global-set-key [(control f3)] 'tiho-remove)

        Non-windwed users can use the popups via completion menu, while
        it's not as nice as X-popup. Call this function from keyboard.

            tiho-control-kbd

        Here is an example of the displayed hotlist in X popup. The second
        string to the right is abbreviation name of the directory, eg `~ftp1'
        is a shortname for /user@site.com:~user/project/this/. The `txt' is
        shortname for $HOME/doc/txt/

            +-------------------+
            |hotlist            |
            |===================|
            |*Backtrace*        |
            |*VC-log*           |
            |.emacs             |
            |.procmailrc        |
            |ChangeLog          |
            |RMAIL              |
            |file.txt     txt   |
            |other.txt    txt   |
            |remote.cc    ~ftp1 |
            |remote.cc    ~ftp2 |
            +-------------------+

    Shortening long filenames

        The typical menu item is quite long, because there is buffer name
        and filename part. The default rule shortens the home directory
        names to "" but if your file is elswhere, you have to modify the
        `tiho-:abbreviate-file-name-table'. There is examples how to use it
        at the end of source file. Like:

            /user@site.com:~user/project/this/  --> ~ftp1

    Hooks: saving hotlist after each cache update

        The buffers are stored into variable `tiho-:cache' and there is two
        hooks that run after the entry is deleted or added to the cache.
        The hooks are `tiho-:add-hook' and `tiho-:remove-hook'. They contain
        default value `tiho-save-hotlist' which updates the cache on disk
        after each change. You can set these hooks to nil if you want to
        manually control when to save cache. (Maybe you load BASE cache
        everytime and modify it during Emacs session, but you mdon't want
        to save this "session" hotlist).

            (add-hook 'tiho-:load-hook 'my-tiho-load-hook)

            (defun my-tiho-load-hook ()
              "My hotlist settings"
              (setq tiho-save-hotlist nil   tiho-:remove-hook nil)
              )

    Saving and restoring the hotlist

        When you're satisfied with the hotlist, save it to file with command:

              M-x tiho-save-hotlist

        If you want to automatically restore the hotlist, when package loads:

            (add-hook 'tiho-:load-hook 'tiho-load-hotlist)

        If you want that the _current_ hotlist is automatically saved when
        you exit Emacs, add also this:

            (add-hook 'kill-emacs-hook 'tiho-save-hotlist)



Tinyigrep.el -- Top level interface to igrep.el

    Preface, Dec 1996

        Some time during summer 1996 Kevin Rodgers <kevinr@ihs.com>
        decided to put together all grep calls to one package, igrep.el:
        `agrep', `egrep', `fgrep' and `zgrep'. It also could search trees
        recursively.

        I immediately picked up the package from the emacs sources group
        and started using it in my emacs. The default `M-x' `grep' command
        that comes with emacs is pale shadow compared to `igrep.el'. There
        were usually some common directories that I wanted to grep all the
        time, like news articles, info pages, my project directories, lisp
        sources, my Emacs init files, so I started to building top level
        interface to utilize `igrep.el' to its fullest potential.

    Description

        o   Toplevel interface to `igrep.el': Easy command menu access.
        o   You can toggle igrep options while you're using the
            echo-area menu.
        o   You can directory searches easily: grep all your
            news files, your Emacs news files, your text files, your lisp
            files, grep all manual paths... just configure one variable.
            You can jump to matches from the *compile* buffer where
            the results appear, like when using normal grep.
        o   The default installation included many default directories
            to search for: Pel .pod files, perl installation .pm files,
            Emacs lisp tree_: cl, vm, tm, semi, mc, gnus and Emacs Info
            tree files, Grep all Manual pages installed in your system,
            grep your ~/bin ... more.

    Do you need this package?

        If you use Emacs "grep" then I advice you to move to igrep.el and
        start using this package too. It simplifies your grep tasks much
        more.Additionally, if you have several directories where you keep
        some persistent data where you want to do lookup from time to time,
        then you propably appreciate this package. It defines all the
        parameters for you and all you need to supply is the SEARCH-STRING.

    Suggestion

        I have found usefull to keep the igrep buffer in a special frame
        when I work in X environment. See if you like this too:

            (if window-system
               (setq special-display-buffer-names
                 '("*compilation*" "*grep*" "*igrep*")))

    A simple example how to use search database

        Suppose you want to search 1) emacs cl*el files 2) all your ~/Mail
        (recurse into dirs) 3) your ~/News files. A sample database
        definitions looks like this:

            (require 'tinyigrep)  ;; gives macro `tigr-db-lisp-elt'

            (tigr-db-push-elt
              (tigr-db-lisp-elt
                 "cl.el" "lisp-cl" "egrep" ;Grep only the cl libraries
                 '(list (concat dir "cl*el"))))
            ;;
            ;; Notice '(nil) which turn on recursive search.
            ;;
            (tigr-db-push-elt '("Mail" ("egrep" ("~/Mail/*") (nil))))

            ;; This greps only ~/News/*
            (tigr-db-push-elt '("News" ("egrep" ("~/News/*"))))

    Special database for current file directory

        Normally you predefine databases in variable `tigr-:database'.
        There is also a special database whose name is `/', which refers to
        files that are under current buffer's filedirectory. Eg. say you
        are editing:

            /user/foo/txt/file.txt

        Selecting a special database `/' will give you a prompt to limit
        search for files under that directory. You can moidfy the file
        pattern as you like:

            Search: /user/foo/txt/*.txt

        You can use this search criteria for successive searches by selection
        `last' database.

    Selecting igrep command from command menu

        When you call TinyIgrep, you will get prompted for database selection,
        which is "lisp-cl", "Mail" or "News" as you just defined them. The
        igrep interface menu looks like this:

            igrep: i)grep g)uess l)ast time d)ired [c)ase r)ecur u)ser]

        And more help on commands you can get with ?, key `c' toggles case
        sensitivity of the search by adding or removing the -i option for
        grep, `r' can be used to toggle recursive mode on or off, and
        `u' toggles user switches on and off. The user options are
        stored to own history list `tigr-:history-igrep-user-options' where
        they can be recalled.

    List of predefined databases

        For your convenience, function `tigr-install-default-databases'
        is run from `tigr-:load-hook', which defines several databses
        as default values. Here is summary of available selections:

       Home:

        o   */*             Search current directory
        o   *home-bin-sh*   Search ~/bin/ for *.sh *.awk
        o   *home-bin-pl*   Search ~/bin/ for Perl *.pl

       Operating system:

        o   *man*           Search manpages
        o   *c-usr-include* Search C header *.h files in /usr/include

       Perl pages:

        o   *perl5-modules* Search Perl 5 modules *.pm in @INC
        o   *perl-modules*  Search Perl modules *.pm in @INC
        o   *perl-pod*      Search Perl installation *.pod pages

       Emacs and Emacs lisp:

        o   *elisp-home*    Search ~/lisp or ~/elisp for *.el
        o   *lisp-dot-files* Search amon all .emacs* files in `load-path'
        o   *load-path*     Search `load-path' *.el
        o   *lisp-emacs-distribution* Search the Emacs installation root

       Emacs packages:

        o   *lisp-pcl-cvs*
        o   *lisp-elib*
        o   *lisp-cl*
        o   *lisp-mc*
        o   *lisp-irchat*
        o   *lisp-bbdb*
        o   *lisp-w3*
        o   *lisp-vm*
        o   *lisp-semi*
        o   *lisp-apel*
        o   *lisp-flim*
        o   *lisp-mel*
        o   *lisp-tiny*

        If you want to define a shotr name for any of these defauls, add
        additional etry eg. for vm. The last parameter could be '(nil) which
        would enable recursive search.

            (tigr-db-push-elt-lisp-package "vm" "vm.el" "grep" nil)

        If you like short names and do lit of list, you can define shorter
        database names:

            (dolist (package '("vm" "gnus" "irchat" "semi-def" "mc" "tinylib"))
                (tigr-db-push-elt-lisp-package
                   package (concat package ".el") "egrep"))
            ;; end of code


Tinyindent.el -- like indented-text-mode, but minor-mode, smart indent

    Preface, sep 1994

        The original auto-indent-mode from autoindent.el was very short
        and limited, so I thought I extend it a little...here is the
        result.  Thank you Alan for giving me a push to extend your code
        into new directions.  When I spoke with Alan and he gave me free
        hands, because he hadn't used the .el for quite a long time.

        I wasn't satisfied with the  indent-relative function, so
        I coded a preprocessor for it. Now the cursor won't jump
        all over the line if the previous one was empty. Just
        try original  M-x indent-relative when there is empty line above
        and you'll see what I mean.

        And where this module really shines: Has it ever been easier to line
        up variables according to '=' or in within lisp 'let*', or writing
        mail messages while this mode is turned on...

    Overview of features

        o   General block editing or indentation MINOR mode. Replacement for
            `indented-text-mode'.
        o   Takes over the TAB and BACKSPACE key.
        o   Looks back to guess right indentation. and uses relative indent
            when not at BOL.
        o   Special indentation is suggested if cursor is at BOL and
            user defined regexp is matched in line above. (like adding
            multiple c++ comments)
        o   Extra tii-tt-mode for writing descriptions within comments. This
            allows user to choose when to use HARD tab or SOFT tab = relative
            to the text above. TAB TAB inserts hard tab, TAB SPC inserts soft
            tab.

    Word about defining keys to maps

        Do not ever use `local-set-key' inside some my-XXX-mode-hook,
        because you may loose these keybindings when minor modes are turned on.
        Always use (define-key XXX-mode-map <key> <func>) inside hooks
        and your keybindings will not be affected.

        Simple example for lisp mode:

   (add-hook 'lisp-mode-hook 'my-lisp-hook)     ;; *better version*
   (add-hook 'emacs-lisp-mode-hook 'my-lisp-hook)

   (defun my-lisp-hook ()
     "My lisp setings"
     (define-key shared-lisp-mode-map           ;; <<<<
       "\M-e" (definteractive (eval-current-buffer) (message "eval ok")))
   ;; End

   (defun my-lisp-hook ()                       ;; *not recommmended version*
     "My lisp setings"
     (local-set-key                             ;; <<<<
       "\M-e" (definteractive (eval-current-buffer) (message "eval ok")))
   ;; End


        In the latter case, turning on the tii<or any> minor mode would
        have caused losting your ESC-e keybinding.


Tinylib.el -- Main library of general functions

    Preface, 1995

        I noticed, that I started using several functions in program
        modules I developed over the time, so it was time to move all common
        parts into general library.

        Briefly:

        o   This is library, so the package itself does nothing,
            there may be some interactive functions, so just skim through code.
        o   Collection of general functions. With these you can solve your
            problems within minutes, instead of spending days thinking
            "How do I do this with lisp? Does there exist a function...?"

    Quick function help

        Please use function

            tinyliby.el / ti::y-get-file-documentation

        which will build up a buffer containing all functions/macros
        and variables used in any lisp package file. You can print the results
        to get an overview of all functions in this file.

        If you feel that some function description is not clear, please
        drop me a mail. There is no plans for separate info files; that's why
        I try to keep the function descriptions as good as possible.

        Also look at the function

            tinyliby.el / ti::y-describe-symbols

        which will help you to find particular lisp information from the
        emacs. Eg. to search for function that has "file" in their name.

    If you're pacakge write, here is more resources

        Here is standard toolset I use for writing/studying/lining up
        variables for lisp...

            tinybm.el           drawing sections (bookmarks)
            tinytab.el          tab minor mode
            tinyindent.el       another "line up my vars" minor mode
            lisp-mnt.el         std emacs package use lm-verify
            eldoc.el            show func doc immediately (under cursor)
            find-error.el       find lisp error. put cursor on it

    What is this 'tiny' thing?

        The term *tiny* does not refer to file size, it just happened some
        years back that released my first package under name "tinyappend.el"
        and I started using the prefix "tiny" in front of packages.

    Code policy

        All functions are written by [jari], unless otherwise stated.
        If I have found interesting function from some other .el I have
        written a reference to that .el. If the code is directly taken
        'almost as is' all the credit belongs to the Author of the
        original code. Cheers for him, to write so recpectable code, that
        it can be used right from the box!

        If someone contributes good, general purpose function, all the
        credit belongs to him automatically. Persons name and date and so
        on is included.

    TinyXXX Libraries' intention

        These libraries are by no means private. My wish is that all Lisp
        developers would contribute their general purpose functions and
        they would be merged into libraries so that the functions would be
        commonly available.

        The biggest problem in the lisp world seems to be compatibility:
        after every new Emacs release you have to be on your toes if that
        broke backward compatibility. This is understandable from the Emacs
        developers point of view: they don't want to carry any old burden
        with the latest high tech product. But it places other lisp package
        writes in an awkward situation: if they do have the chance
        to follow the Emacs development, sooner or later their fine package
        breaks.

        Then comes the issue of Emacs and XEmacs differencies and different
        platforms, now when NT has gained firm grounding.

        In order to reuse the code in all my modules and to keep up with
        the Emacs/XEmacs interface and different releases, I have chosen to
        put the general function to these libraries that you see.

        When I hear about new Emacs functions, I move the old code
        to (b)backward library. This way you can run the packages with any
        decent 19.x+ Emacs version. Feel free to drop me a note if you
        know a function that should be used instead of some of these library
        functions. I'll update all my tools immediately.

    Registration

        If you're going to use these function, it may be good idea to register
        you as a "user" of these libraries. When the libs changes, you will
        be mailed a message and you can follow the development; what new funcs
        may help you better, which bugs are found and may affect you.

        I do not have accees to mailing lists, nor can I maintain one,
        so the registration is used for simple message that inform about the
        lib development phases only.

    Code reliability

        Almost all of these functions are in actual use all the time and
        they have been found to be quite good behaving. This doesn't
        mean that they don't contain bugs. And if you feel that
        function should have more parameters or they should behave "more
        generally", please mail me. I'm willing to take suggestions of
        all kinds.

        The functions are *not* tested systematically, one by one.
        Instead, I have done couple of quick tests after coding to
        verify that the func works expectedly. It may still have bugs,
        when fed with some other data or used in some other task. Please
        be patient and send me backtrace and the values used and I'll fix
        bugs real fast.

        Report bugs immediately, since someone may be using that
        funtion without knowing the error.

    Turn on you debug

        If some function gives you error, immediately turn on debug
        and repeat your task

            (setq debug-on-error t)
            (setq debug-ignored-errors nil)  ;; Emacs 20.x

        Now when error happened, you get *Backtrace* buffer displayed.
        Send me the contenst of the buffer and all variable values that
        are relevant to call. See 'e' command in backtrace to display
        values.

    Function naming convention in this library

        So why this kind of naming? Have you ever tried to find function in
        emacs? Then you know... If you want to find all functions related
        to file handling, you can't just say

            file-[lisp-complete-symbol]

        because the function naming in emacs is "traditional", meaning
        that they are like spoken language, where word "file" may exist
        in any part of the function name, like

            xxx-file-xxx-xxx

        So, to ease finding function while I'm programming in lisp, I chose
        to name functions so that they have some sort of prefix. If you
        want to list all functions related to file in tinylibXX you just do

            ti:f-[lisp-complete-symbol]

        Same goes to any other category. I assure you , while it may not
        look nice, it certainly saves lot of programming time. This
        essentially same as what XEmacs team has done fo the function names.

        Following prefix syntax has been used, so that functions and
        variables can be found easily, when they have common beginning.

            LIB-id-funcName

            LIB = library where function belongs  'ti::'
                  variables have only one ':' --> 'ti:'

            id  = specifier that tell where the function applies to.
            a  = (a)dviced emacs functions
            b  = (b)uffer related
            c  = (c)onversions, convert in general
            d  = (d)ate tools
            e  = (e)vents
            f  = (f)ile handling
            k  = (k)eymap control
            l  = (l)ist manipulation
            m  = (m)isc category
            o  = (o)verlay handling
            p  = shell and (p)rocess handling
            q  = (q)uestions and user interaction in general
            s  = (s)string manipulation
            t  = (t)ext properties (faces)
            w  = (w)indow and frame handling
            x  = (x) and X-popup menu related
            y  = s(y)stem manipulation, information from internals.

        Two char identifiers are for specific tasks/libs

            mt  = (m)ail (t)ools, includes News handling tools too.
                See tinylibmt.el
            xe  = (Xe)macs compatibility functions. You should use
                these is you want to write portable code.
            ck  = Convert key bindings
            id  = Identifying buffer content.

    Local varibale naming in the tinylibXXX.el functions.

        I have tried to use following names in functions' 'let' body.
        However, when I started coding these long time ago I hadn't
        thought about setting up any discipline in variable naming, so there
        is still functions which do not use standard naming.

        I find it very handy, when I always use same names for same purposes,
        it makes the code more easy to read and understand when the variety
        of names is not so big.

        If you think about submitting general code, I'd like to see the
        functions using these variables. Of cource it's up to you if
        you feel naming conventions are waste of time. Still, spend a moment
        thinking who might be reading your code.

            beg end     begin area, end area [points]
            bf, bfn     buffer file name
            bn          buffer name
            bp          buffer pointer  , sometimes "beginning point"
            buffer      buffer [pointer or name]
            cmd         usually a shell or process command string
            ep          end point -- see bp
            func        variable to store a function symbol
            fid         "function id", name which is used in debug trace
            list        a list
            len         length of object [string, list, array]
            line        current line contents as string
            level       matching subexpression level
            mb me       match end/beginning point or Marker beg/end
            nbr         holding integer
            ob          original buffer [pointer or name]
            p           general point
            pb pe       point: beg, end
            ptr         a list pointer that will be moved.
            [-]re[-]    referring to regexp
            reg         register [integer ie. char]
            ret         return value of a function
            str         string
            verb        flag representing 'vebosity' usually (interactive-p)
            win         a window pointer

    Detailled explanation of some functions or macros in this library
    ----------------------------------------------------------------------

    Defining minor mode fast

        If you're eager to define minor mode in 1 minute, then here is
        one macro that does everything for you. After this you have all the
        minor mode variables ready and the mode works in bot Emacs
        and XEmacs including the menus.

            (eval-and-compile   ;; So that defvars and defuns are seen
            (ti::m-fmacro-minor-mode-wizard
             ;;
             ;; 1. prefix for variables and functions
             ;; 2. Modeline name
             ;; 3. prefix key for mode.
             ;; 4. Menu bar name
             ;; 5. <forget this>
             ;;
             "xxx-" " xxxModeline" "\C-cx" "xxxMenubar" nil

             "XXX minor mode. Does fancy things."  ;; mode description
              Defined keys:
              \\{xxx-mode-map}
              "

              "XXX help"    ;; message displayed when user calls mode
              nil           ;; Forms When minor mode is called

             ;; This is used by easy-menu.el and defines menu items.
             (list
              xxx-mode-easymenu-name
              ["Eval whole buffer" xxx-eval-current-buffer    t]
              ..
              )

             ;;  this block defines keys to the mode. The mode minor map is
             ;;  locally bound to 'map' symbol.
             (progn
               (define-key map (concat p "-") 'xxx-eval-current-buffer)
               (define-key map (concat p "=") 'xxx-calculate)
               )
             ))

    Defining minor mode step by step

        If you want to take more personal control over the minor mode
        creation, here I explain step by step what macros you need to include
        in your pacakge to get minor mode created, This takes only
        half an hour and you have basic minor mode ready. Put all
        following calls near top of your file. We suppose we're
        creating XXX-mode.

        _[1]_ First, define standard variables for minor mode.

            (ti::m-vmacro-minor-mode "xxxModeline" "\C-cx" "xxxMenubar")

        After that user has  following varibles for customization. (for
        complete list of created variables, see the macro's description)

            ;; Don't like default key combo C-c x
            (setq xxx-mode-prefix-key "\C-cm")

            ;; The default mode string was too long, use shorter.
            (setq xxx-mode-name "xxx")

            ;;  When mode runs, I want to do this.
            (add-hook 'xxx-mode-hook 'my-xxx-settings)

            ;;  I want to add additional keys
            (add-hook 'xxx-mode-define-keys-hook 'my-xxx-keys)

        _[2]_ Next we need installation function, which installs our minor
        mode so that emacs is aware of it. The minor mode funcktions,
        xxx-mode, will call xxx-mode-define-keys-hook which takes care of
        defining keys to keymaps and creating menus with easy-menu.el. The
        separate installation function is used, because it takes care of
        emacs specific things and if called with additional argument, it
        also knows how to remove the mode gracefully.

            (ti::m-fmacro-minor-mode-install
             xxx-install-mode
             xxx-mode
             xxx-mode-map
             xxx-mode-name
             xxx-mode-define-keys-hook
             )

        _[3]_ Do we have additional files attached to the end of package?
        If yes, then we need pgp-tar unpack function too.

            (ti::m-fmacro-install-pgp-tar "xxx-install-files"  "xxx.el")

        _[4]_ Finally the user callable minor mode function is created.

            (ti::m-fmacro-minor-mode
             xxx-mode
             "XXX minor mode. Does fancy things."
             Defined keys:
             \\{xxx-:mode-map}
             "
             xxx-install-mode
             xxx-mode
             xxx-mode-name
             xxx-mode-prefix-key
             xxx-mode-easymenu
             nil                        ;Yes, print turn on/off message
             "XXX help"
             xxx-mode-hook
             )

        That's it. when you execute all these statements you have basic core
        for emacs minor mode. The only things misisng is the actual
        functions that the minor mode commands uses and the function that
        defines keys and menus for the minor mode. You propably want to
        start from the function that defines keys and menus. Here is ready
        macro for that too.

            (add-hook' xxx-mode-define-keys-hook 'xxx-mode-define-keys)

            (ti::m-fmacro-define-keys
             "xxx-mode-define-keys"
             'xxx-:mode-map
             'xxx-:mode-prefix-key

             'xxx-:easymenu
             'xxx-:easymenu-name
             "Programming help menu."
             (list
              xxx-:easymenu-name
              ["Eval whole buffer" xxx-eval-current-buffer    t]
              ..
              )
             '(progn
                (define-key map (concat p "-") 'xxx-eval-current-buffer)
                (define-key map (concat p "=") 'xxx-calculate)
                ..
                )
             )



Tinyliba.el -- library for (a)utoload definitions

    Preface, 1998

        This is lisp function library, package itself does nothing.
        This library defines some packages' function in autoload state.


Tinylibb.el -- library of (b)ackward compatible functions.

    Preface, 1998

        This is lisp function library, package itself does nothing.
        This library defines new [X]Emacs release functions for older
        [X]Emacs releases.

    Code policy

        If I have found some usefull macro from someone's .el or from
        news, the proper source and name of author + time is preserved. All
        the credit goes to those marvellous programmers!

    Usage

        You must not autoload this package; but always include

            (require 'tinylibm)

        Yes, there is no typo, you load "m" lib. It will handle arranging
        everything for you. This library is included by "m" library
        automatically. Repeat: you don't have to put any of these in your
        packages:

            (require 'tinylib)
            (require 'tinyliba)
            (require 'tinylibb)
            (require 'tinylibo)
            (require 'tinyliby)

    Todo

        1998-10 I just noticed that SEMI included poe*el libraries that also
        emulate various Emacs versions. I really think there should be only
        one emulation library for all package writers. I'm considering
        to move functionatility from this lib and xe lib to SEMI packages.
        [Then Users would need SEMI. Hm.]



Tinylibck.el -- Library to (c)onvert (k)eybindings for XEmacs or Emacs

    Preface

        This file tries to overcome differencies between Emacs and XEmacs
        keybinding. I developed this at the time when I used 19.28 and
        I wanted to use my other packages with any emacs version in
        spite of key definition differencies. This file is in fact
        "library" and propably interests only lisp programmers that want
        to make some old package, that has Emacs specific bindings,
        to work in XEmacs (or vice versa).

    Emacs 19.30+ note

        Newer Emacs release now supports XEmacs styled bindings.
        You can write

            (local-set-key [(control meta up)] 'ignore)

        and it should work both in XEmacs and Emacs. If all your keybindins
        are like that and you don't use Emacs lower than 19.30, then you
        don't need this package. I recommend that you use primarily this
        style.

    Putting your key definitions to separate file

        You should separate all you keybindings to _one_ file,
        do not stuff all your emacs definitions in one huge ~/.emacs,
        but instead use some basic structure like this:

            ~/.emacs            -- the main
            ~/.emacs.kbd.el     -- All the keybindinds
            ~/.emacs.x.el       -- X settings and X-packages loads
            ~/.emacs.vc.el      -- vc settings and modifications
            ~/.emacs.bup.el     -- Backup settings and redefinitions
            ~/.emacs.gnus.el    -- gnus customization
            ..

        You can load your other initialize files from .emacs with `load'
        command. Suppose you have Emacs keybinding startup file; which you
        want to make compatible with XEmacs too. The reason why you should
        use `ti::ck-maybe-activate' is that, it can determine your emacs
        version and decide when the converter is needed and when not.

            ;; at the beginning of keybindings, you add these

            (require 'tinylibm)
            (autoload 'ti::ck-advice-control "tinylibck")

            (ti::ck-maybe-activate 'xemacs-mouse)
            (load "~/.emacs.keys")          ;; All XEmacs styled bindings
            (ti::ck-maybe-activate 'xemacs-mouse 'disable)

            ;;  load rest of the startup files
            (load "~/.emasc.x)
            ...
            ;; End of startup file

    Some lowlevel explanation

        If you're in Emacs, you use X-event bindings like this

            (global-set-key [C-up] 'ignore)

        Unfortunately, this does not work in XEmacs, but using the
        conversion function before the definition, it does.

            (global-set-key (ti::ck-do [C-up]) 'ignore)

        Now the current Emacs version gets the right keybinding,

            for Emacs  it returns       --> [C-up]
            for XEmacs it returns       --> '(control up)

        You can also use the XEmacs keybinding, since the conversion goes
        both ways. Having the following setting:

            (global-set-key (ti::ck-do '(control up)) 'ignore)

        it converts this to suitable form depending on the current Emacs
        in use.

    About advices

        So that you don't have to go and add that 'ti::ck-do' call for every
        keybinding, I have provided advices that hook themself to
        appropriate keybinding functions.  The conversion is then done
        transparently and you don't have to change a thing in you
        keybinding settings.

    About debugging

        If you suspect any weird behavior in your emacs while
        this package is loaded, you should check that the `ti::ck-:debug'
        is turned on. (`M-x' `ti::ck-debug-toggle')

        The buffer `ti::ck-:debug-buffer' constantly records any conversion
        actions and you can find the problems quickly. Please send the
        supicious/false conversion lines to the maintainer of this package
        and if possible, tell how the conversion should go in your opinion.

        I'd recommend that you keep the debugging permanently on, because
        if problems arise afterwards and if the debug were off, there is
        no way to tell what went wrong in what command.

        Important; when you have problems, increase

            ti::ck-:debug-buffer-size

        immediately to some arbitrary big value so that you get all the
        conversions recorded.

    Known limitations

        This package tries to do its best to make the conversion, but
        sometimes it is just impossible. For example the following
        case is beyond of this package. In Emacs you can define

            (define-key xxx-mode-map [?\C-`] 'some-function)
                                     ^^^^^^^

        But when your're in XEmacs and you try to do the same, it gives
        error although tinylibck is currently active. The reason is that lisp
        intepreter never actually passes key  "?\C-`" to `define-key'
        but it actually evaluates the vector in place to an integer value
        and sends that to `define-key' function . The call actually is
        seen in Emacs like this:

            (define-key xxx-mode-map [4194400] 'some-function)
                                     ^^^^^^^^^in my HP-UX 9.05

        And in XEmacs it is evaluates to this:

            (define-key xxx-mode-map [0] 'xxx-tab-backward)

        The code "0" appears, because XEmacs doesn't know Emacs "?\C-`".
        You should write [(control ?\`)] for XEmacs and it would work ok.
        Be aware of this limitation if you plan to use Emacs styled
        bindings. Alternatively, you can tell that you that some
        particular piece of code has been written by using XEmacs style.
        (Wouldn't you want to you use it all the time in Emacs...)

            ;;   This is Emacs file.
            (require 'tinylibck)                   ;Keybind converter.
            (ti::ck-advice-control)             ;turn it on

            ;;   But here I want to use xemacs style for a while
            (define-key tit-mode-map [(control ?\`)]  'tit-tab-backward)
            ;; And other similar keybindings ...
            (ti::ck-advice-control 'disable)    ;don't leave it on

    Thank you

        Vladimir Alexiev <vladimir@cs.ualberta.ca>
        Presented initial idea of the conversion process.
        Commented how the conversion should go in XEmacs.

        Stephen Eglen  <stephene@cogs.susx.ac.uk>
        Stephen had the patience to send bug reports from XEmacs 19.12 and
        test new versions of tinylibck.el


Tinylibid.el -- Library for (Id)entifying buffer, regardless of mode

    Preface, feb 1995

        Seems quite uninteresting package to you? I bet it does, unless
        you're a lisp programmer who has infite time to twiddle his
        c++-mode-hook + 20 others hooks and have all the time develop nice
        little funcs to make living in emacs easier :-/

        While someone may think that all users stick to one mode eg. when
        they are programming C++, that's not obvious. For example I move
        constantly between all kind of modes during programming and the
        trouble is, that while the buffer LOGICAL content remains the same,
        the hooks knows nothing about it. Hooks are just dummies that gets
        called whenever you turn some mode on, try C++ mode over nroff code
        and you'll be suprised...[not a serious example of cource]

        Now let's see one example: like I coded this package:

        .   write list               ;lisp-mode + folding-mode
        .   hmm, write some comments ;tii-mode,  no folding
        .   hmm, need center-command ;text-mode
        .   code again               ;lisp + ..
        .   adjust defconst var pos. ;tii-mode (tinyindent.el)
        .   code again               ;lisp-mode

        I have bound all common modes into keys that I can access very fast
        so that changing modes is no problem. What is the problem, is that
        when you turn off the CODE-mode, all info about comment-start etc.
        vanishes. The tii-mode and TIC (tinycom.el) fortunately doesn't
        care about the modes, because they have their own heuristics to
        determine suitable comments etc.

    Overview of features

        o   This is LIBRARY package and should be called from lisp.
        o   Try to identify the buffer by using various criterias.
        o   Usefull for checking what kind of file is in buffer and making
            decisions based on that, like in hooks.

    Imenu example

        If your're using imenu.el to generate buffer jump points, it is
        very likely that the imenu command won't generate right jump points
        if you're in wrong mode.

        let's use imenu example. This is how I used to have it configured:

 ;; ** Hm **
 ;;
 (defun my-imenu-mouse (event)
   (interactive "e")
   (my-imenu))
 ;;
 (defun my-imenu (&optional arg)
   "Sets parameters to imenu."
   (let* (raise
         )
     (setq imenu-max-items 20
          imenu-sort-function nil)
     (cond
     ((memq major-mode '(lisp-mode emacs-lisp-mode lisp-interaction-mode))
       (setq imenu-create-index-function 'imenu-example--create-lisp-index
            imenu-sort-function         'imenu--sort-by-name
            raise t
            ))
      ((memq major-mode '(c++-mode))
       (setq imenu-create-index-function 'imenu-example--create-c++-index
            imenu-sort-function         'imenu--sort-by-name
            raise t
            ))
      ((memq major-mode '(c-mode))
       (setq imenu-create-index-function 'imenu-example--create-c-index
            imenu-sort-function         'imenu--sort-by-name
            raise t
            ))
      )
     (if raise (imenu))
     ))
 ;; End

        Code seemed pretty obvious don't' you think ? It sniffs around to
        see if we're on some mode and then configures imenu according to
        it.

        Here is much better and more robust way. It'll let you be in any
        mode while retaining right imenu. [The example can be
        automatically extracted with function ti::m-pkg-rip-magic from
        tinylib.el, follow the instructions there.]

 ;; ** I'd use this **

 (require 'imenu)

 ;;  Separate functions for keyboard and mouse.
 (defun my-imenu-mouse (event &optional arg)
   (interactive "e\nP")
   (my-imenu arg))
 ;;

 (defun my-imenu (&optional arg)
   "Sets parameters to imenu. If called with arg, the output is
 unsorted.
 "
   (interactive "P")
   (let* (
         (s-func (if arg nil 'imenu--sort-by-name))
         (table
          '((lisp-mode
             imenu-example--create-lisp-index)
            (emacs-lisp-mode
             imenu-example--create-lisp-index)
            (c++-mode
             imenu-example--create-c++-index)
            (c-mode
             imenu-example--create-c-index)
            ))
      ;;  So, in what mode were really?
         (mode (or (ti::id-info t) major-mode))
         (el (assoc mode table))
         )
     (if (null el)
        (message "Sorry, no imenu for this buffer.")
       (setq imenu-max-items            20
            imenu-sort-function         s-func
            imenu-create-index-function (nth 1 el))
       (imenu)                          ;launch it !
       )
   ))
 ;; End

    Your mode is not supported ?

        I'm sure that this file cannot identify all modes out there, since
        I'm only aware of these included in this package. Please send me
        any example file that is edited in particular mode, I'd be glad to
        support more modes.

    What buffers to identify ?

        The aim of this package is to be 'aid'; offer some help for user's
        that need to set up their hooks or use commands that are based on
        buffer content. This is *not* the same as buffer recognition, and
        this package will not be one. To recognize all buffers and their
        contents would be waste of time.

        Summarum: let's be reasonable and _think_ what buffers we need to
        identify and add support to those.


Tinylibm.el -- library of s(m)all macros or functions

    Preface, 1995

        This is lisp function library, package itself does nothing.
        It contains small functions or macros.

    Code policy

        If I have found some useful macro from someone's .el or from
        news, the proper source and name of author + time is preserved. All
        the credit goes to those marvellous programmers!

    Usage

        You must not autoload this package; but always include

            (require 'tinylibm)

        You don't need any other require commands: all my other library
        functions get defined as well by using autoload.  Repeat: you don't
        have to put these in your packages:

            (require 'tinylib)   ;; leave this out
            (require 'tinyliby)  ;; not needed either.


Tinylibmenu.el -- Library for echo-area menu

    Preface, Feb 1996

        Oh Boy, my ~/.emacs.keys.el file started looking like a mess.
        There were hundreds of bindings that were impossible to remember
        any more. Many times I was staring at the buffer and wondering

          ..I'm sure I have bound function xxx somewhere..but I can't
          remember where...

        Normally I'd reach for the M-x COMMAND to try to remember the
        function name, but other times I'd hit `C-x' `b' to bring up all
        bindings. Then I would start tedious search with `C-s' to find the
        function I was longing for. I thought that there definitely had to
        be some way to construct menu that would use echo area. Instead of
        remembering that I had done these bindings

            "C-cmf"             , m = (m)ode functions, f = folding-minor-mode
            "C-cmF"             , ... auto-(f)ill minor mode
            ...

        When I have TinyMenu, I can call, say `f1', to bring up menu which
        assists me to find proper function in the echo area.

    Overview of features

        o   This package can be used as lisp library; Mode's
            keybindings can be put behind echo area menu. (similar to
            menu bar, but easier to use.)
        o   Regular Emacs user can also put less used binding to guided
            echo menu by just defining couple of menu variables.

    Customizing ready menus

        If some package defines good menus and you only want to change them a
        little and not to copy the whole 'defvar MENU' to your .emacs, you
        can use following functions to manipulate the menu items

            ti::menu-add
            ti::menu-set-doc-string

        Say, you have following menu

            (defconst ti::menu-:menu-sample
            '(
              "?)help, 1)test1, 2)test2"
              ((?1 . (  (ti::menu-test1 1 2 3)))
               (?2 . (  (ti::menu-test2 1 2 3)))
               )))

        and you don't like keybinding '?2'. You first delete the menu item,
        then add yours and lastly you update the doc string that is printed
        in echo area. Here is how you do all these three steps.

            (ti::menu-add 'ti::menu-:menu-sample ?2  nil 'delete)
            (ti::menu-add 'ti::menu-:menu-sample ?t '( (my-test 1 2 3)))
            (ti::menu-set-doc-string 'ti::menu-:menu-sample
                                 "?)help, 1)test1, t)myTest")

        And the modified menu looks like this

            (defconst ti::menu-:menu-sample
            '(
              "?)help, 1)test1, t)myTest"
              ((?1 . (  (ti::menu-test1 1 2 3)))
               (?t . (  (my-test 1 2 3)))
               )))

        If you want to replace many commands from the menu, it is lot
        easier if you copy the menu `defvar' and make direct changes there.
        If you want to make it all with lisp, here is example which
        replaces 2 items from the menu

            (mapcar
              '(lambda (x)
                 (let ((key (car x))
                       )
                   (ti::menu-add 'ti::menu-:menu-sample nil 'delete) ;; Remove old
                   (ti::menu-add 'ti::menu-:menu-sample key (cdr x)) ;; Add new
                   ))
            '((?1 . ( (my-1 1 2 3)))     ;; New menu item replacements
              (?2 . ( (my-2 1 2 3)))
              ))
            ;; End

            (ti::menu-set-doc-string 'ti::menu-:menu-sample "?)help, 1)my1 2)my2")

    Having a test run

        The easiest way to get a hold on the echo menu is that you try it.
        Follow these steps. Then you're ready to make your own menus.

        .   Load this file. M-x load-file ~/elisp/tinylibmenu.el
        .   Start menu with `M-x' `ti::menu-menu-default'
        .   Press key `?' or `h' to get help and `q' to quit menu.
        .   Try offered choices


Tinylibmt.el -- Library of (m)ail and news (t)ool functions

    Preface 1995

        o   This is library. Package itself does nothing.
        o   Collection of functions to deal with Mail/News specific tasks.


Tinylibo.el -- Library for handling (o)verlays

    Preface 1995

        The functions were developed to ease the usage of highlighting,
        which really seemed "inside" stuff when I first wanted to use
        colored text in emacs.

        o   This is LIBRARY module, it does nothing on its own.
        o   Offers functions for 19.xx overlay handling

    Code policy

        All functions are written by [jaalto], unless otherwise notified.
        If I have found interesting function from some other .el I have
        written a reference to that .el. If the code is directly taken
        'almost as is' all the credit belongs to the Author of the
        original code. Cheers for him, to write so recpectable code, that
        it can be used right from the box!

        If someone contributes good, general purpose function, all the
        credit belongs to him automatically. Persons name and date and so
        on is included.


Tinylibt.el -- Text property handling library

    Preface, apr 1995

          [This is primarily a library]

        Now, when this highlightging is available in 19.xx, why don't we
        use it for marking texts too, especially when we are looking for
        documentation of some program and we want to find certain words, or
        that we want to see TABS in the buffer. This little .el eases the
        job of visualizing items in buffer.

        Where I use this most is inside GNUS/DING/RMAIL hooks, to mark
        interesting peoples articles and seeing where is my articles.  The
        font-lock/lazy-lock are a little bit too heavy for those things,
        because these buffers hold "solid" data, text, that does not
        change, and I feel that executing arbitrary 'ti::t-re-search'
        command to highligh the headers I want is more easier that with
        font-lock, especially when I can change the faces in the fly with
        'ti::t-re-search'.

        Yes, I'm aware of the capabilities of DING, which highlights
        articles for you already, but sometimes I want more personal
        highlighting in summary buffer etc...

        But the font-lock/lazy-lock are unreplacable in programming modes,
        which has to deal with dynamic text.

    Overview of features

        o   This package is primary aimed for elisp programmers, but
            interactive users will also find handy functions.
        o   Shows matched text with color in the buffer.
        o   This is *NOTHING* like font-lock, lazy-lock or hilit19,
            which are demand driven packages intended for certain major modes.
            Use this package to "manually" mark interesting things in
            any buffer.
        o   Examples: highlighting on/off tabs, Verifying PGP
            fingerprints against trusted list like http://www.uit.no/
        o   UNDO: adjustable stack size. Stack is cleared if
            stack limit reached (stack 'wraps')

    User functions

        Mostly this package is designed for lisp programmers, who add
        some highlight commands in hooks. For quick text highlighting,
        you can use these interactive functions:

            ti::t-looking-at
            ti::t-buffer                        ;; Highlight in whole buffer area
            ti::t-re-search-forward
            ti::t-re-search-backward
            ti::t-undo

            ti::t-clear-buffer-properties
            ti::t-clear-region-properties

            ti::t-mark-region
            ti::t-unmark-region

            ti::t-mouse-mark-region
            ti::t-mouse-unmark-region

    Setting different face (programming)

        If you want permanetly change the face, when marking text
        use commands

            ti::t-search-face-set   ;to set
            ti::t-search-face-reset ;to get default color back

        If you want temporarily use some face, supply direct FACE parameter
        when you call search functions, like:

            ti::t-re-search-forward (re &optional level face)

    Note

        This is for simple text highlighting only. Like finding certain items
        or marking something quickly and temporarily (great for text files)

        You can mix font-lock/hilit19 and TIMA package, but remember that
        these packages have different goals. Use TIMA only for finding
        things in buffer, or marking certain articles in gnus...

        Be carefull: if you use `ti::t-clear-buffer-properties', you will
        wipe out all text properties.



Tinylibxe.el -- Emulation library for Emacs and XEmacs

    Preface 1996

        o   This is library, package itself does nothing.
        o   Compatibility for both XEmacs and Emacs

        I saw some incompatibilities reported for XEmacs and Emacs, which
        prevented writing portable code. I started collecting some
        problematic things here. Please send me more lisp code if you know
        more imcompatibilities, so that developers don't have to struggle
        so much.

    Overlay.el in XEmacs19.15

        Good news; XEmacs 19.15 will have new package that emulates
        Emacs overlay functions. Beware, at least VM goes nuts in XEmacs if you
        load this...
        The author is Joe Nuspl <nuspl@nvwls.cc.purdue.edu>

    What you should know -- keep this in mind

        This library's intention is to make it possible to use some package
        that is written only in Emacs or only in XEmacs in mind. Normally
        You couldn't use that package in another emacs, because there may
        be functions that are not implemented.

        When you load this library, it emulates those unknown functions
        as much as it can, so that that you can use the package for
        both emacs. However, it may not be possible to reproduce
        exacttly the same behavior in the Emacs that wa not the primary
        target for the package. The emulation may in worst case be
        only so, that you are able to load the package without errors,
        but the functionality of the package doesn't correspond
        to the original version.

        When you write your own packages, do not try to make use of the
        latest glory details of the Emacs. If you do, you can be
        sure that your package won't work anywhere else.

    Coding to specific Emacs

        I'd like propose that you don't test against missing fetatures
        when it comes to XEmacs and Emacs compatibility, but instead use
        direct tests

            (emacs-p)           ;; from 'M' lib, tinylibm.el
            (xemacs-p)

        In these those _specific_ cases where you would like to use "special"
        code for either Emacs version.



Tinyliby.el -- library of functions related to Emacs s(y)stem

    Preface, 1995

        Some emacs system related functions are collected hre, that
        I used all the time. I was working with `tinydgboot.el', which let
        me boot Ding 0.xx or GNUS 4 configuration without leaving emacs. I had
        to introduce myself to totally new areas in emacs: the symbols in
        obarray.

        Briefly

        o    This is lisp code library. Package itself does nothing.
        o    Collection of Emacs s(y)stem related functions.

    Code policy

        All functions are written by [jari], unless otherwise notified.
        If I have found interesting function from some other .el I have
        written a reference to that .el. If the code is directly taken
        'almost as is' all the credit belongs to the Author of the
        original code. Cheers for him, to write so recpectable code, that
        it can be used right from the box!


Tinylisp.el -- Emacs lisp programming help grabbag

    Preface, Feb 1997

        My private lisp help functions were scattered around my files and
        in other private libraries. One day I decided that I wanted a minor
        mode to access all those tools I had written for lisp. I didn't
        want to continue stacking up my `lisp-mode-hook' for all the growing
        features.

        So, if you're programming in elisp, this minor mode may slightly
        increase your productivity :-)

    Overview of features

        Lisp coding help

        o   Create list of all variables from the buffer. (or occur menu)
            You can use this list to update your bug report function or just
            to get an overview of the variables. Chck names and the order how
            you have used them (The order is important if you use defcustom)
        o   Create function list (or occur menu)
        o   Create autoload list
        o   Evaluate current definition under point (reparse function,
            reset defvar or even defcustom variable)
        o   Print variable's value under point, set variable's value
            under point (backs up the original value which you can restore)
        o   Call function under point (to test it immediately)
        o   Indent function/variable around point.
        o   FINDS LISP CODE ERROR POINT.
        o   In DEBUGGER *Backtrace* hit 'R' to record the content of the value
            to *tili-record* This is great when you want to send bug report
            to maintainer and you can attach the state of the variables
            with it.

        o   Code flow help: jump to variable of function definition even if
            it is located in different file. Does not use TAGS; but assumes
            that function is `known' to Emacs.
        o   Two extra echo area modes: Show underlying properties/overlays or
            Show charcters' syntax information.

        Edebug support

        o   Sit on function name and call `tili-edebug-instrument' and
            the remote function will be instrumented. If you used just
            plain edebug, then you'd have to manually load the function into
            current point and hit `edebug-eval-defun', for each function.
            (Note that "i" auto-instrument doesn't always work from
            edebug)
        o   Easily uninstrument functions: at point, in buffer,
            everything known

        Elp support -- Lisp code profiling

        o   Access elp commands from echo menu
        o   Profile your package or buffer's functions easily.
            Sit somewhere in function and un/instrument it with one command.
            Un/instrument all functions in the buffer with one command.

        Elint support -- Lint your elisp code

        o   catches mispellings and undefined variables
        o   function calls with the wrong number of arguments, and
            some typos such as (let (a (car b)) ...)

        Checkdoc support --  Check doc strings for style requirements

        o   ftp://ftp.ultranet.com/pub/zappo
        o   Easy interface to checkdoc commands.
        o   A tool that makes sure your package follows the guidelines
            presented in File: elisp, Node: Documentation Tips.

        Find-func.el support

        o   If we cannot determine function by itself, call this package.

        Remarks

        o   Please take a look new XEmacs package bench.el (19.15 and 20.2)
            for bechmarking.

    Tutorial, how do you check your package

        o   $ f  Take a look at your function names: are they well named,
            so that same categories begin with same words. Below it would be
            a mistake to have latter as xxx-clear-buffer, because then
            you cant find all common function with `lisp-complete-symbol'
            command on xxx-buffer-*. Code is not a spoken language but
            meant to be used by programmers (Compare function naming in
            XEmacs and Emacs, where XEmacs does the the right thing)

                xxx-buffer-handling
                xxx-buffer-clear

            Check also that your macros are defined first before functions.
            If possible, maintain this definition order in your file

                defvar, defconst, defcustom  (on top of file)
                defsubst
                defmacro
                defun

        o   C-u $ v Check variable names as the function names above,
            but also see that you have defined right user variables which
            should be using `defcustom'. The extra C-u argument will print
            this information.
        o   $ x  Check the lisp package layout: first line and footer must
            be in proper format and that Author etc. tags are in
            their places.
        o   Check the documentation strings with Checkdoc.
            To get overview of errors, do: $ c -  and $ c RET
            which a) turned off query b) checked whole buffer for errors.
            When you have got a clear look, then start correcting mistakes
            and do $ c a (semiautomatic correction) $ c BACKSPACE to correct
            full buffer.

    Defcustom.el and evaluating an `defcustom' variable

        If you don't know what defcustom is, or if you don't use it, you
        can ignore this section. The defcustom variables are evaluated
        pretending like they were `defconst', but because this evaluation
        is a bit special, pay attention to following paragraph.

        If you got thrown to error during evaluation, pay attention now,
        CALL COMMAND $ Z or `M-x' `tili-emergency' IMMEDIATELY. For full
        details, see function documentation strings in the source file for
        these:

            (defadvice defconst
            (defun     tili-eval-at-point

    Find lisp code error position

        The most usefull functions in this package are the two error
        finding functions which try their best to put you on a line that
        generates the lisp error. You can use this feature to eg. check
        your ~/.emacs starup files and find the spot where
        `eval-current-buffer' fails.

        The best function, `tili-error-find-1', was programmed by Mikael
        Djurfeldt <mdj@sanscalc.nada.kth.se> and is included here with his
        permission. Thanks Mikael, the funstion has saved from me a lot
        of debugging!

    Following lisp code call chain

        The traditional way to follow lisp code is to use TAGS file (See
        'etags' or 'ctags' shell binary and C-h a "tags") which reads bunch
        of *el files and builds up internal representation of all defined
        symbols and their locations.

        But using tags is not very flexible if you write the code yourself,
        because when you add new fucntion or new variable, the TAGS file is
        immediately out of date. Hm. The TAGS is general tool for many
        programming languages, but in Emacs lisp, we can take advantage of
        the fact that Emacs already knows where the symbols are defined.
        The information is stored to `load-history' whenever you run `load'
        `require' `load-file' or `load-library'.

        In this package, there are two functions that make use of
        `load-history' and if the symbol is not in the history, they try to
        find definition from the current buffer. You see, if you do
        `eval-current-buffer' the definition information is _not_ stored to
        `load-history'. With these commands you can browse some packages
        without any extra TAGS file.

          [The only assumption is that you have `loaded' the file !!]

            $ '     tili-jump-to-definition (do not record call chain)
            $ +     tili-jump-to-definition-chain (record call chain)
            $ \177  tili-back-to-definition (propably your backspace key)
                    This returns to previously saved call-chain point

        The jump command also know following prefix arguments

            M-0 $ ' tili-jump-to-definition (empty call chain)
            C-u $ ' tili-jump-to-definition (record call-chain)

    Examining text properties and overlays in buffer

        If you have ever played with text properties or overlays (called
        extents in XEmacs), you know how hard it is to examine buffer's
        characters and debug where the properties are.

        In this package there is "constant char browing mode" where every
        time you move your cursor, the face info and/or overlay info is
        displayed in the echo-area. If you supply `3' `C-u' arguments, the
        information is also recored to the separate buffer. This is the
        most easiest way to examine some chacter properties in arbitrary
        buffer positions. See C-h f on following function:

            $ p     tili-property-show-mode

    Examining charcter syntax

        Major modes define syntax tables for characters and sometimes you
        want to see the syntax class of a character under cursor. This mode
        behaves in the same manner as text propery display, just turn it on
        and it will constantly show char info.

            $ y     tli-syntax-show-mode

    Snooping interesting variables

        Has is happeed to you that your're debugging package and it
        installs many hooks and and sets many different variables and then
        you suddenly realize that it went all wrong? You may evn have
        noticed that some ill behaving package keeps preventing file
        writing!

        No problem, you can define interesting variable sets to peek their
        contents, eg. checking all file related hooks for problems.  And if
        you supply C-u prefix arg, your editings are updated to the
        variables. With any other non-nil arg, the contents of the
        variables are recorded (kinda before install -- after install
        snooping) See function:

            $ s     tili-snoop-variables

        And additional prefix arguments: You can save variables states,
        modify them as you like, and go back to restores values.

    Elp: notes

          [excerpt from Barry's elp.el]
          ...Elp can instrument byte-compiled functions just as easily as
          interpreted functions, but it cannot instrument macros.  However,
          when you redefine a function (e.g. with eval-defun), you'll need to
          re-instrument it with M-x `elp-instrument-function'.  This will also
          reset profiling information for that function.  Elp can handle
          interactive functions (i.e. commands), but of course any time spent
          idling for user prompts will show up in the timing results.

        To elp functions right, follow these steps. _*important*_ '(defun"
        must be left flushed in order the function to be found. If there is
        any leading spaces before the '(' or 'defun', then function won't
        be found and will not be (un)instrumented.

        o   $ E A Restore (a)ll elp'd functions
        o   $ -   Eval buffer containing functions (or eval single function)
        o   $ I   Instrument all functions in buffer (or single function)
        o   $ h   Run the harness test that calls the functions

    Elp: Summary mode's sort capabilities

        When you call $ E s to show the elp result(s), the results buffer
        is put into `tili-elp-summary-mode' where you can sort the columns
        with simple keystrokes. The sort keys correspond to the column names.

            f)unction Name  c)all Count  e)lapsed Time  a)verage Time
            =============   ==========   ============   ============

    Elp: customizations

        You should be aware of this variable in elp; which resets the
        list every time you display it.

            elp-reset-after-results

        You can toggle it's value from the echo menu.

    Edebug support

        To instrument function for edebug, you'd normally have curson inside
        current function and call `C-u' `M-x' `edebug-eval-defun'. But
        suppose you only see function call like this:

            (my-function arg arg arg)

        then you'd have to a) find out where the function is defined
        b) load that file c) position cursor over the fuction definition
        d) call edebug to instrument it. That's too much of a work. Instead
        there are commands that do this for you. See edebug submap `C-e'
        for edebug commands

            $ C-e RET   Instrument function _named_ at point
            $ C-e DEL   Uninstrument function _named_ at point
            $ C-e SPC   Instrument all functions in buffer
            $ C-e x     Uninstrument all functions in buffer
            $ C-e X     Uninstrument all functions instrumented by $ C-e RET



Tinyload.el -- Load set of packages when Emacs is idle (lazy load)

    Preface, Jul 1997

        While I had arranged my Emacs `rc' files to use all possible and
        imagineable autoloads, there still were packages that couldn't be
        autoloaded due to their setup nature or behaviour. I still had to
        put `require' commands into my `.emacs' in order to use those
        modules. It also meant that for every `require' command, the Emacs
        startup slowed. I had a very very complex boot configuration, so
        waiting 2 minutes for Emacs startup screen was too frustrating. It
        was all my fault, why did I had to stuff all interesting packages
        in the startup file...And guess what, This package was born. Now
        my emacs is ready for typing in 10 seconds. Voila.

        What this package does, it caches the load requests and executes
        them when it thinks there is free time. Instead of setting up
        all at once on startup, we build the emacs configuration piece
        by piece, untill your 100% configuration is there.

        The benefit is that your Emacs start instantly, and when it is
        idle, it loads all the remaining packages that you wanted to be
        available in your daily Emacs session.

    Overview of features

        o   Delayed (Lazy) loading of packages (at some later time); eg after
            15 seconds of idle time, remaining files are loaded one by one.
        o   You no longer have to use `require' in your .emacs, instead,
            you define `tilo-:load-list' where you put the request.
        o   Your .emacs starts 10x faster when the extra `require'
            `load' commands are out.

    First user notice

        When you use this package for the first time, you may feel
        uncomfortable with the amount of messages you see running by in
        your echo area. And if you're in echo-area prompt (eg. after `C-x'
        `C-f') those messages ruin your display there too.

        Just don't panic. Move your cursor key to the left or right or do
        something else and the loading will be interrupted. As long as
        there is activity in your Emacs the load will not happen.

        The messages that are displayed in the echo area are important,
        because they get stored to *Messages* buffers and you can take a
        look if anything strange happened. Like if some package couldn't be
        loaded at all. Pay attention to *fatal* messages.

    Messages in *Message* buffer

        There are different types of messages

            TinyLoad: fdb ok      (10% 1/10)              [1]
            TinyLoad: elp 'noerr! (20% 2/10)              [2]
            TinyLoad: fatal load error ~/.emacs.init.el   [3]

        o   [1] Package was loaded and show some remaining
            statistics.
        o   [2] You had defined 'noerr parameter and the
            recent load of the package failed: it didn't exist along
            `load-path'.
        o   [3] When file was beeing loaded; some error was generated. You
            should study this file by hand and spot the problem manually.
            Be sure that the syntax of the file is correct.

        In addition to these basic messages, there are some internal
        messages that do not concern regular user, only the maintainer.
        When he TinyLoad wakes up; you will see following message

            Tinyload: timer expired; invoking load process... [ok;ok;N]
                                                                | |  |
                                                   process status |  |
                                                    Continue status  |
                                    Busy count; and deadlock indicator

        Which simply means that Emacs called the laoder function and
        because *Continue* *status* was nil, user did nothing at the time
        of invocation. If the message [busy;stop;N] then user was doing
        something that weren't allowed to be interrupted. Usually this
        happens when cursor is in echo area eg. after `C-x' `C-f'.
        If the cursor never leaves the echo area or if the busy situation
        continues for a certain period of time, the program automatically
        clears the busy signal and continues loading. You should not see
        infinite [busy;stop.N] messages. If you really see 100 such messages;
        then contact the author: there must be an unresolved deadlock and
        a bug in the program.

        When the `tilo-:load-list' has been handled, the laoder process
        terminates itself. The following message tells that the process has
        ceased to exist. If you want to start reading the list again,
        call `M-x' `tilo-install'.

            TinyLoad: Bye, No more packages to load.

    Tutorial

        You better understand how you would use this package if I demonstrate
        the usage with examples. Let's supposes your emacs startup consists of
        following `rc' files.

            .emacs              -- the main load controller
            .emacs.path.el      -- settings paths/1st line mode list...
            .emacs.bup.el       -- Backup settings
            .emacs.set.el       -- Std Emacs variable settings

            .emacs.keys.el      -- Keyboard settings
            .emacs.font.el      -- Fonts and Font lock; faces settings
            .emacs.hooks.el     -- All add-hook commands and mode settings.
            .emacs.gnus5.el     -- GNUS 5 customizations (could be .gnus too)
            .emacs.std-pkg.el   -- Loading std Emacs packages and their setup
            .emacs.pkg.el       -- Non-std distrib, additional packages
            .emacs.tips.el      -- Tips (code samples) from the Usenet
            .emacs.mail.el      -- mail agent; mode; settings

        Now suppose your .emacs load all these files like this

            ;; .emacs -- Emacs startup controller

            (require 'rc-path   "~/.emacs.path")
            (require 'rc-bup    "~/.emacs.bup")
            (require 'rc-set    "~/.emacs.set")
            (load "~/.emacs.keys.el")
            (require 'rc-font   "~/.emacs.font")
            (load "~/.emacs.hooks")
            (load "~/.emacs.gnus5")
            (load "~/.emacs.std-pkg")
            (load "~/.emacs.pkg")
            (load "~/.emacs.tips")
            (add-hook 'mail-mode-hook
                      '(lambda () (require 'rc-mail "~/.emacs.mail")))

        Both `require' and `load' commnds have been used: you use the
        `require', if you don't expect that the file will change during
        your emacs session and you use `load' if you expect it to
        change. If you would call

            M-x load-file ~/.emacs

        Only the `load' command's files would be loaded again. All the
        `require' files would have been skipped, because the `rc' resource
        features had already been defined.

        Okay, loading all these files, either with `require' or `load',
        takes too much time when you start Emacs; it is time to activate the
        delayed loading. Your emacs looks like this after some rearrangements

            ;; .emacs -- Emacs startup controller
            ;; We want to have these minimum features immediately available

            (require 'rc-path   "~/.emacs.path")
            (require 'rc-bup    "~/.emacs.bup")
            (require 'rc-set    "~/.emacs.set")
            (load "~/.emacs.keys.el")

            ;;  Load this setup when I start composing mail.

            (add-hook 'mail-mode-hook
                      '(lambda () (require 'rc-mail "~/.emacs.mail")))

            ;;  But we can afford loading these later

            (defconst tilo-:load-list
              '(("~/.emacs.font"    'rc-font)
                ("~/.emacs.hooks"   'rc-hooks)
                ("~/.emacs.gnus5"   'rc-gnus5)
                ("~/.emacs.std-pkg" 'rc-std-pkg)
                ("~/.emacs.pkg"     'rc-pkg)
                ("~/.emacs.tips"    'rc-tips)
                ("~/.emacs.mail"    'rc-mail)
                ))

            ;;  Byte compile this and the require is fast.

            (require 'tinyload)

        Whe you load this .emacs, only the most necessary files are loaded
        and your Emacs is up very fast. When the `tinyload' finds that
        your Emacs is idle it loads all the rest packages you defined in
        the `tilo-:load-list'. As simple as that.

          NOTE: Please pay attention to one detail above. The ~/.emacs.mail
          will be loaded from load list _and_ it will be loaded when
          you call M-x `mail'. Do you believe there is redundancy? The
          idea is that you may call M-x `mail' way before the TinyLoad
          reaches that file in its load list and the hook guarrantees that
          you get the setup at mail invoke time.

          But it may be the other way round: TinyLoad has already loaded
          the mail setup for you and thus invoking M-x `mail' is fast,
          because there is nothing to load any more.

          Similar things you should do to GNUS, VM, RMAIL and others that
          you call and whose setup you want to have immediately available

        For more complex setup, refer to end of this source file, where I
        have attached my personal setup.

    Delayed loading, require and autoload

        Above you saw how to load your Emacs `rc' files. But the delayed
        loading is not only suitable for those. It also helps you to load
        files, that can't be autoloaded.

          If you can arrange loading a packages with `autoload' command,
          do that. Never put `require' or direct `load' command into your
          Emacs `rc' file, because load commands eat start time.

        Well defined package explain in the *installation* section two ways
        how to load it: here is an example from tinytab.el

            (require 'tinytab)

            or use this; your .emacs is read quicker

            (autoload 'tit-mode              "tinytab" t t)
            (autoload 'tit-return-key-toggle "tinytab" t t)

        The first way forces loading the file (takes time); and the latter
        only tells that the package's functions `tit-return-key-toggle' and
        `tit-mode' exist. If you happen to call those functions, _only_
        then the package gets loaded. The big difference here is that when
        you put the latter in your Emacs rc file, Emacs reads it 20x faster
        than the `require' command.

        It is not always possible arrange loading package with autoloads,
        because the package may behave so that in order to get the features
        installed, package must do the setup by itself: you can't do it
        yourself as in autoload case. Here are few packages that can't be
        autoloaded:

            tinymy      -- collection of utilities
            fdb         -- Emacs Debug error filter
            fa-extras   -- Filling extras
            suggbind    -- Command reminder

        When you would normally include a `require' command into your Emacs
        `rc' file, you can now move the package to load list and keep
        only autoloads in the `rc' files.

            ;; Old .emacs.pkg.el rc file

            (autoload ....
            (autoload ....
            (require 'fa-extras)
            (autoload ....

            ;; New .emacs.pkg.el rc file

            (autoload ....
            (autoload ....
            (autoload ....

        And the missing entry has been moved to `tilo-:load-list'.

    Use separate rc file for load definitions

        It may be good idea to make a separate `rc' file that only has
        the load list definition and a call to tinyload.el, like this:

            ;; .emacs.tilo.el -- load definitions for tinyload.el
            ;;
            ;; If you compile this file, defconsts shuts up ByteCompiler

            (defconst tilo-:load-list
              '(...
                ...
                ))
            (require 'tinyload)
            (provide 'rc-tinyload)
            ;; End of file

        And then you add following call to your .emacs, to the end
        of the file Id assume, while the place really doesn't matter.

            (require 'rc-tinyload "~/.emacs.tilo")

    Timer process used

        A normal timer process is used to load the packages from the load
        list. The timer runs in regular intervals and loads one package at
        a time: more packages are not loaded if there was input pending at
        the time of previous load.

        The load messages are recorded to *Messages* buffer. In Old Emacs
        releases this buffer does not exist; but it will be created for you.

    About implementation

        When you define `tili-:load-list', the value of the variable is
        saved under property 'original. When the idle timer runs, the list
        is read from the beginning and each package at a time is loaded.
        The last unloaded package position is saved under property 'pos.

        The situation looks like this:

            tili-:load-list 'original   --> (list) original contents
            tili-:load-list 'pos        --> (nth nbr) next package to load.

        If your do something in your emacs while the list is beeing looped,
        or when the loader function is about to be called, that interrupts
        the work. Next time the timer funtions run runs, happens:

        o   It checks if the current list matches 'original. Yes, means that
            the list hasn't been modified. No, means that it should examine
            the list all aver again, starting from the beginning.
        o   If the list was original, it picks the 'pos point and
            loads all the remaining packages, one at a time until it
            sees activity.
        o   If there is nothing to load, the 'pos points to the end
            of list. Function returns immediately and does nothing.

    Force loading

        There is also property 'fatal-list which contains entries that
        couldn't be loaded. The list is updated while the loading takes
        place. If you examined the failed files and made some corrections;
        you can try to reload the whole load list again if you call

            C-u M-x tilo-loader-process

    Restart

        If you want to restart the evaluation of load list, call `M-x'
        `tilo-install', which will install the package again by removing
        old processes and resetting counters.


Tinylock.el -- Simple emacs locking utility

    Preface, feb 1995

        This is again one of those 'tiny tools' I came up with time to
        time. It was inspired by a post to gnu.emacs.help group where
        someone asked for emacs locking capability. Two years ago I did
        similar terminal locking shell script, but I never thought it
        would be nice for emacs too.

        I had a sketch of what to do 2 months ago, but I was so busy I
        never completed this el. So I couldn't post the answer to person
        asking for the locking capability.

        I find this usefull, when I'm leaving my work place and want to set
        my emacs in consistent state, so that no-one accidentally messes my
        C++ project files. I normally leave all xterms and emacses open
        during the weekend and anyone may use my X-tube meanwhile. And
        nowadays when I use PGP I appreciate that I can lock my mail
        buffers and PGP pass phrases inside emacs safely when I go
        somewhere else for a while.

    Overview of features

        o   Locks emacs completely until right key is entered.
        o   Auto-locks emacs after NN minutes idle time
        o   False login attemps are stored in history log.
        o   Blanks display or displays message buffer when locked.
        o   Hooks: before and after lock is activated and removed

    About locking procedure

        Don't get shocked now... When the lock gets in effect there must be
        no running processes inside emacs that would generate error and
        make emacs vulnerable to break in's.

        That's why all the running processes are killed before the lock
        takes in effect. If you have some valuable processes that are
        constantly running, you must make a separate "process control"
        function that would restart any such processes. Use the appropriate
        hook to activate those processes again after the emacs is
        unlocked. Use hooks

            til-:before-lock-hook       ;; Save processes here
            til-:after-lock-hook        ;; restore processes here

        and following function which tells you what processes are running.

            M-x list-processes

        All extra frames are also deleted. At least for now, because I
        don't know a reasonable way to save the frame configurations
        right now. Please send me piece of code or pointer to package
        that can save and restore frames and the windows back to previous
        state if you know good solution.

    About auto locking feature, Emacs prior 19.34

        When you load this package the `til-:load-hook' runs
        `til-process-control' command that setup up a timer process that
        wakes up periodically. If the emacs has not changed compared to
        last saved emacs state, then the auto locking takes in effect
        immediately.

        In old Emacs the activity is determined in simple way

        o   if buffer list order has changed user is doing something.
        o   if `switch-buffer' was used, user is doing something
        o   if any buffer's size has changed, user is doing something.

        This checking may not be anough in somes: if user just scroll some
        text in buffer for NN minutes, then from `til-process' 's point of
        view there has not been any activity and the user may suddenly
        notice that emacs locks up. Doing nothing but viewing one buffer
        all the time is fortunately rare.

    About auto locking feature in new Emacs

        New Emacs releases have command `run-with-idle-timer' which we use
        if it is available. When there has been no activity for NN minutes,
        your Emacs locks up.

        The advice code and the other tricks we needed to detect idle
        activity in lower emacs versions aren't installed in these Emacs
        versions, so you don't have to worry about sudden lock.

    Auto lock password

        Do not put password in your ~/.emacs, but answer to the question
        which is asked when this file is loaded. If you want to change it
        during your emacs session, call function

            M-x til-auto-lock-set-password

    Changing the auto lock interval

        The auto lock interval depends on the wake up time of timer
        process. The default time is 20 minutes when you load this
        file. You can change the time by calling

            M-x til-auto-lock-set-interval

        Or by putting this code in your ~/.emacs

            ;; First define the hook, so that we can append to it
            (setq til-:load-hook
               '(til-timer-control til-auto-lock-set-password)

            ;; add function to the end
            (add-hook 'til-:load-hook 'my-til-auto-lock-set-interval 'append)


            (defun my-til-auto-lock-set-interval ()
              "Change interval to 10 minutes."
              (til-auto-lock-set-interval 10))
            ;; end of example


Tinylpr.el -- Easy Emacs lpr command handling, popup, completions

    Preface, 1996, overview of features

        o   Managing printers or print styles easily
        o   Queue information
        o   Has ready X-popup example to select print styles etc.
        o   Echo menu provided to select printing advice:

            TinyLpr: 01c2 r)egion b)uffer l)ine numbers d)printer
                     Q)ueue s)tyle >P

        o   Ps print support in another `P' echo-menu:

            TinyLpr: 01c2(ps) rR)egion bB)uffer sS)Spool d)espool

    Story behind this package

        Long time ago, I get frustrated that in out environment there
        existed dozen printers and also I had dozed ways to print the
        file. In HP-UX there exists many printing related commands:

            mmpage       multi-page 1-8, like sunOS enscript
            lp
            lpr
            a2ps
            squeeze.awk  my own empty line squeezer. Ever run CPP on C/C++ ?
            groff        I make some nroff files...
            banner       big letters
            lpstat
            col -bx      remove ctrl codes from man pages
            pps          pretty printer for PostScript -- jau@tut.fi
            pr           format files
            fold         fold long lines for finite width output device
            adjust       for filling, centering, ..justifying

        If I wanted to print the file in some other format, ie combining
        some of the commands I had to go and chnage the

            lpr-switches

        every time. That was real tedious. And I stopped that after first
        experiments. Instead I made nice popup menu to emacs where I could
        see lpstatus, select print command, cancel print job etc...


Tinymacro.el -- Fast way to assign newly created macro to key

    Preface, 1995

        Started as a very little project when <mosh@ramanujan.cs.albany.edu>
        (Mohsin-Ahmed) 1995-03-17 in gnu.emacs.help post asked for easy way
        to assign newly created macro to some key.

        I sent a reply, where I had made simple function to do such thing,
        unfortunately Mohsin bounced me and complained that it didn't work
        right and that he didn't want only one macro, which was recycled
        every time. I had sent code which used only one, and the same
        function name every time it was called, effectively erasing the old
        macro.

        I started twisting the code little bit, and so I finally came up with
        this package, which uses user configurable macro-name-functions.

    Description

        o   Two keystrokes to make a macro: one to record, one to
            assign it to key.
        o   To see the macro assignments to keys, just call `tim-macro-info'
        o   Default macro count is 10, but you can increase it with `tim-:stack-max'



Tinymail.el -- Some mail add-ons. Report incoming mail, TAB complete

    Preface, Apr 1996

        This mail composing helper functions have been with me over a year
        or so but and I finally decided to put them to a nice package.
        Hope you find use for this 'tiny tool' too and don't
        hesitate to drop me a mail if you know more nifty things that
        I could add here to improve this package.

    Overview of features

        o   Generate sendmail PLUS emulated address: login@domain (Mr Foo+info)
            Works like real sendmail PLUS addressing:
            login+info@domain (Mr Foo)
        o   Generate anti-ube addresses to prevent UBE from arriving to your
            mailbox.
        o   Some handy additions to mail sending interface.
        o   `X-Sender-Info' field is generated while you type To address.
        o   Changes Fcc dynamically according to header content.
        o   Very easy TAB completion: two modes, alias and definition string.
            Also completes password file entries if your .mailrc doesn't
            have match.

        o   Easy interface for completing field with TAB. Eg completing
            Followup-To/Gcc/Newsgroups and any user defined field; like
            Class or Priority
        o   Fcc/Gcc folder can have compression extension .gz or .Z
        o   Customizable TAB key. You can use tab for other purposees
            in other headers than Cc/To where it completes email addresses.

        o   Mail, GNUS 4/5 message, VM, MH compatible.
        o   MIME support: turns on Multipart sending if buffer size is
            bigger than 50K. (this is just an example function) for
            `timi-:post-hook'.

       BBDB supported

        Search BBDB for partial matches when you complete To and Cc
        fields in header. Eg if you remember person's address, "site" or
        something, hit just TAB and all found `Net' field completions
        are offered.

        Notice that you have to _manually_ add Eg full
        user name, phone number, whatever to the Net Field on order to
        complete to those items. The default `:' command adds only
        this:

            Foo Bar
                 net: abc@example.com

        An in order to make that usefull for completion purposes, you need to
        modify the field with `C-o'

            Foo Bar
                 net: Foo Bar - Head of Skyscraper inc. <abc@example.com>

        Now you can complete to any word found in the `Net' line.

    Installation note

        This package installs itself to `mail-setup-hook' and you should
        know why if you try to get the package running for some other
        mail agent that Emacs mail, RMAIL, GNUS and VM where this pacakge
        has been tested.

        The `mail-setup-hook' is called *after* the basic headers, like
        To and Subject, are already in the buffer. Function `timi-mail'
        needs to read the contents of To in order to determine how
        it starts (it puts 1 or 2 spaces at the beginning of To field at
        the initial start, so that the pacakges Cc control is started
        right. When you call simple mail, C-x m, the auto Cc feature is on
        (1 space) and when you hit reply, the auto Cc feature is off
        (2 spaces).

        So, if your mail agent doesn't call `mail-setup-hook', find similar
        hook that runs after the headers are in the buffer and install
        to that hook `timi-mail'.

    Completion: Guess Completion feature

        There are two basic completion modes: 'alias and 'string,
        which is selected via `timi-:complete-mode'. They refer to
        your ~/.mailrc definitions:

            alias Peter-Pan     "Disney character -- <ppan@disney.com>"
                  |             |
                  alias mode    string match mode

        when you hit the completions key (TAB in headers) the current
        word is picked at point and searched from either of these two
        definition lists.

        Since the alias expansion is familiar to everyone, I'll only explain
        the latter. It is very powerfull completion indeed. Say you
        have this in your ~/.mailrc

            alias tweedle "Mister Foo, Skyscraper Doing co. <foo@company.com>"

        Then you start composing a message. The lines 1-4 present what
        possibly you can type into the To: field before you hit the
        comletion key, TAB.

            1  To: company
            2  To: Foo
            3  To: sky
            4  To: mister

        It doesn't matter what you type initially; it can be anything you
        remember from the person's definition string. At this point you
        call `timi-complete-guess' key, TAB, and any of those lines, 1-4,
        will be replaced with

            To: Mister Foo, Skyscraper Doing co. <foo@doing.com>

        Easy? Yup, and if there are more matches to, say "foo", you're offered
        a completion list of alias names, where you can pick exact match.

        You no longer have to remember "exact" alias names, It's enough
        if you remember "something" that belongs to person's definition:
        email, surname, firstname, domain part....

       Accepting the found match from .mailrc

        TinyMail supports running several completion function so that
        the right match is inserted into the buffer. In order to
        discard the found match from .mailrc file, you can set a trigger
        to `timi-:confirm-mailrc-regexp'. Suppose, you want to confirm
        completion whenever you are sending mail to your collegues that
        work in "disney.com". You'd set:

            (setq timi-:confirm-mailrc-regexp "disney.com")

        And if the match was picked from mailrc, you have a chance to
        reject the string and move on with other completion functions.

            To: world

        When you hit tab here, a string "info@disneyword.com" was found from
        the mailrc, but that's not what you want to insert and because
        you had set timi-:confirm-mailrc-regexp, you get confirmation:

            TinyMail: Use? info@disneyword.com

        Which you answer "n". The completion was cancelled and all
        other function in the Shared Tab key have a chance to find more
        suitable choice. (See Shared tba key explanation later)

    Completion: Password table

        In addition to .mailrc completion, there is support for completing
        entries found from *passwd* file. If the Guess complete above fails
        the password file is examined if the mode is turned on. See
        variable

            timi-:password-mode

        Which is set to t by default. When you complete password entries
        for the first time, building all necessary variables will take
        some time. This is normal and you have to live with that.

        Once the password file completions have been parsed, the content
        is written to cache file

            timi-:password-file

        Next time you need password completions, if this file exists,
        it will be read insted of heavy /etc/passwd file parsing. If you
        want to force reading the /etc/passwd again, just delete that file
        and it will be recreated next time passwd completion is used.

    Completion: Custom completion of any header

        You can complete any fild by setting variable
        `timi-:table-header-complete' For example to complete two header,
        you would set the variable like this. See variable documentation
        for more information.

            (set-alist
             'timi-:table-header-complete
             "Class"                ;; Add new header with completion list
             '("confidential"
               "private"
               "for internal use only"
               "personal private"
               "personal another"
               ))
            ;; end example

    Minor mode: basic information

        Emacs clears `post-command-hook' in case of errors and in response to
        too many `C-g' keypresses and this causes TinyMail to die, because
        it is sintalled in the hook. To reinstall the hooks, you call

            C-c t m

    Minor mode: To field tracking

        While you're composing message, this package awakens in
        regular basis and checks your To: field's content. If it finds
        anything to do, it adds some more fields to your message.

            To: foo@bar.com             <-- let's assume this triggers

        Result is:

            To: foo@bar.com
            X-Sender-Info: Jerry Foo. 21st, NY, p. 222-333-444.

        As soon as the X-Sender-Info tracking is done, the To-field
        content is saved. When the tracking awaken again, it *checks* if
        the To-field content has changed against this saved value. If it
        hasn't, nothing is done.

        This means, that you *can* modify the contents of X-Sender-Info
        field after the post command function has finished. If you later
        want to force it to track the headers again, change the To-field
        contents somehow (add space to the end...)  and this gives a signal
        that to-field has changed.

    Minor mode: Fcc field tracking

        By default the Fcc is not added in your mail message, thus the
        automatic Fcc tracking doesn't get activated. Add following entry
        into your emacs to record your outgoing mail messages

            (setq mail-archive-file-name "~/.RMAIL.out")

        When Emacs sees that you have set this, it adds the Fcc field to
        your mail message. Alternatively you can press keys

            C-c C-f C-f    ;; mail-fcc

        in *mail* buffer and it asks you to insert the Fcc field.  Only
        now, when the Fcc is in the message, the automatic Fcc handling
        starts snooping around your headers and changing it if it finds a
        match from variable

            timi-:table-fcc

        If you want to disable Fcc changing (and edit it by hand),
        put two spaces at front of the Fcc. like this:

            FCC:  ~/.RMAIL.secondary
                ^^

       Fcc and saving outgoing copy in compressed format

        If you have an ccount that has quota limits, you want to save space
        as much as possible. You can save your outgoing mail copy in
        compressed format if you prepend the filename with ".gz" or
        ".Z". TinyMail will automatically load jka-compr if it sees any of
        those extensions. The fcc folder definition looks like this.

            (defconst timi-:table-fcc
               (list
                (list "elisp-archive"    " ~/.mail.elisp-post.gz")
                (list "bug-gnu"          " ~/.mail.bug.gz")
                (list "."                " ~/.mail.out.gz") ;; general
                ))

        The `my-z' function adds ".gz" into the filename if you have enabled
        the compression. The implementation of the `my-z' function is
        presented in the end of the file. You can use it to construct other
        filenames as well. You _have_ to add (require 'jka-compr) is you
        want to use compresses RMAIL file.

            ;;  first one is defined in paths.el
            (setq rmail-file-name        "~/RMAIL.gz")
            (setq mail-archive-file-name "~/.RMAIL.out.gz")

    Minor mode: Gcc archiving in Gnus

        Gcc featuire is similar to Fcc, but the Gcc is special in GNUS 5
        newsreader. All instruction you read above about Fcc are same for
        Gcc tracking feature. The only table you have to configure is

            timi-:table-gcc

        Before you start defining Gnus folders; you must create them to
        Gnus from *Group* buffer with commands G m. Eg. I have created
        following Gnus folders for newsgroup posting

            nnfolder+archive:post-pgp
            nnfolder+archive:post-emacs
            nnfolder+archive:post-gen

        Which are used when I hit F key to answer to message. [See setup
        below] You might wonder "...if I use code below and TIMI; what
        happens?". The code below sets the Gcc folder only once when you
        start composing message, propably a followup and there is a
        `Newsgroups' header in the buffer. But if you hit R r to reply
        directly to person (or use message-mode for mailing), there is `To'
        header in the buffer. Only now TIMI changes the Gcc field according
        to `To' field contents.

        The code below is for Newsgroup posting, TIMI, in the other hand is
        for private mail handling.

            (setq gnus-message-archive-group 'my-gnus5-archive)

            (defun my-gnus5-archive  (group)
              "Achive outgoing mail to right group: Create the group by G m"
              (interactive)
              (let* (
                     )
                (or (stringp group)                 ;No accidents...
                    (setq group ""))
                (cond
                 ((string-match "pgp\\|anon\\|privacy" group)
                  (my-z "nnfolder+archive:post-pgp"))
                 ((string-match "emacs\\|gnu" group)
                  (my-z "nnfolder+archive:post-emacs"))
                 (t
                  (my-z "nnfolder+archive:post-gen")
                  ))
                ))
            ;;


    Feature: Sending message to mailing list

        In Gnus you may have defined mailing lists like this

            list.linux-announce
            list.ding
            list.java

        And your personal work and mail groups with

            mail.private
            mail.misc

            work.documents
            work.fault
            work.customer

        And so on (daemon messages to junk.daemon, Spam to junk.spam ...)
        Now suppose you are reading group list `list.xxx' and you hit `f'
        to send followup to an article. Your composed message looks like this:

            To: Artile-posted-by-person-foo  <foo@bar.com>
            Cc: some-list-member,  <list-xxx@listmanager.service.net>

        The Message goes to two people in the list and get's CC'd to
        list. Not what you want. You want simple:

            To: <list-xxx@listmanager.service.net>

        And this is what TinyMail does for you. All you need to do it to
        make sure the current list group has Group parameter `to-list'.
        defined. You add one with G p From *Group* and typing

            ((to-list . "The List NAME <list-foo@bar.com>"))

        This feature is controlled by `timi-:feature-hook' which contains
        function `timi-mail-send-to-list'. If you remove the function from
        the hook, this feature is disabled

    Feature: Reporting incoming mail in local mail spool

        Function to control mail reporting:

            turn-on-timi-report-mail
            turn-off-timi-report-mail

        When you load this package a Report Mail feature is activated.
        If you're running windowed Emacs, the X-dragbar (top of the frame)
        is used to display the last incoming mail and count of pending
        unread mail. Here the last message was from Mr. foo and the
        pending mail count in spool is six.

            "foo@bar.com 6" ;; See variable `timi-:report-format-string'

        In non-windowed Emacs this same information is displayed in echo
        are instead. If you would like to have it always displayed in
        echo are, even in X envinronment, then set variable
        `timi-:report-window-system' to nil before loading this package.

        If you would like see more infomation about the arrived mail, you
        can adjust `timi-:report-spool-buffer-control' eg. to keep
        permanent record of incoming mail. Value 'keep says that the report
        mail buffer is kept when mail is queried, so you can glance it from
        time to to for full information about arrived messages.

        If the only feature you want is the mail reporting functionality,
        you can activate it and disable all other settings with:

            (setq timi-:enter-mail-hook-list nil)  ; Don't activate timi-mode
            (require 'tinymail)

       Setting up report mail notify program

        The `timi-:report-mail-notify-program' feches the Berkeley Mailbox
        formatted information from mailboxes. The default program used
        is from(1), but in case you don't have it, a equivalent command
        "grep '^From ' $MAIL" is used. See also frm(1)
        and nfrm(1) newmail(1) mailfrom(1) if you can use them in your system.

        If you use Gnus and separate spool files, like you do with Procmail,
        then you need to gather all the information from the spool files.
        Let's suppose you don't want to know about mailing list messages,
        but only messages saved to your private and work spool files:

            ~/Mail/spool        or nnmail-procmail-directory
            mail.misc
            mail.private
            mail.programming
            mail.emacs
            mail.java
            ...

            work.meetings
            work.docs
            work.customer
            ...

        In that case you have to install custom mail notify program. A
        simple multiple mailbox grep will work here. Note, we also grep
        default MAIL:

            (setq timi-:report-mail-notify-program
              (format
                "grep '^From ' %s %s %s "
                (or (getenv "MAIL") (error "No $MAIL defined"))
                (concat (expand-file-name "~/Mail/spool/") "mail.*")
                (concat (expand-file-name "~/Mail/spool/") "work.*")))

        Take a look at variable `timi-:report-spool-buffer-control' which
        has default value 'keep where the `timi-:report-mail-notify-program'
        results are gathered. You may find it usefull to keep the
        `timi-:report-spool-buffer' *timi-mail-spool* visible in some
        distant frame to act like biff(1). From there you can find more
        detailled information of incoming message queue, than the simple
        message count in echo-area or x-dragbar.

        _Note_: XEmacs has package `reportmail.el'. In case that package
        is loaded, the report mail feature here is not installed.

    Feature: TM/SEMI MIME support

        When you're sending a big message and you have Tm mime-edit
        mode active, the split flag will be turned automatically on
        if the message size exceeds `mime-editor/message-default-max-lines'
        You will see odeline indicator "SplitN", where N is approximated
        count of the splits. If you don't want to send split message
        (you really should to save network capasity), then you have
        to turn off the split flags: `mime/editor-mode-flag'.
        Use frunction `timi-tm-editor-toggle-split-flag' to toggle the flag.
        _Note_: "split1" means that there is only one message to be sent, if
        it says "Split2", then approx. 2 parts will be sent.

    Feature: Saving unused mail buffers on Emacs exit

        This file installs one function to `kill-emacs-hook' that loops
        through all mail buffers and appends the buffer content to

            timi-:dead-mail-file

        If you had some unfinished messages that you didn't yet send, you
        can restore the copy from this file when you restart emacs again.
        By default function `mail-send-and-exit' is adviced so that when
        you send mail and hit C-c C-c the *mail* buffer is not buried, but
        killed (ie. there is no dead mail in your emacs when you send
        them). In gnus 5 message-mode, you hsould also use following to
        trash sent mail

            (setq message-kill-buffer-on-exit t)

        If you don't want to use this feature, add following command to
        your .emacs

            (add-hook 'timi-:load-hook 'my-timi-:load-hook)
            (defun my-timi-:load-hook  ()
              (remove-hook 'kill-emacs-hook 'timi-save-dead-mail))
            ;; End

        _Note_: VM keeps the sent mail buffer around. This package won't
        install `timi-save-dead-mail' if VM is already present when package is
        loaded. If you load TinyMail first and VM afterwards, the hook got
        installed at the load phase of TinyMail. If you're a VM user, you
        may prefer the above suggestion where `my-timi-:load-hook' makes
        sure the hooks is not there.

    Feature: anti-ube email addresses

       Philosophy

        Changing the email address so that is is not pointing to your natural
        address is usually referred as "address munging". There are two schools
        that take firm position to express their views in this matter. Those
        who say that it is "plain wrong to munge address" and those who say
        "RFC does not require you to use REAL, returnable, address". I'm
        from the non-purist side and I think that the email address is property
        of an individual who take measureres to protect himself from getting
        into the email harvester's "2 billion email address on a CD rom for
        $100"

        To clear your mind from doubts whether it is right to munge the
        address according to RFC hear [1997-11-05 gnus.emacs.gnus,
        Marty Fouts]:

        o   The real implementation of news software doesn't care if the from
            field is munged or not
        o   No RFC forces the address of the poster to be a *reachable* addr.
            It only requires such addresses to be syntactically correct.
        o   RFC 1036 _specifically_ states that it is not an internet
            standard.
        o   netnews is a *public* forum. mail is a *private*
            communication medium. Posting in a _public_ forum does not
            require that I give you access to _private_ address, just as
            speaking at a public meeting does not require that I give you my
            unlisted phone number.

       Why munge From address

        o   Email address is one's own property. The reasons to munge are
            one's own.
        o   Filter solution is no-road. It's an arms race; some UBE always
            sneaks through and it will never stop the actual UBE.
        o   Not all people have access to filtering tools (eg. Unix Procmail).
        o   POP users download their post and each UBE byte costs in transfer
            time.

        NOTHING WORKS AS WELL AS *NOT* GIVING THE REAL ADDRESS IN THE
        FIRST PLACE.

        With TinyMail you can ativate the address munging very easily
        for selected newsgroups and make those email harverters gatehering job
        more difficult. Human's that want to contact you can still decode the
        address if they want to talk to you direct.

        To activate address munging for newsgrus matching regexp, set variable
        `timi-:from-anti-ube-regexp'. Your `user-mail-address' is be hahsed
        and different adderss is generated every time.

            me@here.com   --> me.ads-hang@here.com, me.hate-ube@here.com ...

    Feature: Sendmail Plus Addressing (introduction)

        [excerpted from Procmail tips, pm-tips.txt, for background]

          Recall from [rfc1036] that the prederred Usenet email address
          formats are following

                From: login@example.com
                From: login@example.com (First Surname)
                From: First Surname <login@example.com>

          A new sendmail supports plus addressing, where the address is
          treated like <login@example.com> and the extra "plus-info" is
          available eg to procmail or other LDAs. See Eli'd faq for more
          information at http://www.faqs.org/faqs/mail/addressing/ A typical
          sendmail enabled plus address looks like:

              login+plus-info@domain

          We can simulate plus addressing with pure RFC compliant address. We
          exploit RFC comment syntax, where comment is any text inside
          parentheses. According to Eli's paper, comments should be preserved
          during transit. They may not appear in the extact place where
          originally put, but that shouldn't be a problem. So, we send out
          message with following `From' or `Reply-To' line:

              first.surname@domain (First Surname+mail.default)

          Now, when someone replies to you, the MUA usually copies that
          address as is and you can read in the receiving end the PLUS
          infomation and drop the mail to appropriate folder: `mail.default'.

          [About subscribing to mailing lists with RFC comment-plus addess]

          It's very unfortunate that when you subscribe to lists, the comment
          is not preserved when you're added to the list database. Only the
          address part is preserved. I even put the comment inside angles to
          fool program to pick up everything between angles.

              first.surname(+list.linux)@example.com

          But I had no luck. They have too good RFC parsers, which throw away
          and clean comments like this. Eg. procmail based mailing lists, the
          famous `Smartlist', use `formail' to derive the return address and
          `formail' does not preserve comments. The above gets truncated to

              first.surname@example.com

          You can put anything inside RFC comment and do whatever you want
          with these plus addresses. _NOTE_: there are no guarrantees that
          the RFC comment is preserved everytime. Well, the standard RFC822
          says is must be passed untouched, but I'd say it is 90% of the
          cases where mail is delivered from one server to another, it is
          kept.

          Example: if you discuss in usenet groups, you could use address

              first.surname@example.com (First Surname+usenet.default)
              first.surname@example.com (First Surname+usenet.games)
              first.surname@example.com (First Surname+usenet.emacs)
              first.surname@example.com (First Surname+usenet.linux)

    Feature: Sendmail Plus Addressing in TinyMail

        The idea of setting PLUS information is that you "tag" you messages
        and when thay are returned to you, you can file the messages to proper
        folders. For me the  my procmail traps the plus infomation and files,
        but you can make Gnus to store the messages too by using fancy
        splitting.

        The sender field generation is disabled in `message-mode-hook'
        by function `timi-message-disable-sender', so that From field is
        trusted. If you still want to generate the *Sender* field, then
        add this after package has been loaded.

            (remove-hook 'timi-message-disable-sender 'message-mode-hook)

       Non-Group posting

        Use your custom function to decide that address to use and what plus
        information to use bt setting function to `timi-from-info-function'.
        Non-Group posting means, that your're not inside ant Gnus Newsgroup
        from where you initialte "post". A typical invocation to no-Group
        posting is C-x m.

       Newsgroup posting

          You might want to set `timi-from-info-function' return different
          email address for usenet newsgroup posts. Order some free email
          address and use that for Usenet discussions.
          That way you can reserve your normal address to your private
          email communication.

        The settings you need to enable the address generation is quite
        basic. Table `timi-:from-table-prefix' sets the left part of the
        plus address component and `timi-:from-table-postfix' can set the
        right part after period.

            timi-:from-table-prefix + timi-:from-table-postfix

        forms the  "+left.right" information added after your
        `user-full-name' part. If `timi-:from-table-prefix' returns
        nothing, the `timi-:from-table-postfix' is used as is.  Here is
        example setup. Pay attention to the "work.misc" which is sole return
        value for all addresses matching "my-work-site".

            (defconst timi-:from-table-prefix
              '(("emacs\\|perl" . "mail")
                ("."   "usenet")
                )
            ;;

            (defconst timi-:from-table-postfix
              '(
                ("games"                                 . "games")
                ("emacs\\|[a-z]+\\.el\\>\\|(def\\|(setq" . "emacs")
                ("perl\\|\\.pl\\>"                       . "perl")
                ("my-work-site\\>"                       . "work.misc")
                )
            ;;

       Gnus support

        If you use Gnus as a newsreader, then you get sme bonus. There are lot
        added value for gnus users so that the default plus information is
        generated based on the group you're posting from. In genral the
        plus address generated is directly the group's name. That's quite
        convenient.

        Mailing lists:

        o   Rename all your mailing lists to start with convertion "list.NAME"
            like list.ding, list.linux, list.procmail, list.dance ...
        o   Edit each mailing lists group parameter with G p from *Group*
            buffer and add mailing list destination address address

                ((to-list . "Mailing List Name <address@domain>"))

        Now when the `to-list' property is set, The Gnus group is labelled
        as "mailing list". If the `to-list' property is not set, the group is
        not considered as mailing list.

    Configuration: Post command and Faster response

        The post command takes a nap regularly and when it awakens, it ;;
        checks what has happened to headers. If you feel that the response
        time ;; is too slow, you can change the value

            timi-:awake-time

        You must remember that the more smaller the time is, the more often
        the post command is run. This means that whenever you hit cursor
        down to move around the buffer, the more likely you see that the
        cursor hangs or doesn't move very quickly. It takes some time to
        run the post-command, so it is not recommended that you use too low
        value.

        Please use PgUp and PgDown keys instead to move over big buffer
        portions to avoid cursor hang effect.

    Configuration: Highlighting colour settings

        The default highlighting is only provided to your convenience. If
        you use `font-lock' the internal highlighting is *automatically*
        suppressed.

    Configuration: Default citation header

        In this packge you find function `timi-citation-generate' which
        generates citation that uses international iso8601 date format,
        user name and the Gnus mailing group from where you're replying

            * Tue YYYY-MM-DD John Doe <johnd@example.com> mail.emacs
            | ...said something

        to activate this citation refererence function with your Mail User
        Agent (Gnus, RMAIL ..), call:

            (add-hook 'timi-load-hook 'timi-install-citation)

        For supercite, you install this function to the handlers and
         select it with index 0.

            (require 'sc)
            (push (list timi-citation-generate) sc-rewrite-header-list)
            (setq sc-preferred-header-style 0)

    Code Note: Shared TAB key

        When TinyMail is active in the mail buffer, it takes ower your tab
        key. The default function `timi-complete-guess-in-headers' is
        electric, meaning that it behaves like ordinary tab if the point
        is not in Cc or To headers. If the point is in C or in To, then
        the completion feature is activated. If you have plans to use the tab
        key to do some other special things in other headers, you're free to
        to do so. All you have to do is to add your own custom function
        into

            `timi-:complete-key-hook'

        and have it return `t' if your function did something. See also
        `timi-:table-header-complete' where you can define custom headers and
        the completions easily.

    Examples

        Look at the end of this file for examples I may have attached.


Tinymbx.el -- Berkley style aka std. mailbox browsing minor mode

    Preface, sep 1997

        I started using Procmail to manage my growing incoming mail and when
        it stuck the messages in different folders I was in trouble. I
        used to direct UBE, UCE and Spam mail to different folders, but
        sometimes my procmail filter just guessed wrong and it put
        perfetly valid file into one of these reject folders.

        Whan, I had to manually check each time if there was some
        some valid message lurked into these mailboxes and then extract
        it out of there. Not very nice job to do. I didn't have Slick
        GNUS 5 at that time looking at the folders and managing my mail
        there so I decided to pull out some code and start making some
        toll for me.

    Overview of features

        o   Browse your standard unix mailbox .mbox .mbx .spool
        o   Kill, copy messages from that mailbox. Copy messaeg bodies.
        o   Font lock, defcustom supported.
        o   Hide or show headers when you browse your mailbox
        o   Simple summaries done with `occur' command. Eg. to browse
            messages based on `From' or `Subject' Headers.

    Showing and hiding headers

        When you browse a email message, it has lot of attached headers,
        which don't interest you at all when you want to look at the
        messages itself. for examples here is one typical header from
        a test message

            From nobody Sun Sep 28 20:57:48 1997
            To: nobody
            Subject: Re: bandwidth (was: [RePol] check this issue)
            References: <tbd8lwmfid.fsf@totally-fudged-out-message-id>
            From: Foo bar <judgeDredd@marylyn.com>
            Date: 28 Sep 1997 20:57:47 +0300
            In-Reply-To: Jeff's message of "Tue, 23 Sep 1997 01:35:26 -0400"
            Message-ID: <tbiuvlmick.fsf@marylyn.com>
            X-Mailer: Quassia Gnus v0.11/Emacs 19.34
            Lines: 3
            Xref: marylyn.com junk-test:4
            X-Gnus-Article-Number: 4   Sun Sep 28 20:57:48 1997

        When you go from this message with `timbx-forward', the headers
        that you're interested in are only shown according to
        `timbx-:header-show-regexp'. The above headers lookes like this after
        processing it:

            To: nobody
            Subject: Re: bandwidth (was: [RePol] check this issue)
            From: Foo bar <judgeDredd@marylyn.com>
            Date: 28 Sep 1997 20:57:47 +0300
            X-Mailer: Quassia Gnus v0.11/Emacs 19.34
            X-Gnus-Article-Number: 4   Sun Sep 28 20:57:48 1997

        By default all the `X-' headers are shown, so you may want to make
        the `timbx-:header-show-regexp' a bit more restrictive if your
        messages have too much X-headers. You can toggle this message
        hiding feature with

            C-q     or timbx-header-hide-mode

    Copying or deleting messages

        When you browse the mailbox, you can perform copy or delete on
        the current message with following commands.

            ' RET   timbx-copy
            ' SPC   timbx-copy-body
            ' d     timbx-delete

    Moving between the messages

        There are couple of movement commands that let you jump from
        one message to another. See also variable `timbx-:move-header-regexp'

            C-p     timbx-forward-body  or Ctrl-home
            C-n     timbx-backward-body or Ctrl-end
            home    timbx-forward       (see timbx-:move-header-regexp)
            end     timbx-backward


Tinymy.el -- Collection user ('my') functions. Simple solutions.

    Preface, Nov 1995

        My .emacs files started to look quite interesting:

            .ema.tips       .emacrs.el      .emacrs.el.b    .emacrs.el.sun
            .emacrs.el~     .emacs          .emacs.18       .emacs.19
            .emacs.19~      .emacs.abb      .emacs.c-fl     .emacs.compile
            .emacs.debug    .emacs.default  .emacs.font     .emacs.ding
            .emacs.font.b   .emacs.gnus     .emacs.gnus.o   .emacs.hooks
            .emacs.init     .emacs.init2    .emacs.ja       .emacs.mail
            .emacs.o        .emacs.o-19     .emacs.out      .emacs.out~
            .emacs.path     .emacs.pc       .emacs.prog     .emacs.set
            .emacs.test     .emacs.time     .emacs.tips     .emacs.vc
            .emacs.w3       .emacs.x-menu   .emacs.xe       .emacs_context
            .emacs.dired..[rest of the files zapped]

        My private functions seemed to grow all the time, most of them were
        turned into packages, but sometimes it was just function or two
        that made my life with emacs easier.

        What you see here is a selection of so called *my* functions. The
        term *my* does not refer to *mine*, but has backround in function
        naming. Remember? all user functions are recommended to be named
        so, that the first word is `my-', like `my-FUNC-NAME-HERE'

    Overview of features

        Timer processes

        o   RMAIL/other buffers saved in regular intervals.
        o   Revert buffer in background and ask confirmation, if file
            has changed on disk. By <duthen@cegelec-red.fr>
            (Jacques Prestataire)
        o   Mail lock watchdog. If you have this lock in your file system,
            you cannot receive mail.

        buffer

        o   Rename any buffer with one key `C-z' `n' to be able to launch
            eg. new *shell* or *mail* buffer.
        o   Scroll command goes to window end/beginning and does not scroll
            immediately. See variable `timy-:scroll-mode' for more.
        o   Trim trailing whitespaces from the buffer when file
            is saved.
        o   Stamp file info when buffer is saved: "Docid:", "Contactid:"
            and LCD package entry fields.
        o   Gzip or ungzip current file buffer.
        o   Add up numbers in rectangle area

        Compile

        o   Guess compile command by looking at the buffer content
            Includes shell scripts "emc" and "mak" to do emaacs
            byte compilation and C/C++ make file compilation.
            Configure variable `timy-:compile-table' and
            `timy-:compile-command-c-code'. The compile commad you
            chose is buffer local and lasts until you change it.

        Files

        o   Toggle write/read-only file permissions on disk with
            C-x q or `M-x' `timy-buffer-file-chmod'
        o   If file saved had #!, it is automatically made chmod u+x.
            Idea and code by Jesper Pedersen <blackie@imada.ou.dk>

        Gnus, mail

        o   Save lisp package in buffer like *mail* to file: find
            package regions.
        o   Copy current buffer's contents to new mail buffer and
            set subject line. You can send diff buffers and file buffers
            conveniently this way: `C-z' `m' (Zend buffer as Mail)

        Keys

        o   Jumps to matching paren {([". _Bound_ to key "%".
        o   Better word movement: LikeThisInC++Mode.
            Moving forward/backward always keeps cursor at the
            beginning of word. See also `c-forward-into-nomenclature'
            _Bound_ to keys `C-left', `C-right' in X and `Esc-b', `Esc-f'
            in non-windowed Emacs.
        o   PgUp and PgDown behave differently; they jump to
            window's beg/end first and only next key hit scrolls.
            _Bound_ to keys `prior' and `next'. Check if your keyboard
            produces another pgUp and PgDown events.

        Line formattting

        o   Fixing all backslash(\) lines in current paragraph to the
            same column as the strting line. Very usefull in makefile mode,
            shell mode or when writing C/C++ macros. It even iserts missing
            backslahes.

        Mouse

        o   Point window and it gets cursor focus: The frame is
            raised and window selected. No need to click window any more.
        o   Show File information in echo-area: Point mouse near
            the end of window and Displayed info contains
            BUFFER MODES SIZE PATH. You do not consume your modeline
            or frame title any more for buffer specific informtion.
            Example output:

                TinyMy: -rw-r--r-- 108k /users/jaalto/elisp/tinymy.el

        Shell

        o   Easy shar/tar/UU commands. configure variables
            `timy-:shar-command' and `timy-:tar-command'

        vc

        o   Key C-x C-q now won't call vc blindly. To prevent mistakes,
            a confirmation will be asked. You can also just toggle the
            buffer's read-only flag, without engaging vc.

        Window

        o   Flip the order of two windows

    Minor modes in this package

       Sort minor mode

        If you have data in columns, use `C-cmS' or `M-x' `timy-sort-mode'
        to toggle sort mode on and off. With it you can sort columns 1-9
        easily. Modeline indicator is "S"

       Display minor mode

        Hotkey `C-cmD' or `M-x' `timy-display-mode'. If you have DOS file and
        you load it into Emacs, you usually see the ^M characters. With the
        display mode active, it hides them from the screen, but they are
        still in the buffer. This display mode will hide other non-ascii
        characters too. See the source if you want to find out the full
        repertoire.

        This display mode is _automatically_ turned on when you load an
        dos-like file that has ^M character at the end of line.
        Modeline indicator is "D".

        Another display maode selection also let's you view MS Word binary
        files in some extent.

    Features immediately activated when package loads

        o   You own Emacs lisp package LCD stamp is updated every time
            you save the package. Configure `timy-:stamp-lcd-regexp'
            to detect your packages.
        o   Your most valuable buffers are periodically saved.
            Configure variable `timy-:save-buffer-modes' and
            `timy-:save-buffer-regexp'
        o   You mailbox lock is kept on eye on, if the lock remains,
            you won't be able to receive mail. (safety measure).
        o   If you use procmail you want to configure
            `timy-:mail-check-inbox-file-permissions'
            otherwise, your mailbox's mode permissions are kept eye on:
            "Permission error: -rw-------" warning will be show if the
            mailbox doessm't have right modes.
        o   Automatic window selection when you point it with moouse cursor.
            See `timy-:install-select-window-auto'.
        o   When buffer that has `#!' to indicate shell
            script, is save, the +x flag is set on for the file.

    What commands are defined when you load this file?

        It's better to look at the code of this file, than to explain all the
        key definitions here, because I may not remember update this
        text section every time I add new interactive commands to the file.

        All the new interactive comnmands can be found from these two
        functions:

            timy-define-keys
            timy-mail-common-keys

        See their description, or alternatively hit

            C-h m                               ;; to view all bindings
            M-x delete-non-matching-lines timy  ;; show timy keys

    Warning

        When you load this package, it install global keybindings that
        *may* (big chance) replace your Emacs or private bindings. Please
        see if you need to rearrange `timy-:load-hook' which now runs
        functions

             '(timy-install timy-define-keys timy-alias)

        Please use this if you want to use your own bindings.

            (setq timy-:load-hook '(timy-install my-timy-keys timy-alias)
                                                 ^^^^^^^^^^^^
            (defun my-timy-keys ()
              )

        There is table of global bindings which you can modify if the
        bindings clash: the auto installl will warn you about this
        automatically and your own bindings are not replaced by default.
        See variable:

            timy-:define-key-table


Tinynbr.el -- Number conversion minor mode oct/bin/hex

    Preface, aug 1997

        One day I was really busy to get my work done in my work's
        laboratory, when I realized that I had forgotten my desk calculator
        back to 3th floor in another building. I had a binary (hex) files
        at front of me and couple of other electronic documents that used
        hex and base10 numbers. I needed my desk calculator badly to
        convert numbers from one format to another. I remembered that there
        was some unix shell calculator, but I really hadn't used it and
        besides, I had forgotten the name of the calculator command. Whups.
        Grin.

        Anyway, instead of running back to get my calculator I made this
        simple minor mode that helped me to get along with the current task
        at hand. It didn't take long to make it, and since then I have used
        it extensively when I browse Technical documents or my C++ code.

    Overview of features

        o   Int         --> hex,oct,bin conversion at current point
        o   hex,oct,bin --> int         conversion at current point


Tinypad.el -- Emulate Windows notepad with extra menu

    Preface, aug 1997

        In gnu newsgroup there was a request that a class had been used to
        using Windows notepad and in order to make the transition to Emacs
        smooth, Emacs should have some notepad emulation mode so that
        pupils wuldnn't get lost completely in new envinronment.

        I thought, "Heck, let's try what can I cook for them"

        And here is it, a small notepad emulation. It installs one new menu
        to Emacs menu bar which is arranged exactly like the Windows
        notepad. I have included only the commands that are directly
        available from inside emacs and eg. 'printer setup' is something
        that is not found there. But in order to be complete emulation, all
        the choices as in normal notepad are available.

        Happy emulating :-)

    Overview of features

        o   Minor mode, but once turned on, occupies every emacs buffer
            until turned off.
        o   Adds menu 'TinyPad' which contains identical
            menu definitions that are found from Winbdows notepad
        o   The keybindings use `Meta' as the Alt key to access the
            menu items, so you may need to configure your keyboard
            with 'xmodmap' in order to get 'Alt' key produce `Meta'
        o   Windows specific commands are not emulated, like
            `Print' 'Setup'.
        o   Following famous windows shortcut keys are _not_
            Emulated; I was lazy and didn't try to reorganize the
            Emacs keys. Erm... for now you have to stick to emacs
            equivalents and live without these.

            Undo   in   Control-z
            Cut    in   Control-x
            Copy   in   Control-c
            Paste  in   Control-v

    Code note

        Why on earth I made this package to use "global" minor mode?
        I can't remember the reason. A simple menubar entry may have
        sufficed just fine.... Oh, it was that remaping the bindings.
        You see, when minor mode is turned on, it conquers the mappings
        underneath.

        [1997-10-23] Hey, I just saw pointer to package Map-zxcv.el which
        takes care oc mapping the missing zxcv, so I don't have to bother
        with those here. Nice. You can ask it from Kim F. Storm
        <storm@olicom.dk>


Tinypage.el -- Handling ^L pages, select, cut, copy, head renumber...

    Preface, jun 1996

        I had found paged.el by Michelangelo Grigni <mic@mathcs.emory.edu>
        one year or so ago and had liked it very much. Unfortunately
        it used narrowing and didn't offer easy page select, copy, cut
        actions which belong to basic page editing.

        Paged.el has one nice feature: It can renumber pages and make summary
        out of them. If I have time I will include those features to
        package too.

    Overview of features

        o   Copy, cut, paste, yank (after/before current page) ^L pages.
        o   Show  page-nbr/page-count/page-size in modeline.
        o   Can renumber numbered header levels, where last level is indicated
            with number. Eg. "A.1 A.2"  or "1.2.1.1 "1.2.1.2"
        o   Shows popup in X to jump to headings
        o   Create table of contents.

    About making pages -- basics

        If you're totally unfamiliar to the concept of page: you make
        pages in emacs by adding the linefeed marker in the text, normally
        on its own line, just before your topics or headings.

            C-q C-l  --> ^L

        That inserts the ^L character in the buffer. That is where your
        page starts. The layout of your doc may look like this:

           ^L
           1.0 Topic one
               txt txt txt txt txt txt txt txt
               txt txt txt txt txt txt txt txt

           ^L
           1.1
                txt txt txt txt txt txt ..

           ^L
           1.1.1.1
                txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt ...


    About renumbering

        This package offers simple renumbering features, but it
        won't do everything for you! Let's first tell what it won't
        do. Renumbering these is piece of cake:

            1.1
            1.7.1.5             (1)
            1.5
            1.5.4.1             (2)
            1.5.4.5
            1.9

        The result is

            1.1
            1.7.1.5
            1.2
            1.5.4.1
            1.5.4.2
            1.3

        tsk-tsk, before you say anything... It went all right.
        Now you see what it won't do for you.

        .   It can't know that the 1.7.1.5 belongs under previous 1.1,
            because no back tracking is done. I won't even try!
            [write a separate package if you want that...I won't do it]

        .   Same goes here, it can't know that the 1.5.4.1 should actually
            start from 1.5.1.1

        The thumb rule is, that you _go_ and make sure all the _first_
        level headings (those that end to X.X.1.1) are right before doing
        renumbering. In the above case, you should have done these before
        calling M-x tip-renumber-forward.

        .   --> 1.1.1.1
        .   --> 1.5.1.1  _AND_ do replace M-% 1.5.4 with 1.5.1

        Then all the renumberin would have gone just fine.
        Little handy work and this package helps you to number your doc easily.


    Renumbering -- be cautious

        If you have index section in you file, you have a little problem,
        because this package does not know nothing about such things.
        If the Index section is at the beginning, just go past it and
        use function:

            M-x tip-renumber-forward

        Using

            M-x tip-renumber-buffer

        Would be disaster. It can only be used for non-index buffers.

    Creating index

        After you have renumbered all, your old index section is useless,
        Just call function

            M-x tip-toc

        And copy the showed buffer in place of the old index.

    Limitations

        Since the numbering is done according to regexp, there is
        no way to avoid the following false hit:

            1.1 Overview
            This is highly technical document concerning the latest
            NASA ultrawave reflective shield technique. You should
            refer to chapter:

                1.5

            Where the Daddy-Cool portable sondium emission detector is
            described in full...

        The Number 1.5 is unfortunately renumbered to 1.2, and possibly
        causing headache in the NASA and in the spying countries...
        If you know elegant way to prevent these false hits, please
        drop me a mail. At this time I haven't much payed attention to this.

    Code Note

        The renumbering used here uses brute force, so the execution time
        is O(n2). If you have more that 30-40 sections, the renumbering
        might take 15-40 minutes. If you care to send me more pleasant
        numbering I'd be very gratefull and you're name would be carved to
        this module. For now, I'm just too lazy to change anything.


Tinypair.el -- self insert character (pa)irs () "" '' <>

    Preface, 1995

        I saw paired-insert.el posted to gnu.emacs.help group, and
        the code was so badly documented that I got frusrated. And when I
        finally got it going, I wasn't quite pleased with it.
        The code showed lot of promises, but it couldn't do smart pairing.
        Instead I started developing this module.

    Overview of features

        o   Minor mode for paired characters.
        o   [] {} <> '' `' ""

    Pairing control

        *Remember* Always ask youself "Does this character the cursor is
        on, belong to _word_ class?", when you wonder why the pairing does
        not take in effect around the current character block.

        The pair control is turned off for lisp mode, because it makes
        things worse if the pairing is on. The pairing in US style includes

            `'

        But European people almost never use backquote, intead they use:

            ''

    General pairing rules, just some of them

        The pairing is done according to assoc lists in the following way:

        o   if there is whitespace in front of char, then pair is inserted
        o   if character is over pair-end, no pairing takes effect.
            Like if you press opening paren when you're sitting on the
            closing paren:

            ()
             *  <-- cursor here, pressing another ( does not pair.

        but this behavior can be controlled through variable

        o  if the cursor is at the beginning of the word (see syntax-table):
            -- if there is no pairs around the word, the whole word is paired.
            -- if there is pair, no pairing takes effect. The char acts as
            self-insert-command.

        o   if previous character is word. then the '  doesn't pair. Reason
            is in english language .........................^

        o   if character is repeated with prefix arg, the pairing isn't done,
            instead the character is repeated as in self-insert-command.

    Cursor positioning

        By default the cursor is positioned in the "middle" of the inserted
        pair chars. But for words, this is impossible, because there is no
        middle position. Please see the variables

            tipa-:word-positioning
            tipa-:word-positioning-function

        which allow you to customize cursor positioning after word pairing.

    Word about syntax tables

        Syntax table play a major part in pairing, especially pairing words
        correctly. Suppose you're writing in text mode:

            ...txt txt... (help is the key)
                           *                    <-- cursor

        If you now press " to have the word HELP paired, you don't get it,
        because normally text mode's syntax table says that "(" belongs
        to group "w" (word) too. So the actual word is seen as "(help" and
        the program determines that you're inside a word, thus not
        allowing the pairing.

        In the other hand, if you were in any other mode, say in C++, the
        "(" is defined as open parenthesis syntax and it that case the
        seen word seen would have been "help" and the " character would have
        been added around the HELP string. Like this:

            ...txt txt... ("help" is the key)
                            *                   <-- cursor

        You may propably want quickly to see the syntax definition of
        characters; use function from my lisp libraries

            (defalias 'syntax-info 'ti::s-syntax-info)

        To return to this syntax problem in text mode, you could do the
        following, to make certain characters out of "w" class.

            (defun my-syntax-default (table )
              "My syntax table settings."
              (modify-syntax-entry ?[ "_" table)
              (modify-syntax-entry ?] "_" table)
              (modify-syntax-entry ?{ "_" table)
              (modify-syntax-entry ?} "_" table)
              (modify-syntax-entry ?( "_" table)
              (modify-syntax-entry ?) "_" table)
              (modify-syntax-entry ?/ "." table)
              (modify-syntax-entry ?\' "\"" table)
              (modify-syntax-entry ?\" "\"" table)
              (modify-syntax-entry ?_ "w" table))

        Then you just change the definitions of syntax table in hook:

            (setq text-mode-hook 'my-text-mode-hook)
            (defun my-text-mode-hook ()
              (my-syntax-default  text-mode-syntax-table))

        Do you wonder why I put {}()[] into "_" class and not in
        corresponding "(" or ")" classes? Well, my stig-paren just went
        beserk and started beeping the bell whenever I was nearby
        ")" class... The "_" shut it down, so I just chose it. You can
        of course put the chars into any class you like.




Tinypath.el -- Manage your Emacs load-path dynamically

    Preface, Feb 1999

        When you have setup your Emacs installation to your liking; a day
        comes when you decide that it's time to seriouly reconsider the
        directory structure of your installed lisp packages. In my case I
        used to simple file hierarchy where single packages were installed
        under:

            ~/elisp/

        and kits were installed directly under this directory, like this:

            ~/elisp/bbdb-2.00.06/
            ~/elisp/psgml-1.0.3/
            ~/elisp/pcl-cvs-2.9.2/

        Actually I used symlinks to the latest version directories, so that
        I didn't have to change my `load-path' every time I install new
        version. It was matter of updating a symlink on disk:

            ~/elisp/pcl-cvs/  --> ~/elisp/pcl-cvs-2.9.2/

        I also wanted NTEmacs to use my Unix Emacs setup, so i mounted H:
        drive to my Unix server $HOME.

            H:  --> Unix $HOME

        Having set PC's HOME Environment variable to point to H:, NTEmacs
        started reading my ~/.emacs startup file. After some win32
        configuration I got all loaded in NTEmacs too. Well, almost. It
        started with simple error messages "Can't load library xxx", then
        soon followed by bigger concerns; "autoloading xxx failed". The
        problem was the mounted H: disk. You see, PC's mount can't
        distinguish symlinked directoried from real directories, so all my
        symlink directories in `load-path' were useless. And that's why
        most of the files were not found any more.

        Well, I decided that I dind't want to rely on symlinks any more, but
        I also dind't want to update `load-path' by hand every time I installed
        new packages or moved files, created dirs, in my Emacs lisp hierarchy.

        I wanted a package that I could point "There, that is the root dir
        of all Emacs lisp; go and sniff for me the installed directories
        and update `load-path'" That's what this package does. Your
        `load-path' is updated automatically without any manual work.

    Overview of features

        o   Give `root' directories of your Emacs lisp code and this package
            recursively adds any found lisp code directories to `load-path'
        o   You can use cache for remembering previous scan. Cache is
            expired periodically.
        o   Extra dvice code for `load' `load-library' `require'
            `locate-library speeds up loading packages dramatically when
            Emasc does not need to seach `load-path' any more.
        o   If you have PC that mounts to Your Unix HOME, a special
            "dump" file that has hardcoded Disk Drive letter in front of
            path names can be produced.

    How to set up your load path

        The `tipath-:load-hook' contains function `tipath-setup' that starts
        examining all directories under `tipath-:load-path-root' which usually
        deduces to ~/elisp or ~/lisp. If you keep all your Emacs lisp files
        under this directory, then you can just load this file and your
        `load-path' gets updated.

            (require 'tinypath)

        If you have many Emacs lisp root directories, like one for site-lisp
        and one for site-packages and one for your ~/elisp; then you have to
        write your own setup function and pass each root directory to function
        `tipath-add-directories-below-root-dir'. Here is example for PC users,
        where the E: disk replicates identical Unix tree structure (it's
        a separate partition where Cygwin based Unix posts have been installed
        See cygwin at http://www.cygnus.com/ ).

            (require 'cl)
            (defconst tipath-:load-path-function 'my-tipath-setup)

            (defun my-tipath-setup ()
              "Set up paths"
              (dolist (path
                       (list
                        tipath-:load-path-root
                        "E:/usr/local/lib/site-lisp"
                        (concat tipath-:load-path-root "/mime/semi/link/")
                        ))
                (tipath-add-directories-below-root-dir path)))

            (require 'tinypath)

        There is nothing complex here: The `dolist' just sends additional
        directories to search to `tipath-add-directories-below-root-dir'.

    Finding the load-path directories

        If you only used default ~/elisp for your files, the
        `tipath-:load-path-function' started recursively searching all the
        directories under the root. `tipath-:load-path-root'. Not all
        directories are counted in when the search descends to directories.
        Variable `tipath-:load-path-ignore-regexp' tells if the directory
        should be ignored. By default:

        o   Package's additional subdirectories like texinfo, tex, doc, etc,
            misc, RCS, CVS, zip are ignored.
        o   any temporary directories names /t/ /T/ /tmp/ /temp/ are ignored.
        o   Dotted directories are ignored: /.dir/
        o   If direcrory does not contain any files ending to .el or elc.

    Updating lisp packages in directories

        Suppose you have installed a new version of a package:

            ~/elisp/gnus/pgnus-0.74/
            ~/elisp/gnus/pgnus-0.76/

        Both these directories end up added to the `load-path', but that is
        not usually wanted. If this is our own private directory, we
        usually want want to use the latest version. The solution is to
        move the old versions either a) under another name or b) under
        some directory that is ignored by default. What I do; is that I
        keep a backup of last package that has worked fine; so I rename it:

            % mv ~/elisp/gnus/pgnus-0.74/ ~/elisp/gnus/tmp-pgnus-0.74/

        All directories that start with prefix *tmp* are ignored; so the
        problem is solved. However if you update package in a site-lisp
        directory, there may be potential problem that somebody needs older
        version of the package. If you just made a backup like above, that
        user can not load the old package any more, because it doesn't show
        up in `load-path'

        I don't have an answer how to solve this, I would just announce
        that "new version has been installed; the old one is at OLD-DIR"
        and have user's to manually arrange their `load-path'. A simple
        lisp command would solve their setup. The statemet below adds the
        old directory the the *beginning* of `load-path' and thus any
        require command would find it.

            (load "~/elisp/tiny/tinypath")
            (pushnew OLD-DIR load-path :test 'string=)

        Remember to mention to users that they need to update cache with
        `tipath-cache-regenerate', so that OLD-DIRECTORY is included.

    Using the cache

        Now when you're freed from update burden of the directories in your
        disk, you can concentrate organising the files under sensible
        directories. For example I have quite deep directory structure and
        when I find some user announcing a file in a gnu.emacs sources
        group, I put in separate directory if the designer is known person.
        Here is example:

            ~/elisp/users/kevinr/       Kevin Rodger's files
            ~/elisp/users/ilya/         Ilya Zakharevich's files
            ~/elisp/users/bwarsaw/      Barry Warsaw's files

            ..

            ~/elisp/bbdb-2.00.06/
            ~/elisp/psgml-1.0.3/
            ~/elisp/pcl-cvs-2.9.2/
            ~/elisp/tiny/               My Tiny Tools

            ~/elisp/mime/               MIME packages
            ~/elisp/mime/semi/          SEMI packages
            ~/elisp/mime/tmm/           TM packages

            ~/elisp/lcd/                LCD packages
            ~/elisp/lcd/misc/           http://www.cs.indiana.edu:800/LCD/
            ~/elisp/lcd/functions/

            ...

            ~/elisp/other/

        All these paths in `load-path' and you can imagine how slow Emacs
        becomes. a) it takes a considerable amount of time to recurse this
        whole ~/elisp tree structure. b) it takes even more time to find
        some package xxx; when Emacs sees a call (require 'xxx); because
        Emacs must start looking into every single directory under
        `load-path' until it can or cannot load the required package.

        What we need is cache. And when you load this package the cache is
        already enabled. The variable `tipath-:cache-expiry-days' controls
        the interval when it is concluded that new tree recursion is needed
        to update the files and `load-path'. If you however install new
        packages, it is best to call `M-x' `tipath-cache-regenerate' to
        build up to date image of your files and `load-path'.

        If you do not want to use cache, set `tipath-:cache-expiry-days'
        to nil before loading this package.

        _Warning:_ You can't install any new *directories* to the lisp
        trees while the cache is active. You can however install new
        *files* into these directories. Those new files are not knows to
        cache, so the file load time is much slower.

    Cache file and different Emacs versions

        Many sites have installed different Emacs versions and it is important
        that each Emacs loads correct cache file. The cache file's name is
        derived from the emacs version:

            tipath-:cache-file + EMACS-TYPE + EMACS-VERSION + .el

    Mounted Unix disk and win32 Emacs in PC

        o   If you have PC that mounts your Unix disk permanently (like most
            of the company workers)
        o   if you have installed NTEmacs to your PC
        o   If you want to use your Unix account as shared to your NTEmacs

        Then, you may find a need to generate exact replicate of your
        `load-path' that is suitable for your PC's NTEmacs. I suppose here
        that you DO NOT install any lisp packages to your PC, but keep all
        the lisp configs and packages in Unix disk. Now it's matter of
        taking advantage of the existing packages located in your Unix by
        simply *dumping* a suitable `load-path' for your win32 Emacs.

        The `load-path' cannot be used as is; because it contains absolute
        references to thw "/users/fool/elisp...". That can easily be fixed.
        In _Unix_ Emacs, after loading this package, call function
        `tipath-load-path-dump' which asks a disk Drive that mounts your
        Unix disk. than can be H: for example (for HOME). The function will
        output a modified `load-path' to the file pointed by
        `tipath-:load-path-dump-file'.

        Use the dumped file in NTEmacs. You can automate this by setting
        `tipath-:load-path-function' to `tipath-load-path-setup-win32'

    Code note: General

        Because this package is among the first you load from your .emacs,
        i had to copy some function fromytinylib* into this package to make
        it independent until the point where the `load-path' got defined.
        In the code you may find markings "#copy:" which indicate functions
        that were copied/simplified to be used here. Autload statements
        defer loading functions until the end is reached.

    Code note: Custom

        [1999-02-21] This package is purposively not defcustomed, because
        defcustom appeared only in 20.x and many are still using 19.34.
        Yes, there is defcustom available for older emacs, but it is not so
        straight forward to use.

        The biggest reason is however that this is the _very_ first files that
        you load. If you were using defcusom in 19.x Emacs, you would have to
        load it before this package. Meaning, that you would have to adjust
        `load-path' or worse, carve the absolute path to custom:

            ;; If runnning that-and-that-emacs; then we need to load this...
            (load "~/elisp/custom/custom.elc")  ;; Must load the compiled lib

        Overall, it's  just easier to say

            (load "~/elisp/tiny/tinypath.el")

        And after that worry about defcustom, or anything else, which can
        now be found without absolute paths, because `load-path' has been
        defined.


Tinyperl.el -- Grabbag of Perl related utilities. Pod documentation

    Preface, march 1998

        I had introduced myself top perl 1994 and made some small and
        intermediate big perl 4 libraries. But then there was a long
        period when I saw Perl 5 conquering the Perl community and I
        didn't have a chance to lern new Object and Reference technologies
        that were added to the language. Now, 1998 I returned to the Perl
        business and started converting all my programs to take advantage
        of Perl 5.004_04 features.

        As a result I needed some additional Emacs functions to keep my
        Perl work going: Mostly this module offers POD page viewing commands.

    Overview of features

        tiperl-mode minor mode:

        o   Instant function help: See documentation of `shift', `pop'...
        o   Show Perl manual pages in *pod* buffer
        o   Load source code into Emacs, like Devel::DProf.pm
        o   Grep through all Perl manpages (.pod)
        o   Follow POD manpage references to next pod page with TinyUrl
        o   Coloured pod pages with `font-lock'

        Other minor modes:

        o   Separate `tiperl-pod-view-mode' for reading pod2text pages
        o   Separate `tiperl-pod-write-mode' for writing POD documentation

    Package startup

        At package startup the perl binary's `tiperl-:perl-bin'
        @INC content is cached. If you have Modules somewhere else than
        the standard @INC, then add additional `-I' swithes to the
        `tiperl-:inc-path-switches' so that these additional paths are
        cached too.

        Also the Perl POD manual page path is cached at startup.
        This is derived from Config.pm module $Config{privlib}.

        If you need to change any of these during the sessions, reload
        the package or call `tiperl-install' to update the changed values.

    Saving TinyPerl state

        Whn you use this package for the first time, the Perl @INC is read
        and all .pl and .pm files along the path are cached and written to
        file `tiperl-:state-file'. Next time you load this package the
        cahce file is read. This speed up packageinitialisation by 10x,
        because the time consuming @INC lookup is no longer needed.

        However, if you upgrade Perl or add new packages along @INC; you
        must rebuild the cached information and have it updated to
        `tiperl-:state-file'. You do this by calling `tiperl-install' with
        a prefix argument (eg. `C-u').

    Perl Minor Mode description

        Turning on `tiperl-mode' in any buffer gives you commands commands
        to retrieve POD pages. This is most usefull with the programming
        mode `perl-mode' (It is added to perl-mode-hook by default):

            C-c ' f             tiperl-pod-find-file
            C-c ' P             tiperl-pod-by-module
            C-c ' P             tiperl-pod-by-manpage
            C-c ' k             tiperl-pod-kill-buffers

            C-c ' m             tiperl-module-find-file
            C-c ' d             tiperl-perldoc
            C-c ' g             tiperl-pod-grep

        o   `tiperl-pod-find-file'
            run pod2text over file pointed by the function
        o   `tiperl-pod-by-module'
            Complete the installed Perl modules, like "Getopt::Long"
            and run pod2text
        o   `tiperl-pod-by-manpage'
            Complete Perl manual pages, like "perlfunc.pod" and run pod2text
        o   `tiperl-pod-kill-buffers'
            Kill all *pod* buffers from Emacs
        o   `tiperl-module-find-file'
            Complete installed module in @INC and load the file into Emacs.
            Like giving name "Getopt::Long"
        o   `tiperl-perldoc' Uses perldoc -f to diplay documentation of
            a perl function at point.
        o   `tiperl-pod-grep'
            Grep regexp from all Perl POD manual pages. Answers to
            our question "Is this discussed in FAQ".

    POD view mode description: navigating in pod page and following urls

        When pod is loaded to buffer, another package TinyUrl is turned on.
        It can track several different kind of URLs, including perl pod
        manpages for references like

            See perlfunc manpage
                ^^^^^^^^^^^^^^^^

            See [perltoc]
                ^^^^^^^^^

            Devel::Dprof manpage
            ^^^^^^^^^^^^^^^^^^^^

        You can click on the point to jump to the referenced pod page. Wait
        couple of seconds on the current line that has any of there
        reference and the URLs found are marked. If you don't want to use
        TinyUrl package, add this setup after TinyPerl package has been
        loaded

            (add-hook tiperl-:load-hook 'my-tiperl-:load-hook)

            (defun my-tiperl-:load-hook ()
              "My TinyPerl customisations."
              (remove-hook 'tiperl-:pod2text-after-hook 'turn-on-tiurl-mode-1))

        In *pod* buffer where the pod ducumentation is shoved, an additional
        browsing mode `tiperl-pod-view-mode' is turned to help moving around
        topics:

            ;;  moving down/up topics

            PgDown              tiperl-pod-view-heading-forward
            PgDown              tiperl-pod-view-heading-backward

            S-PgDown    tiperl-pod-view-heading-forward2
            S-PgDown    tiperl-pod-view-heading-backward2

            ;; Moving down/up one pod page at a time
            ;; The pod pages are all gatehered to single buffer *pod*

            Meta-PgDown tiperl-pod-view-forward
            Meta-PgUp   tiperl-pod-view-backward

            ;;  The normal PgUp/Down command is avalilable here

            Control-PgDown      scroll-up
            Control-PgUp        scroll-down

    POD Write mode description

        There is minor mode to help you writing POD in the current buffer
        The minor mode is in function `tiperl-pod-write-mode'.

            PgDown      tiperl-pod-write-heading-forward
            PgUp        tiperl-pod-write-heading-backward

        With shift

            PgDown      tiperl-pod-write-token-forward
            PgUp        tiperl-pod-write-token-backward

        Inserting default POD templates for program

            C-c.p       tiperl-pod-write-skeleton-script-manpage (p for POD)
            C-c.f       tiperl-pod-write-skeleton-script-function
            C-c.i       tiperl-pod-write-skeleton-item

        Inserting default POD skeletons for Modules or Classes.

            C-c.B       tiperl-pod-write-skeleton-module-header
            C-c.E       tiperl-pod-write-skeleton-module-footer
            C-c.F       tiperl-pod-write-skeleton-module-function

        The POD skeletons for Modules are based on following Module layout

            F I L E   B A N N E R

            P O D  H E A D E R
            NAME
            REVISION
            SYNOPSIS
            DESCRIPTION
            EXPORTABLE VARIABLES
            EXAMPLES

            #   module interface is written next

            use strict;

            BEBGIN
            {
                  .. EXPORT          # The export interface
                  .. EXPORT_OK
            }

            Define exported globals

            Define private variables

            P O D   I N T E R F A C E   S T A R T

            P O D  P U B L I C for public functions or method
            sub ...

            P O D  P U B L I C for public functions or method
            sub ...

            NORMAL banner of private function
            sub ...

            NORMAL banner of private function
            sub ...

            P O D   F O O T E R
            KNOWN BUGS
            AVAILABILITY
            AUTHOR

            1;
            __END__

    Perl SelfStubber

        If you're developing Perl modules, you can turn it to use autoload
        so that it compiles much faster and it deleays loading of functions
        until they are called. To use SelfStubber, you need to arrange your
        module to read like below. Notice the "BEGIN" and "END" tokens
        that are for function `tiperl-selfstubber-stubs', which will
        fill in the section with the right stubs.

        If you don't have "BEGIN" and "END" sections in your file, calling
        `tiperl-selfstubber-stubs' prints the found stubs in separate Shell
        buffer.

            package MyClass;

            use Exporter;
            use SelfLoader;
            use vars qw($VERSION @ISA @EXPORT @EXPORT_OK );

            @ISA    = qw(Exporter);

            @EXPORT = qw( .. );

            $VERSION = ..

            # BEGIN: Devel::SelfStubber

            # END: Devel::SelfStubber

            1;
            __DATA__

            <implementation: functions and variables>

            __END__

    Submitting your perl script to CPAN

        In addition to archiving your Perl libraries to CPAN, you can also
        submit perl scripts there. In order to get your submission right
        refer to page:

            http://www.perl.com/CPAN-local//scripts/submitting.html

        The most iportant point is that your script includes pod that describes
        your script. It must contain at minimum the headings README,
        SCRIPT CATEGORIES, COREQUISITES, OSNAMES which are already include in
        the pod skeleton via command

            `tiperl-pod-write-skeleton-script-manpage'


Tinypgp.el -- PGP minor mode, remailing, keyring management

    Preface 1996

        Please, read these URLs before you use this package. The pages are
        updated constantly. Drop me a mail if the manual doesn't cover some
        topic or if there are unclear sections.

        .ftp://cs.uta.fi/pub/ssjaaa/pgp-xhd.html  -- X-Pgp specification.
        .ftp://cs.uta.fi/pub/ssjaaa/tipgp.html    -- TinyPgp.el manual
        .ftp://cs.uta.fi/pub/ssjaaa/ema-tipgp.ini -- TinyPgp.el init file


Tinypm.el -- Emacs (p)roc(m)ail minor mode

    Preface, Sep 1997

        The year 1997 was a turning point in my daily email management. I
        started receiving 10-25 UBE messages per week to my private account
        and that raised my body temperature by couple of Celsius degrees. I
        wanted to get rid of the UBE so that it never landed in my primary
        inbox, $MAIL. Then I discovered procmail and that solved the
        problem of mail handling. It also made possible to subscribe to
        several mailing lists without bloating the primary inbox: procmail
        filed the incoming mail to defined mailing list inboxes.

        I also started using Gnus to read the mailing lists, but the mail
        splitting work is best handled by procmail. Why? Because procmail
        is always running, while your Emacs and Gnus isn't. Procmail
        processes incoming messages as soon as they are received and takes
        care of them, like forwarding those UBE messages to appropriate
        postmasters, if you had written such recipe to your .procmailrc.

        To get more info about procmail, send an e-mail to the following
        address

            To: <jari.aalto@poboxes.com>
            Subject: send help

        Procmail installation kit can be found at
        ftp://ftp.informatik.rwth-aachen.de:/pub/packages/procmail/

    What is Procmail?

        [Excerpted from the procmail faq at <http://www.iki.fi/~era/procmail/>]

        Procmail is a mail processing utility, which can help you filter
        your mail; sort incoming mail according to sender, Subject line,
        length of message, keywords in the message, etc; implement an
        ftp-by-mail server, and much more.  Procmail is also a complete
        drop-in replacement for your MDA. (If this doesn't mean anything to
        you, you don't want to know.)

    Some terms

        [Excerpted from the Email Abuse FAQ]

        ._UBE_ = Unsolicited Bulk Email.
        ._UCE_ = (subset of UBE) Unsolicited Commercial Email.

        _Spam_ = Spam describes a particular kind of Usenet posting (and
        canned spiced ham), but is now often used to describe many kinds of
        inappropriate activities, including some email-related events. It
        is technically incorrect to use "spam" to describe email abuse,
        although attempting to correct the practice would amount to tilting
        at windmills

    Overview of features

        o   Minor mode for writing Procmail recipes (use tab for
            indenting)
        o   Linting procmail code: From batch command line or
            interactively. In interactive mode yuser can auto-correct code
            on the fly. Linting erformance is about 160 recipes in 15 seconds.
        o   Font-lock supported.
        o   files that have extension .rc or name .procmailrc trigger
            turning on `tipm-mode' (By using `auto-mode-alist'). Please
            check that the first line does not have anything that would
            override this, like "-*- text -*-".

        Quick reference

        o   M-x `tipm-mode' activates Procmail writing mode
        o           C-c ' L  to Lint whole buffer interactively
        o   C-u     C-c ' L  to Lint whole buffer and gathers info.
        o   C-u C-u C-c ' L, same as above, but be less pedantic.

        Required packages

        o   tinylib*.el     all lisp libraries
        o   tinytab.el      General programming mode. TAB key handling
        o   tinymy.el       Aligning \ continuation chars to the right
        o   tinycompile.el  General parser for compile output. See Lint.

    Writing the procmail code

        The coding functions are provided by other modules. The tab key
        advances 4 characters at a time, and minimalistic brace alignment
        is supported when you press tab before the ending brace.

            TAB     tit-tab-key                     tinytab.el

        The RET autoindents, but this can be turned off by calling

            C-c ' RET   tit-return-key-mode             tinytab.el

        Whole regions can be adjusted with commands

            C-TAB   tit-indent-by-div-factor        tinytab.el -->
            A-S-TAB tit-indent-by-div-factor-back   tinytab.el <--
            C-c TAB tit-indent-region-dynamically   tinytab.el <-->

        Jumping to matching brace or matching parentheses

            %               timy-vi-type-paren-match        tinymy.el

    Tabs and spaces

        When the procmail mode is active, the tab key does not produce a
        tab character, but sufficient amount of spaces. There is a reason
        for this, mostly due to Lint parser which has to move up and down
        columnwise when checking the code. The movements can't be done if
        the code includes tabs. If you need a literal tab in your regexps,
        you can get it with standard emacs way 'C-q` `TAB'.

    Aligning the lines that have backslashes.

        In procmail, you use backslashes a lot, like in the following example.
        The backslashes here are put after each line, but this construct is
        error prone, because if you later on add new `echo' commands or
        otherwise modify the content, you may forget to update the
        backslashes.

            :0 fh
            * condition
            | (formail -rt | \
               cat -; \
               echo "Error: you requested file"; \
               echo "that does not exist";\
               ) | $SENDMAIL -t

        To fix this code block, you can use command C-c ' \ or
        `tipm-fix-backslashes-region'. It would have been enough to write
        the first backslash and then call C-c ' \ and the rest of the
        backslashes would have been added.

            :0 fh
            * condition
            | (formail -rt |                                    \
               cat -;                                           \
               echo "Error: you requested file";                \
               echo "that does not exist";                      \
               ) | $SENDMAIL -t

    Rules on how to write Procmail recipe

        In order to use the Linting service, This package requires that
        you write your procmail code in following manner. These rules are
        needed, so that it would be possible to parse the procmail code
        efficiently and more easily.

         [recipe start]

            :   # although legal procmail, illegal here. Use :0

         [flag order]

        In order to autocorrect read flags from the buffer, the flag order
        must be decided: and here is the de facto order. The one presented
        in the procmail man page "HBDAaEehbfcwWir" is errourneour, because
        flags "aAeE" must be first, otherwise it causes error in procmail
        (heresay). The idea here is that the most important flags are
        put to the left, like giving priority 1 for `aAeE', which affect
        the receipe immedately. Priority 2 has been given to flag `f',
        which tells if receipe filters somthing. Also (h)eader and (b)ody
        should immediately follow `f', this is considered priority 3.
        In the middle there are other flags, and last flag is `c', which
        ends the receipe, or allows it to continue."

            :0 aAeE HBD fhbwWirc: LOCKFILE
               |    |   |  |   |
               |    |   |  |   (c)ontinue or (c)opy flag last.
               |    |   |  (w)ait and Other flags
               |    |   (f)ilter flag and to filter what: (h)ead or (b)ody
               |    (H)eader and (B)ody match, possibly case sensitive (D)
               The `process' flags first. Signify (a)ad or (e)rror
               receipe.

        Every recipe starts with ':0 flags:', but if you prefer ':0flags:'
        more, you can use following statement. This 'flag-together or not
        format is automatically retained when everytime you call Lint.

            (setq tipm-:flag-and-recipe-start-style 'flags-together)

         [lockfile]

        The lockfile names must be longer than two characters. Shorter
        lockfile name trigger an error. Also lockfile must have extension
        $LOCKEXT or .lock or .lck; no other non-standard extensions are
        allowed. The lockfile name must be within charsert [-_$.a-zA-Z0-9/]
        and anything else is considered as an odd lock file name.

            :0 : c          # Error, should have been :0 c:
            :0 : file       # Invalid, should read "file.$LOCKEXT"
            :0 : file.tmp   # Invalid, non-standard extension.
            :0 : file=0     # Invalid filename (odd characters in name)

         [condition line]

            * H B ?? regexp # valid procmail, llegal here: write "HB"

         [Variables]

        The literal value on the right-hand side must be quoted with double
        quotes if a simple string is being assigned. If there is no quote or
        backtick, then Lint assumes that you forgot to add variable
        dollar($). Try to avoid extra spaces in the variable initialisation
        construct too `:-'.

            DUMMY  = yes        # Warning, did you mean DUMMY = $yes
            VAR    = ${VAR:-1}  # No spaces allowed: "$ {" is illegal.

         [program names]

        Program `sendmail' must be named sendmail, but it can also be variable
        $SENDMAIL. Similarly, program `formail' must be named `formail' or
        it can be variable $FORMAIL. Use of $MY_SENDMAIL or $MY_FORMAIL are
        illegal and cause missing many Lint checks.

         [commenting style]

        In recent procmail releases you're allowed to place comments inside
        condition lines. Lint will issue a warning about this practise
        if your procmail version does not support this. But while you
        may place comments inside conditions, they should be indented by
        some amount of spaces. The default indent is 4 spaces.

            * condition1    --> * condition
            # comment               # comment
            # comment               # comment
            * condition2        * condition

        This is recommended for readability (separating conditions
        from comments) and Lint will fix these comment misplacements.

         [redirecting to a file]

        If you print something to file, then the shell redirection tokens
        > and >> must have surrounding spaces, otherwise they are not
        found in the procmail code. (because > can be used in regexps)

            :0 :
            | echo > test.tmp       # Do not use "echo >test.tmp"

    Linting procmail code

        Writing procmail recipes is very demanding, because you have to
        watch your writing all the time. Forgetting a flag or two, or adding
        unnecessary flag may cause your procmail code to work improperly.
        The Lint interface in this module requires that

        o   You write your procmail code in certain way. (see above)
        o   buffer is writable and can be modified. This is due
            to fact that program moves up and down to the same column
            as previous or next line. In order to make such movements,
            the tabs must be expanded when necessary.

        To help *Linting* you procmail code, there are two functions

            C-c ' l         tipm-lint-forward
            C-c ' L         tipm-lint-buffer

        These functions check every recipe and offer corrective actions if
        anything suspicious is found. If you don't want to correct the
        recipes, you can pass prefix argument, which gathers Lint run
        to separate buffer. In parentheses you see the buffer that was
        tested and to the right you see the program and version number.
        In this buffer you can press Mouse-2 or RET to jump to the line.

            *** 1997-10-19 19:37 (pm-test.rc) tinypm.el 1.10
            cd /users/foo/pm/
            pm-test.rc:02: Error, Invalid or extra flags.
            pm-test.rc:10: Error, Invalid or extra flags.
            pm-test.rc:10: info, Redundant `Wc:' because `c:' implies W.
            pm-test.rc:11: String `>' found, recipe should have `w' flag.
            pm-test.rc:15: info, flag `H' is useless, because it is default.

        The output buffer can be sorted and you can move between blocks
        with commands

            sl      tipm-output-sort-by-line
            se      tipm-output-sort-by-error
            b       tipm-output-start
            e       tipm-output-end

    Lint: auto-correct

        In many cases the Lint functions are able to autocorrect the code:
        answer `y' to auto-correct current point. If you want to correct
        the place yourself, then abort the Linting with `C-g' and fix the
        indicated line.

    Lint: directives

        Most of the time the Lint knows what is best for you, but there
        may be cases where you have very complex procmail code and you
        know exactly what you want. Here are the Lint directives that you
        can place immediately before the recipe start to prevent Lint
        from whining. The word `Lint:' can have any number of surrounding
        spaces as long as it is the first word after comment.

            # Lint: <Lint flags here>
            :0 FLAGS

        The comment must be in the previous line, the following is not
        recognized.

            # Lint: <Lint flags here>
            #   I'm doing some odd things here and ....
            :0 FLAGS

        Here is list of recognized Lint directives. each directive must have
        leading space.

        o   `-w'. In "|" recipe, ignore exit code. If you don't give
            this directive, the missing "w" flag is suggested to put there.
        o   `-i'. If you have recipe that, 1) has no "f"  2) has nt ">"
            3) has "|" action, then the recipe doesn't seem to store
            the stdin anywhere. This may be valid case eg. if you use
            MH's rcvstore. You can suppress the "-i" flag check with
            this directive.
        o   `-c'. This is used in conjunction with `-i' when you only
            do something as a side effect and you reaally don't want copy.

    Lint: error messages

        The error messages should be self-explanatory, but if you don't
        understand the message, please refer to `pm-tips.txt' file available
        from the mentioned file server above.

       "info, backticks in var init. Not a recommended practise"
        See `pm-tips.txt' and section that talks about variable definitions.

    Lint: batch mode from command line

        You can also lint the procmail files from command line prompt
        like this. (You must have Emacs 19.30+ which has working -eval)

                % emacs -batch -q -eval                                     \
                   '(progn (load "cl") (push "~/elisp" load-path)           \
                    (load "tinypm" )                                        \
                    (find-file "~/pm/pm-test.rc")                           \
                    (tipm-lint-buffer-batch)                                \
                    ) '

        Change the filename "~/pm/pm-test.rc" to the file being linted.
        The Lint results will appear in file `tipm-:lint-output-file' which
        is ~/pm-lint.out by default. Below you see a shell script to run
        the above command more easily. Rip code with `ti::m-pkg-rip-magic'

 #!/bin/csh -f
 # @(#) pm-lint.sh -- LINT A procmail batch lint with emacs tinypm.el
 #
 # $Docid: 2003-05-17 Jari Aalto $
 # $Contactid: jari.aalto@poboxes.com $
 #
 set file  = $1
 #
 set EMACS = xemacs-19.14
 set out   = $HOME/pm-lint.lst
 #
 #  notice all these 3 lines must be concatenaed together! There must be
 #  no \ continuation characters. to the right.
 #
 $EMACS -batch -q -eval
     '(progn (load "cl") (push "~/elisp" load-path) (load "tinypm")
     (find-file "'"$file"'") (tipm-lint-buffer-batch) ) '  2>&1 $out
 #
 # end of pm-lint.sh


    Highlighting

        Just couple of words about the chosen regexps for procmail code.
        Notice, that if you make a mistake, the dollar($) in front of
        identifier is not highlighted. This should help with spotting
        errors by eye better.

            $VAR = ${VAR:-"no"}     # Error, extra $ to the left.
             ===



Tinyreplace.el -- handy query-replace, area, case preserve, words

    Preface, 1995

        I saw post in gnu.emacs.help where brianp@ssec.wisc.edu (Brian Paul)
        asked for help to replace his C variables: "Suppose I want to
        replace all occurances of the variable i in my C program with j."
        The normal emacs function query-replace wasn't suitable for this
        task because it offered too many false hits. (Guess how many i
        characters are used in non-variable context!).

        Well later I rembered that one could have used \bi\b to search
        words. But the nature of "word" is very different here as it
        would have been with \b; it relies on syntax table which you
        seldom want to change, whilst the "word definition " here can be
        changed on the fly :-/

        Things are not that simple always, in fact, the first
        implementation of this package had to do with the latex math
        equation replace, so that program would automatically skip over
        normal text and perform replace within the blocks only. I think
        the engine offers lots of other usages too.

        I decided to pull out the v1.0 and make it complete package.

    Overview of features

        o   Companion to emacs's query-replace. Simple interface.
        o   Text beeing replaced is highlighted AND terminals that cannot see
            the highlight will see "=>" string marking the line beeing
            processed
        o   Preserve case while replacing "FoO" --> "BaR" (symmetry)
        o   Toggle case sensitivity and symmetry during the replace.
        o   Word match mode on/off during replace: 'matchTHIS or THIS '
        o   "Narrow to function", go to "beg of file" when you start
            replacing. You're put back to position where you were when
            you quit.
        o   Can replace over many files. (Reads compile buffer output)
            ChecksOut files from RCS when needed (if they are not locked)
        o   You can define `tire-exlude-line-regexp' that skips any line
            matching looking-at regexp at the beginning of line.

    How to use

        If you know lisp, you can go and take straight advantage of the
        engine function:

            tire-replace-region-1

        Normally functions work within area defined by you, but
        there is 'applications' section which offers several ready to run
        functions for various needs:

            tire-replace-region     ;like query replace but in selected area
            tire-replace-forward    ;start from current point.

            tire-latex-blk-replace  ;replacer text surrounded by latex BLOCKS
            tire-latex-math-replace ;replace text within latex
                                    ;math equations only.

    What commands do I have while replacing interactively?

        There is some handy commands that normal emacs replace lacks

        o   toggle case sensitivity during replace
        o   toggle symmetry during replace
        o   Go to start of buffer _now_ (return back when you exit replace)
        o   search backward
        o   limited undo
        o   Narrow to current function, so that you can replace local variables
        o   Flash function name where you're (only for some programming
            languages.)

        See function tire-replace-region-1 for command explanation.  To
        abort the search, you just press Ctrl-g or 'Q' and you'll be
        returned to the starting point of search.

    Command line prompt explanation

        The command line prompt will look like this

            Replace 'xx' with 'yy' (a,bvuBFNU? [+CSX] !ynqQ)

        Where the flag settings active are displayed between brackets.  +
        means that you have used (N)arrow command, C indicates case
        sensitivity, S tells that symmetry is activated and X means that
        line exclude is oboeyed. For full explanation of the commands,
        please press

           ?

        Which will print the command summary and explanation momentarily.

    Special commands in command line

        When you edit the Seach string or destination string, there is
        some keys that you can use.

            C-l     Yank the text under point to current prompt
            C-o     Yank previous SRING1

        The Yank command is `C-l' not `C-y', because if you edit and kill
        inside the promt line, you can use regular `C-y' to yank text
        back. The `C-l' command read space separated text from the buffer and
        you most like have to edit the imported text a little.

        The `C-o' command yank first string(the one that is searched) to
        the prompt. This is also handy if you used `C-l' to yank then you
        eidited a lot the yanked text and want to move it to the next
        prompt. This way you don't have to do the editing again, but only
        modify the previous string.

            <   Move buffer's yank point backward
            >   Move buffer's yank point forward

        When you select region and you're ready to give replace arguments;
        the point in the buffer propably isn't in a suitable place for `C-l'
        yank command. You can move the buffer's yank point with these
        command. The text to the left shown to you briefly tells where the
        point currenly is.

        This feature propably is at its best in acompile buffer where you
        have grep results and you draw region around the the files where
        you want the replace to happen. Move a little with [<>] and you
        will be soon in a line that has the grep word, then yank it to the
        replace prompt.

    Note about the arrow pointer

        Users that do not have highlight capability to see which portion of
        text will be replaced will appreciate the arrow at the beginning of
        line to show where the text is located.

        The option "a" that refreshes the arrow marker is *forced* to ask a
        minibuffer question in order to change the state of arrow (hide or
        show). I found no other way to do this and I think it's a bug in
        19.28 emacs, because the state is not immediately shown in buffer.

        Drop me a mail if you know how to do the updating without using the
        extra `read-from-minifuffer' "Refresh arrow.." question.

    Note about commands

        The commands are hard wired in this module and you cannot add new
        ones as you can in replace.el which is minor-mode based.  This
        package is meant to be companion to replace.el, and for that reason
        the interface has been designed to be as simple as possible without
        any additional modes.

        If you need some new command, please mail me direcly and I'll see
        what I can do. There will never be a plan to ever convert this
        module to minor mode.



Tinyrlog.el -- RCS rlog minor mode. ChecOut, CheckIn...

    Preface, Dec 1996

        In my work I have to manage very complex RCS revision numbers,
        multiple branches and I may have several branches CheckedOut for
        testing, correcting, and developing new features. It seemed natural
        to handle this "multiversioning" control from the rlog output.

    Overview of features

        o   Companion to vc.el, Minor mode in RCS rlog buffer (C-x v l)
        o   Highlighing supported in windowed emacs's rlog buffer.
        o   You can 1) Lock a file 2) unclock file
            3) show status 4) pop to buffer where rlog belongs and more
            5) ChekOut multiple revisions for viewing purposes
            6) (un/mark viewed versions) and more..

    Do you need this package

        If you don't use RCS/CVS don't load this package, it only works for
        `rlog' output and expects to parse only buffer in that format. If
        you don't use many branches and thusly vc's rlog output much, this
        package may not be essential to you.

        This pacakge uses colors if window system is detected, but
        it partially copes with non-window system too, so that eg. marks
        appear in the buffer as charaxter codes.

            revision 1.25       locked by: xx;
            date: 1997/11/10 17:20:45;  author: xx;  state: Exp;  lines: +3

        In the above lines the first line, starting from "1.25" is
        highlighted (version number). In next line: 97/11/10
        (the YY year is significant), "xx" and "Exp" are highlighted.



Tinyrmail.el -- RMAIL additions, pgp, mime labels

    Preface, overview of features

        o   Detect PGP, MIME mail and label incoming messages accordingly.
            User can add more checking functions and labels to incoming email
            messages
        o   New label summary cmd with AND eg. finding {pgp,v} verified pgp
        o   Flag incoming mail as deleted by regexp.
        o   "S" command for Spam message reply.
        o   Commands to fix your RMAIL messages.
        o   advice: "n" and "p" do not to auto display msg in Summary buffer
        o   advice: mouse click in Summary does not automatically update msg
        o   advice: `rmail-ignored-headers' now reformats old messages too.

    Description

        This little package offers some autmatic detection of PGP
        MIME  mails: It attaches labels to your incoming mails.
        There is also new summary function, which enables you to
        make a query by ANDing the labels in your RMAIL.

        This means, that you can now classify your message, like this:

            BASE
            SUBSET-IDENTIFIER
                    MINOR-IDENTIFIER
                       NOTE-IDENTIFIER

         Eg. For PGP mails I have

            {pgp}
            {pgp,v}         -- verified signature
            {pgp,u}         -- not verified
            {pgp,v,e}       -- verified and encrypted

        The normail rmail's summary function gives you the OR summary, which
        would mean, that if you wanted symmary by {pgp,v}, it would give
        you all mail that has either {v} or {pgp} somewhere. Well, this
        summary is not suitable if you use one CHAR to denote attributes
        of your base-identifiers (multichar)

    Automatic deletion of incoming mail

        There is default function to mark messages as deleted according
        to regexp. Please configure this variable to suit your needs:

            tirm-:delete-regexp

        If you want more personal control whether the mail
        should be deleted or not, please remove the default delete function
        and add your own:

            (add-hook 'tirm-:load-hook 'my-tirm-:load-hook)

            (defun my-tirm-:load-hook ()
             "Cancel some default settings and modify parameters."
            (remove-hook 'tirm-:get-new-mail-hook 'tirm-delete-function)
            (add-hook    'tirm-:get-new-mail-hook 'my-rmail-delete-function)
            )


            (defun my-rmail-delete-function ()
             ...)

    Replying to UBE aka spam messages

        The spamming has become a very serious promlem in private
        email communication. Not only the spammers send mail to newsgroups,
        but they are harrashing private mailboxes as well.

        With this package you can send reply to a spammer and complaint
        to all postmasters that have allowed the spam mail to travel through
        their networks. The addresses are parsed from the Received headers
        of the message and verified by `nslookup'. ou can turn off the
        nslookup if you wasn't faster response, but this may result
        bounched messages back to you.

            (setq tirm-:ube-use-nslooup t)

        So that you don't sned complaint to your local admin and not to
        some other known middleman domain (like forwarding service), you
        should also set following variable to regular expression to reject
        some addresses:

            (setq tirm-:ube-ignore-site-regexp "YOUR-SITE\\|155\\.0\\.233")

        The text to the beginning of message is read from file pointed
        by `tirm-:ube-message-file'.

    New commands in RMAIL

        Refer to function tirm-define-default-keys for exact setup.
        Currently the only new command added is

            "L" tirm-rmail-summary-by-labels-and
            "U" tirm-ube-send-to-postmasters
                UBE = Unsolicited Bulk Email

    Fixing RMAIL format

        Sometimes you may get following error after you have hit "g"
        to get new mail: "Cannot convert to babyl". The reason for
        this behavior is still not quite clear to me, but the cause
        is in the incoming message that does not have

            From

        Field at the beginning of message. I have seen even some garbage
        Prepended to field so that it looked like

            m?From

        What have to start editing the RMAIL file directly to fix its
        format. Change the mode to text-mode, run M-x widen and search the
        last message that rmail was not able to read. You will easily find the
        point where "**** EOOH" markers do not appear any more.

        Now starts the fixing part to make rmail happy again:

        o   Make sure From line is left flushed. Edit if needed and put
            lines in their right places.
        o   Select all individual message's headers at a time.
        o   Call function tirm-fix-make-rmail-message-header
            which you should propably bound to some convenient key.
            The ESC-z combination is propably free for temporary use.
            (local-set-key "\ez" 'tirm-fix-make-rmail-message-header)

        After you have converted all headers to rmail format, you can
        start rmail again with command

            M-x rmail-mode

        If you made any mistakes, rmail will let you know and you have to
        repeat the header fixing again. (possibly removing the prevous
        EOOOH markers and reconverting them). We aren't quite finished
        yet. You see, on error, rmail leaves the read mail into your home
        directory. Please check that

            ~/.newmail-USERNAME

        file doesn't contain any new message that aren't already in your RMAIL
        buffer. If there is only old message, delete that file. Now we
        have finished and you can again use "g" to get new mail.

    Standard Rmail distribution changes

        This package changes the standard Rmail distribution sligtly and here
        summary. If you want to disable these features or only use some of
        them, you have to put separate configuration to your .emacs.
        To disable forms:

            (setq tirm-:load-hook '(tirm-install))

        To disable advices, you do

            (setq tirm-:load-hook '(tirm-install my-tirm-install))

            (defun my-tirm-install ()
              (ti::m-ad-control
                '(rmail-show-message
                  rmail-summary-enable
                  rmail-summary-next-msg
                  )
                 "^tirm"
                 'disable
                 ))


        `tirm-:forms-rmail'

        o   Every time RMAIL package is loaded these forms are executed.
        o   These define some keybindings to summary buffer
            that I have found appropriate. Mouse-2 selects message
            (and does not yank as the original). RET key also selects message.
        o   The post command hook is cleared so that you can search regexp
            in summary buffer. Normally moving a cursor would move the
            current message too.
        o   The "q" quit key is too easily pressed and I have removed it
            alltogether. If I really want to quit RMAIL, I usually
            quit Emacs too.

        Advices:

        *rmail-show-message* active

        The message's headers are now always reformatted. If you change
        variable `rmail-ignored-headers', the old messages are not affected
        until you "t"oggle headers. This advice does it for you
        automatically every time you select message. This advice slows
        message displaying a bit, but for me, it isn't very noticeable.
        You can very well turn this off if you dont' change content of
        `rmail-ignored-headers'.

        *rmail-summary-enable* active

        This replaces whole function. The original function did automatic
        message update whenever you moved around summary buffer. Now you
        can keep summary buffer search separated from the current
        message displayed.

        *rmail-summary-next-msg* active

        Same as above.



Tinyscroll.el -- Enable or Disable autoscroll for any buffer.

    Preface, May 1996

        I was in the middle of testing one of my new packages which didn't
        quite work as I wanted, I was loading all the lisp files to see if
        it breaks. I watched the *Message* buffer to fill with statements

            Loading abbrev...
            Loading abbrev...done
            ...
            Loading rmail...
            loading rmail done...
            ...

        But suddendly the emacs died. It kicked me off to the shell and I
        had no idea what package was the last one that got loaded.

        You see, the *Message* buffer keeps growing, but you have to tap
        the pgDown key to get to the end, all the time. Instead I decided
        to pull out some lisp to do general autoscrolling for any buffer,
        so that I can just sit back and watch the buffer move. No more
        guessing in *Message* buffer what was the last message before Emacs
        sunk :-)

    Overview of features

        o   Select buffer, and hit auto scroll on/off. You can scroll any
            buffer.
        o   All windows for the buffer are scrolled in all frames.
            If frame is miimized and contains window to sroll, frame will
            be maximized ("popped up")
        o   If buffer's point-max doesn't move, it ignores
            scrolling.
        o   Default scroll activated for: *Compilation* *Grep* and *Messages*

    How to use this package

        The scroling here is based on timers, where the lowest interval can
        be one 1 second. This means that you don't get smooth and
        continuous scrolling, but regular update of the buffer, which may
        in rare cases seem jerky. However, using timers is the only
        possibility if we want to have general scroll utility for *any* buffer.

        To enable/disable autoscroll for current buffer, use these:

            M-x tisc-control            ;to activate scroll
            C-u M-x tisc-control        ;to deactivate scroll

    Lowest window of the same buffer always scrolls

        It is an interesting problem, when you have SAME buffer in multiple
        windows, to decide which window to scroll.  I didn't want to scroll
        all windows, since otherwise I wouldn't have used two/or more
        windows for the same buffer.

        I decided that the lowest window for the buffer always scrolls. You
        can't change that. This was a design decision and I won't support
        scrolling middle/upper buffers. Just arrange your windows so that
        the scrolling one goes to the bottom.



Tinysearch.el -- Grab and search word under cursor

    Preface, 1994

        In 7 Nov 1994 <aep@world.std.com> (Andrew E Page) posted
        interesting code by article name 'Script Example: Search for next
        word', which I took a look. The idea of code was excellent, but it
        didn't work as expected at all. Gradually the idea was crystallized
        into this package.

          "Why we need search word package, when in emacs I can do `C-s' to
          enter search mode: C-w C-w C-w to grap words immediately after
          point and finally C-s to start searching...?"

        Well, people tend to forget, that life was out there when 19.xx
        wan't in hands of developers. This package was originally made for
        18. The advantage of this package is the variable

            tisw-:word-boundary-set

        which you can easily change whenever you need (eg. thru
        functions). To do the same in emacs, you have to go and modify the
        syntax entries involved...then come back again when you're done. I
        never do that, I seldom touch the syntax entries. Besides all
        mode-xxx go crazy if I would do so. Now you see the advantage?

        And of course I feel more comfortable to do just one keypress,
        like `f2' to search forward instead of cubersome C-s C-w C-w
        C-w [n times] and finally C-s

    Description

        Grab word under oint and searches fwd/back. The word is inserted
        into Emacs's search ring, so that you can later continue with `C-s'
        or with `C-r' call.

    Why doesn't it find my C++ function class::InitClass() ??

        User pressed the search function over the call:

            InitClass(;
            i =  i +1;

        Now he can't find the function definition... Well, remember that
        this searches 'true' words, not part of them. A word is surrounded
        by at least one whitespace, since it's not a word if it is cat'd
        together with something else. Obviously the function definition
        didn't contain any spaces...

        The problem is, that if is you say ':' belongs to character set in C++,
        [because you propably want to grab variables easily.
        including the scope operator 'clss::variable' or '::global'] ,
        the find funtion expects to find word in boundary

            nonWordWORDnonWord

        And as you can see, the if ':' belongs to word, it can't
        simultaneously belong to NonWord !

        Summa summarum: Revert to emacs C-s for a moment, since the
        word is automatically added to the search buffer.

    Word accept function note:

        There is variable `tisw-:accept-word-function', which has
        default function

            tisw-accept-word

        The function's purpose is to check if the searched word is
        accepted and that search should be terminated. Currently there it
        contains some programming logic for C/C++ languages, so that
        certain hits are ignored. Consider following case:

            struct *foo;   - 1
            foo->x;        - 2
            x->foo         - 3

            int foo, x;    - 4
            foo = x;       - 5        * start of 'foo' and 'x' search backward

        C/C++ mode, searching for 'foo' finds 4,2,1  -- Not 3
        C/C++ mode, searching for 'x'   finds 5,4,3  -- Not 2
        But in text-mode, you would find all occurrances.

        The added logic to C++ ignores the struct's MEMBER matches so that
        you really can find the "main" variables. If you don't like
        this added feature, you can alwasy go to

            M-x text-mode

        For a while, or if want to permanently switch this feature off,
        you set the variable `tisw-:accept-word-function' to nil, which
        causes all hits to be accepted.

        Needless to say, that you can use put your own checking
        function in that variable to control the accurrances better.



Tinytab.el -- Programmers TAB minor mode. Very flexible.

    Preface, oct 1995

        I saw a post in gnu.emacs.sources (what an source of
        inspiration!), where someone asked:

            "Is there anyway to reset the number of spaces that TAB does?
             Like, I want to make it jump four spaces instead of the
             usual whatever.How can I set the tabs to 4?
            "

        And the typical answer was:

            "In .emacs, set the variable tab-stop-list, like so:
             (setq tab-stop-list (list 4 8 12 ...))
            "

        Well, I didn't want to touch the original tab-stop-list, since I
        want to have 8 tabs normally. But I like to have 4 tabs when I'm
        doing my shell programming or whatever text formatting, I though it
        was time to turn on my think-and-create-mode.

        The goal was very simple: write a minor mode, that you can turn on
        and off, which handles _only_ tab key. That shouldn't be hard at
        all.

        Yes, If someone of you know, I have also written tinyindent.el,
        which is tab-alike mode too. But there is a subtle, but very
        important difference, it behaves according to previous lines, so
        its job is to "line up" with the previous text(code).

        Instead, this mode was supposed to be plain rigid. The tab goes
        where I want it, and I can control the amount of movement to either
        direction, back or forward. Hm. Maybe I should merge these two
        packages in long run?

    Overview of features

        o   Programmable TAB. If you set the count to to 4,
            you can virtually program "blindly" without any other modes.
        o   Selectable: 2, 4, 8 .. space indent.
        o   moving commands: tab-forward, tab-backward
        o   modify commands: tab-insert, tab-delete
        o   indent commands: tit-indent-by-tab-width, forward , backward
        o   Simple Positioning of braces { } supported when TAB hit.

        Extras

        o   special auto-indent function offered for return key,
            switch it on, and you can continue your shell,awk,perl comments...
        o   Press C-c TAB and your in constant indentation mode where
            keys "wq" "as" "zx" indent region <--> by 1,2 and 4 until
            esc pressed.

    What this package does?

        It mimics `tab-stop-list' with minor mode if some analogy can be
        drawn. You only set one variable, that controls the amount of
        movement, whereas you would have to put many values inside
        `tab-stop-list'. The variable for tab widths is:

            tit-:width-table

        The advantage is, than you don't have to alter the `tab-stop-list'
        at all. When the mode is off, the tabs are back again as they were
        (or as the other mode thinks how the tab should be)

        But what I like most, is the movement and deletion functions, that
        really make day shine when you program. They all operate according
        to the variable `tit-:width'. Try out the functions

            tit-indent-by-tab-width
            tit-indent-by-tab-width-back

        to format region of code forward and backward easily and you know
        what I mean. (this is different than using command indent-region)
        When you delete backward "one indentation level", you can do it
        when the division factor is 2/4/8.

        The nearest column that satisfies the division factor is used when
        "indenting back". See the example:

        Before:
                  *             << cursor here
        123 567 9012            << columns, starting from 1

        After:
               *                << cursor here, at div-factor compliant point
        123 567 9012            << columns, starting from 1

        Don't forget to look at function

            tit-change-tab-width

        Which allows you to switch between 2, 4, 8, you name it,
        tabs widths with one key press.

    Major modes and this minor mode

        When you use some programming mode, say C++ mode, it usually
        provides function to indent the line right when you press tab key.
        If you then turn on this mode, you loose the mode specific indenting,
        because turning on minor mode overrides the underlying major mode
        bindings.

        I have included one simple function to deal with major modes: it
        preserves the original indenting style in some extent, so that you
        can use this minor mode and current major mode together. In
        variable `tit-:tab-insert-hook' there is function
        `tit-tab-mode-control' which looks at variable

            tit-:mode-table

        and if the mode is listed in the table _and_ current point is at
        the beginning of line, then the line is handled by original major
        mode and not by this minor mode. This allows you to indent the
        line initially and then use normal tab indent within the current
        line according to this minor mode. I mostly use this tab mode to
        adjust variable placement inside code.

        However, this minor mode is normally meant to be used as turn
        on/off basis in such programming modes that indent lines when you
        pressing tab key. Current compatibility function
        `tit-tab-mode-control' only allows you to get some flexibility when
        this mode is temporarily on.

        Bind this mode to some fast key which you can use to toggle this
        mode on/off when you need tab for a moment in programming modes.
        If you don't want any support to major modes, put following into
        your ~/.emacs

            (setq tit-:mode-table nil)

    Return key addition

        In this package there is also this little function which will
        make itself a must in no time:

            tit-return-key-mode   ;; I have bound this to C-c C-m

        When the function is active, you can continue the ndentation from
        current position.

                                // Comment here. Call C-c C-m...and press RET
                                // And it automatically indents here.

        See variable

            tit-:auto-indent-regexp

        what line prefixes are "copied" along with the indented spaces.

    Development note

        This package solely concerns TAB key. Nothing outside of it is
        counted. I have no intention to make this a full fledged
        programming mode, since there is `sh-mode', `ksh-mode', `perl-mode'
        and many more for other languages. I almost added

            (make-variable-buffer-local 'tit-:width)
            (make-variable-buffer-local 'tit-:width-table)

        But after thinking I decided not to add it to this package, since
        most of the time user is satisfied with the tab "4", at least
        that's what I use mostly. And changing the width usually means
        a little flick of my finger to reach out the function

            tit-change-tab-width

        In very rare occasions one wants different tab widths in different
        buffers and in those cases you can add the lisp commands
        `make-variable-buffer-local' to mode hooks or after `tit-:load-hook'.


Tinytag.el -- grep database: example show C++ synatx call while coding

    Preface, overview of features

        o   simple database searching, some analogue to emacs TAGS package.
        o   you can flip databases very easily to show the right data.
        o   example: showing c++ funcall syntax in echo area while you program.
        o   installs hp-ux or netbsd c function databases automatically.

    Story behind this package

        The word "tag" refers to famous tags package in emacs that allows
        you to browse your c/c++ code easily.

        I was in the middle of my c++ project at work and I noticed that I
        constantly looked up the man pages to find correct syntax for
        calling stdio.h c-functions. I never remembered them right from out
        of my mind. I calculated, that I spent over 40% of the time with
        the man pages, figuring out what #include statements each function
        might have required, and what type of parameters they needed.

        I've had it. no more. there must be a way out of this...

        If you have programmed in lisp, you propably know package called
        eldoc.el (get it fast if you haven't) by noah friedman
        <friedman@prep.ai.mit.edu>. It shows you the lisp function call
        arguments when your cursor is right over some function.

        what a cool tool! You never have to go to elisp info pages just to
        check what the function takes, and you don't have to pop up extra
        buffer with c-h f <func>. It's a real time saver.

        Okay, now you guessed what I was after... started immediately
        thinking how could I get similar interface to c++. Since eldoc
        looks the lisp args from memory (emacs obarray, symbol storage), I
        could do the same, but with external reference files: databases.

        I needed to generate all function syntaxes out of the man
        pages. that was pretty easy with some piece of perl code. the final
        output after ripping all the 3c man pages was like this, which I
        put to database 'funcs'

            <dirent.h> dir *opendir(const char *dirname);
            <dirent.h> int closedir(dir *dirp);
            <dirent.h> int readdir_r(dir *dirp, struct dirent *result);
            <dirent.h> long int telldir(dir *dirp);
            <dirent.h> struct dirent *readdir(dir *dirp);
            ...
            <string.h><strings.h> char *index(const char *s, int c);
            <string.h><strings.h> char *rindex(const char *s, int c);

        Notice that my perl stuck the '#define' statements to the beginning
        of each function.

        When I had the 'function' database, only thing I needed more was
        the lisp code to handle the database lookup for me and display the
        c++ call syntax for current function name under point. now i have
        "eldoc" running in my c/c++ buffer too with the help of this
        tinytag package.

        Hope you find some other uses for this package too. I assume you
        can use similar approach for any programming language. just set up
        the database, entries to search/display, per line.  that's it.

    Word about installation -- performance problems [19.29 or lower]

        Skip this part if you have 19.30+

        When you load this package, it immediately installs an _example_
        post-command function. It assumes that you're using the "Having a
        test drive" C++ database and stored it as explained.  You propably
        want to remove that default post-command function and use your own
        definition. Here is how you remove it.

        Doing this is also recommended if you don't want post command
        actions, but want to use the tinytag-main[-mouse] functions
        directly. Call them only when you need them.

        .   before any load command say:
            (setq tinytag-:load-hook nil)
        .   If package is already loaded, say:
            C-u M-x tinytag-install.

        If your databases are big, or if you're afraid of the overall emacs
        performance I STRONGLY ADVICE THAT YOU REMOVE THAT post-command
        with methods (2) or (1) You can always call the database with the
        supplied keyboard or mouse commands when you need the information.

    Having a test run

        I have included sample C++ database from my HP 10 man 3C pages,
        the HP C functions. The list was generated by a little
        perl script I wrote.

        So that you can put this package in immediate use, you can use the
        sample HP C-database, but rememeber, you really should replace
        those definitions with your own systems equivalents, because
        not all functions are found in all systems. Vendors are different.

        This is how you test this package.

        o   Go to empty buffer
        o   Add statement "strcat(a,b)" to the buffer
        o   Turn on C++ mode
        o   Be sure to have tinytag on (M-x load-library tinytag.el)
        o   Move your cursor over the word "strcat" and wave it
            back and forth about 5 times. This is needed for older emacs.
            <For 19.30 and up, you just have to move cursor once>

        If the "show up" time is too low for you, you can decrease
        the threshold value. (For emacs lower than 19.30 only)

            (setq tinytag-:post-command-hook-wakeup 10)

        You should see the "strcat"'s function's definition displayed in
        the echo area. Next, you can start writing your own databases to
        languages you use.

    Differencies between 19.30+ and lower

        The 19.30 Emacs has idle hook, which runs after you move cursor. It
        doesn't run if you move mouse.  19.28 on the other hand has post
        command hook, that runs every time you either move cursor _OR_
        move mouse.

        Now, to get display fast in 19.28, you propably want to wave
        your mouse fast couple of times. In 19.30 you can have immediate
        display with just one cursor move over the word.

    What to do if you don't see the definition displayed?

        First of all check that this pacakge is installed into
        `post-command-hook'. Emacs has a habbit to empty the hook if you
        press `C-g' in the middle of running lisp code. Call this
        function and it does the installation again.

            M-x tinytag-install

        Next, if you have confirmed that the hook is on, tun on debug
        with

            M-x tinytag-debug

        Then call this function directly over the word whose definition
        you want to display (eg. strcat in C++)

            ESC ESC (tinytag-post-command-1)    ;; 19.30+ (ESC ESC :)

        After that call there is buffer *tinytag-debug* that has some
        information about called fucntions and parameters. Please
        investigate the call chain for possible problem. Is the database
        selected right? if the regexp used for search right? If you don't
        know how to read the debug buffer's output, just send the buffer's
        content to me and describe what you did and what was your current
        major mode.

    Thank you

        Peter Simons <simons@petium.rhein.de> sent me
        NetBSD and Linux C databases and his perl script can help you
        to create your own database from the man pages.


Tinytf.el -- Document layout tool for '(T)echnical text (F)ormat'

    Preface, Jan 1997

        Late in the your 1996 I decided to put several text documents
        available to my University's ftp site. However I tried to find some
        decent text2html converter, so that I could let people read docs in
        nicer format with their favourable net browser. I didn't find any
        suitable program to do the conversion and that made me code a
        little perl script which generates quite nice html page from plain
        text file. For example the documentation in this lisp file can be
        very easily converted into html page.

        In addition I wrote Emacs mode to help me to write and format the
        text for that perl filter.

        In the end of package you find PGP signed tar file that contains
        additional progrmas for making html pages out of tetx file that has
        been written using 'Techical format'.

    Overview of features

        The text layout you write

        o   You write text in rigid format called 'Technical'
        o   There are only two heading levels, one at column 0, and
            another at column 4. NO OTHER SUB-HEADINGS SUPPORTED.
        o   Text is written in column 8
        o   Each column has different meaning how text is intepreted
            into html with t2html.pls perl script.
        o   The full 'Technical text format' is described in the
            function description of `titf-mode'.

        This package

        o   Shows text with outline style: you can open and close
            headings.
        o   Provides commands to move among headings easily.
        o   Capitalizes heading with one command.
        o   Numbers headings with one command.
        o   Text is untabified in regular intervals.
        o   On-line help in 19.30+. It assist you writing the text
            by displaying message in echo area: how the text is intepreted by
            t2html.pls program. (how the text looks in html)
        o   Offers functions to mark text with special text MARKERS that
            produce <STRONG> or <EMP> in the html output.

    What is 'Technical text format'?

        In short: it is list of text writing and formatting rules.
        And you're looking at it right now in this document too.

        This package offers minor mode for text files and helps you to
        maintain correct layout. You can even convert file into html very
        easily with the attched perl script at the end of tinytf.el code
        file. You don't need to know a shred about the html language
        itself. And it is much easier to update text files, than deal with
        html itself. When you have text ready, you just feed it to the
        t2html.pls perl script and it gives you nicely formatted html page.
        Writing html *home* pages is different story, but putting some text
        document available in html format is easily made possible with this
        package.

        In the other hand, while you may not be interested in html, you
        could still consider writing your documents in 'Technical format'
        -- with word *technical* I refer to the layout of the text, which
        is very _rigid_. In order to use facilities in this package,
        eg. heading hiding/showing, the headings must be placed in
        columns 0 and 4 and the first word must be in *uppercase*.  The
        actual text you write starts at column 8.

        If you decide write text like this, you become accustomed to the
        layout very quickly and it also helps keeping your documents in
        the same format.

        All in all, this package was primarily designed to help writing
        text documents for t2html.pls and viewing document in *outline*
        styled selective display. Please refer to mode description for
        full details of the text layout format.

    TF described briefly

        --//-- TF decription start

        0123456789 123456789 123456789 123456789 123456789 column numbers

        Table of contents

                Do not write any text inside this heading. It will
                be generated by tinytf.el automatically with M-x `titf-toc
                command.

        Heading 1 starts from left

         emphatised text at column 1,2,3


            This is heading 2 at column 4, started with big letter

                Standard text starts at column 8, you can
                *emphatize* text or make it _strong_ and show
                variable name like =ThisVariableSample=. notice that
                `ThisIsAlsoVariable' and you can even _*nest*_ the markup.
                more txt in this paragraph txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt txt txt txt

               strong text is between columns 5, 6, 7
               "Special EMP text in column 7 starts with double quote"

                txt txt txt txt txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt

                 strong text at columns 9 and 11

                  Column 10 has quotation text
                  Column 10 has quotation text
                  Column 10 has quotation text

                    Column 12 is reserved for code examples
                    Column 12 is reserved for code examples
                    All text here are surrounded by SAMP codes

            Heading 2, at column 4 again

                txt txt txt txt txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt

                o   Bullet 1 txt txt txt txt txt txt txt txt
                    ,txt txt txt txt txt txt txt txt

                    Notice that previous paragraph ends to P-comma code,
                    it tells this paragraph to continue in bullet
                    mode, otherwise this column at 12 would be
                    intepreted as SAMPLE code.

                o   Bullet 2, text starts at column 12
                o   Bullet 3. Bullets are adviced to keep together
                o   Bullet 4. Bullets are adviced to keep together

                .   This is ordered list nbr 1, text starts at column 12
                .   This is ordered list nbr 2
                .   This is ordered list nbr 3

                .This line uses BR code, notice the DOT-code at beginning
                .This line uses BR code
                .This line uses BR code

               "This is emphatized text starting at column 7"
                .And this text is put after the previous line with BR code
               "This starts as separate line just below previous one, EM"
                .And continues again as usual with BR code

                See the document #URL-HOME/document.txt, where #URL-HOME
                tag is substituted with -base switch contents.

                Make this email address clickable <foo\@site.com>
                Do not make this email address clickable -<bar\@site.com>,
                because it is only an example and not a real address.
                Noticed the minus(-) prefix at the beginning of url?

        Heading level 1 again at column 0

            Subheading, column 4

                And regular text, column 8
                txt txt txt txt txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt
                txt txt txt txt txt txt txt txt txt txt txt txt

        --//-- TF decription end

    Post command note

        While you type text in the buffer, the post command activates at
        regular intervals to untabify the buffer. The untabify is done
        because it makes formatting text easier and when you print the text
        file, you can be sure that the output is the same regardless of
        the tabs.

        If you have Emacs 19.30+ there is additional help feature available
        to you. When you sit still in some column position for few seconds,
        the column description will be shown automatically. That should
        help you keeping informed of the text layout.

    How do you write text

        This package turns on two minor modes: `tit-mode', that handles your
        TAB key movements and `titf-mode', the Technical format minor
        mode.

        If you're uncertain about how the column will be treated in html
        output, call following function. If you have 19.30+ this is not
        necessary, see note about post command above.

          Do you wonder why 'z' prefix is default? Well, I wanted a fast
          key that was mostly unused. You can change that if you prefer
          some other key. See installation.

            z RET   titf-column-info-display

        Normal text you write as usual, but if you want to mark regions
        as "quotations" or "code examples" there is appropriate indent
        commands

            z /     titf-indent-region-text
            z '     titf-indent-region-quote
            z ;     titf-indent-region-sample
            z :     titf-indent-region-strong

            z t     titf-indent-paragraph-text
            z a     titf-indent-paragraph-text-as-is
            z l     titf-indent-paragraph-text-and-fill
            z q     titf-indent-paragraph-quote
            z Q     titf-indent-paragraph-quote-and-fill
            z s     titf-indent-paragraph-sample
            z 0     titf-indent-paragraph-zero

        The `titf-indent-paragraph-text-as-is' is a bit special, because
        it won't fill the text while it moves the paragraph to the text
        position. Instead it adds symbolic <BR> codes to the front of every
        moved line. In html this ensures that the lines will be shown
        exactly as you see them. See also BR mark commands.

        There is no functions for bullet creation, because you can write
        them easily by hand. Remember to use some filling mode to fill
        bullet text nicely (filladapt.el). Bullets look like this

            o   This is bullet..
                and cont'd line here
            o   Yet another buller
                and cont'd line here

        The `tit-mode' will advance your tab key by 4 every time, so the
        text in the bullets go to the right column (12). Remeber also to
        keep the `tit-return-key-mode' on, that allows continuing
        indented lined from the same indent level when you press return.
        See also bullet conversion command, which reformats previous
        text that used dashes(-) to separate bullets.

            z b     titf-bullet-format

    BR marking commands

        In Html; the text would normally wrap according to the borwser's
        page width. But sometimes you may witsh to tell exactly that
        it shouldn't wrap the lines according to browser. For example
        if you want to include a quoted text "as is" from the usenet
        posts to your page, you need o add symbolic BR code to the beginning
        of each line. Like including the following quotation

            >>Jim has a good point here...
            >>I would have expected that the symstem depends on..
            >Yeah; but you hadn't looked at the /usr/adm/today.log
            >

        In order to add this to your page "as is"; you can do this:
        indent it as "Sample" and it will automatically show like that.
        But normally you want it to show as quoted text where you refer.
        Then you do:

            z Q         titf-indent-paragraph-quote
            z m b       titf-mark-br-paragraph

        Which will prepend dot-code(.) to the front of every line.
        You can also add the *dot-code* by yourself or use following
        command

            z m B       titf-mark-br-line

    Heading writing and handling

        You can only use 2 heading levels, which normally suffices.  Sorry,
        there is no support for more deeper headings. You start headings
        with big letters or number at column 0 or 4. Here is some
        specialized commands for headings.

        This one converts first character of each heading to
        uppercase. This fixes mistakenly left lowercase letters.

            z f h     titf-heading-fix

            before command:
            heading
                heading

            after command:
            Heading
                Heading

        You can (re)number heading easily with following command. If
        there is no number in the line, one is added to the beginning of
        heading.  And if you have added new heading somewhere in the
        middle of text, just call this function and it renumbers all
        headings again.  Running commadn with *prefix* *arg* removes
        numbering.

            z f 0     titf-heading-numbering

            before command:
            heading
                heading
            heading
                heading

            after command:
            1.0 heading
                1.1 heading
            2.0 heading
                2.1 heading

        One note about renumbering. Some people write heading number so
        that they are closed with parenthesis. This style is not
        recommended with technical format style and when you do renumber,
        those parenthesis will be removed. The parenthesis style is not
        supported because it is visually more clearer if you just write
        plain numbers without extra parenthesis.

            before command:
            1.0) heading
                1.1) heading

            after command:
            1.0 heading
                1.1 heading


    Heading fixing

            z f a   `titf-fix-all'
                    Do lot's of things. Trim away trailing blanks
                    from buffer. Untabify buffer.
                    Renumber headings if needed. Delete extra whitespace
                    around headings.

            z f c   `titf-heading-fix-case'
                    convert current heading to lowercase

            z f C   `titf-heading-fix-case-all'
                    convert all heading to lowercase

    About table of contents

        When you write text, you don't write the table of contents, but
        the headings. Be sure to add heading "Table of contents" somewhere
        in the document. To generate table of contentns use commands:

            z T             titf-toc, Try with C-u argument too
            z mouse-1       titf-toc-mouse

    Selective display

        The hiding and showing of the headings and their text is done by
        using the outline/folding style display. There is no magic in this;
        but there is two interesting commands that you can use in any
        selective display buffer.

            z P     Prints selctive display (what you actually see)
            z C     Copy selective display

    Word about key definitions when mode is turned on

        When the minor mode is active it overrides some commonly used
        keybindings and moves their original function under Control key.
        For example:

            original PgUp    --> Now Control-PgUp
            original PgDown  --> Now Control-PgDown

            PgUp             --> Moving heading backward
            DownUp           --> Moving heading forward

        If you are using X envinronment or your emacs recognizes mouse,
        then there is one handy binding that opens or closes heading
        levels when you click over them.

            [mouse-3]       titf-mouse-context-sensitive

        If you press this mouse button anywhere else than over the
        headings, it'll call original binding. This feature is similar as
        what is used in folding.el

    Code note: about the outline layout

        Speed was my primary goal when I added the outline code. But that
        came with a price: I would have liked that the Heading 0 were
        separated by at least one empty space so that the buffer would
        look visually better.

            heading1-1
                heading1-1
                heading1-2
                                        << empty space here
            heading2-1
                heading2-1
                heading2-2

        But that would have required adding some extra code to do bound
        checking every time the block is collapsed/opened. Currently I'm
        not going to add that checking because it would reduce speed and
        the check would cause unnecessary complexity to current code
        flow.

        If I have time, I may take a look at that more. For now, please
        try to bear the spartan look of the outlined headings.

        Please do send me a patch that would correct the "spartan" look,
        if you decide to hack my code. Also check that the performance
        isn't decreased much with elp.el. [Yes, the performance matters
        very much: I hide/unhide text files that are 200K and written
        in TF format.]

    Code note: prefix key 'z'

        The prefix key definition is on `titf-:mode-prefix-key' That is
        currently "z" by default. At least it is seldom types "zz" inserts
        plain "z". I wanted to choose fast key and avoind wrist pain
        as much as possible. When you write TF text, you use this mode a lot
        and accessing commands should be easy too.


Tinyurl.el -- Marks and jump to urls on current line

    Preface, oct 1997

        Hm. one day a collegue of mine had a problem with his VM and he
        explained to me that he wanted the `mouse-2' to run netscape
        browser instead of the default Emacs `w3' browser. While he was
        waving his cursor over the http link, I suddendly realized: that
        I wanted that in my RMAIL buffers too. (I later moved straight to
        GNUS). It seemed that every package had it's own url handling: VM, TM,
        GNUS, MH?

        But really, how about the rest of the buffers and modes? There was
        no general ULR dispatcher minor mode that would work with any buffer
        and with any mode.

        Now there is; I can browse any buffer or document and jump to URLs
        on the line. Works for programing modes too. You just position
        the cursor somewhere on the line, wait 2 secs  and the URLs are marked
        ready for launching.

    Overview of features

        o   General URL handler: not just the regular http, ftp, but
            also for programming languages like Perl/Lisp/C++ and
            man page cut(1) references and more...

        o   Requirements: In XEmacs, you must have `overlay.el' package.
            Emacs needs nothing special.

        o   When this global minor mode is on, wait few seconds and the
            current line will be scanned for urls. Because not all
            terminals show clolor, there is additional "!" character added to
            the front of URL for calling you to *push* it.
        o   Once the minor mode is turned on, it occupies every buffer,
            but there is also function to turn the mode on or off per buffer
            basis, see `tiurl-mode-1'. When new file is loaded,
            `tiurl-mode' is activated for the buffer too.
        o   Defines binding `mouse-2' and `M-RET' to call the url at
            point. These bindings are electric: If there is no button to push,
            the original binding is called according to underlying mode.
        o   You can change the url handler sets on the fly: eg.
            call lynx for a while, then switch to Netscape or use your custom
            browser. See `M-x' `tiurl-set-handler'
        o   Centralised url handling. If you call `tiurl-install-to-packages'
            then GNUS, TM, VM etc. now call TinyUrl and you only need to
            configure things in one place.

    Technical note

        The URL is highlighted by setting `mouse-face' to 'highligh. But
        at least my Emacs 19.34 in Unix X window sometimes won't show the
        highlight when I move mouse cursor over the url. Go figure why.
        I have heard similar reports from XEmacs 20.4.

        If you know what is causing this effect, let me know.

    Turning the URL recognizer on

        After you loaded the package with `require' or via autoload,
        calling `M-x' `tiurl-mode' will toggle the global minor mode on and
        off. The modeline indication shows brief `Ux' when the mode is
        active. (x) is the shortname for browser that will activate, eg. "n"
        for "netscape" browser set, (l) for lynx and (w) w3.

        If you want to turn the mode on or off for current buffer, use
        function `tiurl-mode-1'. If you visit new files, the `tiurl-mode'
        is enabled. if you make new buffers, the `tiurl-mode' is not
        enabled.

    Editing the url and selecting access method manually

        You can pass a prefix argument like `C-u' before you press
        `mouse-2' or `M-RET' and edit two parameters: a) The URL location
        itself and b) the access method. Say eg. that your default command
        table is netscape and you see url

            file:/users/foo/file.txt

        The `file:/' would be normally considered external and accessed via
        `url' method, which in this case is netscape. But you would like
        to use Emacs `find-file' instead. Send `C-u' and leave the url as
        is and change access method to:

            file

        That's it. Remember however that you have full control and
        if you choose nonsense access method, which has nothing to do with
        the url, then you also carry the results, whatever they may be.

    Ignoring URL in the buffer

        You can use hook `tiurl-:dispatch-hook' to check URL. If any of the
        functions return t, then the original binding in the mode is called
        and the TinyUrl is not used.

        Eg. In Dired buffer you want to ignore all URLs. There is default
        function `tiurl-dispatch-ignore-p' that does just this.

    Centralised URL handling

        If you called `M-x' `tiurl-install-to-packages' or had installation:

            (add-hook 'tiurl-:load-hook  'tiurl-install-to-packages)

        then GNUS, VM, TM, and other packages redirect urls to TinyUrl.
        This way you don't have to setup each package to your taste.
        Plus you got the benefit that you can change url handler set
        on the fly with `tiurl-set-handler'.

    Ignoring some buffers for mode turn on and offs

        If you want to exclude some buffers from the mode turn on or offs,
        say *VM* which does its own highlighting, then define your
        custom function like this

            (setq tiurl-:exclude-function 'my-tiurl-exclude)

            (defun my-tiurl-exclude (buffer)
               "Exclude some buffers that use their own highlighting."
               (string-match "VM\\|Article" (buffer-name buffer)))

        This only concern the golobal `tiurl-mode' function. You can
        still use `tiurl-mode-1' anywhere to toggle the mode setting.
        You use this variable when you don't want `tiurl-mode' to
        appear in buffer at all.

    Cacheing URLs for later use (offline reading)

        If you're not connected to the Net, then it doesn't make sense
        to call browser directly, but instead cache the pushed urls
        to separate buffer. When you're online again, you can go to the
        cache buffer and relaunch pointers.

        The offline reading is possible with Gnus, where you can toggle
        between "plugged" and "unplugged" Gnus. The default unpluggged
        condition detector is `tiurl-unplugged-p'. It returns nil if you're
        running Gnus and it's in unplugged state.

        You can place your own unlpugged state detector to variable
        `tiurl-:unplugged-function'. Cache buffer used is
        `tiurl-:url-cache-buffer', which is *URL-cache* by default.

    Validating url

        The `tiurl-mark-line' function doesn't check the validity of a
        matched regexp that was marked as pushable url. It's a dummy
        function that can only attach "buttons" and does nothing about
        their contents. But when you actually push the url, the url is run
        through functions in `tiurl-:validate-hook'. When any of the
        function returns t, it is a *go* sign. The default handler
        `tiurl-validate-url' rejects any url that match "foo|bar|quux".

        See also `tiurl-:reject-url-regexp' for more simpler use.

    Choosing what agent handles which URL

        There is predefined `tiurl-:command-table' which is consulted where
        URL request should be delegated. By default http:// or ftp:/ or file:/
        requests are handed by `browse-url-netscape' and remote tar or gz
        fileas are loaded with ange-ftp.

        You can completely customize the URL delegation by writing your
        own url handler set and placing it to `tiurl-:url-handler-function'.

    Changing the url handler list

        When you click the url to run the viewer, the current url handler
        list determines what method is used. Eg. If you normally want
        netscape to handle your URL, then the current set is labelled
        "netscape". But in some situations, where you want to eg. view text
        files or your resources in PC EXceed are low, or you want fast browser;
        then there is also "lynx" set. You change the browser set with command

            tiurl-set-handler   Meta mouse-2

        The modeline will show the first string from your active set; `Un'
        for Netscape, `Ul' for lynx set and `Uw' for w3 based set. You can
        add as many handler sets as you want by adding them to
        `tiurl-:command-table'

    Exclamation character marks pushable URL

        When you see character "!" (netscape) or "?" (captain hook, W3
        browser) to appear in the front of the URLs, then you know that
        items are pushable. You can call the URL by clicking it with
        `mouse-2' or tapping `M-RET'. In the following line, two url's have
        been detected. The first one sends normal http request and the
        second one would create mail buffer for the address.

            Some previous line here
            !http://foo.cm/dir/file.txt  !<foo@bar.com>
            Another line below

        Elswhere your `mouse-2' and `M-RET' behave as usual. If you would
        like to paste(the mouse-2) somewhere in the "previous" or "another"
        line, that would work as you expected. But you can't paste inside
        the URL, because the URL is currently activated. If you need to do
        something like that, then you can use either of these strategies:

        o   Use `C-y' to yamk the text inside marked url.
        o   move cursor out of the URL line; wait few seconds for
            "!" to disappear (the line is cleared). Go back and paste before
            you see "!" to appear back again.
        o   Turn off the mode off with `M-x' `tiurl-mode-1' for a while if
            you don't need the URL features right now.

          _Note_: The character "!" that you see, is not a real editable
          character, but part of the overlay. While your text may appear to
          be modified. That is not what happened. See Emacs info pages for
          more about overlays.

        You can use variable `tiurl-:display-glyph' to control if the
        glyph is shown or not.

    Face that controls the highlighting the URL

        The properties of the URL overlay is defined in variable
        `tiurl-:overlay-plist' and there may be some things that you
        can customise. Suppose you're a keyboard user and you don't
        use mouse a lot, therefore the used face property `mouse-face'
        is not the best for you. You want that the url is marked visually
        right away. To do the cahange, copy `tiurl-:overlay-plist' to
        your .emacs, before the the load or TinyUrl and have it read:

            (defvar tiurl-:overlay-plist
             '(rear-nonsticky   t
               rear-sticky      nil
               priority         1
               face             highlight        ;; was: mouse-face
               before-string    "!"
               url              t
               owner            tiurl
               ))

    Accepted email URL

        The default accepted format is <foo@site.com> and if you see
        foo@site.com, that will not be recognized. Your can get this
        accepted by changing `tiurl-:email-regexp'. You could use \\< and
        \\> (word border marker) regexps instead of default characters < >.

    Support for programming language URLs

        I'll gladly support any other languages. If you know the language
        you're using, drop me a mail and help me to undertand how I would
        add support to it. Especially I'd like to hear specs from Java
        programmers.

       C/C++

        The default agent to find C/C++ .h files is find-file.el's
        `ff-find-other-file'. This will handle your #include urls.

       Perl

        There is support for finding the perl "use package;" and "require
        package.pl;" urls via `tiurl-find-url-perl'. The default find path for
        perl is `@INCPATH'. Perl related urls are delegated to TinyPerl
        package. in addition perl compile error lines are recognized:
        "ERROR at FILE line NBR".

        Perl pod page references in the format "perlfunc manpage"
        "See [perltoc]" are recognized and they take you to the pod page.

       Emacs lisp

        The url handler function is `tiurl-find-url-lisp' and Emacs `load-path'
        is searched. The usual urls "load-file", "load-library" "autoload"
        "load" are recognized. If you need to jump to function or variable
        definitions, you want to use a TinyLisp package, which offers
        minor mode solely for Emacs lisp programming purposes: Profiling,
        debugging, snooping hooks, you emacs packages, browsing code etc.

       Other languages

        Please let me know if you know package or you have code that can
        find other Language's URLs.

       Memory list

        o   Remember to define `ff-search-directories' for *find-file.el*
            so that your C/C++ #include <url> will be found correctly.

    Filename filter eg. running catdoc for MS Word files

        There is table `tiurl-:file-filter-table' which can be used to
        handle found url. Eg if you want to treat all files ending
        to extension .doc as MS word files and feed them through
        `catdoc' <http://www.45.free.net/~vitus/ice/catdoc/> which spits 7bit
        out, you can associate shell action to handle url. Respectively
        if you want to use `xv' for viewing your images, you can associate
        that to the url. The default table handles these cases if you
        have xv and catdoc present. See variable description for more
        information. (You can also use your custom lisp url handler there)

          If you want to load the raw file into emacs, just supply
          prefix argument when you push url and you will be given choice
          to by-pass the set filters (if there is any) for the url.

    Code note: adding buttons to the current line

        The idle timer process is used to mark current line's urls with
        overlays. Please wait few seconds on a line and the ulrs that
        can be *pushed* are marked. If there is no idle timer available,
        then a `post-command-hook' is used.

         [Emacs with no `run-with-idle-timer' function]

        Using `post-command-hook' is not an ideal solution, but at least
        this package works with older Emacs versions. The threshold how
        quicly the line is scanned for url buttons is determined by
        variable `tiurl-:post-command-hook-threshold'. The deafult value
        7 should give you enough time to use `mouse-2' (paste) before the
        line is buttonized. Remember that *vawing* you mouse creates
        events, so you can force buttonizing the line quite quickly.

    Code note: overlay properties

        The overlays have nice feature where you can add string to be
        displayed to the side of an overlay. See the overlay properties in
        the Emacs info pages for more. The overlay `priority' in this
        package is by default set to highest possible, so that the URL
        highighting is guarranteed to be dislayed. If you use some other
        package that also uses overlays, then decrease that package's
        overlay priorities. (If the package doesn't allow you to adjust the
        priorities, contact the package maintainer. To my opinion the
        priority value should be defined for all overlays).

        The only part that you should touch in the property list of the
        overlays, is the displayed string. You can choose anything you
        want, but prefer one character. By default the "!" is shown in
        both Windowed and non-windowed version.

        The overlays also have property `owner' which tells where the
        particular overlay belongs. In this case the owner is this package,
        `tiurl'. IMO, all overlays should identify themselves via
        this 'owner property.

    Code Note: overlay management

         Let's consider what `font-lock' does for buffer for a moment: it
         mrks whole buffer with faces (colors). I didn't want to bloat the
         buffer with full of clickable overlays, while I could have done
         that. Instead old overlays are removed and new ones are created
         only for current line, typically the count is between 1 .. 4. When
         you move to another place, these old overlays are destroyed and
         new ones created. The current line may now may have only 1 URL, so
         only one overlay was needed this time.

         For that reason you must wait for idle timer process to do its
         work on current line, before you can see those clickable URL
         buttons.

         Using only small number of overlays keeps the code clean and user
         friendly. It's also faster than buttonizing whole 500K faq
         document in one pass.

    Code Note: Adding support for new URL type

        If you see new url that you would like to have supported and you
        know lisp, then the changes needed are:

        o   `tiurl-mark-line', Add regexp to match the URL. Think carefully
            Where to put the regexp and make is as restrictive as you can.
            Remember that first OR match is picked.
        o   `tiurl-type', Add new type for URL
        o   `tiurl-command-table-default-1' Add default handler
        o   Write the URL handler.
        o   Run `tiurl-command-table-defaults-set' to make the new handler
            seen in the default agent function list

        To make changes do this:

        o   copy original version to `tinyurl.el.orig'
        o   Make changes
        o   Produce diff `diff -u  tinyurl.el.orig tinyurl.el'

        Then send diff to the maintainer. Use unified diff format (-u)
        if possible. Second chance is to use context diff (-c). I won't
        accept diffs send in `old' format: diff tinyurl.el.orig tinyurl.el

    Sending a bug report

        If you have a line where url is highlighted, but it doesn't cover
        right characters, then do this:

        o   `M-x' `tiurl-submit-bug-report'
        o   Copy the _WHOLE_ line to the mail buffer.
        o   Turn on debug with `M-x' `tiurl-debug-toggle'
        o   Be sure Url gets highlighted. End debug with
            `M-x' `tiurl-debug-toggle' and copy the content of
            *tiurl-debug* to the mail
        o   Attach desctiption of the bug and send mail.

        Btw, in win32 the file url on `C:' disk is written like

            file:///C|/foo/bar/baz.html#here



Tinyxreg.el -- Restoring points/win cfg stroed in reg. via X-popup

    Preface, oct 1995

        I saw post in comp.emacs by  <cpg@cs.utexas.edu> Carlos Puchol

            I find that my life would be remarkably eased if only I
            could "jump" to the marks from a menu.

            Please, let me know if i can implement this myself
            through some sort of macro or something.

        As a hobby I started quicly sketching what the person should
        do.. I dind't plan to write any code. It just happened that I
        got interested in the subject and started experimenting with
        couple of functions.

        As a result I had complete package in hand within an hour or
        so, which I also posted to the group. Later on I properly
        packaged all the functions here and rewote whole thing.

    Overview of features

        o   Stores point/win cfg to X-POPUP LIST while storing it to register
        o   Use X-popup to pick register associated with the file.

    Register update note

        If you wonder why some of the registers disappear from the popup
        while you were sure you just stored some point to them, the reason is
        here.

        If you kill some buffer, or reload it again with
        find-alternate-file that means that the register reference "dies".
        That's why the main function tixr-jump-to-register calls a house
        keeping function tixr-update to make sure you can't select invalid
        registers. So, trust the poup: it tells what registes are
        available.




End of file
