2

Let's say I have a bunch of vim mappings (although it could be code in any language), each of which with a comment line or lines above them:

(using # not " so the comments get highlighted nicely)

# A comment
nnoremap <Leader>a ...
# D comment
nnoremap <Leader>d ...
# B comment
nnoremap <Leader>b ...
# H comment
nnoremap <Leader>h ...
# C comment
#   comment cont'd
#   comment cont'd
nnoremap <Leader>c ...
# F comment
nnoremap <Leader>f ...
# G comment
nnoremap <Leader>g ...
# E comment
nnoremap <Leader>e ...

How do I sort these lines, while preserving the association of comments with the first non-comment line below them?

i.e. I want this output:

# A comment
nnoremap <Leader>a ...
# B comment
nnoremap <Leader>b ...
# C comment
#   comment cont'd
#   comment cont'd
nnoremap <Leader>c ...
# D comment
nnoremap <Leader>d ...
# E comment
nnoremap <Leader>e ...
# F comment
nnoremap <Leader>f ...
# G comment
nnoremap <Leader>g ...
# H comment
nnoremap <Leader>h ...
1
  • 3
    This question isn't identical, but the same techniques apply: Sort every few lines
    – Rich
    Commented Jun 18, 2020 at 11:02

1 Answer 1

3

Visually select your lines, then run:

" join the comments and the related command
*g/^\s*#/,/^\s*[^# ]/-s/\n/\="\x01"

" sort the lines
*sort

" split back the lines
*s/\%x01/\r/g

To operate on the whole buffer rather than the visual selection, replace the * range with %.

Note that – in Vim – the comment leader is ", not #; unless you're writing a Vim9 script (:h vim9-differences).

1
  • 1
    I edited the comments a bit; OP was explicitly using lang-bash, and I’d rather not confuse people :)
    – D. Ben Knoble
    Commented Jun 18, 2020 at 11:36

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