Vim: Arrow keys to navigate within soft-wrapped text block.

Created on 27 Feb 2018  Â·  10Comments  Â·  Source: VSCodeVim/Vim

Thanks in advance. I'm sorry if this has an easy fix. I did spend quite a bit of time trying to find a solution or a configuration option and I hope I didn't miss something trivial. I also poked around the Slack channel but must have joined at a slow time.

Is this a BUG REPORT or FEATURE REQUEST? (choose one): BUG REPORT maybe? Probably FEATURE REQUEST?
What happened: See https://github.com/Microsoft/vscode/issues/34448 . The arrow keys don't allow me to navigate among visual (soft-wrapped) lines in any mode. I have remapped j and k to gj and gk in non-insert modes, but in insert mode, I get around with the arrow keys.

What did you expect to happen: I expect (or at least wish) that navigation with arrow keys works as it does with vanilla VS Code. That is, I want to navigate up and down within soft-wrapped lines using the arrow keys (or at least have the option to enable it.)

How to reproduce it (as minimally and precisely as possible): Type a long line with soft wrap, and then try to navigate within it.

Environment: Ubuntu, Xmonad based custom desktop environment using Xorg.

  • Extension (VsCodeVim) version: v0.11.0
  • VSCode version: 1.20.1
  • OS version: 17.10.1

All 10 comments

On the Slack channel, some helpful people pointed out that I should avoid using the arrow keys anyway, as there are almost always better ways to move about in normal-mode. I think that's largely true. Although I already use a lot of vim movement commands effectively, I'm compelled to work harder to build more effective habits when working in a very small neighbourhood of a file (where I would normally default to using arrows).

In the meantime, a suitable workaround is to rebind the keys. I tried this, of course, before posting the issue, but I didn't know well enough to apply <C-o> first:

    "vim.insertModeKeyBindings": [
        {
            "before": ["<up>"],
            "after": ["<C-o>", "g", "k"]
        },
        {
            "before": ["<down>"],
            "after": ["<C-o>", "g", "j"]
        },
    ]

Thanks to @arussellk, @Nick and @chillee from the slack. https://vscodevim.slack.com/archives/C0ENQMTUM/p1520358214000115

Thanks for the tip! Seems like I need to configure that without the angle brackets around up and down:

  "vim.insertModeKeyBindings": [
    {
      "before": [
        "up"
      ],
      "after": [
        "<C-o>",
        "g",
        "k"
      ]
    },
    {
      "before": [
        "down"
      ],
      "after": [
        "<C-o>",
        "g",
        "j"
      ]
    },
  ],

Hm, looks like this isn't working anymore, with or without the angle brackets...

Edit: but it does seem to work after adding an arbitrary extra no-op config key before 🤨... such as this:

  "vim.insertModeKeyBindings": [
    {
      "before": [
        "+"
      ],
      "after": [
        "+"
      ],
    },
    {
      "before": [
        "up"
      ],
      "after": [
        "<C-o>",
        "g",
        "k"
      ]
    },
    {
      "before": [
        "down"
      ],
      "after": [
        "<C-o>",
        "g",
        "j"
      ]
    },
  ],

Opened #2924 to report this.

the easy workaround is uing the default up down of vscode's shortcut setting( ctrl+k+s ), it is overrided by vim after install the vim extension:

  {
    "key": "down",
    "command": "cursorDown",
    "when": "textInputFocus"
  },
  {
    "key": "up",
    "command": "cursorUp",
    "when": "textInputFocus"
  },

Edit: @metasong This doesn't actually work. It has a critical problem with it:

It escapes from autosuggest boxes. Here's a gif:

kapture 2019-01-11 at 13 25 56


Click here to show original broken keybindings (saved for posterity). Do not use!
Cool, looks like that works @metasong, cheers!

So the settings to change in order to get j, k, ↑ and ↓ to skip only single lines with VS Code Vim:

settings.json

{
  "vim.normalModeKeyBindingsNonRecursive": [
    {
      "before": ["j"],
      "after": ["g", "j"]
    },
    {
      "before": ["k"],
      "after": ["g", "k"]
    },
    {
      "before": ["down"],
      "after": ["g", "j"]
    },
    {
      "before": ["up"],
      "after": ["g", "k"]
    }
  ]
}

keybindings.json

[
  {
    "key": "down",
    "command": "cursorDown",
    "when": "textInputFocus"
  },
  {
    "key": "up",
    "command": "cursorUp",
    "when": "textInputFocus"
  }
]

Ref: my dotfiles

@timtro Did you end up finding a better fix for this? Or alternatively, are you still using settings similar to your original settings or my fixed settings?

It would be cool to hear a more official / less hacky recommendation for how to moving among word wrapped lines.

Maybe an improved version of @metasong's keybinding somehow that doesn't escape autocompletes? It also felt like after a while, this keybinding would cause performance problems... Would need to test this more, if there was a solution.

cc @jpoon @Chillee @arussellk

I think I may have come up with a fixed version of @metasong's keybindings (fixing the problem of escaping the autocomplete / suggest widget), based on the when condition from the extension keybindings.

It looks like this:

  {
    "key": "up",
    "command": "cursorUp",
    "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Insert' && !suggestWidgetMultipleSuggestions && !suggestWidgetVisible"
  },
  {
    "key": "down",
    "command": "cursorDown",
    "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Insert' && !suggestWidgetMultipleSuggestions && !suggestWidgetVisible"
  }

This doesn't need any changes to settings.

I will start using this and see if there are any other problems (including performance issues) with it.

Edit: Performance is great, much better than the original method.

@timtro Did you end up finding a better fix for this? Or alternatively, are you still using settings similar to your original settings or my fixed settings?

It would be cool to hear a more official / less hacky recommendation for how to moving among word wrapped lines.

Maybe an improved version of @metasong's keybinding somehow that doesn't escape autocompletes? It also felt like after a while, this keybinding would cause performance problems... Would need to test this more, if there was a solution.

cc @jpoon @Chillee @arussellk

Much less hacky: I switched back to (Neo)vim and (more importantly) stopped using the arrow keys to navigate so much. I just hit escape reflexively when I'm done editing and use h,j,k,l to move about.

I still use VS code from time to time—especially for markdown (thanks to markdown-preview-enhanced.)

Yeah, Neovim / Vim are options too, but VS Code has just too much good stuff to switch completely :)

My option above works really well actually, and it's just copying over the conditions from the extension - so not all that hacky.

I've opened a pull request to document this method as current best practice: #3623

Now that the documentation PR is open, you can probably close this one @timtro.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

orn688 picture orn688  Â·  3Comments

AndersenJ picture AndersenJ  Â·  3Comments

edwintorok picture edwintorok  Â·  3Comments

lucastheisen picture lucastheisen  Â·  3Comments

elithrar picture elithrar  Â·  3Comments