Merge topic 'ccmake-custom-colors'

671fe28313 ccmake: Improve coloring, allow customization
f56a695440 ccmake: Rename cmCursesColor::{Options => Choice}

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4629
This commit is contained in:
Brad King
2020-04-27 14:39:54 +00:00
committed by Kitware Robot
6 changed files with 107 additions and 8 deletions

View File

@@ -0,0 +1,34 @@
CCMAKE_COLORS
-------------
Determines what colors are used by the CMake curses interface,
when run on a terminal that supports colors.
The syntax follows the same conventions as ``LS_COLORS``;
that is, a list of key/value pairs separated by ``:``.
Keys are a single letter corresponding to a CMake cache variable type:
- ``s``: A ``STRING``.
- ``p``: A ``FILEPATH``.
- ``c``: A value which has an associated list of choices.
- ``y``: A ``BOOL`` which has a true-like value (e.g. ``ON``, ``YES``).
- ``n``: A ``BOOL`` which has a false-like value (e.g. ``OFF``, ``NO``).
Values are an integer number that specifies what color to use.
``0`` is black (you probably don't want to use that).
Others are determined by your terminal's color support.
Most (color) terminals will support at least 8 or 16 colors.
Some will support up to 256 colors. The colors will likely match
`this chart <https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg>`_,
although the first 16 colors may match the original
`CGA color palette <https://en.wikipedia.org/wiki/Color_Graphics_Adapter#Color_palette>`_.
(Many modern terminal emulators also allow their color palette,
at least for the first 16 colors, to be configured by the user.)
Note that fairly minimal checking is done for bad colors
(although a value higher than what curses believes your terminal supports
will be silently ignored) or bad syntax.
For example::
CCMAKE_COLORS='s=39:p=220:c=207:n=196:y=46'

View File

@@ -80,3 +80,11 @@ Environment Variables for CTest
/envvar/CTEST_PROGRESS_OUTPUT
/envvar/CTEST_USE_LAUNCHERS_DEFAULT
/envvar/DASHBOARD_TEST_FROM_CTEST
Environment Variables for the CMake curses interface
====================================================
.. toctree::
:maxdepth: 1
/envvar/CCMAKE_COLORS

View File

@@ -0,0 +1,5 @@
ccmake-custom-colors
--------------------
* :manual:`ccmake(1)` learned to read a :envvar:`CCMAKE_COLORS`
environment variable to customize colors.

View File

@@ -2,6 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesColor.h"
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <unordered_map>
#include <utility>
#include "cmCursesStandardIncludes.h"
bool cmCursesColor::HasColors()
@@ -19,11 +25,54 @@ void cmCursesColor::InitColors()
if (HasColors()) {
start_color();
use_default_colors();
init_pair(cmCursesColor::BoolOff, COLOR_RED, -1);
init_pair(cmCursesColor::BoolOn, COLOR_GREEN, -1);
init_pair(cmCursesColor::String, COLOR_BLUE, -1);
init_pair(cmCursesColor::Path, COLOR_YELLOW, -1);
init_pair(cmCursesColor::Options, COLOR_MAGENTA, -1);
init_pair(BoolOff, GetColor('N', COLOR_RED), -1);
init_pair(BoolOn, GetColor('Y', COLOR_GREEN), -1);
init_pair(String, GetColor('S', COLOR_CYAN), -1);
init_pair(Path, GetColor('P', COLOR_YELLOW), -1);
init_pair(Choice, GetColor('C', COLOR_MAGENTA), -1);
}
#endif
}
short cmCursesColor::GetColor(char id, short fallback)
{
static bool initialized = false;
static std::unordered_map<char, short> env;
if (!initialized) {
if (auto* v = getenv("CCMAKE_COLORS")) {
while (v[0] && v[1] && v[1] == '=') {
auto const n = std::toupper(*v);
char buffer[12];
memset(buffer, 0, sizeof(buffer));
if (auto* const e = strchr(v, ':')) {
if (static_cast<size_t>(e - v) > sizeof(buffer)) {
break;
}
strncpy(buffer, v + 2, static_cast<size_t>(e - v - 2));
v = e + 1;
} else {
auto const l = strlen(v);
if (l > sizeof(buffer)) {
break;
}
strncpy(buffer, v + 2, l - 2);
v += l;
}
auto const c = atoi(buffer);
if (c && c < COLORS) {
env.emplace(n, static_cast<short>(c));
}
}
}
initialized = true;
}
auto const iter = env.find(id);
return (iter == env.end() ? fallback : iter->second);
}

View File

@@ -13,12 +13,15 @@ public:
BoolOn,
String,
Path,
Options
Choice
};
static bool HasColors();
static void InitColors();
protected:
static short GetColor(char id, short fallback);
};
#endif // cmCursesColor_h

View File

@@ -17,8 +17,8 @@ cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height, int left,
// the widget into a string widget at some point. BOOL is safe for
// now.
if (cmCursesColor::HasColors()) {
set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Options));
set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Options));
set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Choice));
set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Choice));
} else {
set_field_fore(this->Field, A_NORMAL);
set_field_back(this->Field, A_STANDOUT);