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 }