1

I have a an interactive Perl script, which prints prompts to STDERR and reads lines from STDIN. The final output of this script is an IP address, printed to STDOUT. Here's a numpty version of such a script as an example.

my @pieces;
for (1..4) {
    print STDERR "please enter piece $_ of the IP:";        chomp(my $in = <>);
    push @pieces, $in;
}  
print join '.', @pieces;
print "\n";

I use the vim-fireplace vim plugin. This plugin has a feature where I can say:

:Connect nrepl://127.0.0.1:9999

I want to know how to configure vim so that when I issue a particular command, let's say:

:InteractiveConnect

it will do the following:

  1. Run the Perl script, allowing me to enter 4 pieces of the IP address.
  2. Capture the IP address output by the Perl script.
  3. Interpolate the IP address into the :Connect command
  4. Run the :Connect command.

A bit more info based on some of the responses:

If I call this script using:

:!/path/to/myscript.pl

Then it executes fine and I am able to see the result from it printed in the vim window, followed by

Press ENTER or type command to continue

If the output of the script is being saved in some buffer after execution via !, is it possible to get access to that buffer in vimscript and just capture the bit I want (the last line) with a regex?

clumsyjedi
  • 477
  • 6
  • 15

2 Answers2

2

Okay, there's probably a more elegant way to do this, but how about this:

function! <SID>InteractiveConnect()
    let tempfile=tempname()
    exe '!/path/to/your/script.pl >' . shellescape(tempfile)
    try
        exe 'Connect nrepl://' . readfile(tempfile, '', -1)[0]
    finally
        call delete(tempfile)
    endtry
endfunction
command! -nargs=0 InteractiveConnect call <SID>InteractiveConnect()

This creates a temporary file, writes to it with the script (using system() doesn't work because it doesn't wait for input), reads the last line in the tempfile to the Connect command, and then finally deletes the tempfile.

joshtch
  • 299
  • 1
  • 10
  • Thanks, but that's not really what I'm after. This command passes command line arguments to the Perl script. The script I have posted above does not work this way. It prints a prompt, then reads the user response from STDIN. Then once the user has answered enough questions it prints the answer. – clumsyjedi Jun 20 '14 at 01:37
  • So you want to be prompted for the input instead of entering it directly from the vim command? – joshtch Jun 23 '14 at 03:50
  • Can you give a more representative minimum working example? It would also help to have an idea of how the command's output is formatted. Edit regarding previous comment: oh, sorry, that's why it's called "interactive" connect. – joshtch Jun 23 '14 at 03:56
  • I don't know if I can reduce the Perl script any more, what I have included in my question is a very pared down version of the functionality I actually need. If you save this script in a file and run it it should be apparent how it gets it's inputs. – clumsyjedi Jun 23 '14 at 04:41
  • I've updated the original question a bit. Thanks for looking. – clumsyjedi Jun 23 '14 at 04:46
  • Okay I've fixed it and confirmed it working on OSX. Let me know if it's working for you. – joshtch Jun 23 '14 at 20:32
0

Maybe something like:

exec 'Connect nrepl://' . matchstr(system('your/script.pl'), '^.\+\%$')

(Untested.) This runs the script using system() then matches the output against the regular expression ^.\+\%$, (where \%$ means end-of-file; if your file is terminated with a newline, an additional \n might be neccessary before it) and feeds the matched str to the Connect command. .

Oberon
  • 3,219
  • 15
  • 30