Copy with proper indentation

Mads Kristensen

You want to share some code you’ve written with a colleague, so you select it in the editor and hit Ctrl+C to copy it. As you paste it in Outlook/Slack/Teams, you realize that the indentation levels are inconsistent due to your original selection. You must now either go back to Visual Studio and do a box selection and copy that, or manually fix the indentation issue in Outlook. You know this, yet you make this mistake almost every time. Sounds familiar?

Image selection

It usually happens because you start your selection without the leading indentation. But every subsequent line has it. The result looks something like this when you paste it into Outlook:

Code with improper indentation pasted into Outlook

If this has happened to you, you’re not alone. In fact, multiple developers have reported this and requested a feature to fix it, so remember to vote for it if you agree.

Let’s do an experiment to see if we can fix this problem once and for all.

The experiment

We’ve created an extension called Copy Nice for this experiment. It removes unwanted indentation when you copy text from the editor. The question is, how does it determine if indentation is unwanted or not?

Consider this selection:

A common code selection pattern when copying code snippets

Notice how the first line of the selection doesn’t have its leading indentation selected. Also, all other lines in the selection contain only whitespace in the same span. This pattern is very common when copying code to share it with others in email or IM or elsewhere. In this case, Visual Studio recognizes the pattern and strips the leading indentation from the selection to end up with a well-formatted code snippet.

A well-formatted code snippet pasted into Outlook

For Visual Studio to correctly identify when to strip indentation, these conditions must all be true:

  1. Selection mode is not Box Selection
  2. Selection is not multi-caret selection
  3. Selection spans multiple lines
  4. Selection must start on an empty indentation

This makes sure that what you copy is always what you expect. But in case you want to disable this feature, you can of course do that from the Edit -> Advanced -> Strip Leading Whitespace on Copy command.

Toggle the feature on/off in Edit -> Advanced -> Copy Without Indentation

Next steps

If this feature is interesting to you, please install the Copy Nice extension and take it for a ride. Make sure to share any ideas and bugs on the GitHub issue tracker, and feel free to send pull requests too. The feature request ticket is a suitable place to share your comments and thoughts, so make sure to vote and comment there as well.

Do you like the idea of community experiments like this one? Let us know in the comments below.

21 comments

Discussion is closed. Login to edit/delete existing comments.

  • MgSam 7

    I don’t know how much Microsoft pays you, Mads, but whatever it is, it’s not enough. 🙂

    • Mads KristensenMicrosoft employee 1

      Kind words. Thank you 🙂

    • Eugene Ivanoff 0

      +1

    • Eli Black 0

      Yes, thank you, Mads! 🙂

  • Cirrus One 0

    Excellent. It would be nice if you had something similar for paste when pasting from Excel cells back to VS. Eg say you have the following in a single cell in Excel

    public string PropertyXYZ1 => "From Excel1";
    public string PropertyXYZ2 => "From Excel2";

    Copying and pasting that cell back into VS doubles up the quotes and also places additional quotes around the whole value, eg

    "public string PropertyXYZ1 => ""From Excel1"";
    public string PropertyXYZ2 => ""From Excel2"";
    "
    • Mads KristensenMicrosoft employee 2

      I just tried this, and Excel puts the wrong quotation marks on the clipboard. It’s not VS that misinterprets the pasted string and adds extra quotes. So, the feature could be to analyze the text on paste and look for known anti-patterns and correct them when inserting into the text buffer. This might be error prone…

      • Cirrus One 0

        It’s definitely Excel and not VS that is the source of the problem. Currently I get around this by copy and pasting from Excel to Notepad and then do a 3 step replace

        "" -> @ (need to be careful that temporary character is not in original string)
        
        " -> empty
        
        @ -> "

        and then copy and paste the final result from Notepad to VS.

        It would be nice if VS had a paste tool to do this automatically, an n-stage replace on paste would likely be less error prone than using and maintaining an auto detect and fix.

        I don’t know if I’m the only one that uses Excel but I find it useful for boilerplate code to replace types and property names, especially when matching database columns.

  • John B 1

    Works great. I might reword “Selection must start on an empty indentation” to “Selection must not include first line’s indentation” in the various places that appears. Thanks!

  • Thomas Ardal 3

    As already mentioned in the Developer Community, I’m very happy with this extension. Using it all the time now without even thinking about it. Fixed the initial request perfectly 💪🏻

  • Stefan Hogedal 3

    I, who am proud of having learned to always copy full lines, don’t like the 4th requirement.

    • Mads KristensenMicrosoft employee 0

      Can you explain what the problem is with that? If you copy the full line, then the extension will no-op because you didn’t start the selection indented.

      • Jahmai Lay 1

        Copying full lines is a good habit that people shouldn’t be trained out of, but also removing the prefixed indentation while copying full lines could be useful.

  • Yves Goergen 1

    The mistake lies in step one. Just select entire lines. It makes your life so much easier, everywhere. No special Visual Studio magic needed. If you’ll get used to this changed behaviour, you’ll only be unhappy when it doesn’t change in all other applications as well. I’d be much more pleased if Microsoft would finally fix the massive amount of critical bugs in the existing VS editors, most of all the broken-beyond-repair Razor editor. It messes around everything and even destroys code! Isn’t that more important than such gimmicks like this one here? I’m very disappointed by Microsoft.

    • Mads KristensenMicrosoft employee 2

      I agree copying the full line is a solution, but it has its issues.

      1. You sometimes forget to do that and must go back and redo the copying
      2. If you paste into Teams or Notepad, there is no way to easily remove all leading indentation using box selection like in Office apps

      Working on paper-cut level issues like this one is not mutually exclusive to fixing other issues in Razor or any other area. Separate teams, separate buckets of work.

      • Chuck Ryan 1

        It might not be, but even a good idea does not justify continuing to expand the bloated monstrosity that VS has become with trivial tweaks and the internal contest Microsoft is holding to see who can find the least useful way to add a new search.

        Please stop adding even more ways for the system to fail, as your talents would be much more valuable if applied to de-bloating the beast.

  • Andreas Plahn 1

    As usual Mads, small but yet so smart thinking. Thank you!

  • Markus Hastreiter 0

    I usually press ALT while selecting the text for that matter. It keeps the start column intact. What I find more annoying is that Copy&Paste does not respect the theme (colors from syntax highlighting and background color). Is there an extension for that as well?

    • Mads KristensenMicrosoft employee 0

      I don’t know of such an extension

    • Trey Morris 0

      There’s several available depending on your version of Visual Studio. Here’s the one from Microsoft DevLabs:

      Copy As Html – Visual Studio Marketplace

      • Richard Cox 0

        Note: the presence of the Copy as HTML extension will prevent this extension working.

        As I never really use the copy as HTML, this wins as being more commonly useful!

  • Julien CouvreurMicrosoft employee 0

    Awesome. Thanks! I’d filed an issue just on this: https://github.com/dotnet/roslyn/issues/64993
    I still wonder whether this should be the default behavior when copying contents out of a raw string literal…

Feedback usabilla icon