diff --git a/keymap/vim.js b/keymap/vim.js
index 5ed2d9bf7385dbe239a32063313c1475aa76483d..4484f7a8ea928761027da2758ed84fd3388f69aa 100644
--- a/keymap/vim.js
+++ b/keymap/vim.js
@@ -226,6 +226,7 @@
     { name: 'sort', shortName: 'sor' },
     { name: 'substitute', shortName: 's', possiblyAsync: true },
     { name: 'nohlsearch', shortName: 'noh' },
+    { name: 'yank', shortName: 'y' },
     { name: 'delmarks', shortName: 'delm' },
     { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
     { name: 'global', shortName: 'g' }
@@ -4522,6 +4523,13 @@
       nohlsearch: function(cm) {
         clearSearchHighlight(cm);
       },
+      yank: function (cm) {
+        var cur = copyCursor(cm.getCursor());
+        var line = cur.line;
+        var lineText = cm.getLine(line);
+        vimGlobalState.registerController.pushText(
+          '0', 'yank', lineText, true, true);
+      },
       delmarks: function(cm, params) {
         if (!params.argString || !trim(params.argString)) {
           showConfirm(cm, 'Argument required');
diff --git a/test/vim_test.js b/test/vim_test.js
index 7080c3062f3759af74861a86c6abe617ee05abda..800791debcf68bd11e09214b70392ea6b1b38400 100644
--- a/test/vim_test.js
+++ b/test/vim_test.js
@@ -3725,6 +3725,14 @@ testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {
   helpers.doKeys('n');
   helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting');
 }, { value: 'match nope match \n nope Match' });
+testVim('ex_yank', function (cm, vim, helpers) {
+  var curStart = makeCursor(3, 0);
+  cm.setCursor(curStart);
+  helpers.doEx('y');
+  var register = helpers.getRegisterController().getRegister();
+  var line = cm.getLine(3);
+  eq(line + '\n', register.toString());
+});
 testVim('set_boolean', function(cm, vim, helpers) {
   CodeMirror.Vim.defineOption('testoption', true, 'boolean');
   // Test default value is set.