Vimperator

Introduction

Vimperator is a plugin for Firefox that makes the user interface Vim-alike: it introduces many of the Vim UI concepts so that the browser becomes predominantly keyboard driven. If you love Vim's keyboard driven navigation then making the browser a comfortable experience is worthwhile. If you don't already know Vim then it's unlikely to be of interest as Vimperator substantially changes the UI. Newer versions of Vimperator seem to over ride fewer of the standard keys than previously (e.g. ctrl-t works), but it's still a considerable change. It's like Marmite!

Vimperator running on Ubuntu 14.04 LTS Firefox

Figure 1: Vimperator - History list

Figure 1 Shows Vimperator running, the bottom command-line bar is displaying some actions in green text (e.g Space). The main window is displaying the history list, both the URL and the title of the page. The top shows the tabs with small numbers on each which let me use a keyboard short cut to easily switch between them. I've kept the menus but notice that the location bar, and the scrollbars have been removed to optimise the space. The look and feel is fully customisable through a theme.

If you're using Firefox the alternative is Pentadactyl, though in 2016 this is less maintained. If you're using Chrome or Chromium then Vimium is a similar plugin.

As the plugin makes substantial changes to the interface it interacts with Firefox a lot. There are conflicts with different versions of Firefox and a number of elements didn't work for me. For comparison purposes, (using the command :version), I'm on:

Vimperator: 3.14.0 (created: 2016/06/07 23:58:16)
Firefox:    Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0

The key to understanding Vimperator is the mental model. It's trying to bring Vim modes (Normal mode, Insert modes) to the browser and you have to think of these in the context of the different activities we do in a browser (browsing, viewing the current page, tab management). The help is very extensive (:help) and worth reading.

Use-cases

The use-case for Vimperator is if you find Vim more comfortable and want the browser to have a similar interface. In my case it's a bit uncomfortable switching out of my editor window into a browser window and then having to shift my hands around to the mouse. As I spend a significant amount of time in a browser window it involves a lot of mental shifting as I have to remember different UI conventions.

It's also quite useful on a small laptop screen as you can remove a lot of the UI elements.

Strengths

  • All the UI conventions of Vim in the browser

All the main UI conventions such as normal mode commands, keyboard shortcuts, maps and commands are there. It's amazing how much functionality has been created.

  • Very configurable through a simple text file

Configuration uses a vim-centric set of conventions in a revision control friendly text file (~.vimperatorrc). The file can also be used to configure Firefoxs settings making it simple to keep a complete set-up.

  • Many of the existing short-cuts (ctrl-t) still work

Vimperator uses many Vim keys, but many of the standard browser keyboard shortcuts (e.g.Ctrl-Shift-k) continue to work fine. It's also possible to configure Vimperator so that it remaps keys to commands, so if it's over-writing something that you want it can be re-enabled.

Weaknesses

  • It's quite a fragile plugin as it's changing a lot of elements

Vimperator makes a lot of changes to Firefoxs UI which can mean that different versions of the plugin and Firefox don't work well together. Some pieces of functionality didn't work for me, and looking through the Issues on Github there are other complaints. Testing it seems to be quite difficult for the developers.

  • The functionality is extensive but inconsistent

There's a lot of functionality, but it can be inconsistent. Some users complain that it's not Vim-like enough, citing alternatives. Personally, I found it more than enough and as it's OSS we can always implement any features we want!

  • Some reports that it slows down Firefox

Some complaints that it slows down Firefox or takes a lot of resources. I haven't had any problems yet, but it is early days.

Modes and interaction

Normally interacting with Firefox involves using the menus at the top, the location bar or other dialogs, and the mouse for context menus. With Vimperator many of these UI elements remain (e.g. menus and mouse context menus) but the focus moves to interacting through the keyboard.

Vimperator provides a comprehensive set of keyboard shortcuts which the next sections document. Additionally, it adds a bar across the bottom which is interacted with using vim-like commands. Anyone whose used Vim will be familiar with this modal method of interacting. Many of the commands are documented in the Command mode sections. The shortest version of the command is shown before the square brackets that document additional letters than can be typed - tab completion also works.

Broadly, these notes follow the help documentation (:help) structure, they don't cover everything, just the things that were important to me.

Browsing

This section covers the main activities when you're browsing a page. Typically, it's the basics like opening URL's, tabs and history management which you normally access through Firefox menus or the navigation bar.

Keyboard shortcut Command mode Explanation
<insert>   Disables the extension so you can interact normally. To re-enable press <insert> again.
o <url> :o <url>

Open one or more URL's in the current tab. Multiple URL's are separated with commas:

  1. filesystem: /etc/fstab
  2. Default search: o <search term>
  3. Defined search engine: open <search engine name> <search term>
  4. Multiple tabs: o <url1>, <url2>
t <url> :tabopen <url> Open one or more URL's in new tabs.
w <url> :wino <url> Open one or more URL in a new window.
p   Pastes in the clipboard and opens, to open in a new tab use gP. Using t <ctrl v> might be better.
H :ba Back one step in history.
<ctrl>o :ba Back one step in history.
L :fo Forward one step in history.
<ctrl>i :fo Forward one step in history.
  :ju Show a jumps list. Note: doesn't work for me.
gu   Go up one step in the URL.
gU   Go to the root of the site.
gr   View in Reader View to show clutter free reading.
r   Reload the page. Use R to skip the cache.
<ctrl>c :st[op] Stop load the current page. :stoa[ll] stops all pages loading.
d :q[uit] Quit - no session is saved
ZZ :xa[ll] Quit - save session.

Disabling vimperator

You can disable the extension for specific sites automatically through the configuration, to temporarily disable it use the <Insert> key.

Current tab (buffer)

Navigating within a page, which Vimperator calls a buffer. As with Vim buffers there are a lot of methods for moving through the document. The main surprise I found was text copy and paste, as y copies the URL, to copy some highlighted text use Y. Note that <ctrl>-c and <ctrl>v still work, if you're used to them.

Keyboard shortcut Command mode Explanation
0   Absolute left
$   Absolute right of the window. If viewing in text this is a dollar symbol, it's being escaped with backslash for RST formatting.
gg   Top of the document
G   Bottom of the document
h   Left scroll
j   Down scroll.
k   Up scroll.
l   Right scroll.
<ctrl>d   Scroll down half a page.
<ctrl>u   Scroll up half a page.
<ctrl>b   Scroll up a full page.
<ctrl>f   Scroll down a full page.
y   Yanks the current location to the clipboard.
Y   Yanks / Copies highlighted text to the clipboard. Doesn't work for me.
<ctrl>c   Copies highlighted text to the clipboard.
<spacebar>   Scroll one page down.
<shift><space>   Scroll one page up.

Tab management

Vimperator - buffer list showing

Figure 2: Vimperator - Buffer list

Vimperator thinks of tabs as buffers in the vim manner. There are a variety of ways to change between them and reorganise them using keyboard shorts cuts and command line commands. Figure 2 shows a buffer list being displayed through the ls command.

One tip is to use the Local Marks A-Z to mark a tab (:ma A) and switch to it with 'A in any tab - provides a nice way to switch between specific locations on tabs.

The most important commands are in the table below. Vimperator also lets you manage tab groups, but I've skipped that as I don't use them (see help tab).

Keyboard shortcut Command mode Explanation
B :ls Show a list of tabs. The shortcut B is not standard as in Vim it means to back a word (including punctuation.
[count]b[index]  

b brings up the buffer list. If you know index of the buffer you want to move to you can provide it 5b would move directly to the fifth buffer. Alternatively, provide it after the window pops up, b7 to go to the seventh tab.

You can also provide a URL rather than an index, and it uses tab completion.

The mark # shows the previous buffer, change to it with b#, it does odd matching on the URL but does work.

gt :tn[ext] Go to the next tab.
gT :tp[revious] Go to the previous tab.
<ctrl>n   Go to the next tab.
<ctrl>p   Go to the previous tab.
<ctrl>^   Go to the previously selected tab.
g0   Go to the first tab.
g$   Go to the last tab.
  :tabm [N] Move the tab to position N. If 0 it's made the first tab. Moving -/+ is also possible, tabm +4 moves 4 to the right.
d :bd Close the current tab. There is also d but I've no-oped it as it's a vim command and may cause me confusion.
u   Undo closing a tab.

Command-line mode

Command-line mode is for entering ex commands and text search patterns. All the commands are input with a colon (:) at the start in the same manner as Vim.

Keyboard shortcut Command mode Explanation
<ctrl>c   Quit command-line mode without executing.
<escape>   Quit command-line mode without executing.
<up arrow>   Recall the previous command from the history list that matches the command.
<down arrow>   Move forward through the history list.
<tab>   Complete the command.

Marks

Vimperator supports a range of different marks:

  • Bookmarks - standard bookmarks
  • QuickMarks allow you to define up to 62 (a-zA-z0-9) web sites that you access commonly
  • Local marks to store the position within a web page
  • History is a special type of mark.

Personally, I find bookmarks more useful as they're easier to handle (I haven't documented all the commands here), and the QuickMarks capability is very interesting.

Bookmarks

Keyboard shortcut Command mode Explanation
a :bma[rk] Bookmark the current site. You can add -title=title, -keyword=keyword, -tags=tag1,tag2
A   Toggle whether you have a bookmark for the current location.
  :bmarks [filter] Open the bookmarks, they can be filtered with [filter]. The use extended hint commands to open it [filter] can be -tags.
  :delbm[arks] [url] Delete the current tabs bookmark. If a [URL] is provided then it deletes that one.

History

History is a bit more annoying that it should be. The best way to use it is to type :hist<return> to pop up the history window, and then o <part of the url> to filter down to what you want. Ideally history would accept numbers so you could open the 'third' row or similar to Hints mode.

Keyboard shortcut Command mode Explanation
H   Go back one step in the browser history.
L   Go forward one step in the browser history.
<ctrl>o :ba[ck] Go back in the browser history, an optional number can be provided
<ctrl>i :fo[rward] Go forward in the browser history, an optional number can be provided.
  :hist [filter] Show history in the message window. They can be filtered by [filter] Use extended hint commands (;t) to open: :hist blah.com <return> ;t bl<tab>

QuickMarks

QuickMarks provide a short cut list of bookmarks for common sites that you go to. Think of them as the common sites on the browser start page.

Keyboard shortcut Command mode Explanation
  :qmark [a-zA-Z0-9] <url> Set a mark to the specified URL. If no URL is set then the current tab URL is used. You can also mark multiple URLs.
go<qmark>   Open the specified mark in this tab e.g. goa would be go to mark a
gn<qmark>   Go to new tab, specified mark.
M   Set a mark for the current URL
  :qmarks [arg] Display the QuickMarks. If [arg] is provided then it shows those e.g. abc a range such as a-c doesn't seem to work.
  :delqm[arks] [mark] Delete the specified quick mark.

Quickmarks can be set in vimperatorrc:

qmark h https://news.ycombinator.com/

Local Marks

Local marks provide positions within the page. The range in upper case letters (A-Z) work between buffers so you can switch from specific positions in a document.

Keyboard shortcut Command mode Explanation
m<a-zA-z> :ma[rk] Create a mark of the specified letter. The a-z range are local to the buffer, so navigate within a page easily. Whereas, the A-Z range work between buffers which let you navigate easily between multiple points across tabs.
'<mark>   Jump to the mark. Either ` or ' will work.
  :marks [arg] Show the marks for the buffer. If [arg] is supplied show the ones specified.
  :delmarks <mark> Delete the specified mark. delmarks ! deletes all marks for the current buffer.

Jumps

To see the history of the tab we can use the :jumps. This is some functionality that doesn't work for me, according to their issue list there may be a bug.

Insert mode - Forms

Insert mode happens when you're in a form, there are other key bindings, but the main one for me is being able to start Vim locally with the contents:

Keyboard shortcut Command mode Explanation
<ctrl>i   Starts the editor of your choice. Depends on the editor setting.
<tab>   Move to the next text field.

We can set the editor with something like:

" define the editor
set editor="/usr/bin/gvim -f"
" call with <leader>i as well as Ctrl-i as Ctrl-i is sometimes over-ridden
inoremap <Leader>i <C-i>

Key mappings

The key mapping commands can be used to redefine either standard key bindings or define new ones (:help mapping). Keys can be mapped in four modes:

  • Normal mode: When browsing normally
  • Visual mode: When selecting text with the cursor keys
  • Insert mode: When interacting with text fields
  • Command-line mode: When typing into the Vimperator command line
Shortcut Command mode Explanation
  map {lhs} {rhs} Normal and Visual mode mapping. Right hand side is remapped, allowing for nested and recursive mappings.
  nmap {lhs} {rhs} Normal mode map. Right hand side is remapped, allowing for nested and recursive mappings.
  vmap {lhs} {rhs} Visual mode map. Right hand side is remapped, allowing for nested and recursive mappings.
  imap {lhs} {rhs} Insert mode map. Right hand side is remapped, allowing for nested and recursive mappings.
  cmap {lhs} {rhs} Command-line mode map. Right hand side is remapped, allowing for nested and recursive mappings.
  noremap {lhs} {rhs} General map: Normal mode and visual mode. No remapping of right hand side is performed.
  nnoremap {lhs} {rhs} Normal mode, no remapping of right hand side is performed.
  vnoremap  
  inoremap Insert mode.
  cnoremap Command-line mode, no remapping of right hand side is performed.
  unmap {lhs} {rhs} Remove the mapping for left hand side.
  nunmap Remove the mapping from Normal mode.
  vunmap Remove the mapping from Visual mode.
  iunmap  
  cunmap Remove the mapping from Command-line mode.
  map Show alls maps
  nmap Show all Normal mode maps
  vmap Show all Visual mode maps.
  imap Show all insert mode maps.
  cmap Show all Command-line mode maps.
  map {lhs} Show all maps for {lhs}
  nmap {lhs} Show all Normal mode maps for left hand side.
  vmap {lhs} Show all Visual mode maps for left hand side.
  imap {lhs} Show all Insert mode maps for left hand side.
  cmap {lhs}  

Arguments and key sequences

If the special argument <silent> is provided as the first argument of the {rhs} then nothing is echoed until the map is complete.

" Create a map for F2 which calls the Javascript for date
:map <F2> :echo new Date().toDateString()<CR>

" Create two maps so that g1 and g3 call tabs 1 and 3 respectively
" The second map is silent so nothing is echoed to the Command line
:map g1 :tabn 1<CR>
:map <silent> g3 :tabn 3<CR>

There are a lot of additional capabilities around mappings and commands which I haven't documented as I'm not using them. But it's very extensive!

Mapping space

Space bar is hard coded so it can't be manually remapped. As I use spacebar for <Leader> in vim the only way to remap it is as follows:

" https://github.com/vimperator/vimperator-labs/issues/10
" To Enable map <Space>
js <<EOM
  window.addEventListener('keypress',function (event) {
    var code=event.charCode;
    if ((liberator.mode === modes.INSERT && modes.extended === modes.MENU)
    ||(liberator.mode ==modes.NORMAL && code==32)
    ||(liberator.mode ==modes.COMMAND_LINE && code !=32)){
      let map = mappings.get(liberator.mode, events.toString(event));
      if (map) {
        event.preventDefault();
        event.stopPropagation();
        map.execute();
      }
    }
  },false);
EOM

" My Customization
map <Space> <Leader>

User-defined Commands

User defined commands are easy to add:

Command Explanation
:com[mand] List current user commands.
:com[mand] {cmd} List the user commands that start with {cmd}.
:command {attr} {cmd} {rep} Add the user command {cmd} which executes the text in {rep}. The command may start with a lower case letter.

Arguments may be provided and completion, see the documentation (help mapping) for more information.

" Add the command :close to close a tab
:command close :bd
" Add the command :Google to open the supplied args at google.com
:command -nargs=* Google open google <args>

Configuration

Configuration is stored in ~/.vimperatorrc. To create an initial configuration file use :mkv. If you're playing with settings then do source ~/.vimperatorcc, if new extensions are also being loaded then the browser needs to be restarted with :res[tart].

Each option can be set on the command-line or in the configuration file, as follows:

set option=values
set gui=menu,tabs

The help file for options (:help options) is very complete, to see the current options do :set. The most important for me are:

Option Current definition Description
defsearch defsearch=duckduckgo Sets the default search engine.
online online=on Whether Firefox is online or not. The default value is on.
smartcase smartcase=on Search is generally case insensitive. This allows case sensitive search if an upper case letter is used.
scrollbars scrollbars=false Whether scrollbars are displayed or not. Size of page is shown in the status line.
toolbars toolbars=nonavigation Show various toolbars. I've turned off the navigation bar as the status line has it.
tabnumbers tabnumbers=true Show small tab number in the top of each tab.
gui gui=menu,tabs Controls which parts of the Firefox GUI are displayed. I have it set to show the menus and tabs.

Current configuration:

" To enable mapping <Space>
js <<EOM
  window.addEventListener('keypress',function (event) {
    var code=event.charCode;
    if ((liberator.mode === modes.INSERT && modes.extended === modes.MENU)
    ||(liberator.mode ==modes.NORMAL && code==32)
    ||(liberator.mode ==modes.COMMAND_LINE && code !=32)){
      let map = mappings.get(liberator.mode, events.toString(event));
      if (map) {
        event.preventDefault();
        event.stopPropagation();
        map.execute();
      }
    }
  },false);
EOM

" Map spacebar to be leader
map <Space> <Leader>

" Maps
" map <F2> :echo<Space>new<Space>Date().toDateString()<Return>
map <silent> <Leader>1 :tabn<Space>1<Return>
map <silent> <Leader>2 :tabn<Space>2<Return>
map <silent> <Leader>3 :tabn<Space>3<Return>
map <silent> <Leader>4 :tabn<Space>4<Return>
map <silent> <Leader>5 :tabn<Space>5<Return>
map <silent> <Leader>6 :tabn<Space>6<Return>
map <silent> <Leader>7 :tabn<Space>7<Return>
map <silent> <Leader>8 :tabn<Space>8<Return>
map <silent> <Leader>9 :tabn<Space>9<Return>
map <silent> <Leader>0 :tabn<Space>10<Return>

" Make it easy to move between tabs
map <Leader>l :tabnext<Return>
map <Leader>h :tabprevious<Return>

" Add the command :close to close a tab
:command -description "Closing tab" close :bd

" Stop d from closing a tab as this is a Vim command
" Use :bd
map d <Nop><Return>

" Remove scrollbars
:set scrollbars=false

" Improve scrolling for <ctrl>d and <ctrl>u
" :set scroll=3
" Improve general scrolling: j jjj is an alternative
" https://github.com/vimpr/vimperator-plugins/blob/master/_smooziee.js is an alternative
:noremap j 3j
:noremap k 3k

" GUI configuration
" Show menus and tabs, but not the navigation bar.
:set gui=menu,tabs
:set toolbars=nonavigation

" Show small numbers on the tabs to ease navigation
:set tabnumbers=true

" Make the default search engine for 'o' duckduckgo
:set defsearch=duckduckgo

" QuickMarks: go<letter>
qmark h https://news.ycombinator.com/
qmark n https://newsblur.com

" Colour - Molokai with a couple of adjustments
colorscheme molokai
hi CmdLine color: #aaa; background: #333; font-size: 14px; font-weight: normal; font-family: Ubuntu; padding: 0px; vertical-align: middle; border: none;
hi Hint -append font-size: 150%;

" Change hints to letters that are easy to type and numbers
set hintchars=jkhlasdfgyuiopqwertnmzxcvb1234567890

" Source in any local changes
source! /home/steve/.vimperatorrc.local

" vim: set ft=vimperator:

Plugins

Vimpr is a repository of plugins for Vimperator. Plugins are loaded as follows:

  • Find the plugin you want.
    There are 162 plugins to choose from currently!
  • Download and copy it to ~/.vimperator/plugin/
    Note that you don't have to add them explicitly in the RC file.
  • Configure the plugin
    Some have configuration parameters that can be added to the RC file.
  • Reload Firefox
    Rather than restarting you can :source ~/.vimperatorrc

You can see what's been loaded with :scriptnames

Interesting plugins

  • Convert bookmarklets to commands
    I have a bookmarklet for saving content to instapaper and posting to newblur. This plugin converts them to commands starting with bm, so bmsavetoinstapaper and bmshareonnewsblur which is great.
  • Autoreload current page when file changes
    There are lots of other ways to do this, but this is neat. Provides an :autoreload command which you provide with the file to keep checking.
  • Split browser
    Not working, but very cool. Splits just like Vim! Requires this plugin and doesn't seem to work with Fox splitter currently.

Google and vimperator (Gmail)

Some sites provide good keyboard shortcuts, it's possible to tell Vimperator to switch off and ignore cerntain keys with the :ignorekeys option. The main site this is interesting for is Gmail - it's possible to achieve a partial solution, but it's still pretty annoying to be honest.

If you just want to switch it off for the site in entirety do as follows:

" Don't use keys for some sites
:ignorekeys add https://gmail.com/
":ignorekeys --except= https://mail.google.com/
":autocmd LocationChange mail\\.google\\.com :set editor=gvim -f -c 'set ft=mail'

The alternative is to use plugins [2], which means the rest of the keys are available. The two plugins are _libly.js and feedSomeKeys_3.js plugins. Both can be downloaded from the plugin repository. Then add the following:

" Libly must be loaded before other plugins
:source ~/.vimperator/plugin/_libly.js
command! -nargs=+ lazy autocmd VimperatorEnter .* <args>
lazy fmaps -u='mail.google.com/mail' c / j k n p o u e x s r a # [ ] ? gi gs gt gd ga gc
lazy fmaps -u='mail\.google\.com/mail/.*/[0-9a-f]+$' c / j,n k,p n,j p,k o u e x s r a # [ ] ? gi gs gt gd ga gc
lazy fmaps -u='github\.com/[^/]+/.+' -events=vkeydown s,t gc gi gp gw
lazy fmaps -u='duckduckgo\.com/\?q=' -events=vkeydown l j k <enter> s,d gm,m gt,t
lazy fmaps -u 'www\.google\.com/calendar -events=vkeypress j k T,t a D,d w m x c e z / + q s ?
lazy fmaps -u='calendar\.google\.com/.*' -events=vkeypress k p j n r t 1 d 2 w 3 m 4 x 5 a c e <backspace> <delete> <ctrl> z s / <shift> = + q ?

Also see Jons blog

After loading, you should be able to see the loaded key maps by using the command :fmap. When you open Google mail the listed keys are available and send directly to the application, to use vimperator press <Insert> and then other keys (e.g. Ctrl-n to switch tabs) are still available.

Annoyingly, there is currently no way to get gmail to edit an email with ctrl-I at the moment [1], though you can use the old HTML view instead.

Colours and Fonts

It's worth checking the font that's being used in Firefox through the preferences dialog. I changed mine to Ubuntu as by default Vimperator will use the default Mono font.

Vimperator has many of the configuration parameters you'd expect for setting fonts, colours and changing aspects of the interface. For color themes the easiest way is to look at the repository:

  • Find the colour scheme that you want.
    The vimperator color repository is the best option.
  • Download and install it to ~/.vimperator/colors/
    Don't forget to grab it in raw form!
  • Configure it in your ~/.vimperatorcc
    On the command line do :colorscheme <name> for testing, it will provide auto-completion for what's available as soon as there's a space.
  • Restart Firefox
    Restart to test that the configuration is working, or do :source ~/.vimperatorrc

NOTE: Molokai is available on pschmitt's github, thanks to Vimperator tips and tricks for the pointer!

Firefox configuation

A side-benefit of using Vimperator is that you can define Firefox configuration in a text file. The Arch Wiki has some useful configuration tweaks. The settings I used are:

" Firefox settings
" GPU accelerated rendering
set! layers.acceleration.force-enabled=true
set! layers.offmainthreadcomposition.enabled=true
" Improve network performance
set! network.http.pipelining=true
" Save session every 60 seconds, default every 15 seconds
set! browser.sessionstore.interval=60000

Vimperator resources and footnotes

[1]https://github.com/vimperator/vimperator-labs/issues/247
[2]http://stackoverflow.com/questions/26711895/how-to-unmap-some-key-bindings-for-a-particular-site-in-vimperator

Comments

If you have comments or questions about Vimperator please comment below!

blog comments powered by Disqus