Abstract

The script "vim_mode" adds modal editing to the input line of the IRC client "irssi", very similar to the editing within the text editor "vim".

While the editing commands within irssi's input line are pretty good already, this adds a few commands which you have been missing - especially when you have used a modal editor like vi (calvin, elvis, nvi, stevie, or vim).

You can easily copy/delete words with "dw" and "yw" repeat the last kind of change with the dot key (.), store copies/deletions within 26 clipboards/registers and paste from these later on.

You can also quickly jump around the input line with "find" (fFtT) and "search" (/?) commands - and repeat those searches with a simple 'n' or 'N'.

You can also repeat jumps and changes with the "number prefix", eg "5w" and "3dw".

Installation

The installation basically consists in downloading the script to irssi's "script" directory/folder - and calling it from inside with a "/script load" command.

Downloading:

  $ URL=http://github.com/shabble/irssi-scripts/raw/master/vim-mode/vim_mode.pl
  $ cd ~/.irssi/scripts/
  $ wget $URL

  $ $EDITOR ~/.irssi/default.theme

Then from within irssi you give these commands:

    /script load prompt_info.pl
    /script load vim_mode.pl

Now "vim_mode" should be loaded and usable.

Modes

This script adds "editing modes" to your editing.

The editing consists between switching from "insert mode" (the default mode when editing irssi's command line) and the "command mode" for jumping around and making changes.

The current mode can be shown within the activity line. To enable this, issue the following command within irssi:

    /statusbar window add vim_mode

TODO: Use color within the input line prompt to indicate the current mode, ie "INSERT/COMMAND/COMMAND LINE/REPLACE)".

Insert Mode

Within irssi this is the default mode of operation, ie when you type keys then they'll be inserted to it.

The usual key bindings of keys to commands within irssi apply. See "/bind" for a list.

The following two commands, ESC and CTRL-C, have been added to switch to "command mode" which then allow to use digits and letters for even more commands.

<esc>     end insert mode and switch to command mode.
<c-c>     CTRL-C also switches to command mode.

Command Mode

In command mode you can use letters and digits to jump around quickly, eg jump directly onto characters, search for strings backward and forward, repeat searches - and then also to do changes such as making copies or deletions, storing these in clipboards/registers, and repeating the last change with '.'.

Jumps

Jump to start or end of the current line:

0    "column zero"  jump onto *first* character of line
^                   jump onto *first* non-whitespace char
$                   jump onto *last*  character of line

Jump by word boundaries:

b         "back"    jump back    to previous begin_of_word
e         "end"     jump forward to next       end_of_word
w         "word"    jump forward to next     begin_of_word

Jump by WORD boundaries:

B         "Back"    jump back    to previous begin_of_WORD
E         "End"     jump forward to next       end_of_WORD
W         "Word"    jump forward to next     begin_of_WORD

Note: There is a difference between "words" and "WORDs". "words" consist of letters and digits only ([a-zA-Z0-9_]). "WORDS" consist of a series of non-whitespace characters.

Jump by character:

<space>   jump right    move cursor onto next character right
l         jump right    move cursor onto next character right
h         jump left     move cursor onto next character left

Switching lines within history:

j         jump down     move cursor onto next line within history
k         jump up       move cursor onto prev line within history

Switch to insert mode:

a         "append"  switch to insert mode *after*  current position
i         "insert"  switch to insert mode *before* current position

A         "Append"  switch to insert mode *after*  the last position
I         "Insert"  switch to insert mode *before* first non-whitespace

o         "open"    hmm.... ideas?
O         "Open"    hmm.... ideas?

Searching

fX        "find"    find  next     'X'
FX        "Find"    find  previous 'X'

tX        "to"      jump onto character before next     'X'
TX        "To"      jump onto character after  previous 'X'

Note: These command only work on the *current* line. So using these commands will not switch away from the input line into the history.

Examples:

TODO:

n    "next"  find next match in last search direction
N    "Next"  find next match in *opposite* of last search direction

Number Prefix

Most commands should allow a *number* as a prefix, ie you type a sequence of digits to form a number N and then a command. Usually, the effect will be that the commands is then repeated N times.

Examples:

    5h      jump left  five times
    9l      jump right nine times
    23x     delete 23 characters
    3f.     find the third dot (forward)
    3dfx    three times delete until you find an 'x'
            delete unto (and including) the 3rd 'x'

Switching Lines

Within irssi we are dealing with one line at a time. This is usually the input line which, after a press of ENTER/RETURN is then added to the list of all commands, called the "history". We can think of that history as a file for which we are adding one line at a time to its end.

The commands that we usually use within vi (vim) to switch to other lines are here used to access other lines within irssi's history.

The command to access a given line number is 'G'. You give the number as digits *before* using 'G', ie like this: <digit> <digit> ...... <digit> 'G'

Example:

   23G      switch to line #23
   42G      switch to line #42

If *no* number is given then the highest number is used, and this should be your input line. :)

Note: When you move away from the input line it is preserved, ie it is still the last line of the current history - even though it has not been issued or "sent" yet.

When you return to the last input you were editing then the current position of the cursor is restored. (yay!)

Up+Down the History

Within vi (vim) you use 'j' and 'k' to switch lines:

    j       switch to next     line within history
    k       switch to previous line within history

The commands j/k only switch by one line down/up- but you can add a number prefix to speed this up:

    23k     go back/up      by 23 lines
    42j     go forward/down by 42 lines

Command Combinations

One of the biggest strengths of the vi editor is the combination of copy/delete commands with jumps. This allow for so many combinations that it would be very hard to integrate them to menus and submenus.

There are some standard commands which are actually combinations:

  A   $a    jump to last  character of line, then append
  I   ^i    jump to first non-whitespace,    then insert

  C   c$    change     rest of  line from current position
  D   d$    delete     rest of  line from current position
  S   cc    substitute complete line from *any*   position

While "cc" isnt really combining the change command with anything, it is simply a convention to refer to the current line as the text to be operated upon. This convention is applied to the 'd' and 'y' commands with "dd" and "yy" (see below).

Change+Copy+Delete

Simple deletions are made with the x/X keys:

x    "delete here"   delete the current character under the cursor
X    "delete left"   delete the character before the current character (TODO)

Many times a copy or or change is made to the current line. You either just copy it ("yy"), or maybe delete it ("dd"). Then again, you might want to start over completely by erasing it, but then you do not want it gone completely, but fill it with new content right away - then you will"change" it ("cc").

yy   copy   current input line to the default register;        stay  in command mode.
dd   delete current input line; save copy in default register; stay  in command mode.
cc   change current input line; save copy in default register; switch to insert mode.

Note: A "change" command is like a deletion - only it switches to insert mode after deletion; this saves an 'i' or 'a' for the mode change.

Paste

There are two ways to paste from the default register: The "paste" commands with keys 'p' and 'P': The lowercase 'p' pastes *after* the current position - and the uppercase 'P' paste *before* the current position.

So to *append* a deleted word to another word first use 'e' to jump onto its end and use 'p'. And to *prepend* a deleted word to another word first use 'b' to jump onto its beginning and use 'P'.

Registers

Copies and deletions both copy *into* the default register (aka clipboard). When you "paste" then you insert a copy *from* the default register.

When you use a "register name" (a '"' followed by a character a-z) before a copy or deletion command then you paste *from* that register.

Examples:

    "ayy    copies  current line and copies it into register 'a'
    "zdd    deletes current line and copies it into register 'z'

You could also read it left to right like this:

    "ayy    use register 'a' to copy   the current line into
    "zdd    use register 'z' to delete the current line into

Or to say it a little different:

    "ayy    into register 'a', copy   the current line into
    "zdd    into register 'z', delete the current line into

IDEA: Add text objects, which enables copying or deleting of the current word or sentence.

    ciw     change inner word
    diw     delete inner word (incl trailing spaces)

    ciw     change inner word
    daw     delete all   word (incl trailing spaces)

    yiw     copY   inner word
    yaw     copY   all   word (incl trailing spaces)

All commands also apply when the last key is an 's' (instead of 'w'); then the copy/deletion refers to the current *sentence*.

There's not only copying and deleting into registers, but also pasting from registers:

    "ap     from register 'a' paste *after*  current position
    "dP     from register 'd' paste *before* current position

Repeat

There is a special thing in "vi". Every "change command" (ie no jumps) is memorized and can be repeated with the dot (".") command.

So when you delete the next word with "dw" then you can repeat it simply by typing a '.' - and also repeat it three times with "3.".

Or use "2p" to paste twice.

Replace Command

The command "rX" replaces the current character with 'X'.

    The '''n'''erd is waiting.

Place the cursor on the 'n' of "nerd", then type "rh" - and you'll get "herd":

    The '''h'''erd is waiting.

(Probably needs a better example. ;-)

Special

The command '~' (tilde) switches the case of the current character if it is a letter - and then moves onto the next character.

Example:

    the greatest irc client is irssi.

When the cursor is on the 't' of "the" then typing '~' three times gives you:

    THE greatest irc client is irssi.


IDEAS: The following are some more ideas. Maybe you want to implement them for us?


Marks

(not implemented yet)

Marking a character as a position can be quite useful, too.

  ma      mark current position with   'a'
  `a      return to    position marked 'a'
  'a      return to    position marked 'a'

Marks should be preserved within the complete history - for each window. So there are marks 'a' through 'z' for every window's history.

Replace Mode

(not implemented yet)

Start "replace mode" from command with 'R'. Then every keystroke replaces the current character with the key pressed - and then moves onto the next character. You might know this from other programs as "overstrike mode".

This mode is also ended with an ESC - and returns to command mode.

Searches

(not implemented yet)

Often enough you do not want to take guesses but search for a given string in the history. That's where the commands '/' and '?' come in:

    /foo      search forward  for next occurrence of "foo" in history
    ?bar      search backward for next occurrence of "bar" in history

As the current input line is the last line of the history a search is usually initiated with a *back* search using "?".

Quite often I look for some URL by searching for "http:":

Examples:

    ?irssi      look for word "irssi" within history.
    ?http://    look for the  latest  URL in history.

Then again, "/lastlog http:" may yield a better overview. ;-)

Visual Mode

(not implemented yet)

Visual mode a la Vim, ie first you do a "visual selection" (aka highlighting) of text - and then you type a key to initiate a command which then operates on the text. You would either use 'y' to "copY" ("yank") the text, or 'd' to delete it, or something like 'u' or 'U' to make all the letters lowercase or uppercase, respectively.

Withing Vim there are also operators replace all characters with a given 'X' - or to rotate the letters halfway around the alphabet (aka rot13) - lots of fun here. :)

There are lots more in Vim - but most are only useful refer for a multi-line inpu, eg reformatting the text to the current textwidth, shifting/indenting text right and left, and filtering lines through an external script.

BUGS

dot command: insertions are changes, of course, but currently insertions are NOT remembered - and therefore cannot be repeated with the dot command.

undo+redo: the "undo" command seems to work nicely - but the "redo" command seems to be broken.

TODO

things to do for the first release:

(1) fix the bugs. heh!

(2) drop ex mode: to get the first reelase out the door, drop ex mode for now, as it requires changes to be made manually with an editor to another file. annoying.

(3) undo/redo: add "snapshots" of changes during insert when the user changes the insert position with jump commnds.

(4) mode indication color: add some colour to indicate the current mode. could also use "bold" characters on input line.

(5) describe these options:

/set vim
vim_mode_cmd_seq =
vim_mode_debug = OFF
vim_mode_utf8 = ON

Authors

Who came up with this stuff, anyway? Here they are:

kind

realname

nickname

town

email

code

Tom Feist

shabble

?

shabble+irssi(at)metavore.org

code

Simon Ruderich

rudi_s

?

simon(at)ruderich.org

docs

Sven Guckes

SvenG

Berlin

irssi-vim(at)guckes.net

Catch us on channel #irssi on the FreeNode network!

    /connect irc.freenode.org
    /join    #irssi
    /msg     rudi_s  ping!
    /msg     shabble ping!
    /msg     SvenG   ping!

Work started Sep26/27. Communication was done via #irssi - and code was collaborated on via "git".

Links

the "vim_mode" script: http://github.com/shabble/irssi-scripts/raw/master/vim-mode/vim_mode.pl

the source for this documentation: http://www.guckes.net/irssi/vim_mode.additions.txt

the IRC client "irssi": http://www.irssi.org/

the text editor "vim": http://www.vim.org/

IrssiVim (zuletzt geändert am 2010-09-30 04:55:57 durch svenguckes)