Document id

$Id: emacs-tiny-tools-part1.src,v 1.3 2002/09/14 18:40:37 jaalto Exp $

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 Emacs path configuration, email, Gnus spam reply functions, 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: you cannot download single files or install only a single file. the minimum requirement are all libraries tinylib*.el plus any individual utility package.

Generated documentation

This document is automatically generated from the Emacs lisp files with 2 small perl scripts. ripdoc.pl is available at http://cpan.perl.org/modules/by-authors/id/J/JA/JARIAALTO/ and the other is hosted at http://perl-text2html.sourceforge.net/

      % 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

Other packages

And more...which are not listed in these


Tiny-setup.el --- Tiny Tools configure center.

Preface, overview of options

This file will configure all Tiny Tool files. The alternative method is to look into each package individually and to follow instructions there to set up the files.

To use this file, see control function tinypath-setup for full description like this:

      M-x RET load-library RET tiny-setup RET
      C-h f tinypath-setup
      M-x tinypath-setup-display
  
      M-x tiny-setup RET                       Default 'all setup
    

To setup all tools from $HOME/.emacs, use:

      (load "~/path/to/tinypath.el")   ;; Emacs autosetup, SEE THIS!
      (require 'tiny-setup)            ;; control center
      (tiny-setup 'all)                ;; configure all at once.
    

Administration

This part should concern the maintainer only.

Autoload files

If loaddef files were not included in the package or if they were mistakenly deleted. The tiny-setup.el startup is not possible without the autoload files.

To generate autoloads recursively, call function tiny-setup-autoload-batch-update with the ROOT directory of your lisp files. The only requirement is that each directory name is unique, because the generated autoload file name contains directory name: tiny-autoload-loaddefs-DIRNAME.el

Compilation check

To check for possible leaks in code, ran the byte compilation function from shell by using XEmacs compiler. The Emacs byte compiler is not that good in findings all errors. See function tiny-setup-compile-kit-all.

Profiling

To check how much time each file load would take, see function tiny-setup-test-load-time-libraries. Here are results as of 2001-03-18 running Win9x/512Meg/400Mhz, Emacs 20.7

      Timing tinyliba,  took     2.025000 secs (autoloads)
      Timing tinylibb,  took     0.011000 secs
      Timing tinylibm,  took     0.977000 secs
      Timing tinylib,   took     0.982000 secs
      Timing tinylibxe, took     0.000000 secs
      Timing tinylibid, took     0.006000 secs
      Timing tinylibo,  took     0.005000 secs
      Timing tinylibt,  took     0.011000 secs
      total time is 4.027999997138977 seconds

    


Tinyadvice.el --- Collection of adviced functions

Preface, Apr 1996

What you see here is a selection of adviced functions that have proven to be extremely useful. Some of them have been written by the author (if there is no author mentioned) and some of them have been collected form the emacs newsgroups.

Here is one example how to to fontify automatically, whenever compilation buffer runs:

      (add-hook 'tinyadvice-:compile-internal-hook 'my-compile-font-lock)
  
      (defun my-compile-font-lock  ()
        "Compile buffer fontifying immediately."
        (interactive)
        (let* ((buffer tinyadvice-:compile-internal-buffer))
          ;; According to buffer you could set up different font
          ;; keyword parameters, say for
          ;; *compilation*
          ;; *grep*
          ;; *igrep*
          ;;  My setup automatically turn on the lazy-lock too, see
          ;;  font-lock-mode-hook
          (with-current-buffer
           buffer
            (turn-on-font-lock))))
    

Note: XEmacs

These advices are for Emacs and it would be a surprise if they worked in XEmacs. Use at your own risk. Send fixed XEmacs compatible advices to maintained if you try them.

These advises and Emacs releases

Many of these enhancements could have shipped with the Emacs itself. And there was a time when these were suggested to be added to the next Emacs release. For some reason the developers were not interested in the features at that time.

How to use this package

The best way is to load this package, print the whole file and read the comments about individual functions and how they change things.

Note on adviced file functions

If you set variable tinyadvice-: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 are low of quota, e.g. you can now compress Gnus .newsrc.eld and gnus will read the .newsrc.eld.gz transparently. See write-file and find-file function documentation for full explanation of this feature.

Overview of features

In general, advices are activated only if Emacs release doesn't have similar kind of support.

Handling advices

If you have some other emacs version that is not supported in the tinyadvice-: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 tinyadvice-load-hook '(tinyadvice-install my-tinyadvice-load-hook))
  
      (defun my-tinyadvice-load-hook ()
        "Configure 'tiny tool's advices' to my taste."
        (interactive)
        ;; This diables two advices
        (tinyadvice-advice 'disable
           '(switch-to-buffer mouse-delete-other-windows)))
      (require 'tinyadvice)
    

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 by calling:

      C-u M-x tinyadvice-advice
    

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

Code note

You see this in the code:

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

If emacs version is wrong, the advice is never actually assembled. You can't activate or deactivate this function with tinyadvice-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 Breton pbreton@i-kinetics.com T. V. Raman raman@adobe.com


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

Preface, March 1994

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. Add function tinyappend-install-default-key-bindings to tinyappend-:load-hook if you want to use these key bindings.

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

    


Tinybookmark.el --- Keep file in organized sections

Preface, feb 1995

Long ago I used little function I wrote that inserted section breaks, those that I call book marks. There was also folding.el to keep the code in separate sections. Findings things was easy when you just searched either book marks or jumped between folds. Next imenu.el was announced which provided X-pop up for book marks and adding support to it was the start of this package.

Overview of features

How to keep 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. There is folding.el and tinybookmark.el, which might seem to do double job, since they both divide code into more easily manageable sections. The key point is that when folding is used, one works within some special section and possibly want to hide all the rest of the code. But when jumping easily back and forth on the buffer, it us unfolded and TinyBookmark is used. Now, to confuse you more, there is also imenu.el which can be used to jump inside code. It can be configured so that it will pick all function names inside list, and when you want to go to specific function, just pick one from imenu.

To summarize:

How to use this package

There is following function that inserts book mark on the current line

      tinybookmark-insert
    

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

      tinybookmark-repeat
    

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

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

The How-to-use is book mark, because it has & on it, whilst the latter isn't – it is used inside code to make it more readable and The latter on is not included in imenu.

About the book mark 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, a-z come 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 unintentionally 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 variables 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 first in the list, just change v- to 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 probably 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 detailed functions under h-cc, Not
      ;;  named, because there is only 2 small funcs
      ;;  easily found.
    

Again there are couple of points 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 book mark 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 "level of noisiness" 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 characters.

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 sub section 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 case statement etc.

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

Internal break 2, to separate long case elements etc.

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

Book Mark 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 book marks. 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 tinybookmark-parse which will empty the cache and re-read all book marks. If you write lot of code the points that were cached do no longer represent exact points of book marks, because they have been sliding off their places. If you want always have updated book mark points, there is variable tinybookmark-cache-update which you can set to 'always, if you want the cache to be updated always prior showing X-menu. In large buffer this remarkably slows down the menu appering. See variable for more choices.

Automatic book mark detection

In order book marks 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 book mark and the book mark name is indicated in subexpression 1 [\\(.*\\)] , look at this file, how it is constructed. In order to find all book marks 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 book marks from your RMAIL file.

One word about the regexp construction, let's see 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 book marks. See function tinybookmark-regexp-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 surprised. This is totally normal behavior: whenever you switch mode for the buffer the new mode kills all local variables, including cache information. Obviously the information must be restored when you call the hot list again. The cache could have been programmed to be buffer local, but in the present format only one cache s active at the time. This was simpler to implement and manage in the code.

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 key bindings mentioned. Hit the mouse bindings and you're running book mark package. Since the break marks are used in commentary also, the list of book marks are not in their most informative form, I use following convention to name book marks;

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

Design thoughts

Sooner or later someone wonders: "Can't we have sub-breaks listed nicely with indentation in front lines in X-popup?" Present answer "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 "#|/%" character set we limit the use of breaks. Besides deciding what are sub-breaks, main-breaks with regexp may be too slow. Besides, the breaks are intended to to give an overview of the buffer. Please use imenu to find single functions if you don't feel like tapping couple of pgUp/pgDown after the point is positioned in the break section.


Tinybuffer.el --- Change buffers 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: iswitchb.el which is included in standard Emacs distribution

If you have windowed environment and want to have hot list of your permanent buffers available, use imenu.el or tinyhotlist.el and you can select RMAIL; GNUS; VM; scratch buffers instantly.

Description

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

      (setq tinybuffer-:load-hook nil)
    

To change buffers forward or backward, the default setup would install following key bindings:

In iswitch mode, the command prompt looks like following. The mode name is put last if buffer has and associated file name, so that filename gets as much display as possible.

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

Have a look at tinybuffer-:ignore-regex which you can configure to ignore some buffers permanently.

Thanks

Original idea for this package comes from yic-buffer.el by choo@cs.yale.edu (young-il choo) 1990-08-07.


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

Preface, overview of features

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

Dired description

When you load a file from dired with dired-view-file, the file is remembered. You can load several files for viewing and when you have finished, call tinycache-flush (Defaults to C-c k in dired) to remove all the remembered (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 bunch 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, i.e. compile-goto-error, is cached if it is not in emacs already. I.e. 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 tinycache-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

Mode line 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 mode line 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 tinycache-flush or when you kill the root buffer.

For that purpose there is function tinycache-mode to turn off the cache for current buffer. When the cache mark says "+c" in the mode line, it tells you that the file will not be killed when you tinycache-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 that time all the buffers cached are checked and the ones that do not exist any more are removed.

Buffer list commands

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     tinycache-flush, remove all cached files from this dired
      C-c c m     tinycache-dired-mark
      C-c c u     tinycache-dired-unmark
    

Thanks

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


Tinychist.el --- Command history 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 sent 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 everything, so that when you load it, it will automatically load command history for the right emacs and when you exit emacs, the command history is saved to disk.

Overview of features

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 habit 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 versions are a little picky about the order of command line options, please look 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 ti::add-command-line-arg in tinylibm.el

How it works

Your emacs must support kill-emacs-hook, so that the command


Tinycomment.el --- Smart comment setting utility

Preface, Sep 1994

In 1994-10-18 Era Eriksson wrote in gnu.emacs.help that he didn't like 'modes' because they redefined his tab key strangely. What he wanted was tab 8 in _every possible case_. He wrote: "..if mode messes with tab key, I don't want it". He also wanted his comments always to be positioned at column 56 (tab #7). The problem was that how he could he add comments with tab key, when the mode occied it already. He also always used to program using fundamental-mode; what a cool dude. As a result this package was born. The original lisp file sent to Era was posted under name general-comment.el.

What's this all about, short introduction

Let's see...You're in C/C++ mode, and want to switch to better mode before starting to adjust comments. But wait, the new mode doesn't know about C++-comments! Or if you're editing ~/.Xdefauls, there is no mode for it (at the time of writing), no-one to know the comment syntax. Boom. Now it's time to give this packet a run. It hooks itself directly to \M-; replacing any previous function. The packages 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. This is handy in temporary buffers that do not have filename: e.g. scratch buffer. Repetitive calls to M-; shift between comment classes: comment is adjusted according to previous one, or move it on the line.

Overview of features

Limitations

This isn't designed for modes that have comment-end, you get only '/* */' string e.g. in C-mode and no comment class shifting.

Examples

At the end of file there is simple general editing mode, which can be used 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 writing this package.

Overview of features


Tinydesk.el --- Save and restore files between Emacs sessions

Preface, feb 1995

At work working with windowed system, Emacs stays open from day to day. In fact people seldom even logout, so Emacs and the files just wait there nicely and there is seldom a need for a sophisticated session saver.

But sometimes sometimes it may be necessary to visit lab next floor to see what's troubling a C++ program. There has to be a way to transfer the list of files that was being editing and bring them into lab where person can replicate the setup.

These functions save Emacs configuration into file, which can later be opened again in Emacs somewhere else. Later Emacs versions introduced "~/.saves*" files that you may find disturbing occupying your home directory with many files. With this package all the files are grouped in only one "state" state file, which can be reused.

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

Overview of features

      --  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.
    

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.

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".

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 $HOME/.emacs. The setup saves the state when Emacs exists and asks if you want to return to saved session on Emacs startup. (You did also copy the installation lines too...)

      (defconst tinydesk-:directory-location "~/elisp/config")
  
      (defconst my-tinydesk-session
        (concat tinydesk-:directory-location "/state.last-session"))
  
      (add-hook 'kill-emacs-hook 'my-save-session)
  
      (defun my-save-session ()
        "Save loaded files to state file."
        ;;  if you want to save dired buffers too.
        ;;  use (tinydesk-save-state my-tinydesk-session '(4))
        (tinydesk-save-state my-tinydesk-session) nil)
  
      (if (and (file-exists-p my-tinydesk-session)
               (y-or-n-p "Recover session "))
          (tinydesk-recover-state my-tinydesk-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, here is one convention that you could use. Name every filename so, that they have common prefix:

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

The XXX describes the name of the state file you just saved. Later on it's easier to use Emacs file name completion 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 tinydesk-recover-state ask for filename. Prefix arg to `tinydesk-save-state saves' says to load directories too.

Automatic state file saving

Emacs 19.29+ has feature that makes it possible to recover a session. See bunch of auto-save-list-* variables.

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, ... This package installs tinydesk-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 tinydesk-recover-state <FILE>. The name of the file of the latest saved state is in file "periodic"

Development note

There is no plan to duplicate desktop.el functionality to save points and modes and so on. This is for simple state restoring only.


Tinydiff.el --- Diff and patch minor mode. Browsing, patching.

Preface, jan 1996

Long ago there was set of simple functions lying around to generate instant diffs for the file that was being edited, before it was checked in with RCS. At the time vc.el was not in the Emacs distribution. Looking at diffs and using "goto-line" command in other buffer gave an idea to make a separate diff mode. The project turned out to be a bit bigger than just taking simple diff. You may wonder, why would you use this utility over ediff.el? If you like working with "command line" diff interface, then you may want to use this utility over ediff.el. There is a command prompt when various diff options can be manipulated with key bindings. Lik: Change rcsdiff to diff command, copy previous argument etc.

Overview of features

Taking diff

Browsing diff

Sending or saving diff

Patch

Genrating diff – parsing diff

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

      M-x tinydiff-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 tinydiff-diff-show   (I have bound this to C-z C-d)
    

And it generates diff and puts you on tinydiff-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 tinydiff-diff-show
    

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-r 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-r 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

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-r 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        e.g. 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 tinydiff-patch          non verbose
      C-u M-x tinydiff-patch      verbose
    

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

      tinydiff-:patch-list
    

To match files and their associated patch directories if you receive patches for other files regularly. This function is most useful 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.

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 tinydiff-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

Command 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.

Command 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

Command 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

There is ediff.el, which is much more complete package than this is. The 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 tinydiff-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.

Example

This hook setup turns on the view mode for easy scrolling of buffer.

      (add-hook 'tinydiff-:diff-hook  'my-tinydiff-diff-hook)
  
      (defun my-tinydiff-diff-hook ()
        "Turn on view-mode in diff buffer."
        ;; See tinydiff-:diff-buffer.
        (view-mode 1))
    

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.


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

Preface, Jan 1996

This package started evolving, when there was need for something more from ange-ftp, like background file loading. Ange-ftp also had nasty habbit of putting user to just downloaded .zip or .tar.gz buffer. That not what was usually wanted, but to download the files somewhere other than inside emacs. There was need for ability to mark files for download and get them all at once to a download directory. With standard ange-ftp you would have to load them one by one. Sometimes you may want to go associated ange-ftp buffer and give commands directly there, so a command to switch between ange-ftp and dired buffers would be handy.

Now you can do this with standard ange-ftp and Emacs dired.

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. (Further note: EFS was later installed to XEmacs and it does not work any more with Emacs.)

Overview of features

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

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:

      tinydired-:use-only-one-buffer-flag
    

Dired and ange-ftp additions

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           Mark file
    

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 marked file(s)
    

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

      a 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 "jdoe@example.com")

How to use this module 3 – special vc

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

      tinydired-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 useful packages

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

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 tinydired-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 tinydired-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

      tinydired-: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 --- Eat blocks of text at point, forward and backward

Preface, overview of features

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 other 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 standard Emacs bindings are bound instead. Many of this package's 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>              tinyeat-backward-preserve (*)
      Meta d          kill-word           tinyeat-forward-preserve  (*)
      Meta SPC        just-one-space      tinyeat-delete-whole-word (*)
      Meta k          kill-sentence       tinyeat-delete-paragraph  (*)
      Meta C-d        down-list           tinyeat-kill-line-back    (*)
      Meta ESC        mark-defun          tinyeat-erase-buffer
      Meta C-y        <none>              tinyeat-yank-overwrite
    

Story behind this package

One day the developer got frustrated of moving cursor around the point and using keys del or backspace to write C++ and LISP symbols. The start situation was:

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

He decided to change 'myname' to something else. Normally he would reach out for ESC-d for kill-word to delete myname and type the new name:

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

Next, he noticed that there were extra spaces involved. A call to fixup-whitespace would make it go away ... Hmm that was not bound to any key by default (in this particular Emacs he was using at the time), so he had to type it the long way round: M-x fixup-whitespace. His thoughts were: "Oh, why I hadn't I bound it to some easily reacheable key". The story continues. He looked at the function once more and decided that name symbol-name-mynew wasn't a good one after all. He decided to delete 3 words backward. Now, how do you do that?

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

He murmurs, "where is the command to delete backward ...". After spending valuable minutes to find the delete-backward-word command with the emacs M-x apropos and hitting the page up and down keys to find anything that would look like what he wanted, he sits back with despair, "Rats again, there is no such command". Silently he ends up tapping the backspace until he reaches correct point:

      (defun lisp- ()
                  *
    

and starts typing a new name...

      (defun lisp-my-func ()
    

All is perfect for a moment. Then, he notices that there are too many newlines above the newly created function