welcome: please sign in
location: WritingCommands

Writing Commands

Writing new commands for Conkeror is simple. This page will give you the basic information you need to know to write commands. The Conkeror source contains lots of commands that you can reference for examples.

You can think of a command as having two halves. One half is the output half: a javascript function that implements what you want the command to do. The other half is the input half, or interactive definition. The interactive definition does the following:

That third bullet point is the most complex, and we will return it it shortly.

Let's write a simple command to have something concrete to study. The first thing we need is a javascript function that does what we want the command to do. In this example, we want a command that echoes a message to the minibuffer. Since the command function is only supposed to perform output, we have to determine what it needs to know about the user interface in order to produce its effect. Our function will need to be provided with a conkeror window in which to echo a message, and a message. So we can define the command function like this:

function echo_message (window, message) {

Too easy.

Note that our command function is itself completely free of code to collect information from the user. The command function should contain only output side-effects, with input side-effects being located in the interactive definition. This keeps the code clean and organized, and ensures that command functions can be called non-interactively by other scripts.

Our interactive definition is here:

    "echo a user-supplied message in the minibuffer",
    function (I) {
            (yield I.minibuffer.read($prompt = "message: ")));

There is a lot here, but we will take it apart, and you will see that it is really not all that complex.

The first argument of interactive is a string giving the name of the command. We follow the emacs convention and use all lower case with words separated by hyphens.

After the command name is the docstring. It may be null if you don't want to write documentation for your command.

The last argument to interactive is a function of one argument that carries out the user-interface interaction, and finally calls the command function (echo_message). The argument to this function, which by convention is the variable I, is called the interactive context. The interactive context contains some useful information, including window, which is the Conkeror window in which the command was called. Since echo_message expects to be called with a window, we pass it I.window.

The second argument to echo_message is the message. We will collect the message by prompting the user. The javascript keyword yield is used to perform this interaction asynchronously. (Note, the parentheses around yield are required.)

The call to I.minibuffer.read contains some odd looking syntax, $prompt = "message: ". This style of assignment to a variable beginning with $ is a Conkeror convention for keyword arguments. Javascript itself does not contain keyword argument syntax, but Conkeror provides a keywords system. We felt this to be desirable for functions like minibuffer.read because often many parameters of the interaction can be customized, and it would have been too messy and consistency too hard to maintain, using positional arguments for all of them. Keyword arguments always start with $. Here we just set the $prompt keyword to a suitable prompt.

After evalling our command function and interactive definition, we can now call our new command with M-x echo-message.

More on the interactive context

Here is a list with some of the useful information accessible through the interactive context:


The current Conkeror browser window.


The minibuffer of the current window.


The current buffer in I.window.


The document-object of the website currently viewed. Useful for creating small scripts in the style of bookmarklets or Greasemonkey userscripts.


URI of the page shown in the current buffer.

Conkeror.org: WritingCommands (last edited 2010-02-12 11:56:05 by retroj)