true_atlantis has asked for the wisdom of the Perl Monks concerning the following question:

Is there a way to grab every character of input, not like 'while(<>)' where it will run the loop after each time you press Enter? Im trying to write a shell that has tab completion, so grabbing 'tab' would be essential. thanks.
  • Comment on Grabbing input - every char, not after <Enter>

Replies are listed 'Best First'.
Re: Grabbing input - every char, not after <Enter>
by FunkyMonk (Bishop) on Sep 17, 2007 at 21:03 UTC
    Term::ReadKey does what you ask, but there's also Term::ReadLine::Gnu which includes completion

    As an example of Term::ReadKey, here's a subroutine I wrote some time ago that waits until Y, N, R or Q is pressed:

    sub get_YNRQ { while (1) { ReadMode 4; my $ans = uc(ReadKey(0)); ReadMode 0; return $ans if $ans =~ m/[YNRQ]/; } }

    update: added example code

Re: Grabbing input - every char, not after <Enter>
by johngg (Canon) on Sep 17, 2007 at 21:07 UTC
    You should have a look at Term::ReadKey which will allow you to do what you describe.

    Cheers,

    JohnGG

      I was told to look at 'Term::ReadKey' but the sample code in perldoc just does the same thing as 'while(<>)' would. does anyone have a reference web page that shows how to grab every key, or give me an example loop? thanks
        It works for me:
        use Term::ReadKey; ReadMode 4; # Turn off controls keys while (not defined ($key = ReadKey(-1))) { # No key yet select undef,undef,undef,0.1; # sleep 0.1 secon +d } print "Get key $key\n"; ReadMode 0; # Reset tty mode before exiting
        run that:
        $ perl test.pl <press d> Get key d $
        update: the while() look does take up a tremendous amount of CPU time, though, so I added the select() call

Re: Grabbing input - every char, not after <Enter>
by dug (Chaplain) on Sep 17, 2007 at 21:04 UTC

    `perldoc -f getc` has information that you may find useful.

    -- Douglas Hunter
      getc won't do what the OP wanted. From perldoc:
      However, it cannot be used by itself to fetch single characters without waiting for the user to hit enter

        I didn't recommend using getc. I recommended reading the getc documentation, because the majority of the getc documentation is devoted to solving the OP's problem.

        Thanks,

        -- Douglas Hunter