CaptHook - hook management for vile

Allows multiple, prioritized actions to be easily assigned to Vile's various built-in hooks.


   :perl "use CaptHook"

   :autocolor-hook <command> <label> <priority>
   :autocolor-hook-targets <label> <buffers>
   :autocolor-unhook <label>
   :buffer-hook <command> <label> <priority>
   :buffer-hook-targets <label> <buffers>
   :buffer-unhook <label>
   :cd-hook <command> <label> <priority>
   :cd-hook-targets <label> <dirs>
   :cd-unhook <label>
   :exit-hook <command> <label> <priority>
   :exit-unhook <label>
   :read-hook <command> <label> <priority>
   :read-hook-targets <label> <files>
   :read-unhook <label>
   :write-hook <command> <label> <priority>
   :write-hook-targets <label> <buffers>
   :write-unhook <label>
   :majormode-hook <command> <label> <priority>
   :majormode-hook-targets <label> <buffers>
   :majormode-unhook <label>




Vile comes with the ability to assign certain actions to certain events. These actions are called "hooks". (I use the term "hook" a little loosely here and there in this manual page, but the intention at each instance is generally clear, I hope.) For more information on Vile's built-in hooks, please see the Hooks section of Vile's help text (available from within Vile, as :help).

First, let's be clear about what this package, affectionately known as the "Captain", does NOT allow you to do. There are, currently, seven supported hooks in Vile: autocolor, buffer, cd, exit, read, write and majormode. The Captain does NOT allow you to extend this set. You get those seven hooks and that's it (as far as I know).

So what does the Captain do for you? Normally you can only assign one command to any one of Vile's hooks. If, for example, you wanted to have lots of things happen whenever you changed buffers (i.e. activated the buffer-hook), then you'd have to write a special procedure (in your .vilerc probably) that incorporated all the actions you wanted, and then you'd assign that procedure to the $buffer-hook variable. But why should you have to write a special procedure? Especially since I went to all this time and effort to build this package that comes with all these neat commands and stuff? The answer is, of course, that you shouldn't. When it comes to setting up your Vile hooks, you should just let the Captain be your, um..., Captain...

The Captain provides commands that allow you to add (and remove) multiple actions to any of Vile's built-in hooks. Each action is assigned a label and a priority. Labels are used to reference the action later, e.g. when removing an action. The priorities determine in what order the actions are executed when a particular hook is activated (see PRIORITIES).

Here's a simple example:

   perl "use CaptHook"

   autocolor-hook 'HighlightFilter' 'filter' 10
   buffer-hook 'set-variable $iconname $cbufname' 'icon' 10
   buffer-hook 'perl Vile::beep' 'beep' 20
   read-hook 'search-forward \\\S' 'skipws' 20
   perl "use directory"
   cd-hook 'directory $cwd' 'dir-list' 100

In this example we have 1) setup the autocolor-hook in a more-or-less standard fashion, 2) fixed it so that every time we change buffers we set Vile's icon label to match the current buffer name, AND Vile beeps (the beeping gets damn annoying real fast, by the way), 3) whenever we edit a new file, Vile moves the cursor over any initial whitespace, and 4) whenever we change Vile's current directory, the new directory name is displayed in the message buffer. Wasn't that easy? No scurvy, no large deceased sea birds around your neck, no problems.

Another nifty feature is the use of targets. The Captain allows you to limit the activation of certain hooks to certain targets. Targets can be buffers, files, or directories, depending on the type of hook in question. In a nutshell, first you create a hook, then using the hook label, you specify for which targets it should be used. For example, suppose you have created a read hook, called myuid, that searches for your UID. You could set it up so that the myuid hook is only activated for certain files:

   read-hook-targets 'myuid' '/etc/passwd, /etc/group, /etc/aliases'

As another example, you could turn autocolor off for certain buffers, e.g. Help, like this:

   buffer-hook 'setl autocolor 0' 'color-off' 100
   buffer-hook-targets 'color-off' '[Help]'

Something to note: When the Captain is initially loaded, he assigns to each of Vile's hook variables one of his own activation functions. However, he does note if any of Vile's hook variables have been set previously and, if so, he saves the settings, adding them to his own sets of hook actions. (The priority assigned to any extant actions is fairly arbitrary... As a matter of fact, I'm making it up right now. It's, um, probably like 1542 or something.) Since other Perl packages or sourced macro files might setup some of the Vile hooks, you should probably make loading the CaptHook package and setting up your hooks the last thing that happens in your .vilerc file.

Now, I know some of you may think this is all overkill, but just you wait until some clever soul hacks up a package that dynamically manipulates certain hook-action priorities based on changing editor conditions (possibly related to the current temperature in Arlington, MA), and then you will all be exclaiming, "Thank goodness we had the Captain or implementing this highly contrived and vague example would have been nearly, if not almost but not quite completely impossible!"


Command priorities are assigned by the user whenever a new hook "action" is added. Me thinks you can use any string for a priority. However, the Captain sorts priorities in a numerically ascending order, so you would be wise to always use numbers to avoid confusion. Adding actions with priorities of 1, 2, 3, etc. is fine, until you want to add an action after the first and before the second. Then you'd have to resort to fractions, e.g. 1.5, and how many of those could there be? Um, nevermind. The point is that it might be less awkward to use priorities like 10, 20, 30, etc. instead. Then you can always stick in a 12 or 25 or whatever, and save those decimal points for professions that really need them, like chartered accountancy for instance. Ah, chartered accountancy, there's the life! I could have been a chartered accountant you know. I had the handwriting for it, no doubt. But my mum insisted I become a pirate instead. "Pirating was good enough for your no-account father, the bastard, and it'll be good enough for you! Now finish your grog!", she'd say. Sigh. Many's the hour I whiled away sitting in the crow's nest dreaming of the life I could have had. A solid floor under my feet, my own desk, sharpened pencils all neat in their holder... Oh, buggerit. Let's get on with the installation...


[Note: CaptHook may already be pacing the deck for you as part of your Vile installation.]

Install somewhere in perl's @INC path. Depending on your Vile installation, /usr/local/share/vile/perl might be a good place.

Add perl "use CaptHook" to you .vilerc file. Then use the Captain's ...-hook commands to set up your hooks. Note that other packages may set hooks too, so you should probably activate CaptHook last, giving him a chance to come along side and board any previously setup hooks... so to speak.


perl "use CaptHook"

Invite the Captain on board...

autocolor-hook <command> <label> <priority>
buffer-hook <command> <label> <priority>
cd-hook <command> <label> <priority>
exit-hook <command> <label> <priority>
read-hook <command> <label> <priority>
write-hook <command> <label> <priority>
majormode-hook <command> <label> <priority>

Add a command to be invoked during a particular hook (obviously which hook depends on which variation you use). Note that these are cumulative. Running :buffer-hook ... twice with two different labels gives you TWO commands that get executed whenever you change buffers. The order of execution will depend on the priorities given (see PRIORITIES). Reusing a label will result in the replacement of any command already assigned to that label, for a given hook. I.E. You can have a cd-hook and a buffer-hook with the same label, but you cannot have two cd-hooks with the same label.

autocolor-hook-targets <label> <buffers>
buffer-hook-targets <label> <buffers>
cd-hook-targets <label> <dirs>
read-hook-targets <label> <files>
write-hook-targets <label> <buffers>
majormode-hook-targets <label> <buffers>

It is possible to limit certain hooks so that they only take effect for certain targets. Autocolor, buffer, and write hooks can be targeted for certain buffers. Cd hooks can be targeted for certain directories. Read and majormode hooks can be targeted for certain files. Targets are delimited by commas.

autocolor-unhook <label>
buffer-unhook <label>
cd-unhook <label>
exit-unhook <label>
read-unhook <label>
write-unhook <label>
majormode-unhook <label>

Delete a command assigned to a particular hook (which hook depends on which variation you use). The label given should match the label used when the no-longer-needed command was originally "hooked".


Invoke the set of commands assigned to a particular hook. Each of the do-*-hooks commands is assigned to an appropriate one of Vile's $*-hook variables when the Captain boards the good ship Vile. (The order in which a particular set of commands is invoked depends on the priority assigned to each command in the set (see PRIORITIES).) Normally these are used to automatically trigger a set of actions whenever a hook is activated, but they could be invoked manually as well.


Discover the Captain's treasure map.


Probably result in some odd interactions here and there... For instance, I've already noticed that this:

   autocolor-hook HighlightFilterMsg filter 1

uncovers a 'bug' in the Vile Perl extension. Specifically, you'll see a lot of the message "BUG: curwp not set to a visible window", even though things seem to still work.

By the way, if anyone requests a show-hooks command, I'll make 'em walk the plank!




Drat. No one to blame but myself...


J. Chris Coppick, 2001 (last updated: June. 26, 2002)

Ahoy, Maties!