27
27
import java .util .Locale ;
28
28
29
29
import org .fusesource .jansi .internal .CLibrary ;
30
+ import org .fusesource .jansi .internal .CLibrary .WinSize ;
30
31
import org .fusesource .jansi .io .AnsiOutputStream ;
31
32
import org .fusesource .jansi .io .AnsiProcessor ;
32
33
import org .fusesource .jansi .io .FastBufferedOutputStream ;
33
34
import org .fusesource .jansi .io .WindowsAnsiProcessor ;
35
+ import org .fusesource .jansi .internal .Kernel32 .CONSOLE_SCREEN_BUFFER_INFO ;
34
36
37
+ import static org .fusesource .jansi .internal .CLibrary .ioctl ;
35
38
import static org .fusesource .jansi .internal .CLibrary .isatty ;
36
39
import static org .fusesource .jansi .internal .Kernel32 .GetConsoleMode ;
37
40
import static org .fusesource .jansi .internal .Kernel32 .GetStdHandle ;
38
41
import static org .fusesource .jansi .internal .Kernel32 .STD_ERROR_HANDLE ;
39
42
import static org .fusesource .jansi .internal .Kernel32 .STD_OUTPUT_HANDLE ;
40
43
import static org .fusesource .jansi .internal .Kernel32 .SetConsoleMode ;
44
+ import static org .fusesource .jansi .internal .Kernel32 .GetConsoleScreenBufferInfo ;
41
45
42
46
/**
43
47
* Provides consistent access to an ANSI aware console PrintStream or an ANSI codes stripping PrintStream
@@ -179,6 +183,20 @@ public class AnsiConsole {
179
183
@ Deprecated
180
184
public static PrintStream err ;
181
185
186
+ /**
187
+ * Try to find the width of the console for this process.
188
+ * Both output and error streams will be checked to determine the width.
189
+ * A value of 0 is returned if the width can not be determined.
190
+ * @since 2.2
191
+ */
192
+ public static int getTerminalWidth () {
193
+ int w = out ().getTerminalWidth ();
194
+ if (w <= 0 ) {
195
+ w = err ().getTerminalWidth ();
196
+ }
197
+ return w ;
198
+ }
199
+
182
200
static final boolean IS_WINDOWS = System .getProperty ("os.name" ).toLowerCase (Locale .ENGLISH ).contains ("win" );
183
201
184
202
static final boolean IS_CYGWIN = IS_WINDOWS
@@ -210,17 +228,19 @@ private AnsiConsole() {
210
228
}
211
229
212
230
private static AnsiPrintStream ansiStream (boolean stdout ) {
213
- final OutputStream out = new FastBufferedOutputStream (new FileOutputStream (stdout ? FileDescriptor .out : FileDescriptor .err ));
231
+ FileDescriptor descriptor = stdout ? FileDescriptor .out : FileDescriptor .err ;
232
+ final OutputStream out = new FastBufferedOutputStream (new FileOutputStream (descriptor ));
214
233
215
234
String enc = System .getProperty (stdout ? "sun.stdout.encoding" : "sun.stderr.encoding" );
216
235
217
236
final boolean isatty ;
218
237
boolean isAtty ;
219
238
boolean withException ;
239
+ final int fd = stdout ? CLibrary .STDOUT_FILENO : CLibrary .STDERR_FILENO ;
220
240
try {
221
241
// If we can detect that stdout is not a tty.. then setup
222
242
// to strip the ANSI sequences..
223
- isAtty = isatty (stdout ? CLibrary . STDOUT_FILENO : CLibrary . STDERR_FILENO ) != 0 ;
243
+ isAtty = isatty (fd ) != 0 ;
224
244
withException = false ;
225
245
} catch (Throwable ignore ) {
226
246
// These errors happen if the JNI lib is not available for your platform.
@@ -230,6 +250,7 @@ private static AnsiPrintStream ansiStream(boolean stdout) {
230
250
}
231
251
isatty = isAtty ;
232
252
253
+ final AnsiOutputStream .WidthSupplier width ;
233
254
final AnsiProcessor processor ;
234
255
final AnsiType type ;
235
256
final AnsiOutputStream .IoRunnable installer ;
@@ -238,6 +259,7 @@ private static AnsiPrintStream ansiStream(boolean stdout) {
238
259
processor = null ;
239
260
type = withException ? AnsiType .Unsupported : AnsiType .Redirected ;
240
261
installer = uninstaller = null ;
262
+ width = new AnsiOutputStream .ZeroWidthSupplier ();
241
263
}
242
264
else if (IS_WINDOWS ) {
243
265
final long console = GetStdHandle (stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
@@ -287,6 +309,14 @@ else if (IS_CONEMU || IS_CYGWIN || IS_MSYSTEM) {
287
309
type = ttype ;
288
310
installer = uninstaller = null ;
289
311
}
312
+ width = new AnsiOutputStream .WidthSupplier () {
313
+ @ Override
314
+ public int getTerminalWidth () {
315
+ CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO ();
316
+ GetConsoleScreenBufferInfo (console , info );
317
+ return info .windowWidth ();
318
+ }
319
+ };
290
320
}
291
321
292
322
// We must be on some Unix variant...
@@ -295,6 +325,14 @@ else if (IS_CONEMU || IS_CYGWIN || IS_MSYSTEM) {
295
325
processor = null ;
296
326
type = AnsiType .Native ;
297
327
installer = uninstaller = null ;
328
+ width = new AnsiOutputStream .WidthSupplier () {
329
+ @ Override
330
+ public int getTerminalWidth () {
331
+ WinSize sz = new WinSize ();
332
+ ioctl (fd , CLibrary .TIOCGWINSZ , sz );
333
+ return sz .ws_col ;
334
+ }
335
+ };
298
336
}
299
337
300
338
AnsiMode mode ;
@@ -377,7 +415,7 @@ else if (term != null && term.contains("-256color")) {
377
415
} catch (UnsupportedCharsetException e ) {
378
416
}
379
417
}
380
- return newPrintStream (new AnsiOutputStream (out , mode , processor , type , colors , cs ,
418
+ return newPrintStream (new AnsiOutputStream (out , width , mode , processor , type , colors , cs ,
381
419
installer , uninstaller , resetAtUninstall ), cs .name ());
382
420
}
383
421
0 commit comments