diff --git a/keymap/vim.js b/keymap/vim.js
index 7cf5a956e004b5e979a4704eb23191e27f50c03f..b082268183720adb0ed3494297cae383c36f5f92 100644
--- a/keymap/vim.js
+++ b/keymap/vim.js
@@ -2637,25 +2637,32 @@
       incrementNumberToken: function(cm, actionArgs) {
         var cur = cm.getCursor();
         var lineStr = cm.getLine(cur.line);
-        var re = /-?\d+/g;
+        var re = /(-?)(?:(0x)([\da-f]+)|(0b|0|)(\d+))/gi;
         var match;
         var start;
         var end;
         var numberStr;
-        var token;
         while ((match = re.exec(lineStr)) !== null) {
-          token = match[0];
           start = match.index;
-          end = start + token.length;
+          end = start + match[0].length;
           if (cur.ch < end)break;
         }
         if (!actionArgs.backtrack && (end <= cur.ch))return;
-        if (token) {
+        if (match) {
+          var baseStr = match[2] || match[4]
+          var digits = match[3] || match[5]
           var increment = actionArgs.increase ? 1 : -1;
-          var number = parseInt(token) + (increment * actionArgs.repeat);
+          var base = {'0b': 2, '0': 8, '': 10, '0x': 16}[baseStr.toLowerCase()];
+          var number = parseInt(match[1] + digits, base) + (increment * actionArgs.repeat);
+          numberStr = number.toString(base);
+          var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : ''
+          if (numberStr.charAt(0) === '-') {
+            numberStr = '-' + baseStr + zeroPadding + numberStr.substr(1);
+          } else {
+            numberStr = baseStr + zeroPadding + numberStr;
+          }
           var from = Pos(cur.line, start);
           var to = Pos(cur.line, end);
-          numberStr = number.toString();
           cm.replaceRange(numberStr, from, to);
         } else {
           return;
diff --git a/test/vim_test.js b/test/vim_test.js
index 18268ee789139815c7fe84e2ca4926862cd2e59c..5a42b90fa8aca61dfb1dbcbb9b98895150b44cd1 100644
--- a/test/vim_test.js
+++ b/test/vim_test.js
@@ -4235,4 +4235,250 @@ testVim('beforeSelectionChange', function(cm, vim, helpers) {
   eqCursorPos(cm.getCursor('head'), cm.getCursor('anchor'));
 }, { value: 'abc' });
 
+testVim('increment_binary', function(cm, vim, helpers) {
+  cm.setCursor(0, 4);
+  helpers.doKeys('<C-a>');
+  eq('0b001', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0b010', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0b001', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0b000', cm.getValue());
+  cm.setCursor(0, 0);
+  helpers.doKeys('<C-a>');
+  eq('0b001', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0b010', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0b001', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0b000', cm.getValue());
+}, { value: '0b000' });
+
+testVim('increment_octal', function(cm, vim, helpers) {
+  cm.setCursor(0, 2);
+  helpers.doKeys('<C-a>');
+  eq('001', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('002', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('003', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('004', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('005', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('006', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('007', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('010', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('007', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('006', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('005', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('004', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('003', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('002', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('001', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('000', cm.getValue());
+  cm.setCursor(0, 0);
+  helpers.doKeys('<C-a>');
+  eq('001', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('002', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('001', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('000', cm.getValue());
+}, { value: '000' });
+
+testVim('increment_decimal', function(cm, vim, helpers) {
+  cm.setCursor(0, 2);
+  helpers.doKeys('<C-a>');
+  eq('101', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('102', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('103', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('104', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('105', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('106', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('107', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('108', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('109', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('110', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('109', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('108', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('107', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('106', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('105', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('104', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('103', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('102', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('101', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('100', cm.getValue());
+  cm.setCursor(0, 0);
+  helpers.doKeys('<C-a>');
+  eq('101', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('102', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('101', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('100', cm.getValue());
+}, { value: '100' });
+
+testVim('increment_decimal_single_zero', function(cm, vim, helpers) {
+  helpers.doKeys('<C-a>');
+  eq('1', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('2', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('3', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('4', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('5', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('6', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('7', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('8', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('9', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('10', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('9', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('8', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('7', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('6', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('5', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('4', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('3', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('2', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('1', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0', cm.getValue());
+  cm.setCursor(0, 0);
+  helpers.doKeys('<C-a>');
+  eq('1', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('2', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('1', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0', cm.getValue());
+}, { value: '0' });
 
+testVim('increment_hexadecimal', function(cm, vim, helpers) {
+  cm.setCursor(0, 2);
+  helpers.doKeys('<C-a>');
+  eq('0x1', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x2', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x3', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x4', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x5', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x6', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x7', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x8', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x9', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0xa', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0xb', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0xc', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0xd', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0xe', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0xf', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x10', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x0f', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x0e', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x0d', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x0c', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x0b', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x0a', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x09', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x08', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x07', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x06', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x05', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x04', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x03', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x02', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x01', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x00', cm.getValue());
+  cm.setCursor(0, 0);
+  helpers.doKeys('<C-a>');
+  eq('0x01', cm.getValue());
+  helpers.doKeys('<C-a>');
+  eq('0x02', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x01', cm.getValue());
+  helpers.doKeys('<C-x>');
+  eq('0x00', cm.getValue());
+}, { value: '0x0' });