Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In vim, how to write a partial line to a file?

Tags:

vim

I want to use vim to write a part of my file to another file. For example, I have the following file:

This is line 1

and this is the next line

I want my output file to read:

line 1

and this is

I know how to use vi to write a range of lines to a file:

:20,22 w partial.txt

An alternative is to visually select the desired text and then write:

:'<'> w partial.txt

However, when using this method, vim insists on writing the full line in the output, and I have found no way to write a partial line. Any thoughts?

like image 823
Magnus Avatar asked Dec 23 '09 14:12

Magnus


1 Answers

I've got two (very similar) approaches to this. There's no way to do it with the built in write command, but it's fairly easy to generate your own function that should do what you want (and you can call it what you like - even W if you want).

A very simple approach that will only handle single-line ranges is to have a function like this:

command! -nargs=1 -complete=file -range WriteLinePart <line1>,<line2>call WriteLinePart(<f-args>)

function! WriteLinePart(filename) range
    " Get the start and end of the ranges
    let RangeStart = getpos("'<")
    let RangeEnd = getpos("'>")

    " Result is [bufnum, lnum, col, off]

    " Check both the start and end are on the same line
    if RangeStart[1] == RangeEnd[1]
        " Get the whole line
        let WholeLine = getline(RangeStart[1])

        " Extract the relevant part and put it in a list
        let PartLine = [WholeLine[RangeStart[2]-1:RangeEnd[2]-1]]

        " Write to the requested file
        call writefile(PartLine, a:filename)
    endif
endfunction

This is called with :'<,'>WriteLinePart test.txt.

If you want to support multiple line ranges, you could either expand this to include varying conditions, or you could pinch the code from my answer to this question. Get rid of the bit about substituting backslashes and you could then have a very simple function that does something like (untested though...) this:

command! -nargs=1 -complete=file -range WriteLinePart <line1>,<line2>call writelines([GetVisualRange()], a:filename)
like image 100
DrAl Avatar answered Oct 09 '22 21:10

DrAl