1 module pp;
2 
3 import std.algorithm;
4 import std.range;
5 import std.stdio;
6 import prettyprint;
7 
8 void main(string[] args)
9 {
10     const columns = terminalColumns;
11 
12     args = args.dropOne; // current executable
13 
14     void processLines(T)(T lines)
15     {
16         lines.each!((const(char)[] line) {
17             writeln(prettyprint.prettyprint(cast(string) line, columns));
18         });
19     }
20 
21     if (args.empty)
22     {
23         processLines(stdin.byLine);
24     }
25     else
26     {
27         // like cat
28         args.each!(arg => processLines(File(arg).byLine));
29     }
30 }
31 
32 private int terminalColumns()
33 {
34     import core.sys.posix.fcntl : O_RDONLY, open;
35     import core.sys.posix.unistd : close;
36 
37     // determine terminal window size even if we're piped
38     int tty_fd = open("/dev/tty", O_RDONLY);
39     winsize w = winsize.init;
40 
41     ioctl((tty_fd != -1) ? tty_fd : 1, TIOCGWINSZ, &w);
42     close(tty_fd);
43 
44     return w.ws_col ? w.ws_col : 80;
45 }
46 
47 private extern(C) int ioctl(int, uint, ...);
48 
49 private struct winsize
50 {
51     ushort ws_row, ws_col;
52     ushort ws_xpixel, ws_ypixel;
53 }
54 
55 private enum TIOCGWINSZ = 0x5413;