bigpotato
bigpotato

Reputation: 27517

Vim: How would I recursively run ":sort" for everything between curly braces?

I'm a web developer and I often have to write CSS:

I always sort the styling alphabetically so this:

.sorted_product_mens_color_list li, .sorted_product_womens_color_list li {
    margin: 0 5px 0 5px;
    padding: 5px;
    border: 2px solid black;
}

turns into:

.sorted_product_mens_color_list li, .sorted_product_womens_color_list li {
    border: 2px solid black;
    margin: 0 5px 0 5px;
    padding: 5px;
}

However, this gets repetitive and I want to just automate it by writing a script that does this in VIM.

How would I either 1) run :sort in a loop within a file within all curly braces or 2) Run that in all CSS files in a directory? (either one)

Upvotes: 3

Views: 768

Answers (2)

Gumnos
Gumnos

Reputation: 423

At the request of @Edmund, I'll add an answer to explain :g/{/+,/}/-sort further. The :g command's syntax is

:{range}g/pattern/{ex command(s)}

The initial range to consider is blank, defaulting to searching the entire file. The pattern is { which searches for the opening brace.

:g/{/{ex command(s)}

The command is the remainder. In this case, that ex command is +,/}/-sort. This breaks down as an optional range ("+,/}/-") followed by a command (sort) to execute on that range. That range starts at the current line (found by the ":g" command) and goes forward one (+ which would be synonymous with +1 since the default is 1) line. Then the "," separates the start of the range from the end of the range. To find the second line of the range, we search forward for the next closing brace ("/}/") and then go back one line ("-", again equivalent to "-1"). Now that we've defined the range as "from the line following the opening brace that we found, through the line before the closing brace", we execute the sort ex command on that range.

Upvotes: 9

Marth
Marth

Reputation: 24812

For a single file you could do :

:g/{/normal! f{viB:sort^M

What this does :

  • :g/{/ : for every line containing a {
  • normal! : enter normal mode (the ! simply skips mappings in the command)
  • f{ : find the (first, but this shouldn't be a problem in css (?)) {
  • viB : enter visual mode between the curly brackets
  • :sort : well... sort the visual selection
  • ^M : press enter (this is a single character, use <C-v><CR> to type it)

For multiple files you could do :

# From you shell
# In zsh you would use 'vim **/*.css' to open all the css files in nested directories
# Not sure about your shell
$> vim *.css     # open css files in the current directory
" In vim
:argdo g/{/normal! f{viB:sort^M:update^M

The :update is the same as :write, except that it will not trigger a write if the buffer wasn't modified.

Upvotes: 8

Related Questions