3

I want to write a function that will remove blank lines given a set of visually selected lines by the user.

After removing the blank lines, I want the input lines still be visually selected.

How can I achieve this? Here is the code that removes blank lines:

function! RemoveBlankLines() range
    exe a:firstline.",".a:lastline."g/^\s*$/d"
endfunction
command! -range=% RemoveBlankLines <line1>,<line2>call RemoveBlankLines()
4

I would have said to use '[ and '] marks, but alas each command executed by :global is messing with them. However, you only need to know the new last line, as the first line won't change. '] won't be enough as well.

I see several solution:

  1. Mark the last line. Cons: it'll modify a mark -> this may mess the marks the end user is using -> not good
  2. have :g count how many lines you have removed. Cons: more verbose code
  3. Don't reselect at the end of the command (which will be odd if it wasn't called from the visual mode), but at the end of a visual mapping.

    xnoremap µ :RemoveBlankLine<cr>gv

    And let the user manually reselect after the call to the command -- I'm not sure you'll be able to use mode() to check whether you are in visual mode to conditionally reselect.

Anyway, back to your exact question, I'll do it this way (2.):

function! s:RemoveBlankLines() range
    let cpt = 0
    silent exe a:firstline.','.a:lastline.'g/^\s*$/d_|let cpt+=1'
    exe a:firstline
    normal! V
    exe (a:lastline-cpt)
endfunction

command! -range=% RemoveBlankLines <line1>,<line2>call s:RemoveBlankLines()

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.