The general pattern we'll be using is: insert text at the beginning of a range of lines.
We have two options:
:[range]normal! Itext
:[range]substitute/^/text
I tend to think of normal!
first, because of the insertion, but the substitute should work just as well. We're going to use substitute here, because it's easier to insert dynamic text at the end of.
Start by defining a function to do most of the work:
function Work() abort
" delete and capture the file.txt line
delete a
" trim newlines and add a space
let @a = trim(@a) . ' '
" insert the value on all lines up to the next '.txt' line
.,/\.txt\|\%$/-1 substitute/^/\=@a
endfunction
Edit: I was able to eliminate the range error by using \%$
as I had been trying to do in my experiments. But the key was that we need a blank line at the end.
We need a bit of prep, because the function uses the pattern /.txt\|\%$/
as part of a range, so we need a blank line at the end if none exists—:s/\%$/\r
,
or alternately, :call setline('$', '')
, :call append('$', '')
, or even :$normal! o
. We can inspect visually, of course, but for the scripter:
if len(getline('$')) > 0
call append('$', '') " or whichever variant you prefer
endif
Then do it with a global command:
:global/.txt/call Work()
Altogether, then, create a script-file called whatever_you_want.vim
with the following contents:
function Work() abort
" delete and capture the file.txt line
delete a
" trim newlines and add a space
let @a = trim(@a) . ' '
" insert the value on all lines up to the next '.txt' line
.,/\.txt\|\%$/-1 substitute/^/\=@a
endfunction
if len(getline('$')) > 0
call append('$', '') " or whichever variant you prefer
endif
global/.txt/call Work()
Now start vim with
$ vim /path/to/your/file.txt -S /path/to/vimscript.vim
Optionally, add to the end of your script
write
quit
if you're quite sure of the results.
The script has the benefit of being embarrassingly repeatable.
N.B. This function was crafted specifically to your example. It will definitely fail if any of your "data" contains .txt
somewhere.