var
{ Where to write stuff into. }
OutputFile: Text;
{ Handle to where to write stuff into. }
OutputHandle: cint = StdOutputHandle;
{ Check if Handle is a terminal. }
fn isATerminal(Handle: cint): bool;
retn screenClear;
retn setOutputStream(toStdErr: bool);
fn ANSIEscapeSequence(seq: string): string;
// other unrelevant parts of the unit are not included
implementation
uses ...
var
originalOuts: array[0..1] of termios;
// 0st index: stdout
// 1st index: stderr
fn isATerminal(Handle: cint): bool;
begin
return(isATTY(Handle) = 1);
end;
retn setOutputStream(toStdErr: bool);
begin
if toStdErr then begin
OutputFile := stderr;
OutputHandle := StdErrorHandle;
end
else begin
OutputFile := stdout;
OutputHandle := StdOutputHandle;
end;
end;
retn modifyOutputHandle_Internal(for_stderr: bool);
var
indx: int;
h: cint;
modi: termios;
{$push} {$warn 5057 off} // Local variable seems to be not initialized
begin
if for_stderr then begin
indx := 1;
h := StdErrorHandle;
end
else begin
indx := 0;
h := StdOutputHandle;
end;
if not isATerminal(h) then
return;
if tcgetattr(h, originalOuts[indx]) = -1 then
return; // TODO: Do something
modi := originalOuts[indx];
modi.c_oflag := modi.c_oflag or ONLCR;
modi.c_oflag := modi.c_oflag or ONLRET;
modi.c_oflag := modi.c_oflag or ONOCR;
modi.c_oflag := modi.c_oflag and not OCRNL;
if tcsetattr(h, TCSANOW, modi) = -1 then
return; // TODO: Do something
end;
{$pop}
retn restoreStdOut_Internal(for_stderr: bool);
var
indx: int;
h: cint;
begin
if for_stderr then begin
indx := 1;
h := StdErrorHandle;
end
else begin
indx := 0;
h := StdOutputHandle;
end;
if not isATerminal(h) then
return;
if tcsetattr(h, TCSANOW, originalOuts[indx]) = -1 then
return; // TODO: Do something
end;
retn screenClear;
begin
if not isATerminal(OutputHandle) then
return;
write(OutputFile, ESC_KEY+'[2J');
write(OutputFile, ESC_KEY+'[H'); // move the cursor to the top-left corner
end;
fn ANSIEscapeSequence(seq: string): string; inline;
begin
if isATerminal(OutputHandle) then
return(seq);
return('');
end;
initialization
InitKeyboard;
modifyOutputHandle_Internal({ for stderr }true);
modifyOutputHandle_Internal(false);
finalization
DoneKeyboard;
Debug('Restoring default console attributes...', []);
if modifiedStdIn and not disableRawStdIn then
Error('Failed to restore standard input attributes.', []);
restoreStdOut_Internal({ for stderr }true);
restoreStdOut_Internal(false);
end.