36

Suppose I've got multiple cursors along several lines, like this:

foo|
barr|
foobar|
baz|

How can I automatically push the whitespace at the end of each line out to a flat edge, like this?:

foo    |
barr   |
foobar |
baz    |

(In these examples, | is supposed to be my cursor.)

When you just Tab or Space from the initial arrangement, you get this:

foo    |
barr    |
foobar    |
baz    |

That's useful, but not what I'm looking for. I'm looking for some kind of keyboard shortcut that will let me indent from a ragged multi-cursor insert out to a straight column.

6
  • Does simply inserting a tab or two work? Sep 14, 2012 at 19:42
  • No, but I might be failing to understand. I've edited to clarify my question. Sep 14, 2012 at 20:53
  • Your edit describes what Space does, and to some extent Tab will to if your lines vary by a large amount, but if they're all pretty close then after two tabs your cursors should all be on a tabstop. You might have to do a bit of adjusting to get them all on the same tabstop, but it'll be less than trying to adjust with spaces. Sep 14, 2012 at 21:21
  • It's weird. Pressing Tab at the end of each line indents the ragged multi-cursor insert out to a straight column, but it's not possible to achieve the same effect using regex. I searched for trailing spaces: \s*$ and replaced them with the tab character: \t - but \t does not achieve the same effect as pressing Tab manually.
    – amiregelz
    Sep 14, 2012 at 22:38
  • 1
    FYI, I posted this as a feature request on Sublime Text 2 request board. Sep 17, 2012 at 14:15

3 Answers 3

10

You could use wbond's Sublime Alignment

It may require you to add this to your settings file (Preferences>Package Settings>Alignment>Settings-User:

// The mid-line characters to align in a multi-line selection, changing
// this to an empty array will disable mid-line alignment
"alignment_chars": ["=", "|"],
// If the following character is matched for alignment, insert a space
// before it in the final alignment
"alignment_space_chars": ["=", "|"]

Replace "|" with whatever character you want to align.

Edit: As mtoast has found out, adding "\n" to "alignment_chars" gives the desired effect. Adding the new line character to "alignment_space_chars" is probably not needed and may delete the text. However, with my limited tests I did not see a difference.

Hold control and click at the end of each line. Then press the alignment hotkeys (For linux the default is ctrl + alt + a). You will find that the cursors are lined up with the furthest cursor position.

Edit2: Adding newline to "alignment_space_chars" will delete text if you highlight a block of text and Sublime Alignment can't find something else to align on the line (like a equal sign).

Also, if Sublime Alignment can't find something else to align, adding newline to "alignment_chars" will pad the end of lines with spaces (or tabs depending on your settings) to match longest line highlighted.

5
  • 1
    Wow, great! I installed the Sublime Alignment package, added "\n" (newline) to my "alignment_chars", and got the desired result. (Note: I didn't add it to "alignment_space_chars", which caused the lines to be deleted.) If you'll add that specific suggestion ("n") to your answer, I'll accept. Oct 2, 2012 at 17:23
  • Nice! Very useful package for perfectionists like me :)
    – amiregelz
    Oct 4, 2012 at 20:52
  • 3
    There's also a similar package: Align Tabular, which is a little more flexible (you're able to align on multiple characters).
    – d_rail
    Sep 24, 2013 at 21:13
  • With AlignTab mentioned above by d_rail, remember to escape | by a single `\`
    – user
    Oct 12, 2013 at 6:57
  • I can't believe that this doesn't have a million up-votes.
    – Charles
    Nov 17, 2016 at 22:06
51

You can also do it without an external package using a minor hack, with only slightly more effort. Here's how:

| represents a cursor in these instructions.

  1. Create cursors on all desired lines using Ctrl+Click or by selecting a block of text and pressing Ctrl+Shift+L. (selection docs)

  2. Add additional spaces to the end of every word, until every cursor is at or past the point where you want your column (does not matter how far past):

    foo     |
    barr     |
    foobar     |
    baz     |
    
  3. (optional1) Type any character followed by a space; let's use c:

    foo     c |
    barr     c |
    foobar     c |
    baz     c |
    
  4. Press Home to make the cursors go the beginning of the lines:

    |foo     c
    |barr     c
    |foobar     c
    |baz     c
    
  5. Press → (right arrow) until the cursors are where you want your column:

    foo    | c
    barr   |  c
    foobar |    c
    baz    | c
    
  6. Press Ctrl+Shift+ to select all following whitespace and c, then press Delete:

    foo    |
    barr   |
    foobar |
    baz    |
    
  7. (optional1) Press Delete again to clean up the extra whitespace character that we added in the optional step.


1 We use the c character followed by a space only if there is additional content on the lines that we want to keep. Without it, Ctrl+Shift+ would select the first word of any additional content on the lines, making deletion tricky.

5
  • 2
    This looks twisted at first but it's a neat hack. Good for pasting columns with proper alignment. Next column can be pasted using text pastry plug-in.
    – user
    Feb 26, 2014 at 18:05
  • 1
    I've been using this technique for a while but be careful, ctrl+shift+right doesn't treat all characters consistently so it may end up selecting more than just white space.
    – SpareBytes
    Jun 12, 2015 at 16:37
  • 1
    A really neat trick, I agree. But I just tried it without a character at the end, and used Shift-End Delete and it just worked. Does it work in some cases but not others?
    – Septagram
    Sep 1, 2015 at 12:54
  • This is what I always do :)
    – Domino
    Apr 9, 2016 at 21:23
  • This doesn't work if the c on one line is before the end of the word on another. Which is the problem I'm having right now. Certain lines don't contain enough character to scroll to the right, so when you do it wraps to the next line, leaving this hack as just that. This is a hack, not a useful catch-all replacement. May 25, 2016 at 1:52
0

For those who want to indent on characters other than = and |, I was able to install the Alignment package and modify the file in Sublime Text > Preferences > Package Settings > Alignment > Settings - User to look like the following:

{
  "alignment_chars": [
    "{create",
   ]
}

I then selected the following code:

  let!(:admin_user) {create(:admin_user, :admin)}
  let!(:another_admin_user) {create(:admin_user, :admin)}
  let!(:superadmin_user1) {create(:admin_user, :superadmin)}
  let!(:superadmin_user2) {create(:admin_user, :superadmin)}
  let!(:nonadmin_user) {create(:admin_user)}

and pressed Command + Ctrl + A to align it.

  let!(:admin_user)        {create(:admin_user, :admin)}
  let!(:another_admin_user){create(:admin_user, :admin)}
  let!(:superadmin_user1)  {create(:admin_user, :superadmin)}
  let!(:superadmin_user2)  {create(:admin_user, :superadmin)}
  let!(:nonadmin_user)     {create(:admin_user)}

Everything was moved to the leftmost column that the {create text could occupy while still being aligned.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .