1

I want to tell a command or mapping to advance to the next non-blank line before executing - but to do this only if the current line is not blank.

Ultimately, I intend to apply this to a command to collapse blank lines in a given range, replacing the blank lines with tabs. This must be done from the first non-blank line to prevent preceding newlines becoming tabs ahead of the first word of the collapsed line.

So I might find the next non-blank line with /^.\+/

I want to apply that to this command that collapses blank lines:

:command -range=0 CollapseLines <line1>,<line2>s/\n/\t/

For example, like this:

:command -range=0 CollapseLines /^.\+/<line1>,<line2>s/\n/\t/

But if I combine the two, it advances to the next non-blank line in disregard of whether the current line is blank or not. So the first line of the range gets missed.

Finally, I intend to use this with a mapping:

:nmap <leader>cl :CollapseLines<CR>j

So the placing of the cursor on the first or current non-blank line might be done in the mapping rather than the command.

0
2

Check :h nextnonblank() function:

nextnonblank({lnum})                    *nextnonblank()*
        Return the line number of the first line at or below {lnum}
        that is not blank.  Example: >
            if getline(nextnonblank(1)) =~ "Java"
<       When {lnum} is invalid or there is no non-blank line at or
        below it, zero is returned.
        {lnum} is used like with |getline()|.
        See also |prevnonblank()|.

So

" if current line is non-blank
if getline('.') !~ "^\s*$"
  let nextline = nextnonblank(line('.') + 1)
  " do smth with nextline
  " echo getline(nextline)
endif

PS, I am not sure what exactly you need, but here is smth implemented a bit differently:


func! CollapseWhatever() abort
    if getline('.') !~ '^\s*$' | return | endif
    exe "normal! vip\<esc>"
    '<,'>-1s/\n/\t/g
endfunc

command Collapse :call CollapseWhatever()

enter image description here

6
  • I see. That is miraculously nippy of you. Thank you. Can this if statement be used in a user command definition or mapping?
    – markling
    Dec 5 '21 at 14:31
  • @markling sure it can
    – Maxim Kim
    Dec 5 '21 at 14:44
  • Aha. Muchos thanks. So how would you do that? \ continuation chars? | pipes? It's beginning to look like it might be easier to use a function. I was hoping to avoid that.
    – markling
    Dec 5 '21 at 14:55
  • To actually move to the next non-blank line then, would require replacing the '"echo getline(nextline)" in your example, to something like ':ex j . getline(nextline) . gg' ? (I'm grasping at straws here ... I hope you can complete the exercise ... getting to that line!)
    – markling
    Dec 5 '21 at 15:04
  • 1
    @markling line numbers are an ex command, so :execute nextnonblank(line('.') + 1) would work, for example.
    – D. Ben Knoble
    Dec 5 '21 at 16:35

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.