RADLib
RADical C++ application framework
RADTerminal.h
Go to the documentation of this file.
1 #ifndef RADTERMINAL_H
2 #define RADTERMINAL_H
3 
9 #pragma once
10 
11 #include <RADCore/RADLicenseGate.h>
12 
13 #include <atomic>
14 #include <cstddef>
15 #include <cstdint>
16 #include <functional>
17 #include <memory>
18 #include <mutex>
19 #include <string>
20 #include <string_view>
21 #include <thread>
22 #include <vector>
23 
24 namespace RADCore {
26  class RADPtyProcess;
27 }
28 
29 namespace RADUi {
30 
32  struct TerminalColor {
34  uint8_t r = 230;
36  uint8_t g = 237;
38  uint8_t b = 242;
39  };
40 
42  struct TerminalLine {
44  std::string text;
46  TerminalColor foreground{230, 237, 242};
49  };
50 
52  struct TerminalCursor {
54  size_t row = 0;
56  size_t column = 0;
58  bool visible = true;
59  };
60 
63  public:
65  void append(std::string_view bytes);
67  std::vector<TerminalLine> snapshot() const;
69  std::string plainText() const;
71  bool isAlternateScreen() const;
75  void setScreenSize(size_t rows, size_t columns);
77  void clear();
78 
79  private:
80  enum class State {
81  Normal,
82  Escape,
83  Charset,
84  Csi,
85  Osc
86  };
87 
88  void consume(unsigned char byte);
89  void consumeNormal(unsigned char byte);
90  void consumeEscape(unsigned char byte);
91  void consumeCsi(unsigned char byte);
92  std::vector<int> csiParams(int defaultValue = 0) const;
93  bool csiPrivateMode() const;
94  int csiParam(size_t index, int defaultValue = 0) const;
95  void applySgr();
96  void putChar(char ch);
97  void newline();
98  void carriageReturn();
99  void backspace();
100  void cursorUp(size_t count);
101  void cursorDown(size_t count);
102  void cursorForward(size_t count);
103  void cursorBack(size_t count);
104  void setCursor(size_t row, size_t column);
105  void eraseInDisplay(int mode);
106  void eraseInLine(int mode);
107  void setScrollRegion(size_t top, size_t bottom);
108  void resetScrollRegion();
109  void scrollRegionUp(size_t top, size_t bottom, size_t count = 1);
110  void scrollRegionDown(size_t top, size_t bottom, size_t count = 1);
111  void insertLines(size_t count);
112  void deleteLines(size_t count);
113  void insertChars(size_t count);
114  void deleteChars(size_t count);
115  void eraseChars(size_t count);
116  void setPrivateMode(int mode, bool enabled);
117  void enterAlternateScreen();
118  void leaveAlternateScreen();
119  void ensureCursorLine();
120  void trim();
121 
122  mutable std::mutex mutex_;
123  std::vector<TerminalLine> lines_{TerminalLine{}};
124  std::vector<TerminalLine> savedLines_;
125  TerminalColor currentForeground_{230, 237, 242};
126  TerminalColor currentBackground_{16, 20, 24};
127  bool bold_ = false;
128  bool reverse_ = false;
129  bool alternateScreen_ = false;
130  bool cursorVisible_ = true;
131  size_t cursorColumn_ = 0;
132  size_t cursorRow_ = 0;
133  size_t savedCursorColumn_ = 0;
134  size_t savedCursorRow_ = 0;
135  size_t screenRows_ = 30;
136  size_t screenColumns_ = 120;
137  size_t scrollTop_ = 0;
138  size_t scrollBottom_ = 29;
139  State state_ = State::Normal;
140  std::string csi_;
141  };
142 
145  public:
147  explicit PtyTerminalSession(std::function<void()> changed = {});
150 
155 
157  bool start(const std::string& shell = {}, uint16_t rows = 30, uint16_t columns = 120);
159  void stop();
161  bool isRunning() const;
163  bool resize(uint16_t rows, uint16_t columns);
165  bool isAlternateScreen() const;
168 
170  void writeInput(std::string_view input);
172  std::vector<TerminalLine> snapshot() const;
174  std::string plainText() const;
175 
176  private:
177  void readLoop();
178 
179  std::atomic<bool> running_{false};
180  std::thread reader_;
181  TerminalBuffer buffer_;
182  std::function<void()> changed_;
183  std::unique_ptr<RADCore::RADPtyProcess> process_;
184  };
185 
187  std::string terminalInputSequence(std::string_view text, bool alt = false, bool control = false,
188  bool shift = false, bool meta = false);
190  std::string terminalSpecialKeySequence(std::string_view key, bool alt = false, bool control = false,
191  bool shift = false, bool meta = false);
192 
193 } // namespace RADUi
194 
195 #endif
PTY-backed terminal session that feeds output into TerminalBuffer.
Definition: RADTerminal.h:144
bool start(const std::string &shell={}, uint16_t rows=30, uint16_t columns=120)
Starts shell in a PTY sized rows by columns.
bool isRunning() const
Returns true while the PTY session is active.
TerminalCursor cursor() const
Returns current terminal cursor state.
std::string plainText() const
Returns visible terminal text without color metadata.
PtyTerminalSession(std::function< void()> changed={})
Creates a terminal session and optional change callback.
void writeInput(std::string_view input)
Writes user input bytes to the PTY.
PtyTerminalSession & operator=(const PtyTerminalSession &)=delete
Terminal sessions own a PTY and are not copied.
void stop()
Stops the child process and reader thread.
PtyTerminalSession(const PtyTerminalSession &)=delete
Terminal sessions own a PTY and are not copied.
std::vector< TerminalLine > snapshot() const
Returns a copy of visible terminal lines.
bool resize(uint16_t rows, uint16_t columns)
Resizes the PTY and terminal buffer.
bool isAlternateScreen() const
Returns true when the terminal is using its alternate screen.
~PtyTerminalSession()
Stops the session and joins the reader thread.
ANSI/VT-style terminal screen buffer and parser.
Definition: RADTerminal.h:62
std::string plainText() const
Returns visible terminal text without color metadata.
TerminalCursor cursor() const
Returns current cursor state.
void setScreenSize(size_t rows, size_t columns)
Sets visible terminal dimensions.
void append(std::string_view bytes)
Appends raw terminal output bytes and updates screen state.
void clear()
Clears terminal contents and parser state.
bool isAlternateScreen() const
Returns true when the alternate screen buffer is active.
std::vector< TerminalLine > snapshot() const
Returns a copy of visible terminal lines.
Definition: RADCore.h:113
Definition: RADAppKit.h:20
std::string terminalSpecialKeySequence(std::string_view key, bool alt=false, bool control=false, bool shift=false, bool meta=false)
Converts named special keys and modifiers to terminal escape sequences.
std::string terminalInputSequence(std::string_view text, bool alt=false, bool control=false, bool shift=false, bool meta=false)
Converts printable text and modifiers to bytes suitable for a terminal PTY.
RGB terminal color used for a rendered line.
Definition: RADTerminal.h:32
uint8_t g
Green component.
Definition: RADTerminal.h:36
uint8_t b
Blue component.
Definition: RADTerminal.h:38
uint8_t r
Red component.
Definition: RADTerminal.h:34
Terminal cursor location and visibility.
Definition: RADTerminal.h:52
bool visible
Whether the application requested a visible cursor.
Definition: RADTerminal.h:58
size_t row
Zero-based visible row.
Definition: RADTerminal.h:54
size_t column
Zero-based visible column.
Definition: RADTerminal.h:56
One logical terminal line with text and colors.
Definition: RADTerminal.h:42
TerminalColor foreground
Foreground color.
Definition: RADTerminal.h:46
TerminalColor background
Background color.
Definition: RADTerminal.h:48
std::string text
UTF-8/text bytes for the line.
Definition: RADTerminal.h:44