1/* CLI colorizing 2 3 Copyright (C) 2018-2020 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "defs.h" 21#include "cli/cli-cmds.h" 22#include "cli/cli-style.h" 23#include "source-cache.h" 24#include "observable.h" 25 26/* True if styling is enabled. */ 27 28#if defined (__MSDOS__) 29bool cli_styling = false; 30#else 31bool cli_styling = true; 32#endif 33 34/* True if source styling is enabled. Note that this is only 35 consulted when cli_styling is true. */ 36 37bool source_styling = true; 38 39/* Name of colors; must correspond to ui_file_style::basic_color. */ 40static const char * const cli_colors[] = { 41 "none", 42 "black", 43 "red", 44 "green", 45 "yellow", 46 "blue", 47 "magenta", 48 "cyan", 49 "white", 50 nullptr 51}; 52 53/* Names of intensities; must correspond to 54 ui_file_style::intensity. */ 55static const char * const cli_intensities[] = { 56 "normal", 57 "bold", 58 "dim", 59 nullptr 60}; 61 62/* See cli-style.h. */ 63 64cli_style_option file_name_style ("filename", ui_file_style::GREEN); 65 66/* See cli-style.h. */ 67 68cli_style_option function_name_style ("function", ui_file_style::YELLOW); 69 70/* See cli-style.h. */ 71 72cli_style_option variable_name_style ("variable", ui_file_style::CYAN); 73 74/* See cli-style.h. */ 75 76cli_style_option address_style ("address", ui_file_style::BLUE); 77 78/* See cli-style.h. */ 79 80cli_style_option highlight_style ("highlight", ui_file_style::RED); 81 82/* See cli-style.h. */ 83 84cli_style_option title_style ("title", ui_file_style::BOLD); 85 86/* See cli-style.h. */ 87 88cli_style_option tui_border_style ("tui-border", ui_file_style::CYAN); 89 90/* See cli-style.h. */ 91 92cli_style_option tui_active_border_style ("tui-active-border", 93 ui_file_style::CYAN); 94 95/* See cli-style.h. */ 96 97cli_style_option metadata_style ("metadata", ui_file_style::DIM); 98 99/* See cli-style.h. */ 100 101cli_style_option::cli_style_option (const char *name, 102 ui_file_style::basic_color fg) 103 : changed (name), 104 m_name (name), 105 m_foreground (cli_colors[fg - ui_file_style::NONE]), 106 m_background (cli_colors[0]), 107 m_intensity (cli_intensities[ui_file_style::NORMAL]) 108{ 109} 110 111/* See cli-style.h. */ 112 113cli_style_option::cli_style_option (const char *name, 114 ui_file_style::intensity i) 115 : changed (name), 116 m_name (name), 117 m_foreground (cli_colors[0]), 118 m_background (cli_colors[0]), 119 m_intensity (cli_intensities[i]) 120{ 121} 122 123/* Return the color number corresponding to COLOR. */ 124 125static int 126color_number (const char *color) 127{ 128 for (int i = 0; i < ARRAY_SIZE (cli_colors); ++i) 129 { 130 if (color == cli_colors[i]) 131 return i - 1; 132 } 133 gdb_assert_not_reached ("color not found"); 134} 135 136/* See cli-style.h. */ 137 138ui_file_style 139cli_style_option::style () const 140{ 141 int fg = color_number (m_foreground); 142 int bg = color_number (m_background); 143 ui_file_style::intensity intensity = ui_file_style::NORMAL; 144 145 for (int i = 0; i < ARRAY_SIZE (cli_intensities); ++i) 146 { 147 if (m_intensity == cli_intensities[i]) 148 { 149 intensity = (ui_file_style::intensity) i; 150 break; 151 } 152 } 153 154 return ui_file_style (fg, bg, intensity); 155} 156 157/* See cli-style.h. */ 158 159void 160cli_style_option::do_set_value (const char *ignore, int from_tty, 161 struct cmd_list_element *cmd) 162{ 163 cli_style_option *cso = (cli_style_option *) get_cmd_context (cmd); 164 cso->changed.notify (); 165} 166 167/* Implements the cli_style_option::do_show_* functions. 168 WHAT and VALUE are the property and value to show. 169 The style for which WHAT is shown is retrieved from CMD context. */ 170 171static void 172do_show (const char *what, struct ui_file *file, 173 struct cmd_list_element *cmd, 174 const char *value) 175{ 176 cli_style_option *cso = (cli_style_option *) get_cmd_context (cmd); 177 fputs_filtered (_("The "), file); 178 fprintf_styled (file, cso->style (), _("\"%s\" style"), cso->name ()); 179 fprintf_filtered (file, _(" %s is: %s\n"), what, value); 180} 181 182/* See cli-style.h. */ 183 184void 185cli_style_option::do_show_foreground (struct ui_file *file, int from_tty, 186 struct cmd_list_element *cmd, 187 const char *value) 188{ 189 do_show (_("foreground color"), file, cmd, value); 190} 191 192/* See cli-style.h. */ 193 194void 195cli_style_option::do_show_background (struct ui_file *file, int from_tty, 196 struct cmd_list_element *cmd, 197 const char *value) 198{ 199 do_show (_("background color"), file, cmd, value); 200} 201 202/* See cli-style.h. */ 203 204void 205cli_style_option::do_show_intensity (struct ui_file *file, int from_tty, 206 struct cmd_list_element *cmd, 207 const char *value) 208{ 209 do_show (_("display intensity"), file, cmd, value); 210} 211 212/* See cli-style.h. */ 213 214void 215cli_style_option::add_setshow_commands (enum command_class theclass, 216 const char *prefix_doc, 217 struct cmd_list_element **set_list, 218 struct cmd_list_element **show_list, 219 bool skip_intensity) 220{ 221 m_set_prefix = std::string ("set style ") + m_name + " "; 222 m_show_prefix = std::string ("show style ") + m_name + " "; 223 224 add_basic_prefix_cmd (m_name, no_class, prefix_doc, &m_set_list, 225 m_set_prefix.c_str (), 0, set_list); 226 add_show_prefix_cmd (m_name, no_class, prefix_doc, &m_show_list, 227 m_show_prefix.c_str (), 0, show_list); 228 229 add_setshow_enum_cmd ("foreground", theclass, cli_colors, 230 &m_foreground, 231 _("Set the foreground color for this property."), 232 _("Show the foreground color for this property."), 233 nullptr, 234 do_set_value, 235 do_show_foreground, 236 &m_set_list, &m_show_list, (void *) this); 237 add_setshow_enum_cmd ("background", theclass, cli_colors, 238 &m_background, 239 _("Set the background color for this property."), 240 _("Show the background color for this property."), 241 nullptr, 242 do_set_value, 243 do_show_background, 244 &m_set_list, &m_show_list, (void *) this); 245 if (!skip_intensity) 246 add_setshow_enum_cmd ("intensity", theclass, cli_intensities, 247 &m_intensity, 248 _("Set the display intensity for this property."), 249 _("Show the display intensity for this property."), 250 nullptr, 251 do_set_value, 252 do_show_intensity, 253 &m_set_list, &m_show_list, (void *) this); 254} 255 256static cmd_list_element *style_set_list; 257static cmd_list_element *style_show_list; 258 259static void 260set_style_enabled (const char *args, int from_tty, struct cmd_list_element *c) 261{ 262 g_source_cache.clear (); 263 gdb::observers::source_styling_changed.notify (); 264} 265 266static void 267show_style_enabled (struct ui_file *file, int from_tty, 268 struct cmd_list_element *c, const char *value) 269{ 270 if (cli_styling) 271 fprintf_filtered (file, _("CLI output styling is enabled.\n")); 272 else 273 fprintf_filtered (file, _("CLI output styling is disabled.\n")); 274} 275 276static void 277show_style_sources (struct ui_file *file, int from_tty, 278 struct cmd_list_element *c, const char *value) 279{ 280 if (source_styling) 281 fprintf_filtered (file, _("Source code styling is enabled.\n")); 282 else 283 fprintf_filtered (file, _("Source code styling is disabled.\n")); 284} 285 286void _initialize_cli_style (); 287void 288_initialize_cli_style () 289{ 290 add_basic_prefix_cmd ("style", no_class, _("\ 291Style-specific settings.\n\ 292Configure various style-related variables, such as colors"), 293 &style_set_list, "set style ", 0, &setlist); 294 add_show_prefix_cmd ("style", no_class, _("\ 295Style-specific settings.\n\ 296Configure various style-related variables, such as colors"), 297 &style_show_list, "show style ", 0, &showlist); 298 299 add_setshow_boolean_cmd ("enabled", no_class, &cli_styling, _("\ 300Set whether CLI styling is enabled."), _("\ 301Show whether CLI is enabled."), _("\ 302If enabled, output to the terminal is styled."), 303 set_style_enabled, show_style_enabled, 304 &style_set_list, &style_show_list); 305 306 add_setshow_boolean_cmd ("sources", no_class, &source_styling, _("\ 307Set whether source code styling is enabled."), _("\ 308Show whether source code styling is enabled."), _("\ 309If enabled, source code is styled.\n" 310#ifdef HAVE_SOURCE_HIGHLIGHT 311"Note that source styling only works if styling in general is enabled,\n\ 312see \"show style enabled\"." 313#else 314"Source highlighting may be disabled in this installation of gdb, because\n\ 315it was not linked against GNU Source Highlight. However, it might still be\n\ 316available if the appropriate extension is available at runtime." 317#endif 318 ), set_style_enabled, show_style_sources, 319 &style_set_list, &style_show_list); 320 321 file_name_style.add_setshow_commands (no_class, _("\ 322Filename display styling.\n\ 323Configure filename colors and display intensity."), 324 &style_set_list, &style_show_list, 325 false); 326 327 function_name_style.add_setshow_commands (no_class, _("\ 328Function name display styling.\n\ 329Configure function name colors and display intensity"), 330 &style_set_list, &style_show_list, 331 false); 332 333 variable_name_style.add_setshow_commands (no_class, _("\ 334Variable name display styling.\n\ 335Configure variable name colors and display intensity"), 336 &style_set_list, &style_show_list, 337 false); 338 339 address_style.add_setshow_commands (no_class, _("\ 340Address display styling.\n\ 341Configure address colors and display intensity"), 342 &style_set_list, &style_show_list, 343 false); 344 345 title_style.add_setshow_commands (no_class, _("\ 346Title display styling.\n\ 347Configure title colors and display intensity\n\ 348Some commands (such as \"apropos -v REGEXP\") use the title style to improve\n\ 349readability."), 350 &style_set_list, &style_show_list, 351 false); 352 353 highlight_style.add_setshow_commands (no_class, _("\ 354Highlight display styling.\n\ 355Configure highlight colors and display intensity\n\ 356Some commands use the highlight style to draw the attention to a part\n\ 357of their output."), 358 &style_set_list, &style_show_list, 359 false); 360 361 metadata_style.add_setshow_commands (no_class, _("\ 362Metadata display styling.\n\ 363Configure metadata colors and display intensity\n\ 364The \"metadata\" style is used when GDB displays information about\n\ 365your data, for example \"<unavailable>\""), 366 &style_set_list, &style_show_list, 367 false); 368 369 tui_border_style.add_setshow_commands (no_class, _("\ 370TUI border display styling.\n\ 371Configure TUI border colors\n\ 372The \"tui-border\" style is used when GDB displays the border of a\n\ 373TUI window that does not have the focus."), 374 &style_set_list, &style_show_list, 375 true); 376 377 tui_active_border_style.add_setshow_commands (no_class, _("\ 378TUI active border display styling.\n\ 379Configure TUI active border colors\n\ 380The \"tui-active-border\" style is used when GDB displays the border of a\n\ 381TUI window that does have the focus."), 382 &style_set_list, 383 &style_show_list, 384 true); 385} 386