SWI-Prolog loses prompt in Emacs


it looks like something went avry in the interaction of SWI Prolog with Emacs (27.x on Windows in my case). Essentially, if you run swipl as an inferior prolog, you lose the prompt ?- . Any idea about how to fix this?

Screenshot attached.

SWI-Prolog losing prompt in Emacs|508x500



On Linux, I usually run Prolog in an Emacs terminal (shell), and start it with the option --no-tty. And I don’t see the problem you describe … BUT I’ve noticed problems with ctrl-D when running emacs on WSL, even when running in a shell. My guess is that the Windows terminal is getting in the way - maybe the latest version of WSL is better? (I haven’t upgraded - I prefer to just avoid Windows in general.)

Another possibility - use the graphical interface with native Windows (or Linux).


The --no-tty does not seem to help.

In any case the point is to ensure that run-prolog works properly in Emacs. It does, but somehow the prompt is lost. My suspicion is that SWI Prolog now does something funky with color an that that confuses the prompt regexp.


Without seeing what’s in your dictionary_bst.pl, it’s hard to know what’s going on.

Did you type in X = 42.?

Anyway, under Linux (Ubuntu) and Emacs-28.0.50 and SW-Prolog 8.3.14, the ?- shows fine.

You can disable the color output by setting the Prolog flag color_term to false. More likely is that it doesn’t think it is connected to a tty. You can change that using set_stream(user_input, tty(true)) if I recall correctly. All in all it is complicated. Different Emacs inferior process modes identify themselves differently :frowning:

Hi Jan

it looks like the issue is the tty one. Invoking set_stream(user_input, tty(true)) seem to do the trick.

All the best



a very clean, IMHO, things to do is to leverage the last Emacs setup and add

:- getenv("INSIDE_EMACS", _), set_stream(user_input, tty(true)).

in your init.pl file.

Actually if this could be added in the official startup, it would solve the problem.

Having said that, I mostly use the integrated environment.

All the best

1 Like

And if you’re tired of typing swipl --no-tty when in an Emacs shell (or starting a *prolog* window):

:- getenv('INSIDE_EMACS', _), set_prolog_flag(tty_control, false).

I’ve verified that the INSIDE_EMACS environment variable exists in Emacs 26.3 and 28.0.50.
If you want to be more precise about the environment, you can verify that the variable is of the form '28.0.50,comint' (and it’s an atom, not a string).

Hi Peter,

I actually went around a couple times more. This is what I have now in my init.pl.

    getenv("INSIDE_EMACS", _),
    getenv("TERM", emacs),
    set_stream(user_input, tty(true)).
    getenv("TERM", xterm),
    set_stream(user_input, tty(true)).

Probably the check on INSIDE_EMACS, is an overkill, but checking TERM seems TRT to do. It definitively works properly in cmd, PowerShell, and git bash on Windows 10 (I presume it will work elsewhere).
Last minor thingy: the regexp for the prompt in prolog-mode.el is probably outdated (it looses the query number). Oh well…

Weeeeellll. Almost there. I now get a warning that one of the goals failed at startup.
Oh well. :roll_eyes:

There are many other possible values for TERM, such as xterm-256color (which is what I get from the standard Ubuntu terminal). But for both xterm and xterm-256color, I see that tty(true) is already set (there was a discussion about this a while ago, and swipl sets tty if isatty() is true (more-or-less; I’m sure there are other complications).

Anyway, for my purposes, the check for INSIDE_EMACS suffices. :wink:

BTW, you can use an atom instead of string for getenv/2, if you wish; the result seems to always be an atom.

On Unix-like systems you normally do not need such hacks. Any application that wants to embed another interactive application typically does so using a pseudo tty and the Unix system call isatty() will tell us. In Windows there is (AFAIK) no good alternative to this. Well, we can find out we are connected to a proper Windows console, but a console is not used for running Prolog inside Emacs.

I have pushed this patch to setup the tty when we detect Emacs on Windows. Not tested.

When running under the shell (comint) in Emacs (swipl 8.3.14), I need this in my init.pl file to get tty-behaviour:

:- getenv('INSIDE_EMACS', _), set_prolog_flag(tty_control, false).

So, it would apear that the isatty() test doesn’t do what you expect in an Emacs window. (This applies for both running in a shell and in an inferior Prolog window.)

tty_control and whether or not the user_input is a tty has different effects. tty_control allows Prolog to change the TTY settings to setup single keystroke interaction to (notably) the tracer and toplevel. This doesn’t work under Emacs. The user_input tty property tells the system this is a tty, so it should prompt (and try to setup other stuff that is useful when talking to a human.

The system tries to detect Emacs at startup, but this code was broken. Possibly 8.3.15 is better. We’ll see :slight_smile:

Of course, I hadn’t done enough RTFM. This is what I have now in my init.pl. Not yet optimal, but getting there.

    (current_prolog_flag(emacs_inferior_process, true)
    -> set_stream(user_input, tty(true))
    ;  true).

All the best

Please check 8.3.15 without any user settings and report your findings. Hopefully it is fixed. Else the report should provide input for a next round refining the rules :slight_smile:

Works the way I want it to. Thanks!

The following is copied from my Emacs window (emacs 28.0.50, built from git://git.sv.gnu.org/emacs.git)

$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.15)

?- member(X,[1,2,3]).
X = 1 ;
X = 2 ;
X = 3.

?- current_prolog_flag(tty_control, Z).
Z = false.
1 Like

Thanks for reporting. Note that YMMV depending on the OS (Windows vs Unix-like), version of Emacs and the Prolog mode you use …

Hi Jan

I just tried 8.3.15 on W10 without anything in my init file.

Things work as expected on:

  • Emacs - minus the prompt regexp (I even tried it on an old 25.x)
  • Git Bash
  • cmd
  • Power Shell



1 Like