Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^3: [challenge] Nested autocompletion -- fixed win32 version

by Discipulus (Canon)
on Feb 21, 2023 at 11:21 UTC ( [id://11150512] : note . print w/replies, xml ) Need Help??


in reply to Re^2: [challenge] Nested autocompletion -- results and some question
in thread [challenge] Nested autocompletion

Hello again tybalt89 and all,

I need to stop trusting code by others, even if by experienced programmers like you :)

It comes out ReadKey.pm is generated from ReadKey.pm.PL and generates different output on different systems: so on linux it checks for undefined values while on win32 it does not. To me this is bug so I created an issue.

The docs of Term::ReadKey say you need to pass a MODE to the ReadKey function.

So instead of my $char = ReadKey; you need instead my $char = ReadKey(-1); next unless defined $char;

For future convenience here is the patched version of your second program, fixed for win32:

#!/usr/bin/perl use strict; # original code posted by tybalt89 at https://perlmonks.or +g/?node_id=11150326 use warnings; # constant autocomplete use List::Util qw( uniq ); use Term::ReadKey; $| = 1; my @animals = (qw( cow camel dog cat )); my @foods = (qw( fish pasture meat )); my @places = (qw( wood sea desert )); my $commands = { select => { completion_list => \@animals, commands => { give => { completion_list => \@foods, }, take_to => { completion_list => \@places, }, }, }, kill => { completion_list => \@animals, } }; my $completed = autocomplete( $commands, 'auto> ' ); print $completed ? "\nThe user entered: $completed\n" : "\nEscape\n"; exit; ###################################################################### sub autocomplete { my $commands = shift; my $prompt = shift // '> '; my $lines = ref $commands ? join "\n", lines($commands), '' : $comma +nds; my $input = ''; my ($clearline, $color, $reset) = ("\e[G\e[K", "\e[32m", "\e[m"); ReadMode 'raw'; eval { while() { $input = "$input\n$lines" =~ /^(.*).*\n(?:.*\n)*\1/ ? $1 : ''; $input = $lines =~ s/^(?!\Q$input\E).*\n//gmr =~ /^(.*).*\n(?:\1.*\n)*\z/ ? $1 : ''; my $words = join ' ', sort + uniq $lines =~ /^\Q$input\E ?(\S+)/ +gm; $lines =~ /^$input\n/m and $words = '*** Completed!'; my $backup = "\e[" . ( 2 + length $words ) . "D"; print "$clearline$prompt$input $color$words$reset$backup"; my $char = ReadKey(-1); next unless defined $char; # you need this on Win32 $char =~ tr/\e\cc// and $input = '', last; $char =~ tr/\n\r// and $lines =~ /^$input$/m ? last : next; $char =~ tr/ -~// and $input .= $char; if( $char =~ tr/\b\x7f// ) # backspace { my $match = 1 + ( () = $lines =~ /^\Q$input\E/gm ); $input = "$input\n$lines" =~ /^(.*).*\n(?:(?:(?!\1).*\n)*\1.*\n){$match}/ ? $1 : ''; } } 1; }; my $error = $@; ReadMode 'restore'; print "$error\n"; return $input; } sub lines { my $cmd = shift or return ''; map s/ +$//r, map { my $key = $_; # fun triple map nesting map { my $prev = $_; map "$key $_ $prev", @{ $cmd->{$key}{completion_list} }; } lines( $cmd->{$key}{commands} ) } keys %$cmd; }

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Replies are listed 'Best First'.
Re^4: [challenge] Nested autocompletion -- fixed win32 version
by tybalt89 (Monsignor) on Feb 21, 2023 at 16:06 UTC

    No, No, No, that's horrible :(

    Check your load average with that change - it hard loops waiting for a character. My reading of Term::ReadKey says

    my $char = ReadKey 0;
    should be used, as this properly sleeps waiting for a character, and will not return undef.

    Of course, I have no idea what it does on Win32, since I can't test it.

      > No, No, No, that's horrible :(

      yes ReadKey -1 on linux consumed almost all my cpu while with 0 cpu usage is minimal. On win32 with -1 the task manager shows only a ~5% of cpu, but I suspect other cpu cycles, another ~5%', are consumend inside 'conhost.exe and somewhere else: infact the overall cpu usage raised around 35%

      Unfortunately I'm not in the postion to apply the win32 definitive fix :)

      L*

      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      Different issue for me. To display colored text (instead of raw escape codes) on Win32, the following module must also be included:
      use Win32::Console::ANSI;

      "It's not how hard you work, it's how much you get done."

        Hello roho,

        what perl -MWin32 -e "print Win32::GetOSDisplayName(),' ',(join '.',Win32::GetOSVersion())" prints for you?

        Infact I read on wikepedia that version 1511 of win10 unexpectedly implemented support for ANSI escape sequences

        L*

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.