TerminalDisplayWin::~TerminalDisplayWin() { if (IsTTY()) { ::SetConsoleTextAttribute(fOut, fDefaultAttributes); // We allocated CONOUT$: CloseHandle(fOut); } }
void TerminalDisplay::NotifyTextChange(Range r) { if (!IsTTY()) return; Attach(); WriteWrapped(r.fPromptUpdate,GetContext()->GetTextInput()->IsInputHidden(), r.fStart, r.fLength); Move(GetCursor()); }
void TerminalDisplayWin::Detach() { if (!fIsAttached) return; if (IsTTY() && !SetConsoleMode(fOut, fOldMode)) { ShowError("detaching to console output"); } TerminalDisplay::Detach(); fIsAttached = false; }
void TerminalDisplay::NotifyResetInput() { Attach(); if (IsTTY()) { WriteRawString("\n", 1); } fWriteLen = 0; fWritePos = Pos(); }
void TerminalDisplayWin::HandleResizeEvent() { if (IsTTY()) { CONSOLE_SCREEN_BUFFER_INFO Info; if (!::GetConsoleScreenBufferInfo(fOut, &Info)) { ShowError("resize / getting console info"); return; } SetWidth(Info.dwSize.X); } }
void TerminalDisplayUnix::MoveInternal(char What, size_t n) { static const char cmd[] = "\x1b["; if (!IsTTY()) return; std::string text; for (size_t i = 0; i < n; ++i) { text += cmd; text += What; } WriteRawString(text.c_str(), text.length()); }
void TerminalDisplayWin::WriteRawString(const char *text, size_t len) { DWORD NumWritten = 0; if (IsTTY()) { WriteConsole(fOut, text, (DWORD) len, &NumWritten, NULL); } else { WriteFile(fOut, text, (DWORD) len, &NumWritten, NULL); } if (NumWritten != len) { ShowError("writing to output"); } }
void TerminalDisplayWin::Attach() { // set to noecho if (fIsAttached) return; if (IsTTY() && !::SetConsoleMode(fOut, fMyMode)) { ShowError("attaching to console output"); } CONSOLE_SCREEN_BUFFER_INFO Info; if (IsTTY()) { if (!::GetConsoleScreenBufferInfo(fOut, &Info)) { ShowError("attaching / getting console info"); } else { fStartLine = Info.dwCursorPosition.Y; if (Info.dwCursorPosition.X) { // Whooa - where are we?! Newline and cross fingers: WriteRawString("\n", 1); ++fStartLine; } } } fIsAttached = true; }
size_t TerminalDisplay::WriteWrapped(Range::EPromptUpdate PromptUpdate, bool hidden, size_t Offset, size_t Requested /* = -1*/) { Attach(); const Text& Prompt = GetContext()->GetPrompt(); size_t PromptLen = GetContext()->GetPrompt().length(); const Text& EditPrompt = GetContext()->GetEditor()->GetEditorPrompt(); size_t EditorPromptLen = EditPrompt.length(); if (!IsTTY()) { PromptLen = 0; EditorPromptLen = 0; PromptUpdate = Range::kNoPromptUpdate; } if (PromptUpdate & Range::kUpdatePrompt) { // Writing from front means we write the prompt, too Move(Pos()); WriteWrappedElement(Prompt, 0, 0, PromptLen); } if (PromptUpdate != Range::kNoPromptUpdate) { // Any prompt update means we'll have to re-write the editor prompt Move(IndexToPos(PromptLen)); if (EditorPromptLen) { WriteWrappedElement(EditPrompt, 0, PromptLen, EditorPromptLen); } // Any prompt update means we'll have to re-write the text Offset = 0; Requested = (size_t) -1; } Move(IndexToPos(PromptLen + EditorPromptLen + Offset)); size_t avail = 0; if (hidden) { Text hide(std::string(GetContext()->GetLine().length(), '*'), 0); avail = WriteWrappedElement(hide, Offset, PromptLen + EditorPromptLen, Requested); } else { avail = WriteWrappedElement(GetContext()->GetLine(), Offset, PromptLen + EditorPromptLen, Requested); } fWriteLen = PromptLen + EditorPromptLen + GetContext()->GetLine().length(); return avail; }
void TerminalDisplayUnix::SetColor(char CIdx, const Color& C) { if (!IsTTY()) return; // Default color, reset previous bold etc. static const char text[] = {(char)0x1b, '[', '0', 'm'}; WriteRawString(text, sizeof(text)); if (CIdx == 0) return; if (fNColors == 256) { int ANSIIdx = GetClosestColorIdx256(C); static const char preamble[] = {'\x1b', '[', '3', '8', ';', '5', ';', 0}; std::string buf(preamble); if (ANSIIdx > 100) { buf += '0' + (ANSIIdx / 100); } if (ANSIIdx > 10) { buf += '0' + ((ANSIIdx / 10) % 10); } buf += '0' + (ANSIIdx % 10); buf += "m"; WriteRawString(buf.c_str(), buf.length()); } else { int ANSIIdx = GetClosestColorIdx16(C); char buf[] = {'\x1b', '[', '3', static_cast<char>('0' + (ANSIIdx % 8)), 'm', 0}; if (ANSIIdx > 7) buf[2] += 6; WriteRawString(buf, 5); } if (C.fModifiers & Color::kModUnderline) { WriteRawString("\033[4m", 4); } if (C.fModifiers & Color::kModBold) { WriteRawString("\033[1m", 4); } if (C.fModifiers & Color::kModInverse) { WriteRawString("\033[7m", 4); } }
TerminalDisplayWin::~TerminalDisplayWin() { if (IsTTY()) { // We allocated CONOUT$: CloseHandle(fOut); } }
//////////////////////////////////////////////////////////////////////////////// /// Invoke this on EOL. Writes out space backspace, to wrap to the next line. /// Otherwise, we stay on the same line and the input gets pushed upwards. void TerminalDisplayUnix::ActOnEOL() { if (!IsTTY()) return; WriteRawString(" \b", 2); //MoveUp(); }
//////////////////////////////////////////////////////////////////////////////// /// Erases the input to the right of the cursor. void TerminalDisplayUnix::EraseToRight() { static const char text[] = {(char)0x1b, '[', 'K'}; // ESC[K if (!IsTTY()) return; WriteRawString(text, sizeof(text)); }
void TerminalDisplayUnix::MoveFront() { static const char text[] = {(char)0x1b, '[', '1', 'G'}; if (!IsTTY()) return; WriteRawString(text, sizeof(text)); }