How to get rid of colorization when compiling under Emacs?

I’m old-fashioned and usually run my Prolog code under Emacs’ compile command. My compile-edit-run cycle includes using swipl -c and then executing the generated file. When I do this, I see ANSI color control characters in the *compilation* window. I’ve tried turning them off with this in my ~/.swiplrc, and by adding the same directive to my program, but that doesn’t help:

:- set_prolog_flag(color_term, false).

I’ve confirmed that this file is read, by putting a deliberate syntax error into it and observing that I get an error message … .which, of course, has ANSI color control characters in it.

I also see color when running under the Emacs terminal and also under the regular Ubuntu terminal, so I suspect that the problem has nothing to do with Emacs.

I see a similar problem when I run the program directly from the source, without the compilation step.

This is more than an æsthetic issue … it confuses Emacs’ compilation-next-error, which I could fix but that requires delving into some Elisp code with which I’m unfamiliar.

(Adding --no-tty doesn’t seem to help; and when I tried it with the swipl -c command, I got save_option 'no-tty' does not exist.)

Possibly fixed with c993fedf8c4da231955e5d430f7e48eaf2ee7405. This does cause setting the color_term flag to be honored for the toplevel. Couldn’t quickly reproduce for -c compilation.

Seems rather odd to use that as part of your normal development cycle anyway. I only use -c for deployment and then only if it is too cumbersome to install SWI-Prolog on the target, the program is really big and needs to be started often (but, qcompile is typically a better alternative for developmen) or it is necessary to keep the code secret (never in my case).

First, why I use qpc -c … it tells me if I’m missing some predicate definitions. Also, I run a lot of tests, and using a .qlf saves me about 0.2s per test. :wink:

Anyway, c993fedf8c4da231955e5d430f7e48eaf2ee7405 doesn’t seem to have fixed the problem, but it’s difficult to tell what’s going on because the error messages are different. (What do I need to rebuild library(pcre)?)

Here’s the output with the current swipl (from the PPA):

/usr/bin/swipl --stand_alone=true --foreign=save --undefined=error --verbose=true \
    -o /tmp/pykythe_test/pykythe.qlf -c pykythe/pykythe.pl
e[31;1mERROR: /home/peter/src/pykythe/pykythe/pykythe.pl:1387:5: Syntax error: Operator expected
e[0me[32m% autoloading prolog_codewalk:must_be/2 from /usr/lib/swi-prolog/library/error
e[0me[32m% autoloading files_ex:add_nb_set/3 from /usr/lib/swi-prolog/library/nb_set
e[0me[32m% autoloading files_ex:member/2 from /usr/lib/swi-prolog/library/lists
e[0me[32m% autoloading files_ex:empty_nb_set/1 from /usr/lib/swi-prolog/library/nb_set
   ...

And here’s the output from the latest github pull:

../swipl-devel/build/src/swipl --stand_alone=true --foreign=save --undefined=error --verbose=true \
    -o /tmp/pykythe_test/pykythe.qlf -c pykythe/pykythe.pl
ERROR: /home/peter/src/pykythe/pykythe/pykythe.pl:185:
	file `library(pcre)' does not exist (is a directory)
Warning: /home/peter/src/pykythe/pykythe/pykythe.pl:185:
	Goal (directive) failed: pykythe:use_module(library(pcre),[re_replace/4])
e[31;1mERROR: /home/peter/src/pykythe/pykythe/pykythe_utils.pl:51:
	file `library(pcre)' does not exist (is a directory)
e[0me[31mWarning: /home/peter/src/pykythe/pykythe/pykythe_utils.pl:51:
	Goal (directive) failed: pykythe_utils:use_module(library(pcre),[re_replace/4])
e[0me[31;1mERROR: /home/peter/src/pykythe/pykythe/module_path.pl:29:
	file `library(pcre)' does not exist (is a directory)
e[0me[31mWarning: /home/peter/src/pykythe/pykythe/module_path.pl:29:
	Goal (directive) failed: module_path:use_module(library(pcre),[re_matchsub/4,re_replace/4])
e[0me[31;1mERROR: /home/peter/src/pykythe/pykythe/pykythe.pl:1387:5: Syntax error: Operator expected
e[0me[32m% autoloading prolog_codewalk:must_be/2 from /home/peter/src/swipl-devel/build/home/library/error
e[0me[32m% autoloading qsave:zip_close/2 from /home/peter/src/swipl-devel/build/home/library/zip
e[0me[32m% autoloading qsave:current_foreign_library/2 from /home/peter/src/swipl-devel/build/home/library/shlib
   ...

Even Discourse does some of the colors :slight_smile: Anyway.

  • pcre: see http://www.swi-prolog.org/build/Debian.txt for the dependencies
  • As far as I can see, -c doesn’t seem to load ~/.swiplrc.
  • Something seems to be loading library(ansi_term). You can figure out what using
    source_file_property/2 or, I often edit the file and put a :- backtrace(25). in it that will typically tell me why it is loaded. It is ok to load this library, but if you want to avoid colors you should set the Prolog flag to prohibit it being active.
  • For tests, I typically do multiple tests from a single Prolog process. That is often much faster.

I added backtrace(25). to ansi_term.pl and got this (not colorized!):

ERROR: /home/peter/src/swipl-devel/build/home/library/ansi_term.pl:43:
	[Thread 1]: exception handler failed to define prolog_stack:backtrace/1
ERROR: /home/peter/src/swipl-devel/build/home/library/ansi_term.pl:43:
	[Thread 1]: exception handler failed to define prolog_stack:backtrace/1
ERROR: /home/peter/src/swipl-devel/build/home/library/ansi_term.pl:43:
	catch/3: Undefined procedure: prolog_stack:backtrace/1
Warning: /home/peter/src/swipl-devel/build/home/library/ansi_term.pl:43:
	Goal (directive) failed: ansi_term:backtrace(25)

I’ve tried set_prolog_flag(color_term, false)) but that seems to take effect too late (and, of course, setting it in ~/.swiplrc doesn’t work because swipl -c doesn’t read that).

Anyway, playing with source_file_property/2 (which is a bit annoying, because it doesn’t like the 2nd arg to be uninstantiated), it appears that this is the chain that loads ansi_term:

'/usr/lib/swi-prolog/library/ansi_term.pl':prolog_listing:('/usr/lib/swi-prolog/library/listing.pl':50):[]
'/usr/lib/swi-prolog/library/listing.pl':prolog_clause:('/usr/lib/swi-prolog/library/prolog_clause.pl':49):[]
'/usr/lib/swi-prolog/library/listing.pl':prolog_clause:('/usr/lib/swi-prolog/library/prolog_clause.pl':49):[]
'/usr/lib/swi-prolog/library/prolog_clause.pl':prolog_stack:('/usr/lib/swi-prolog/library/prolog_stack.pl':44):[]
'/usr/lib/swi-prolog/library/prolog_clause.pl':prolog_listing:('/usr/lib/swi-prolog/library/listing.pl':51):[]
'/usr/lib/swi-prolog/library/prolog_stack.pl':'$toplevel':user:[]

Seems the backtrace code causes this to be loaded. Still, with the latest version you should be ok if you set the Prolog flag at the start of your code. Ideally you’d like the library to discover that coloring is not appropriate, but so far I found no portable way to do so. It tries to figure out it is running under Emacs,
but every mode has its own way to tell that and some provide no information. If you find one, make a pull request.

Emacs *shell* is fine with colorized text. Emacs *compilation* has problems.

It turns out that I was doing the wrong thing to set colorization for *compilation* … the answer is here: https://stackoverflow.com/questions/13397737/ansi-coloring-in-compilation-mode
and when I do this, compilation-next-error (tab key) works as expected.

How do you check for whether colorization is supported? The environment variable TERM should tell you (Emacs tends to set this to dumb).

Added two things: check for $TERM == dumb and in library(ansi_term) I now use the same rules to decide on the default of the color_term flag. This means that if you want to force coloring you must both load this library and set the flag (before or after loading the library). Hope this helps.