Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision 665f43269c6958cbb65487dbaac9e440b9cd5815)
+++ src/Common/SemanticError.cc	(revision 27f5f71928a1b69d8d99509230f59fd8f00e9934)
@@ -149,21 +149,27 @@
 // Helpers
 namespace ErrorHelpers {
+	Colors colors = Colors::Auto;
+
+	static inline bool with_colors() {
+		return colors == Colors::Auto ? isatty( STDERR_FILENO ) : bool(colors);
+	}
+
 	const std::string & error_str() {
-		static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
+		static std::string str = with_colors() ? "\e[31merror:\e[39m " : "error: ";
 		return str;
 	}
 
 	const std::string & warning_str() {
-		static std::string str = isatty( STDERR_FILENO ) ? "\e[95mwarning:\e[39m " : "warning: ";
+		static std::string str = with_colors() ? "\e[95mwarning:\e[39m " : "warning: ";
 		return str;
 	}
 
 	const std::string & bold_ttycode() {
-		static std::string str = isatty( STDERR_FILENO ) ? "\e[1m" : "";
+		static std::string str = with_colors() ? "\e[1m" : "";
 		return str;
 	}
 
 	const std::string & reset_font_ttycode() {
-		static std::string str = isatty( STDERR_FILENO ) ? "\e[0m" : "";
+		static std::string str = with_colors() ? "\e[0m" : "";
 		return str;
 	}
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 665f43269c6958cbb65487dbaac9e440b9cd5815)
+++ src/Common/SemanticError.h	(revision 27f5f71928a1b69d8d99509230f59fd8f00e9934)
@@ -97,4 +97,12 @@
 // Helpers
 namespace ErrorHelpers {
+	enum class Colors {
+		Never = false,
+		Always = true,
+		Auto,
+	};
+
+	extern Colors colors;
+
 	const std::string & error_str();
 	const std::string & warning_str();
