6

Is there a simple way to delete all white spaces on a line until the first character on that line is met?

An example:

           #a list of comments
                # item 1
                # item 2

And I would like it to become:

#a list of comments
# item 1
# item 2

I know how to delete n characters (ex: 8x) and to repeat the command (.), but how could I do without having to input the number of white spaces?

9

You can either visually select the lines and use

:'<,'>s/^\s*//

Which means 'substitute all of the whitespaces following the first column of the line by nothing'

Or go on the first line, use

  • 0 to go on the first column
  • d^ to delete until the first character of the line

And then go to the next line and use the dot command

  • Your first method is a bit too involved for me at this point :). A note to those using an international keyboard (ex US international), don't forget to press the space bar for d^ after the ^! – calocedrus Jun 20 '17 at 7:58
  • 1
    @calocedrus, :h :substitute is really the way to go in your case. Once you'll master :substitute, you'll have a good grasp of a key feature of the major sed *nix command. – Luc Hermitte Jun 20 '17 at 12:41
  • 1
    Many good answers, and they worked for me, difficult to select one vs others! At this point (~ 1 month after I asked), @statox's answer seems to have received most votes so I'll select it as the answer, decision also supported by Luc's advice. – calocedrus Jul 18 '17 at 1:35
6

In addition to statox's methods, you can:

  • Position the cursor at the beginning of the leading whitespace and type dw
  • Position the cursor anywhere in the leading whitespace and type diw
  • Position the cursor at the first non-space character of the line and type d0
  • Visually select all the lines you want to move left, e.g., by typing V on the first line and moving the cursor to the last line, then executing :left

Update

What I actually usually do in such cases is:

  • Visually select all the lines as above, type < to move them left by one shiftwidth, then type . until they're shifted all the way to the left margin.
  • For your second solution, how to quickly move to the first non-space character in the line? The solution selecting multiple lines is excellent. – calocedrus Jun 20 '17 at 8:10
  • @calocedrus As suggested in my answer ^ allows you to go on the first non whitespace character of the line. – statox Jun 20 '17 at 8:35
  • 1
    :left is my preferred method – Peter Rincker Jun 20 '17 at 14:36
4

A few variations on a theme:

Method(s) that will work in vi:

  • Go to the first line that you want to manipulate.
  • Count the lines that you want to manipulate — let’s say there are 17 of them.  Type 17<<.  This will shift each of the following seventeen lines left by one shiftwidth (normally eight characters; i.e., one tab).  Assuming you still have lines with leading spaces, type . to repeat the shift command.  Type . repeatedly until all the spaces are gone.
  • If you want to remove the leading spaces from all lines to the end of the buffer, use <G and then . repeatedly.
  • Any common technique for identifying the end of the range will work similarly.  For example, with the text in your question, you could use </2/ (and then . repeatedly).

Method that will work only in vim:

  • Go to the first line that you want to manipulate.
  • Type V or Ctrl+V to go into visual selection mode (mark the beginning of the range).
  • Move to the end of the range.
  • Type 9<.  This will shift the selected lines left by nine shiftwidths.  As this will typically be 72 characters (9×8), there’s a good chance that that will do the job.  If you still have lines with leading spaces, type . to repeat the shift command (i.e., another72 characters).
  • Or, if you know that you have lines with more than 72 leading spaces (or nine tabs), just use 99<.
3

Deleting a word at the beginning of the line will do the trick:

dw

If you want to repeat that for every line in the file that begins with whitespace:

:g/^ /norm dw
  • this only works if no line starts without leading spaces – Naumann Jun 21 '17 at 10:14
  • yes. the purpose of the match on /^ / is to apply the dw command only on lines that start with a whitespace – ithkuil Jun 21 '17 at 15:26
  • Could you explain what this command does? I know this is a regex match, what's the difference between :g/ and :s/? And what does the '/norm dw' do? – Harv Jun 22 '17 at 19:29
  • g executes a command on every line that matches a given regexp. In this case it executes the dw command in normal mode (hence the norm). If you don't specifiy norm it will interpret the commands as ex commands. s instead substitutes. g/re/p executes the p (print) ex command for every line matching a regexp. Here's where the name of the grep command comes from. – ithkuil Jun 25 '17 at 17:20
1

Here is a single command to do it (starting in Normal mode, on the line you want to modify):

I<c-w><esc>

This switches to Insert mode and positions the cursor on the first non-whitespace character. Ctrl-w will then delete to the beginning of the line.

This can then be . repeated on any other line, from any column.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.