var vimotions = (function () {
		"use strict";

		function addClass(element, className) {
			element.className += " " + className;
		}

		function removeClass(element, className) {
			element.className = element.className.replace(new RegExp("(?:^|\\s)" + className + "(?!\\S)"), '');
		}

		var listItems,
			currentItem,
			motionHandlers = {
				"j": function () {
					if (!isNaN(currentItem)) {
						removeClass(listItems[currentItem], "vimotions-selected");
						currentItem = currentItem < listItems.length - 1 ? currentItem + 1 : currentItem;
					} else {
						currentItem = 0;
					}
					addClass(listItems[currentItem], "vimotions-selected");
				},
				"k": function () {
					if (isNaN(currentItem)) {
						return;
					}
					removeClass(listItems[currentItem], "vimotions-selected");
					currentItem = currentItem > 0 ? currentItem - 1 : currentItem;
					addClass(listItems[currentItem], "vimotions-selected");
				},
				"G": function () {
					var lastItemIndex = listItems.length - 1;
					if (!isNaN(currentItem)) {
						removeClass(listItems[currentItem], "vimotions-selected");
					}
					currentItem = lastItemIndex;
					addClass(listItems[currentItem], "vimotions-selected");
				}
			};

		function handler(evt) {
			if (evt.keyCode === 16) {
				return;
			}
			var char = String.fromCharCode(evt.keyCode);
			char = evt.shiftKey ? char : char.toLowerCase();
			motionHandlers[char] && motionHandlers[char]();
		}

		return {
			bindTo: function (list) {
				listItems = list.children;
				currentItem = NaN;
				document.addEventListener("keydown", handler, false);
			},
			invoke: function (motion) {
				motionHandlers[motion]();
			}
		};
	}());

@@ -315,16 +315,31 @@
 ntItem,%0A
+%09%09%09stack = %5B%5D,%0A
 %09%09%09motio
@@ -363,36 +363,96 @@
 %09%22j%22: function (
+count
 ) %7B%0A
+%09%09%09%09%09count = typeof count !== %22undefined%22 ? count : 1;%0A
 %09%09%09%09%09if (!isNaN(
@@ -529,24 +529,68 @@
 elected%22);%0A%09
+%09%09%09%09%7D else %7B%0A%09%09%09%09%09%09currentItem = -1;%0A%09%09%09%09%09%7D%0A
 %09%09%09%09%09current
@@ -608,16 +608,24 @@
 entItem 
++ count 
 %3C listIt
@@ -635,20 +635,16 @@
 .length 
-- 1 
 ? curren
@@ -655,68 +655,37 @@
 m + 
-1 : currentItem;%0A%09%09%09%09%09%7D else %7B%0A%09%09%09%09%09%09currentItem = 0;%0A%09%09%09%09%09%7D
+count : listItems.length - 1;
 %0A%09%09%09
@@ -764,27 +764,87 @@
 : function (
-) %7B
+count) %7B%0A%09%09%09%09%09count = typeof count !== %22undefined%22 ? count : 1;
 %0A%09%09%09%09%09if (is
@@ -983,9 +983,18 @@
 tem 
-%3E
+- count %3E=
  0 ?
@@ -1012,23 +1012,17 @@
 m - 
-1 : currentItem
+count : 0
 ;%0A%09%09
@@ -1384,68 +1384,275 @@
 ion 
-handler(evt) %7B%0A%09%09%09if (evt.keyCode === 16) %7B%0A%09%09%09%09return;%0A%09%09%09%7D
+getCountFrom(stack) %7B%0A%09%09%09var count = 0;%0A%09%09%09for (var i = 0; i %3C stack.length; i++) %7B%0A%09%09%09%09var parsed = parseInt(stack.pop(), 10);%0A%09%09%09%09if (isNaN(parsed)) %7B%0A%09%09%09%09%09break;%0A%09%09%09%09%7D%0A%09%09%09%09count += parsed * Math.pow(10, i);%0A%09%09%09%7D%0A%09%09%09return count %7C%7C 1;%0A%09%09%7D%0A%0A%09%09function handler(evt) %7B
 %0A%09%09%09
@@ -1748,19 +1748,25 @@
 Case();%0A
+%0A
 %09%09%09
+if (!
 motionHa
@@ -1781,12 +1781,87 @@
 har%5D
- && 
+) %7B%0A%09%09%09%09stack.push(char);%0A%09%09%09%7D else %7B%0A%09%09%09%09var count = getCountFrom(stack);%0A%09%09%09%09
 moti
@@ -1877,18 +1877,28 @@
 s%5Bchar%5D(
-);
+count);%0A%09%09%09%7D
 %0A%09%09%7D%0A%0A%09%09

Add support for multi-key motions