http://qs1969.pair.com?node_id=11151237

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

Hi

I'm testing an application which prompts for manual input $var = readline(STDIN).

Normally I run those programs inside emacs while developing, but it "hangs" when trying to read from readline.

My workaround so far was to manually start in the console, but there I can't click anymore on error messages to jump to the faulty lines.

Now I resorted to redirect STDIN to a handle with fixed input values, but only if run inside emacs.

But I'm still wondering if there are IDEs allowing to interactively prompt for input...

Cheers Rolf
(addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re: Prompting for input inside IDE run (was Reading from STDIN)
by Corion (Patriarch) on Mar 27, 2023 at 06:19 UTC

    How does Emacs launch your program? I was under the impression that it launches programs under debug by redirecting its STDIN and STDOUT to a "console" buffer managed by Emacs and that interactive input/output simply work?

    Maybe if you can tell us how Emacs does this we can find out how to hook up interactive input/output to the Perl program...

      > I was under the impression that it launches programs under debug by redirecting its STDIN and STDOUT to a "console" buffer

      You are describing the debugger API via M-x perldb.

      It runs the debugger in a terminal emulation in an extra buffer and is in parallel scrolling the current point in the original source buffer.

      And it kind of works after typing c for continue (debugger command) I can input stuff. It actually looks exactly like when run with perl -d

      Tho it doesn't seem to have auto linking of Perl's error messages.

      I will update my OP later with an SSCCE explaining the output.

      > I was under the impression that it launches programs under debug by redirecting its STDIN and STDOUT to a "console" buffer

      Well I'm using mode-compile but emacs is more TIMTOWTDI than Perl. I think mode-compile was originally designed for make that's why interactive input isn't that important.

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery

Re: Prompting for input inside IDE run (was Reading from STDIN)
by haj (Vicar) on Mar 27, 2023 at 07:22 UTC

    How do you run those programs inside emacs? I guess this is on Windows? Are you using Powershell as your shell-file-name?

    One annoying effect I see on Windows is that STDOUT is buffered. So, if you're expecting a prompt, then you won't see it in time, but you can still enter your input line when the program seems to "hang". The w32 FAQ has a workaround for "Perl script buffering".

    I could run the following program under M-x perldb and M-x eshell, and it behaves as I would expect:

    use 5.028; # Turn all buffering off. select((select(STDOUT), $| = 1)[0]); select((select(STDERR), $| = 1)[0]); select((select(STDIN), $| = 1)[0]); print "Give me a cookie: "; my $thing = readline(STDIN); $thing =~ /^(a )?cookie$/ or die "That was no cookie.\n"; say "Thanks and goodbye!";
      > How do you run those programs inside emacs? I guess this is on Windows?

      With mode-compile, which is not core, but nevertheless the default in cperl-mode.

      You may want to look into the perl menu in the top-bar after activating cperl-mode.

      <menu-bar> <Perl> <Run> runs the command mode-compile, which is an interactive autoloaded compiled Lisp function in `mode-compile.el'.

      Auto flush was helpful yes, but input is still ignored.

      Actually all input is considered compilation or error navigation commands, which makes sense in a buffer with start

      Now I'm thinking about making my script automatically redirecting stdout and stdin to a spawned console /or buffer. This while still keeping stder in the compilation buffer...

      I did this before in order to debug Term::ReadLine apps, have to dig that out again. I'm weak on tty Channel foo ...

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery

        With mode-compile, which is no not core but the default in cperl-mode.

        That would have been helpful to know. That entry is disabled in my Emacs because I don't have mode-compile. Heck, that thing is pretty stale and can't be byte-compiled nor M-x eval-buffered in Emacs 27...

        Anyway, mode-compile is the culprit. Contrary to its name, it runs the program, using a mechanism which does not make STDIN of the Perl process available to you.

        What you could do is wrap the following lisp snippet into a command which suits you:

        (compile "perl your_script.pl" t)

        Replacing the program name perl and script name your_script.pl by variables is left as an exercise to the reader. The t parameter does the trick to give you what Emacs calls a "comint" environment. So, you end up in a buffer *compilation* in compilation-mode with "clickable" error messages, but the buffer is not read-only, you can just enter text after the prompt.

Re: Prompting for input inside IDE run (was Reading from STDIN)
by GrandFather (Saint) on Mar 27, 2023 at 08:56 UTC

    I use Komodo IDE which is now free to use and has a very good Perl debug environment including a "terminal" window for managing stdio. For various other languages and target systems I use VSCode which has Perl debugging support available, although I've not used it.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
      Thanks, we even have a company license for Komodo :)

      I'll have a look at it.

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery

Re: Prompting for input inside IDE (SSCCE) (half SOLVED)
by LanX (Saint) on Mar 27, 2023 at 14:19 UTC

    SSCCE
    based on Haj's example
    use v5.12; use warnings; STDOUT->autoflush; STDERR->autoflush; STDIN->autoflush; say "Give me a cookie: "; my $thing = readline(STDIN); $thing =~ /^(a )?cookie$/ or warn "That was no cookie."; say "Thanks and goodbye!"; die "exiting here";

    expected output in pre/tt

    
    Give me a cookie:                                               # waits for input
    croock                                                          # manual input             
    That was no cookie. at emacs_input.pl line 10, <STDIN> line 1.  # jumps to line 10
    Thanks and goodbye!
    exiting here at emacs_input.pl line 14, <STDIN> line 1.         # jumps to line 14
    

    For better understanding I manually added meta info

    • STDOUT in black
    • STDIN in red
    • STDERR resp. clickable cross-refs as hrefs
    • additional comments in grey
    FWIW

    I've stumbled over a SO discussion which made this (half) work.

    > C-u M-x compile and ... compilation buffer will be in comint mode, i.e. interactive.

    (the C-u means prefix arg, a very e-lisp-ish annoyance)

    I still have to find a way to make this work inside mode-compile

    Cheers Rolf
    (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
    Wikisyntax for the Monastery

      > I still have to find a way to make this work inside mode-compile

      patching this in mode-compile.el seems to work

      (defun mc--compile (compile-command) ;; Call compile with the compile command ;; but append the remote-command before (if (null mc--remote-command) ;; local compile (mc--compile-sav compile-command t) ; <-- +-- "t" added to list ;; remote compile (let ((thisdir (expand-file-name (or default-directory "~")))) (mc--compile-sav (concat ;; The command to lauch remote commands mc--remote-command ;; Change to this buffer directory ... "'( cd " thisdir " ; " ;; then run the compile command compile-command " )'")))))

      But I'm not too sure, only using emacs for 30 years now...

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery

Re: Prompting for input inside IDE run (was Reading from STDIN)
by Anonymous Monk on Mar 27, 2023 at 06:41 UTC
    emacs has a bunch o results to sort through :)😨
      Thanks!

      Well ... yes and no.

      The first module is actually addressing exactly this, but the solution is extremely magic.

      STDIN is tied inside Perl to trigger elisp-code inside emacs to prompt in the minibuffer.

      This might work, but I prefer a more robust approach which doesn't diverge too much from production.

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery