ref: refs/heads/master
commit 8d3019552bd6ee9e7332454d757b51b07ca34c24
Author: Ján Kupec
Date: Fri Mar 13 14:20:53 2009 +0100
Improved color handling, prepared for zypper.conf.
---
src/Config.cc | 126 ++++++++++++++++++++++++++++++++++++++++++++--
src/Config.h | 20 ++++++-
src/output/OutNormal.cc | 89 +++++++++++----------------------
src/utils/colors.cc | 107 +++++++++++++++++++++++++++++++++++++--
src/utils/colors.h | 70 +++++++++++++++++++++-----
src/utils/prompt.cc | 14 ++---
6 files changed, 329 insertions(+), 97 deletions(-)
diff --git a/src/Config.cc b/src/Config.cc
index eb725b5..9dec290 100644
--- a/src/Config.cc
+++ b/src/Config.cc
@@ -5,23 +5,137 @@
|__/|_| |_|
\*---------------------------------------------------------------------------*/
-#include "utils/colors.h"
+#include <iostream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/Measure.h"
#include "Config.h"
-#include <iostream>
+using namespace std;
+using namespace zypp;
Config::Config()
: do_colors(false)
, color_useColors("never")
- , color_background(false) // dark background
+ , color_background(false) // dark background
+ , color_colorResult ("white") // default colors for dark background
+ , color_colorMsgStatus ("grey") // if background is actually light, these
+ , color_colorMsgError ("red") // colors will be overwritten in read()
+ , color_colorMsgWarning ("yellow")
+ , color_colorPositive ("green")
+ , color_colorNegative ("red")
+ , color_colorPromptOption("grey")
+ , color_colorPromptShorthand("yellow")
{}
void Config::read()
{
- // color_useColors = auges.getOption("colors/useColors");
- // ...
+ debug::Measure m("ReadConfig");
+
+ // get augeas
+
+ m.elapsed();
+
+ // ---------------[ main ]--------------------------------------------------
+
+ // TODO
+
+ // ---------------[ colors ]------------------------------------------------
+
+ // color_useColors = augeas.getOption("colors/useColors");
do_colors =
- color_useColors == "autodetect" && has_colors()
+ (color_useColors == "autodetect" && has_colors())
|| color_useColors == "always";
+
+ ////// colors/background //////
+
+ string s;
+ // s = augeas.getOption("colors/background");
+ if (s == "light")
+ color_background = true;
+ else if (!s.empty() && s != "dark")
+ ERR << "invalid colors/background value: " << s << endl;
+
+ Color c("none");
+
+ ////// colors/colorResult //////
+
+ // c = augeas.getOption("colors/colorResult");
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_colorResult = Color("black");
+ }
+ else
+ color_colorResult = c;
+
+ ////// colors/colorMsgStatus //////
+
+ // c = augeas.getOption("colors/colorMsgStatus");
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_colorMsgStatus = Color("default");
+ }
+ else
+ color_colorMsgStatus = c;
+
+ ////// colors/colorMsgError //////
+
+ // c = augeas.getOption("colors/colorMsgError");
+ if (!c.value().empty())
+ color_colorMsgError = c;
+
+ ////// colors/colorMsgWarning //////
+
+ // c = augeas.getOption("colors/colorMsgWarning");
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_colorMsgWarning = Color("brown");
+ }
+ else
+ color_colorMsgWarning = c;
+
+ ////// colors/colorPositive //////
+
+ // c = augeas.getOption("colors/colorPositive");
+ if (!c.value().empty())
+ color_colorPositive = c;
+
+ ////// colors/colorNegative //////
+
+ // c = augeas.getOption("colors/colorNegative");
+ if (!c.value().empty())
+ color_colorNegative = c;
+
+ ////// colors/colorPromptOption //////
+
+ // c = augeas.getOption("colors/colorPromptOption");
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_colorPromptOption = Color("darkgrey");
+ }
+ else
+ color_colorPromptOption = c;
+
+ ////// colors/colorPromptShorthand //////
+
+ // c = augeas.getOption("colors/colorPromptShorthand");
+ if (c.value().empty())
+ {
+ // set a default for light background
+ if (color_background)
+ color_colorPromptShorthand = Color("cyan");
+ }
+ else
+ color_colorPromptShorthand = c;
+
+ m.stop();
}
diff --git a/src/Config.h b/src/Config.h
index d5b197e..f22b5be 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -10,6 +10,8 @@
#include <string>
+#include "utils/colors.h"
+
struct Config
{
/** Initializes the config options to defaults. */
@@ -21,16 +23,28 @@ struct Config
/**
- * Whether to print colors to stdout. This is evaluated according to
+ * Whether to colorize the output. This is evaluated according to
* color_useColors and has_colors()
*/
bool do_colors;
- /** zypper.conf: color.useColors option */
+ /** zypper.conf: color.useColors */
std::string color_useColors;
- /** dark (false) or light (true) */
+ /**
+ * zypper.conf: color.background
+ * dark (false) or light (true)
+ */
bool color_background;
+
+ Color color_colorResult;
+ Color color_colorMsgStatus;
+ Color color_colorMsgError;
+ Color color_colorMsgWarning;
+ Color color_colorPositive;
+ Color color_colorNegative;
+ Color color_colorPromptOption;
+ Color color_colorPromptShorthand;
};
#endif /* ZYPPER_CONFIG_H_ */
diff --git a/src/output/OutNormal.cc b/src/output/OutNormal.cc
index 4414398..84b1fb2 100644
--- a/src/output/OutNormal.cc
+++ b/src/output/OutNormal.cc
@@ -58,10 +58,12 @@ void OutNormal::info(const std::string & msg, Verbosity verbosity, Type mask)
if (infoWarningFilter(verbosity, mask))
return;
- if (_use_colors && verbosity > Out::QUIET)
- cout << COLOR_WHITE << msg << COLOR_RESET << endl;
+ if (verbosity == Out::QUIET)
+ print_color(msg, COLOR_CONTEXT_RESULT);
else
- cout << msg << endl;
+ cout << msg;
+
+ cout << endl;
}
void OutNormal::warning(const std::string & msg, Verbosity verbosity, Type mask)
@@ -69,18 +71,13 @@ void OutNormal::warning(const std::string & msg, Verbosity verbosity, Type mask)
if (infoWarningFilter(verbosity, mask))
return;
- if (_use_colors)
- cout << COLOR_YELLOW_BOLD << _("Warning: ") << COLOR_RESET << msg << endl;
- else
- cout << msg << endl;
+ print_color(_("Warning: "), COLOR_CONTEXT_MSG_WARNING);
+ cout << msg << endl;
}
void OutNormal::error(const std::string & problem_desc, const std::string & hint)
{
- if (_use_colors)
- cerr << COLOR_RED_BOLD << problem_desc << COLOR_RESET;
- else
- cerr << problem_desc;
+ fprint_color(cerr, problem_desc, COLOR_CONTEXT_MSG_ERROR);
if (!hint.empty() && this->verbosity() > Out::QUIET)
cerr << endl << hint;
cerr << endl;
@@ -92,16 +89,12 @@ void OutNormal::error(const zypp::Exception & e,
const string & problem_desc,
const string & hint)
{
- if (_use_colors)
- cerr << COLOR_RED_BOLD;
-
// problem
- cerr << problem_desc << endl;
+ fprint_color(cerr, problem_desc, COLOR_CONTEXT_MSG_ERROR);
+ cerr << endl;
// cause
- cerr << zyppExceptionReport(e) << endl;
-
- if (_use_colors)
- cerr << COLOR_RESET;
+ fprint_color(cerr, zyppExceptionReport(e), COLOR_CONTEXT_MSG_ERROR);
+ cerr << endl;
// hint
if (!hint.empty() && this->verbosity() > Out::QUIET)
@@ -153,9 +146,6 @@ void OutNormal::progressStart(const std::string & id,
if (progressFilter())
return;
- if (_use_colors)
- cerr << COLOR_WHITE;
-
if (!_isatty)
cout << label << " [";
@@ -163,9 +153,6 @@ void OutNormal::progressStart(const std::string & id,
display_tick(id, label);
else
display_progress(id, label, 0);
-
- if (_use_colors)
- cerr << COLOR_RESET;
}
void OutNormal::progress(const std::string & id, const string & label, int value)
@@ -173,16 +160,10 @@ void OutNormal::progress(const std::string & id, const string & label, int value
if (progressFilter())
return;
- if (_use_colors)
- cerr << COLOR_WHITE;
-
if (value)
display_progress(id, label, value);
else
display_tick(id, label);
-
- if (_use_colors)
- cerr << COLOR_RESET;
}
void OutNormal::progressEnd(const std::string & id, const string & label, bool error)
@@ -190,21 +171,21 @@ void OutNormal::progressEnd(const std::string & id, const string & label, bool e
if (progressFilter())
return;
- if (_use_colors)
- cerr << COLOR_WHITE;
+ if (!error && _use_colors)
+ cout << get_color(COLOR_CONTEXT_MSG_STATUS);
if (_isatty)
- {
cout << CLEARLN << label << " [";
- if (error)
- print_color(_("error"), COLOR_RED, COLOR_WHITE);
- else
- cout << _("done");
- }
+
+ if (error)
+ print_color(_("error"), COLOR_CONTEXT_NEGATIVE);
+ else
+ cout << _("done");
+
cout << "]";
- if (_use_colors)
- cerr << COLOR_RESET;
+ if (!error && _use_colors)
+ cout << COLOR_RESET;
cout << endl << std::flush;
}
@@ -215,24 +196,18 @@ void OutNormal::dwnldProgressStart(const zypp::Url & uri)
if (verbosity() < NORMAL)
return;
- if (_use_colors)
- cerr << COLOR_WHITE;
-
- if (isatty(STDOUT_FILENO))
+ if (_isatty)
cout << CLEARLN;
cout << _("Retrieving:") << " ";
if (verbosity() == DEBUG)
cout << uri; //! \todo shorten to fit the width of the terminal
else
cout << zypp::Pathname(uri.getPathName()).basename();
- if (isatty(STDOUT_FILENO))
+ if (_isatty)
cout << " [" << _("starting") << "]"; //! \todo align to the right
else
cout << " [" ;
- if (_use_colors)
- cerr << COLOR_RESET;
-
cout << std::flush;
}
@@ -249,9 +224,6 @@ void OutNormal::dwnldProgress(const zypp::Url & uri,
return;
}
- if (_use_colors)
- cerr << COLOR_WHITE;
-
cout << CLEARLN << _("Retrieving:") << " ";
if (verbosity() == DEBUG)
cout << uri; //! \todo shorten to fit the width of the terminal
@@ -268,9 +240,6 @@ void OutNormal::dwnldProgress(const zypp::Url & uri,
cout << "]";
}
- if (_use_colors)
- cerr << COLOR_RESET;
-
cout << std::flush;
}
@@ -279,8 +248,8 @@ void OutNormal::dwnldProgressEnd(const zypp::Url & uri, long rate, bool error)
if (verbosity() < NORMAL)
return;
- if (_use_colors)
- cerr << COLOR_WHITE;
+ if (!error && _use_colors)
+ cout << get_color(COLOR_CONTEXT_MSG_STATUS);
if (_isatty)
{
@@ -291,7 +260,7 @@ void OutNormal::dwnldProgressEnd(const zypp::Url & uri, long rate, bool error)
cout << zypp::Pathname(uri.getPathName()).basename();
cout << " [";
if (error)
- print_color(_("error"), COLOR_RED, COLOR_WHITE);
+ print_color(_("error"), COLOR_CONTEXT_NEGATIVE);
else
cout << _("done");
}
@@ -302,8 +271,8 @@ void OutNormal::dwnldProgressEnd(const zypp::Url & uri, long rate, bool error)
cout << " (" << zypp::ByteCount(rate) << "/s)";
cout << "]";
- if (_use_colors)
- cerr << COLOR_RESET;
+ if (!error && _use_colors)
+ cout << COLOR_RESET;
cout << endl << std::flush;
}
diff --git a/src/utils/colors.cc b/src/utils/colors.cc
index 8f34601..2b90c60 100644
--- a/src/utils/colors.cc
+++ b/src/utils/colors.cc
@@ -10,10 +10,53 @@
#include
#include
+#include "zypp/base/Logger.h"
+
+#include "Zypper.h"
+
#include "colors.h"
using namespace std;
+static map str2esc;
+
+Color::Color(const string & color_str)
+ : _value(parse(color_str))
+{}
+
+string Color::parse(const string & value)
+{
+ if (str2esc.empty())
+ {
+ str2esc["green"] = COLOR_GREEN;
+ str2esc["lightgreen"] = COLOR_GREEN_LIGHT;
+ str2esc["red"] = COLOR_RED;
+ str2esc["lightred"] = COLOR_RED_LIGHT;
+ str2esc["grey"] = COLOR_WHITE;
+ str2esc["white"] = COLOR_WHITE_LIGHT;
+ str2esc["brown"] = COLOR_YELLOW;
+ str2esc["yellow"] = COLOR_YELLOW_LIGHT;
+ str2esc["purple"] = COLOR_PURPLE;
+ str2esc["lightpurple"] = COLOR_PURPLE_LIGHT;
+ str2esc["blue"] = COLOR_BLUE;
+ str2esc["lightblue"] = COLOR_BLUE_LIGHT;
+ str2esc["cyan"] = COLOR_CYAN;
+ str2esc["lightcyan"] = COLOR_CYAN_LIGHT;
+ str2esc["black"] = COLOR_BLACK;
+ str2esc["darkgrey"] = COLOR_GREY_DARK;
+
+ str2esc["reset"] = COLOR_RESET;
+ }
+
+ map::const_iterator it = str2esc.find(value);
+ if (it == str2esc.end())
+ {
+ ERR << "Unknown color '" << value << "'" << endl;
+ return string();
+ }
+ return it->second;
+}
+
bool has_colors()
{
if (::isatty(STDOUT_FILENO))
@@ -25,16 +68,68 @@ bool has_colors()
return false;
}
+static const string get_color(const Config & conf, const ColorContext context)
+{
+ switch (context)
+ {
+ case COLOR_CONTEXT_RESULT:
+ return conf.color_colorResult.value();
+ case COLOR_CONTEXT_MSG_STATUS:
+ return conf.color_colorMsgStatus.value();
+ case COLOR_CONTEXT_MSG_WARNING:
+ return conf.color_colorMsgWarning.value();
+ case COLOR_CONTEXT_MSG_ERROR:
+ return conf.color_colorMsgError.value();
+ case COLOR_CONTEXT_POSTIVE:
+ return conf.color_colorPositive.value();
+ case COLOR_CONTEXT_NEGATIVE:
+ return conf.color_colorNegative.value();
+ case COLOR_CONTEXT_PROMPT_OPTION:
+ return conf.color_colorPromptOption.value();
+ case COLOR_CONTEXT_PROMPT_SHORTHAND:
+ return conf.color_colorPromptShorthand.value();
+ default:
+ return COLOR_RESET;
+ }
+}
+
+const string get_color(const ColorContext context)
+{
+ return get_color(Zypper::instance()->config(), context);
+}
+
void print_color(const std::string & s,
const char * ansi_color_seq, const char * prev_color)
{
- if (prev_color)
- cout << COLOR_RESET;
+ fprint_color(cout, s, ansi_color_seq, prev_color);
+}
+
+void fprint_color(ostream & str, const std::string & s,
+ const char * ansi_color_seq, const char * prev_color)
+{
+ if (Zypper::instance()->config().do_colors)
+ {
+ if (prev_color)
+ str << COLOR_RESET;
- cout << ansi_color_seq << s;
+ str << ansi_color_seq << s << COLOR_RESET;
- if (prev_color)
- cout << prev_color;
+ if (prev_color)
+ str << prev_color;
+ }
else
- cout << COLOR_RESET;
+ str << s;
+}
+
+void fprint_color(ostream & str, const std::string & s,
+ const ColorContext cc, const ColorContext prev_cc)
+{
+ const Config & conf = Zypper::instance()->config();
+ fprint_color(str, s, get_color(conf, cc).c_str(), get_color(conf, prev_cc).c_str());
+}
+
+void print_color(const std::string & s,
+ const ColorContext cc, const ColorContext prev_cc)
+{
+ fprint_color(cout, s, cc, prev_cc);
}
diff --git a/src/utils/colors.h b/src/utils/colors.h
index 0e50d0e..c2d84ab 100644
--- a/src/utils/colors.h
+++ b/src/utils/colors.h
@@ -8,41 +8,83 @@
#ifndef UTILS_COLORS_H_
#define UTILS_COLORS_H_
+#include <string>
#include <iosfwd>
+#define COLOR_BLACK "\033[30m"
+#define COLOR_GREY_DARK "\033[1;30m"
+#define COLOR_BLUE "\033[34m"
+#define COLOR_BLUE_LIGHT "\033[1;34m"
+#define COLOR_CYAN "\033[36m"
+#define COLOR_CYAN_LIGHT "\033[1;36m"
#define COLOR_GREEN "\033[32m"
-#define COLOR_GREEN_BOLD "\033[1;32m"
+#define COLOR_GREEN_LIGHT "\033[1;32m"
+#define COLOR_PURPLE "\033[35m"
+#define COLOR_PURPLE_LIGHT "\033[1;35m"
#define COLOR_RED "\033[31m"
-#define COLOR_RED_BOLD "\033[1;31m"
+#define COLOR_RED_LIGHT "\033[1;31m"
#define COLOR_WHITE "\033[37m" // grey
-#define COLOR_WHITE_BOLD "\033[1;37m"
+#define COLOR_WHITE_LIGHT "\033[1;37m"
#define COLOR_YELLOW "\033[33m" // brown
-#define COLOR_YELLOW_BOLD "\033[1;33m"
+#define COLOR_YELLOW_LIGHT "\033[1;33m"
#define COLOR_RESET "\033[m"
-/*
-enum zypper_colors
+
+class Color
{
- ZYPPER_COLOR_MSG_NORMAL = 1,
- ZYPPER_COLOR_MSG_HIGHLIGHTED = 2,
- ZYPPER_COLOR_MSG_ERROR = 3,
- ZYPPER_COLOR_MSG_WARNING = 4
+public:
+ explicit Color(const std::string & color_str);
+
+ std::string parse(const std::string & value);
+
+ std::string value() const
+ { return _value; }
+
+private:
+ std::string _value;
};
-*/
+
+
+typedef enum zypper_color_contexts
+{
+ COLOR_CONTEXT_RESULT = 1,
+ COLOR_CONTEXT_MSG_STATUS = 2,
+ COLOR_CONTEXT_MSG_ERROR = 3,
+ COLOR_CONTEXT_MSG_WARNING = 4,
+ COLOR_CONTEXT_POSTIVE = 5,
+ COLOR_CONTEXT_NEGATIVE = 6,
+ COLOR_CONTEXT_PROMPT_OPTION = 7,
+ COLOR_CONTEXT_PROMPT_SHORTHAND = 8,
+
+ COLOR_CONTEXT_DEFAULT = -1
+} ColorContext;
+
/** Simple check whether stdout can handle colors. */
bool has_colors();
+/** Get ISO terminal escape sequence for color in given \a context. */
+const std::string get_color(const ColorContext context);
+
/**
- * Print string \a s in given color.
+ * Print string \a s in given color to stdout.
*
* \param s string to print
- * \param ansi_color_seq color to print with
+ * \param color_seq color to print with (ISO terminal escape sequence)
* \param prev_color color to restore after printing. If NULL,
* COLOR_RESET will be used
*/
void print_color(const std::string & s,
- const char * ansi_color_seq, const char * prev_color);
+ const char * color_seq, const char * prev_color = NULL);
+
+void fprint_color(std::ostream & str, const std::string & s,
+ const char * ansi_color_seq, const char * prev_color = NULL);
+
+void fprint_color(std::ostream & str, const std::string & s,
+ const ColorContext cc, const ColorContext prev_color = COLOR_CONTEXT_DEFAULT);
+
+void print_color(const std::string & s,
+ const ColorContext cc, const ColorContext prev_color = COLOR_CONTEXT_DEFAULT);
#endif /* UTILS_COLORS_H_ */
diff --git a/src/utils/prompt.cc b/src/utils/prompt.cc
index 1e9c4de..622e732 100644
--- a/src/utils/prompt.cc
+++ b/src/utils/prompt.cc
@@ -96,25 +96,23 @@ const string PromptOptions::optionStringColored() const
if ((it = options().begin()) != options().end() && shown_count > 0)
{
if (defaultOpt() == 0)
- option_str << COLOR_YELLOW << *it;
+ fprint_color(option_str, *it, COLOR_CONTEXT_PROMPT_SHORTHAND);
else
- option_str << COLOR_WHITE << *it;
+ fprint_color(option_str, *it, COLOR_CONTEXT_PROMPT_OPTION);
++it;
}
for (unsigned int i = 1; it != options().end() && i < shown_count; ++it, ++i)
if (isEnabled(i))
{
- option_str << COLOR_WHITE << "/";
+ fprint_color(option_str, "/", COLOR_CONTEXT_PROMPT_OPTION);
if (defaultOpt() == i)
- option_str << COLOR_YELLOW << *it;
+ fprint_color(option_str, *it, COLOR_CONTEXT_PROMPT_SHORTHAND);
else
- option_str << *it;
+ fprint_color(option_str, *it, COLOR_CONTEXT_PROMPT_OPTION);
}
if (!_opt_help.empty())
- option_str << COLOR_WHITE << (shown_count > 0 ? "/" : "") << "?";
-
- option_str << COLOR_RESET;
+ fprint_color(option_str, shown_count > 0 ? "/?" : "?", COLOR_CONTEXT_PROMPT_OPTION);
return option_str.str();
}
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org