Vim: `emmet.triggerExpansionOnTab` enters visual mode

Describe the bug

When emmet.triggerExpansionOnTab is triggered via TAB, the editor enters visual mode.

To Reproduce

  1. Open a new .html file.
  2. In insert mode, type div.
  3. Press Tab.
  4. The editor enters visual mode.

Expected behavior

The editor should remain in insert mode.


Screenshots

Kapture 2020-12-14 at 16 08 25


Environment (please complete the following information):

  • Extension (VsCodeVim) version: 1.18.5
  • VSCode version: 1.52.0
  • OS: macOS Catalina

Additional context

Related to: https://github.com/VSCodeVim/Vim/issues/5474

The PR referenced in the issue above did not fix the issue.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 35
  • Comments: 28 (4 by maintainers)

Most upvoted comments

This is still an issue in 1.21.1 in case anyone was wondering. Thanks for your work! ❤️

any progress now ?

It might be worth a try, but I have the following Emmet settings right now and I can use the abbreviations without getting shoved into visual mode. I had the same problem as everyone else until I added the emmet.includeLanguages setting.

//* Emmet Settings *//
"emmet.triggerExpansionOnTab": true,
"emmet.showExpandedAbbreviation": "always",
"emmet.includeLanguages": {
    "javascript": "javascriptreact"
}

How to fix it

I had faced the same issue (with erb files). After doing some research to configure VSCode for Rails, I’ve fixed this issue by doing:

  • Install the Ruby extension.
  • Add "erb": "html" to the emmet.includeLanguages array setting.

Here’s my full settings file in case you wanna replicate it:

{
    "editor.fontSize": 16,
    "workbench.colorTheme": "Cobalt2",
    "editor.bracketPairColorization.enabled": true,
    "editor.bracketPairColorization.independentColorPoolPerBracketType": true,
    "editor.guides.bracketPairs": true,
    "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": true,
    "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": true,
    "editor.tabSize": 2,
    "editor.fontFamily": "'Fira Code', Menlo, Monaco, 'Courier New', monospace",
    "editor.fontLigatures": true,
    "editor.copyWithSyntaxHighlighting": false,
    "emmet.includeLanguages": {
        "erb": "html",
        "html": "html",
        "html.erb": "html",
        "ruby": "html",
        "html.inky": "html"
    },
    "emmet.triggerExpansionOnTab": true,
    "emmet.showExpandedAbbreviation": "always",
    "workbench.iconTheme": "vscode-great-icons",
    "auto-close-tag.fullMode": true,
    "editor.minimap.enabled": false,
    "files.associations": {
        "*.erb": "erb",
        "Gemfile": "ruby"
    }
}

And the extensions I have installed: image

* Most of them are not related to the issue, but may be worth mention it.

Perhaps this just needs to be reassigned? @berknam seems to not be very active anymore. Considering that we’ve identified the commit that caused this issue in this comment, perhaps the fix is straightforward? As far as I can tell this is still an issue in the latest version of the extension.

@J-Fields any chance this could get re-prioritized? The label seems to suggest that this is an upstream issue, but it seems doubtful if there are version of the Vim extension that work and ones that do not.

Any update?

@rehack Cool!, I install another version(1.16.0) and The problem is gone like magic.

This is How to switch to another version

how to change

@berknam

I personally can reproduce it on both Insiders and non-Insiders version. And am sure that the expansion occurs via editor.emmet.action.expandAbbreviation

Btw, per https://github.com/VSCodeVim/Vim/issues/5495, I downgraded to 1.6 and the issue no longer persist.

So I suspect there should be a commit between 1.6 and 1.7 that causes this.

https://github.com/VSCodeVim/Vim/compare/v1.16.0...v1.17.0

This issue is still relevant. I modified a bit @mrwest808 solution to be able to handle more scenarios with a simple repeated keystroke:

{
  "vim.insertModeKeyBindingsNonRecursive": [
    {
      "before": ["<C-m>"],
      "after": [],
      "commands": [
        {
          "command": "editor.emmet.action.expandAbbreviation",
          "args": []
        },
        {
          "command": "extension.vim_escape",
          "args": []
        }
      ]
    },
    ...
  ],
  "vim.normalModeKeyBindingsNonRecursive": [
    {
      "before": ["<C-m>"],
      "after": ["f", "/", "h", "i"]
    },
    ...
  ],
  ...
}

It will map the <kbd>C-m</kbd> key combination (<kbd>C-m</kbd> is more ergonomic for me) in both insert mode and in normal mode:

  1. The mapping in insert mode triggers emmet and exits to vim normal mode.
  2. The mapping in normal mode would navigate to the most-inner tag that is generated and enters to insert mode again.

You just have to press <kbd>C-m</kbd> twice, and you are golden 👯

I cannot found a solution to do it with one mapping as vscodevim doesn’t support the :normal command yet, and I don’t want to bother with integrating the external nvim to VSCode yet.

With this double mapping you can have more complex emmet expansions:

# The @ character is the cursor position

p.subtitle@
[C-m][C-m]
<p class="subtitle">@</p>

a>span.icon.github@
[C-m][C-m]
<a href=""><span class="icon github">@</span></a>

I’m experimenting with this issue right now (locally in my settings), and I’ve noticed that this abomination of a custom keybinding actually seems to produce the desired effect.

I simply tried recreating the steps I usually do manually to counteract this issue (<Esc> to exit visual mode followed by c i t to enter input mode inside of the newly created tag).

"vim.insertModeKeyBindingsNonRecursive": [
  {
    "before": ["<C-e>"],
    "after": [],
    "commands": [
      {
        "command": "editor.emmet.action.expandAbbreviation",
        "args": []
      },
      {
        "command": "extension.vim_escape",
        "args": []
      },
      {
        "command": "extension.vim_insert",
        "args": []
      },
      {
        "command": "extension.vim_right",
        "args": []
      },
      {
        "command": "extension.vim_right",
        "args": []
      },
      {
        "command": "extension.vim_right",
        "args": []
      }
    ]
  }
]

Can confirm this is still an issue in Vim (v1.22.2):

Version: 1.68.0-insider (user setup)
Commit: c23f0305dbf82b2319b198f4dbf3c5d5bc522f15
Date: 2022-05-16T05:17:17.823Z
Electron: 17.4.3
Chromium: 98.0.4758.141
Node.js: 16.13.0
V8: 9.8.177.13-electron.0
OS: Windows_NT x64 10.0.19044

As mentioned in the comment above, I had the same settings but was not able to get it to work.

Can you show what happens when you do that with Vim disabled?

Kapture 2020-12-16 at 10 00 39

Do you have any remaps in “vim.insertModeKeybindings” for the emmet trigger expansion command?

No I don’t.

The only settings enabled are

{
    "emmet.showExpandedAbbreviation": "never",
    "emmet.triggerExpansionOnTab": true
}

I’ve disabled all extension and only enabled the vim extension and those settings. Note that the editor enters visual mode when Tab is pressed.

Kapture 2020-12-16 at 10 04 48

Side Note

I noticed another thing, if you enable emmet.showExpandedAbbreviation, then pressing Tab works as expected for known HTML elements, but unknown element element, where the suggestion is not shown, then vim enters visual mode.