1 /******************************************************************************* 2 3 Console output 4 5 Console output classes extending those in ocean.io.Stdout. 6 7 Additional features are: 8 * clearline() method which erases the rest of the line 9 * bold() method which sets the text output to bold / bright mode 10 * text colour setting methods 11 12 Copyright: 13 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 14 All rights reserved. 15 16 License: 17 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 18 Alternatively, this file may be distributed under the terms of the Tango 19 3-Clause BSD License (see LICENSE_BSD.txt for details). 20 21 *******************************************************************************/ 22 23 module ocean.io.Stdout; 24 25 26 27 28 import ocean.meta.types.Qualifiers; 29 30 import ocean.io.Terminal; 31 32 import ocean.io.device.Conduit; 33 34 import ocean.io.stream.Format; 35 36 import ocean.io.Console; 37 38 import ocean.text.convert.Formatter; 39 40 41 /******************************************************************************* 42 43 Static output instances 44 45 *******************************************************************************/ 46 47 public static TerminalOutput Stdout; /// Global standard output. 48 public static TerminalOutput Stderr; /// Global error output. 49 public alias Stdout stdout; /// Alternative. 50 public alias Stderr stderr; /// Alternative. 51 52 static this ( ) 53 { 54 Stdout = new TerminalOutput(Cout.stream); 55 Stderr = new TerminalOutput(Cerr.stream); 56 57 Stdout.flush = !Cout.redirected; 58 Stdout.redirect = Cout.redirected; 59 Stderr.flush = !Cerr.redirected; 60 Stderr.redirect = Cerr.redirected; 61 } 62 63 64 65 /******************************************************************************* 66 67 Terminal output class. 68 69 Derived from FormatOutput in ocean.io.stream.Format, and reimplements 70 methods to return typeof(this), for easy method chaining. Note that not all 71 methods are reimplemented in this way, only those which we commonly use. 72 Others may be added if needed. 73 74 *******************************************************************************/ 75 76 public class TerminalOutput : FormatOutput 77 { 78 /*************************************************************************** 79 80 Template method to output a CSI sequence 81 82 Params: 83 seq = csi sequence to output 84 85 ***************************************************************************/ 86 87 public typeof(this) csiSeq ( istring seq ) ( ) 88 { 89 if ( !this.redirect ) 90 { 91 this.sink.write(Terminal.CSI); 92 this.sink.write(seq); 93 } 94 return this; 95 } 96 97 98 /*************************************************************************** 99 100 True if it's redirected. 101 102 ***************************************************************************/ 103 104 protected bool redirect; 105 106 107 /*************************************************************************** 108 109 Construct a FormatOutput instance, tying the provided stream to a layout 110 formatter. 111 112 ***************************************************************************/ 113 114 public this (OutputStream output, istring eol = Eol) 115 { 116 super(output, eol); 117 } 118 119 /// See `FormatOutput.format` 120 public typeof(this) format (Args...) (cstring fmt, Args args) 121 { 122 // FIXME_IN_D2: Use TemplateThisParam in FormatOutput and kill this 123 sformat(&this.emit, fmt, args); 124 return this; 125 } 126 127 /// See `FormatOutput.formatln` 128 public typeof(this) formatln (Args...) (cstring fmt, Args args) 129 { 130 // FIXME_IN_D2: Use TemplateThisParam in FormatOutput and kill this 131 sformat(&this.emit, fmt, args); 132 this.newline; 133 return this; 134 } 135 136 137 /*************************************************************************** 138 139 Output a newline and optionally flush. 140 141 ***************************************************************************/ 142 143 public typeof(this) newline ( ) 144 { 145 super.newline; 146 return this; 147 } 148 149 150 /*************************************************************************** 151 152 Emit/purge buffered content. 153 154 ***************************************************************************/ 155 156 public override typeof(this) flush ( ) 157 { 158 super.flush; 159 return this; 160 } 161 162 163 /*************************************************************************** 164 165 Control implicit flushing of newline(), where true enables flushing. An 166 explicit flush() will always flush the output. 167 168 ***************************************************************************/ 169 170 public typeof(this) flush ( bool yes ) 171 { 172 super.flush(yes); 173 return this; 174 } 175 176 177 /*************************************************************************** 178 179 Output terminal control characters to clear the rest of the line. Note: 180 does not flush. (Flush explicitly if you need to.) 181 182 ***************************************************************************/ 183 184 public typeof(this) clearline ( ) 185 { 186 if ( this.redirect ) 187 { 188 return this.newline; 189 } 190 return this.csiSeq!(Terminal.ERASE_REST_OF_LINE); 191 } 192 193 194 /*************************************************************************** 195 196 Sets / unsets bold text output. 197 198 Params: 199 on = bold on / off 200 201 ***************************************************************************/ 202 203 public typeof(this) bold ( bool on = true ) 204 { 205 return on ? this.csiSeq!(Terminal.BOLD) : this.csiSeq!(Terminal.NON_BOLD); 206 } 207 208 209 /*************************************************************************** 210 211 Move the current cursor position to the last row of the terminal. This 212 method adapts to changes in the size of the terminal. 213 214 ***************************************************************************/ 215 216 public typeof(this) endrow ( ) 217 { 218 this.sink.write(.format("{}{};1H", Terminal.CSI, Terminal.rows)); 219 return this; 220 } 221 222 223 /*************************************************************************** 224 225 Carriage return (sends cursor back to the start of the line). 226 227 ***************************************************************************/ 228 229 public alias csiSeq!("0" ~ Terminal.HORIZONTAL_MOVE_CURSOR) cr; 230 231 232 /*************************************************************************** 233 234 Move the cursor up a line 235 236 ***************************************************************************/ 237 238 public alias csiSeq!("1" ~ Terminal.CURSOR_UP) up; 239 240 241 /*************************************************************************** 242 243 Foreground colour changing methods. 244 245 ***************************************************************************/ 246 247 public alias csiSeq!(Terminal.Foreground.DEFAULT) default_colour; 248 public alias csiSeq!(Terminal.Foreground.BLACK) black; 249 public alias csiSeq!(Terminal.Foreground.RED) red; 250 public alias csiSeq!(Terminal.Foreground.GREEN) green; 251 public alias csiSeq!(Terminal.Foreground.YELLOW) yellow; 252 public alias csiSeq!(Terminal.Foreground.BLUE) blue; 253 public alias csiSeq!(Terminal.Foreground.MAGENTA) magenta; 254 public alias csiSeq!(Terminal.Foreground.CYAN) cyan; 255 public alias csiSeq!(Terminal.Foreground.WHITE) white; 256 257 258 /*************************************************************************** 259 260 Background colour changing methods. 261 262 ***************************************************************************/ 263 264 public alias csiSeq!(Terminal.Background.DEFAULT) default_bg; 265 public alias csiSeq!(Terminal.Background.BLACK) black_bg; 266 public alias csiSeq!(Terminal.Background.RED) red_bg; 267 public alias csiSeq!(Terminal.Background.GREEN) green_bg; 268 public alias csiSeq!(Terminal.Background.YELLOW) yellow_bg; 269 public alias csiSeq!(Terminal.Background.BLUE) blue_bg; 270 public alias csiSeq!(Terminal.Background.MAGENTA) magenta_bg; 271 public alias csiSeq!(Terminal.Background.CYAN) cyan_bg; 272 public alias csiSeq!(Terminal.Background.WHITE) white_bg; 273 274 275 /*************************************************************************** 276 277 Foreground text colour scope class. Resets the default text colour, if 278 it has been changed, when scope exits. 279 280 ***************************************************************************/ 281 282 public class TextColour 283 { 284 /*********************************************************************** 285 286 Flag set to true when this instance has modified the text colour. 287 288 ***********************************************************************/ 289 290 private bool colour_set; 291 292 293 /*********************************************************************** 294 295 Flag set to true when this instance has modified the text boldness. 296 297 ***********************************************************************/ 298 299 private bool bold_set; 300 301 302 /*********************************************************************** 303 304 Destructor. Resets any modified text settings. 305 306 ***********************************************************************/ 307 308 ~this ( ) 309 { 310 if ( this.colour_set ) 311 { 312 this.outer.default_colour; 313 } 314 315 if ( this.bold_set ) 316 { 317 this.outer.bold(false); 318 } 319 } 320 321 322 /*********************************************************************** 323 324 Sets the text colour and optionally boldness. 325 326 Params: 327 method = name of outer class method to call to set the colour 328 bold = text boldness 329 330 ***********************************************************************/ 331 332 private void setCol ( istring method ) ( bool bold = false ) 333 { 334 this.colour_set = true; 335 mixin("this.outer." ~ method ~ ";"); 336 337 if ( bold ) 338 { 339 this.bold_set = true; 340 this.outer.bold; 341 } 342 } 343 344 345 /*********************************************************************** 346 347 Colour setting methods (all aliases of setCol(), above). 348 349 ***********************************************************************/ 350 351 public alias setCol!("black") black; 352 public alias setCol!("red") red; 353 public alias setCol!("green") green; 354 public alias setCol!("yellow") yellow; 355 public alias setCol!("blue") blue; 356 public alias setCol!("magenta") magenta; 357 public alias setCol!("cyan") cyan; 358 public alias setCol!("white") white; 359 } 360 361 362 /*************************************************************************** 363 364 Background colour class. Resets the default background colour, if 365 it has been changed, when scope exits. 366 367 ***************************************************************************/ 368 369 public class BackgroundColour 370 { 371 /*********************************************************************** 372 373 Flag set to true when this instance has modified the background 374 colour. 375 376 ***********************************************************************/ 377 378 private bool colour_set; 379 380 381 /*********************************************************************** 382 383 Destructor. Resets any modified text settings. 384 385 ***********************************************************************/ 386 387 ~this ( ) 388 { 389 if ( this.colour_set ) 390 { 391 this.outer.default_bg; 392 } 393 } 394 395 396 /*********************************************************************** 397 398 Sets the background colour. 399 400 Params: 401 method = name of outer class method to call to set the colour 402 403 ***********************************************************************/ 404 405 private void setCol ( istring method ) ( ) 406 { 407 this.colour_set = true; 408 mixin("this.outer." ~ method ~ ";"); 409 } 410 411 412 /*********************************************************************** 413 414 Colour setting methods (all aliases of setCol(), above). 415 416 ***********************************************************************/ 417 418 public alias setCol!("black_bg") black; 419 public alias setCol!("red_bg") red; 420 public alias setCol!("green_bg") green; 421 public alias setCol!("yellow_bg") yellow; 422 public alias setCol!("blue_bg") blue; 423 public alias setCol!("magenta_bg") magenta; 424 public alias setCol!("cyan_bg") cyan; 425 public alias setCol!("white_bg") white; 426 } 427 }