Is there a way to fix multi-line indenting in Sublime Text 3 so that it adds the indenting characters for the first line inside the selection?

5,467

On Sublime 3 there's this command called Paste and Indent and the keyboard command for that is Super + shift + V where Super is the main command key for your OS. This seems to do the trick.

I found it here: https://gist.github.com/eteanga/1736542


Edit: Original poster adding further information, so people don't have to try to parse the comments.

Going back to the second step of the original problem:

int firstVar, secondVar;
int myVar = 0;
int result = someThing(myVar);

if (result == GOOD_RESULT)
{
firstVar = 4;
secondVar = 11;
}
else
{
}

I select the two lines between the first set of braces (the assignments to firstVar and secondVar, copy them (Ctrl+C), then add an empty line between the second set of braces and place my cursor at the beginning of the blank line (indicated by the |, below):

int firstVar, secondVar;
int myVar = 0;
int result = someThing(myVar);

if (result == GOOD_RESULT)
{
firstVar = 4;
secondVar = 11;
}
else
{
|
}

Then I 'Paste and Indent' (Ctrl+Shift+V), and the code is pasted with the default indentation for the file type, ready for me to change. (Also, if I'd pasted more lines, with different indent levels, they would all be adjusted accordingly.)

int firstVar, secondVar;
int myVar = 0;
int result = someThing(myVar);

if (result == GOOD_RESULT)
{
firstVar = 4;
secondVar = 11;
}
else
{
  firstVar = 4;
  secondVar = 11;
|
}

Unfortunately, it's also left an extra blank line (because if I hadn't put the extra line, it wouldn't have indented at all), but that's easy enough to delete.

(So, sadly, it's still not as good as having the multi-line indentation work correctly, since I have to first create and then destroy a blank line. Just two extra key presses, you say? Sure, but it's two key presses I wouldn't need to do if multi-line indentation worked correctly, and it interrupts my natural flow, so I have to think about that rather than about the code changes I'm trying to make.

(Alternatively, I can de-select the newline character at the end of the last line, by pressing while continuing to hold down Shift, and then I only have to create a new line, but not delete one after pasting. But that's an even less natural thing to do or think about than adding and deleting and extra blank line, and it still involves two extra key presses.

(So either way, this feature is a workaround, not a fix, even if it is an interesting, even cool, feature.)

However, in situations where you already have lines of text between your braces (and you don't need to paste the new code just before the last brace), it works quite well: you don't have to add a blank line, just position your cursor at the beginning of the line where you want to insert the new code and press Ctrl+Shift+V. The lines will be inserted with indentation that matches its surroundings.

Also, you don't necessarily have to use the default indenting. If you place your cursor on some arbitrary column (with only whitespace to the left of it), the 'Paste and Indent' command will indent everything you paste to that column. (If you do this on a line with text to the right of the cursor, that line's indenting will be changed to match that of whatever you pasted.)

As I say, an interesting and fairly cool feature, worth playing with and getting to know, for sure. And worth being The Accepted Answer for this question. But still not quite as good as just having made the multi-line indentation work properly. : )

Share:
5,467

Related videos on Youtube

Wilson F
Author by

Wilson F

Long-time C programmer with some Python experience, recently migrated to full-on web development.

Updated on September 18, 2022

Comments

  • Wilson F
    Wilson F over 1 year

    When I select several lines in Sublime Text 3 and indent them as a block (using either Tab or Ctrl + ]), it adds the new whitespace characters at the beginning of the first line outside the selection instead of inside.

    Say I have a block of code that looks like this (Note: all of the below is just to illustrate the idea; please don't start on me about where my braces are, or how much I indent, etc.):

    int firstVar, secondVar;
    
    firstVar = 4;
    secondVar = 11;
    

    Now, I come back to this code later and need to make the value assignments conditional:

    int firstVar, secondVar;
    int myVar = 0;
    int result = someThing(myVar);
    
    if (result == GOOD_RESULT)
    {
    firstVar = 4;
    secondVar = 11;
    }
    else
    {
    }
    

    Of course, I want to indent it nicely, so I select the two items in the if clause and indent them as a block, with the Tab key, and Sublime Text, as expected, prepends indenting characters (a tab or a pre-determined number of spaces) to each selected line:

    [snip]
    
    if (result == GOOD_RESULT)
    {
      firstVar = 4;
      secondVar = 11;
    }
    else
    {
    }
    

    Then, because I am just going to be assigning different values to them in the else clause, I copy and paste them there, ready to amend:

    if (result == BAD_RESULT)
    {
      firstVar = 4;
      secondVar = 11;
    }
    else
    {
    firstVar = 4;
      secondVar = 11;
    }
    

    And there's the problem: Sublime Text indented the first line of my block, but didn't include the indenting characters in the selection, so when I copy-and-pasted it, I didn't get the indenting of the first line. (I wish I could change the background colour to illustrate better.)

    Not only that, but if I'd cut and pasted it instead, the indenting characters would have been left behind.

    I can work around it somewhat by trying to remember to copy/cut before doing the indenting, but a) I don't always remember and b) then I have to indent the code twice.

    Does anyone know of a fix for this?

  • Wilson F
    Wilson F over 9 years
    Your 1st image is what my selection looks like after I indent. I.e. the start of the selection block is indented, rather than the text within the selection block being indented. ... Your 2nd image is what mine looks like before I indent (in that my selection starts in the 1st column--there may or may not be whitespace starting each line, though that makes no difference to what happens when the text is indented). ... I tried your suggestion at b), but it ended up indenting the preceding line as well as the lines I actually wanted to indent. Thanks for the idea, though.
  • Ciprian Tomoiagă
    Ciprian Tomoiagă over 9 years
    Yeah, sorry, I misunderstood the question a bit. I don't know of a fix so that you would keep your workflow. In my case, it automatically indents the first line of the else clause (after the bracket), so the lost indenting is recovered. But if you cut from if, then yes, the spaces are left behind. Another solution would be to cut/copy whole lines, then insert them with paste from history. However, I don't know of a kbd shortcut for that command.
  • Wilson F
    Wilson F over 8 years
    Hmm. I tried that command, and I'm not seeing any difference between that and ordinary pasting. I expect I'm doing something wrong, but I'm not sure what it could be. Does it only work with one line at a time or something?
  • racl101
    racl101 over 8 years
    It works on multiple lines at a time. It will paste the code with the exact number of spaces indented per line for every line, instead of just affecting some lines. Only thing that will differ is where your cursor is before pasting. If your cursor is all the way at the beginning of the line it will paste with the indenting you for every line you copied, but if your cursor is already the same number of columns ahead of the number of spaces of the first line in the block you copied then the lines will be indented extra by the number of those additional spaces per line, but it will be consistent.
  • Wilson F
    Wilson F over 8 years
    I did some experimentation. It uses cursor position IF a) the cursor is on a blank line AND b) the cursor is not in the first column. If the cursor is on a non-blank line, it will use the indentation of the line it is on (i.e. the starting column of the pasted text will be the same as the starting column of the cursor's line and the indentation of all other pasted lines will be adjusted accordingly). If the cursor is in the first column of a blank line, it will use the first column of the last non-blank line above it. That is actually pretty cool.
  • Wilson F
    Wilson F over 8 years
    I'd be happy to accept this as The Answer, but it needs some further explanation/illustration in the body of the answer, because the explanations in these comments are dense and hard to read. If you don't mind me editing your answer, I'm happy to do it; otherwise I'll leave it to you.
  • Wilson F
    Wilson F about 8 years
    I will assume that no answer means "go ahead", then. : )