bistrot
bistrot

Reputation: 103

passing argument to a vim "execute"

From within Vim, I want to scan a text line by line, and pass its content to an external shell command. For example, I have a list of names and want to say hello to each name of the list. What I've already managed to do is as follows.

Given this text :

John Doe

    Jane Doe

Baby Doe

I can use this command to find the first name only and reuse the token in a substitute command using the backreference syntax (\0 or \1).

:%g/\w\+/ s//--\0--/

This is the output :

--John-- Doe

    --Jane-- Doe

--Baby-- Doe

What I would like to do now is to change my "substitute" command for "execute" shell command.

This command

:%g/\w\+/ exe "!echo hello " "world"

works fine, but how to parameterize it ?

So far, I've tried this :

:%g/\w\+/ exe "!echo hello " \0

and this too :

:%g/\w\+/ exe "!echo hello " &

with no success...

This question has a lot of value since you could then, from Vim, scan a text containing a list of directories and create them on the fly.

Upvotes: 4

Views: 872

Answers (1)

bistrot
bistrot

Reputation: 103

So here is the answer :

The following command will scan a text, trim the newlines and whitespaces to say "hello" to each name in the text :

%g/\<\w\+\>/ y A | exe ' !echo hello '. substitute(substitute(@a, '\n\+\s*', '', ''), '\s*\n\+', '', '') | let @a =""

The next one will create a directory for each non-empty line of the file. This time, the shellescape() function is added :

%g/\<\w\+\>/ y A | exe ' !mkdir '. shellescape(substitute(substitute(@a, '\n\+\s*', '', ''), '\s*\n\+', '', '')) | let @a =""

And if you need a "silent" directories creation, here is the command :

%g/\<\w\+\>/ y A | exe 'silent !mkdir ' . shellescape(substitute(substitute(@a, '\n\+\s*', '', ''), '\s*\n\+', '', '')) | let @a =""

P.S. :

You can also use the almost same command to cleanup a file (getting rid of empty lines and trimming the non-empty ones) into a new file :

%g/\<\w\+\>/ y A | exe 'silent !echo ' . substitute(substitute(@a, '\n\+\s*', '', ''), '\s*\n\+', '', '') . ">> new_file.txt" | let @a =""

Upvotes: 3

Related Questions