Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load line from unopened file into variable in VimScript

Tags:

vim

I need to build a quickfix list based on output from some external command. But the command gives me only file names and line numbers, like:

foo.txt:10
bar.txt:20

I'd like to add the actual contents of the specified file into the quickfix list, like in:

foo.txt:10: this is some line from foofile
bar.txt:20: hello world, we're a line from barfile

Can this be done?

Ideally, I'd like this to be cross-platform, so probably in pure VimScript, with no calls to external commands like sed or the likes?

Simulation

My current behavior can be simulated with a function like:

function! MyFunc()
    let mylist = ["foo.txt:10:...", "bar.txt:20:..."]
    cgetexpr mylist
    copen
endfunction

call MyFunc()

and I'd like the ... parts to become the contents from the real files...

like image 715
akavel Avatar asked Feb 09 '15 02:02

akavel


2 Answers

Here's a solution:

fun! GetFileLine(fn,ln)
    return readfile(a:fn,'',a:ln)[a:ln-1]
endfun

fun! AppendLineToFnLn(list)
    return map(a:list, 'v:val.'':''.call(''GetFileLine'', split(v:val,'':'') )' )
endfun

fun! QuickFixWithLine(cmd)
    cexpr AppendLineToFnLn(split(system(a:cmd),"\n"))
endfun

call QuickFixWithLine('echo myfile:22; echo myfile:40;')
copen
like image 195
bgoldst Avatar answered Nov 20 '22 04:11

bgoldst


Hmh, based on a partially related question on comp.editors and :help readfile, I'd say below might work, however wasteful:

function! MyFunc()
    let mylist = ["foo.txt:10:...", "bar.txt:20:..."]
    let result = []
    for elem in mylist
        let temp = split(elem, ":")
        let line = elem . ":" . readfile(temp[0], "", temp[1])[temp[1]-1]
        call add(result, line)
    endfor
    cgetexpr line
    copen
endfunction

call MyFunc()
like image 28
akavel Avatar answered Nov 20 '22 06:11

akavel