Vim icon indicating copy to clipboard operation
Vim copied to clipboard

`S`/`cc` doesn't auto indent on empty line

Open alnorris opened this issue 7 years ago • 29 comments

When your in Normal mode and your on an empty line and the cursor is at the very left, pressing 'S' in normal Vim auto indents the line and goes into insert mode, but VS Vim doesn't seem to indent at all.

Technical details:

  • VSCode Version: 1.6.1
  • VsCodeVim Version: 0.4.0
  • OS: OSX El capitan

What happened:

  • Typing cc when cursor is at col 0 and in block on empty line: Jumping to input mode, but won't indent correctly
  • Typing cc when cursor is at col 2 (or any col): Removes line and ends up at col 0 with no indentation
  • Typing cc when cursor is at col 0 but there is valid code on line that is inside a block: Removes line as it should do, but cursor ends at col 0 with trailing whitespace
  • Typing cc when cursor is at col >2 (in block, line with valid code, cursor on code): Removes line of code and indents correctly ✅

Here all of those scenarios in a GIF (with tab width of 3 instead of 2) cc

Contributed by @lumio at https://github.com/VSCodeVim/Vim/issues/1828.

What did you expect to happen: Typing cc will always clear the line, indents it and cursor jumps to end of line.

How to reproduce it: See above, but typically typing cc on different col positions.

alnorris avatar Oct 31 '16 15:10 alnorris

Nice catch, if the cursor is at somewhere between first char or last char, S works as expected but doesn't work if it's at the beginning of the file.

rebornix avatar Oct 31 '16 17:10 rebornix

Not sure for what reason cursor updating in commands which invoke delete no longer works, I saw this commit change https://github.com/VSCodeVim/Vim/commit/3dad7cab1d09704c85824b726d9769a71be12817#diff-7addcd1a8a241060a73b1fe4abb39960R1269 so @johnfn might have an idea about that.

I take a quick look but now I'm confused, take S for example, if we want to control the cursor position after running delete operator, how can we do that? delete operator is now a postponed action.

rebornix avatar Nov 01 '16 22:11 rebornix

@rebornix we use PositionDiffs now. We have a "beginning of line" position diff that just tells the cursor to go to the beginning of the line after the transformation is applied. We use that a few times...

johnfn avatar Nov 02 '16 00:11 johnfn

This problem is fixable once the "reindent a selection" command is added, per https://github.com/Microsoft/vscode/issues/19847#issuecomment-277348907

Chillee avatar May 23 '17 06:05 Chillee

Seems dd O works perfectly for me. Is it possible to remap cc to dd O?

xiluo58 avatar Aug 27 '17 05:08 xiluo58

@xiluo58 That's an interesting idea actually. To be clear to anybody who was confused as me, he's suggesting ddO.

Chillee avatar Aug 27 '17 06:08 Chillee

That works for me!

    "vim.insertModeKeyBindings": [{
        "before": ["j", "k"],
        "after": ["<Esc>"]
    }, {
        "before": ["c", "c"],
        "after": ["d", "d", "O"]
    }],

It would still definitely be nice to see the default behavior fixed.

EDIT: Actually it seems like this doesn't work, seeing as though it's an insert mode key binding. I tried otherModesKeyBindings and it doesn't seem to work there.

knpwrs avatar Nov 17 '17 15:11 knpwrs

Any progress on this?

ddO sadly isn't a universal workaround either. For example, it won't work on the last line of a file.

ddO on c:

a
  b
  c

Produces

a
  _
  b

Also doesn't work when single line is indented:

ddO on b:

a
  b
c

Produces:

a
_
c

alexozer avatar Jan 06 '18 17:01 alexozer

I agree a proper indentation should be performed of the lines. This temporary fix seems to work for me. But the previous problems by @alexozer still apply.

    "vim.otherModesKeyBindings": [
      {
        "before": ["c", "c"],
        "after": ["d", "d", "d", "O"]
      }
    ],

Not sure why the third "d" is necessary.

asethwright avatar Jan 09 '18 01:01 asethwright

Hitting Tab after cc seems to do the right thing every time.

Is there a way to automate this?

shaunlebron avatar Mar 03 '18 17:03 shaunlebron

@shaunlebron It doesn't if your cursor starts after the tab position.

Chillee avatar Mar 09 '18 04:03 Chillee

@Chillee do you have an example? would like to reproduce

shaunlebron avatar Mar 09 '18 16:03 shaunlebron

@shaunlebron Take something like

  asd|f

where there's 2 spaces before the asdf. Presing cc takes you to

  |

and a tab adds 2 more spaces, which is not the right thing.

Chillee avatar Mar 09 '18 16:03 Chillee

any updates on this?

asilvadesigns avatar Apr 24 '18 21:04 asilvadesigns

Another problem with remapping to ddO is that for isolated lines (single lines with whitespace immediately above and below), there is no preceding line to base indentation off of, and so O creates the new line above with no indentation. For instance consider the following Python code:

def f():  # next line intentionally left blank

    ret|urn  # | represents the cursor

In vim, cc would clear the line and place the cursor at the correct indentation (four space from the left margin, in this example). But in VSCode Vim, since there's no line above return to base indentation off of, it clears the line and places the cursor at the beginning of the line (outside the function body).

Python isn't the easiest language to infer desired indentation, but when the desired indentation is already given, it should be respected when using cc -- independent of any VSCode capabilities or settings.

That said, I think a better temporary keybinding for a single cc would be ^C. However that's not easily repeatable -- 5cc is not achievable by repeating ^C

rben01 avatar Aug 24 '18 07:08 rben01

Has anyone here managed to figure it out?.. Seems to be an issue still.

aldanor avatar May 18 '19 17:05 aldanor

Sorry to revive such an old thread - but is this really not solved yet? In python it's really annoying and given the love python gets elsewhere in vscode, this appears a bit strange.

@rben01 s workaround of using ^ C works best for me. So much that I'd like to remap it actually, but that doesnt work either:

  "vim.normalModeKeyBindings": [
    {
      "before": [
        "c",
        "c"
      ],
      "after": [
        "^",
        "C"
      ]
    }
  ]

Somebody got a better idea?

casio avatar Nov 02 '19 22:11 casio

There's nothing we can do about this - it's an upstream problem. After a command like cc, we run editor.action.reindentselectedlines, which requires indentation rules to be specified for the current language to work correctly.

Seems like these are relevant issues. Go upvote them please! Python: https://github.com/microsoft/vscode-python/issues/8996 C++: https://github.com/microsoft/vscode-cpptools/issues/883

J-Fields avatar Dec 30 '19 21:12 J-Fields

How about using some kind of workaround until it's fixed properly upstream? It's a very annoying problem and I don't think it's good for the end user to just shove it under the rug waiting for it to potentially be fixed someday somewhere else. Like, O action for example could be implemented just by doing end+enter macro or something like that.

Raikiri avatar Jan 28 '20 00:01 Raikiri

Hi I have Visual Studio Code 1.43.2, vim extension 1.13.1. I cannot remap cc, is it also a known bug? I've included the following chunk in my settings.json, "leader, m" works, but the cc remap does not.

    "vim.normalModeKeyBindings": [
      {
        "before": [ "c", "c" ],
        "after": [ "^", "C" ],
      },
      {
        "before": [ "<leader>", "m" ],
        "commands": [ "bookmarks.toggle" ]
      },
      {
        "before": [ "<leader>", "b" ],
        "commands": [ "bookmarks.list" ]
      }
    ]

This is frustrating, especially when I see this issue was raised in the year of 2016, and now it's 2020.

zeroxia avatar Apr 04 '20 18:04 zeroxia

@zeroxia see https://github.com/VSCodeVim/Vim/issues/4464#issuecomment-577246612

I agree, it's frustrating, but then this is open source...

Spirarel avatar Apr 06 '20 13:04 Spirarel

Have that problem with C#. "Reindent selected lines" does not work for it, but indent adds when use "o". So I made that workaround. But it only works if upper line not empty too.

    "vim.normalModeKeyBindingsNonRecursive": [
        {
            "before": ["S"],
            "after": ["d", "d", "g", "k", "o"],
        },
    ],

ColdSpirit0 avatar Apr 08 '20 02:04 ColdSpirit0

Such kind of key binding works well indeed. However, it now makes u confuse me. It considers the combination as the combination itself, so I need to undo for 3 times. I think an update to implement a real S should be better indeed.

MrHate avatar May 02 '20 05:05 MrHate

offer a workaround for "o", which I use frequently:

    "vim.normalModeKeyBindingsNonRecursive": [
        {
            "before": [
                "o"
            ],
            "after": [
                "o", "_",
            ],
            "commands":[
                "editor.action.formatSelection",
                "deleteLeft",
            ]
        },

gaoshan0621 avatar Jun 24 '20 11:06 gaoshan0621

I have noticed something. "cc" does not automatically indent, while "o" and "O" do, at least most of the time. Therefore, a fix should be possible without upstream/vscode, or not?

sql-koala avatar Oct 06 '20 10:10 sql-koala

@sql-koala Is this still an issue? Because I can't reproduce this. Both cc and S auto indent for me, even on empty lines.

berknam avatar Dec 03 '20 16:12 berknam

Indentation after both o (editor.action.insertLineAfter) and cc (editor.action.reindentselectedlines) is determined by the language support, but they're specified differently, so some language plugins support the former better than the latter. Maybe some supports the latter better than the former, but none that I've found.

I write C++ and python for my job and o works great while cc doesn't in both of these. Typescript and rust, however, both work as expected.

J-Fields avatar Dec 03 '20 17:12 J-Fields

@J-Fields Which part of the language support handles this indentation? Is it the TextMate grammar, the formatter, the language-configuration.json or even something else?

There are many languages (like Swift) which currently aren't supported very well by S/cc either and I would like to help improve support for those.

fwcd avatar Jun 27 '22 15:06 fwcd

remapping cc to ddko seems to work. It seems that o formats differently from O. There might be exceptions though.

Clev7 avatar Aug 19 '22 17:08 Clev7

I've been looking for answers to this for a while, and it's still broken. There are workarounds that get close, but no perfect solutions yet. The main thing I want is for cc<escape> to remove any indentation as it does in Vim, and none of the workarounds I've found achieve this.

CalebMDMI avatar Nov 09 '23 20:11 CalebMDMI