Commit a4779318 for codemirror.net

commit a477931864776e7210207ec19f50c86626118875
Author: nightwing <amirjanyan@gmail.com>
Date:   Sat Dec 4 18:14:57 2021 +0400

    [vim] implement g0 g$ g<Arrow>

diff --git a/keymap/vim.js b/keymap/vim.js
index b7c88848..d6e87085 100644
--- a/keymap/vim.js
+++ b/keymap/vim.js
@@ -72,6 +72,8 @@
     { keys: '<Right>', type: 'keyToKey', toKeys: 'l' },
     { keys: '<Up>', type: 'keyToKey', toKeys: 'k' },
     { keys: '<Down>', type: 'keyToKey', toKeys: 'j' },
+    { keys: 'g<Up>', type: 'keyToKey', toKeys: 'gk' },
+    { keys: 'g<Down>', type: 'keyToKey', toKeys: 'gj' },
     { keys: '<Space>', type: 'keyToKey', toKeys: 'l' },
     { keys: '<BS>', type: 'keyToKey', toKeys: 'h', context: 'normal'},
     { keys: '<Del>', type: 'keyToKey', toKeys: 'x', context: 'normal'},
@@ -94,6 +96,7 @@
     { keys: '<PageUp>', type: 'keyToKey', toKeys: '<C-b>' },
     { keys: '<PageDown>', type: 'keyToKey', toKeys: '<C-f>' },
     { keys: '<CR>', type: 'keyToKey', toKeys: 'j^', context: 'normal' },
+    { keys: '<Ins>', type: 'keyToKey', toKeys: 'i', context: 'normal'},
     { keys: '<Ins>', type: 'action', action: 'toggleOverwrite', context: 'insert' },
     // Motions
     { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }},
@@ -123,6 +126,9 @@
     { keys: '<C-u>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }},
     { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }},
     { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }},
+    {keys: "g$", type: "motion", motion: "moveToEndOfDisplayLine"},
+    {keys: "g^", type: "motion", motion: "moveToStartOfDisplayLine"},
+    {keys: "g0", type: "motion", motion: "moveToStartOfDisplayLine"},
     { keys: '0', type: 'motion', motion: 'moveToStartOfLine' },
     { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' },
     { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }},
@@ -2086,6 +2092,16 @@
         return new Pos(lineNum,
                    findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum)));
       },
+      moveToStartOfDisplayLine: function(cm) {
+        cm.execCommand("goLineLeft");
+        return cm.getCursor();
+      },
+      moveToEndOfDisplayLine: function(cm) {
+        cm.execCommand("goLineRight");
+        let head = cm.getCursor();
+        if (head.sticky == "before") head.ch--;
+        return head;
+      },
       textObjectManipulation: function(cm, head, motionArgs, vim) {
         // TODO: lots of possible exceptions that can be thrown here. Try da(
         //     outside of a () block.
diff --git a/test/vim_test.js b/test/vim_test.js
index 468d4f07..7822d627 100644
--- a/test/vim_test.js
+++ b/test/vim_test.js
@@ -488,11 +488,35 @@ testVim('gj_gk', function(cm, vim, helpers) {
   // Test bottom of document edge case.
   helpers.doKeys('100', 'g', 'j');
   var endingPos = cm.getCursor();
-  is(endingPos != 0, 'gj should not be on wrapped line 0');
+  is(endingPos.ch != 0, 'gj should not be on wrapped line 0');
   var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
   var endingCharCoords = cm.charCoords(endingPos);
   is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');
 },{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentionallylongtotestmovementofgjandgkoverwrappedlines.' });
+testVim('g0_g$', function(cm, vim, helpers) {
+  var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
+  cm.setCursor(0, 4);
+  cm.setSize(120);
+  helpers.doKeys('g', 'Down');
+  var secondLineCoords = cm.charCoords(cm.getCursor());
+  is(secondLineCoords.top > topLeftCharCoords.top);
+  is(secondLineCoords.left > topLeftCharCoords.left);
+
+  helpers.doKeys('g', '0');
+  var start = cm.getCursor();
+  var startCoords = cm.charCoords(start);
+  is(start.ch != 0);
+  is(startCoords.left == topLeftCharCoords.left);
+  is(secondLineCoords.top === startCoords.top);
+  is(secondLineCoords.left > startCoords.left);
+
+  helpers.doKeys('g', '$');
+  var end = cm.getCursor();
+  var endCoords = cm.charCoords(end);
+  is(startCoords.left < endCoords.left);
+  is(startCoords.top == endCoords.top);
+  is(start.ch < end.ch && end.ch < cm.getValue().length / 2);
+},{ lineNumbers: false, lineWrapping:true, value: 'This line is intentionally long to test movement of g$ and g0 over wrapped lines.' });
 testVim('}', function(cm, vim, helpers) {
   cm.setCursor(0, 0);
   helpers.doKeys('}');