ttx 0.1.0
Loading...
Searching...
No Matches
pane.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/container/string/string_view.h"
4#include "di/container/tree/tree_map.h"
5#include "di/container/vector/vector.h"
6#include "di/function/container/function.h"
7#include "di/sync/atomic.h"
8#include "di/sync/synchronized.h"
9#include "di/vocab/error/result.h"
10#include "di/vocab/pointer/box.h"
11#include "dius/sync_file.h"
12#include "dius/system/process.h"
13#include "dius/thread.h"
14#include "ttx/direction.h"
15#include "ttx/key_event.h"
16#include "ttx/mouse.h"
18#include "ttx/paste_event.h"
19#include "ttx/renderer.h"
20#include "ttx/size.h"
21#include "ttx/terminal.h"
24
25namespace ttx {
26class Pane;
27
28struct PaneHooks {
30 di::Function<void(Pane&, di::Optional<dius::system::ProcessResult>)> did_exit;
31
33 di::Function<void(Pane&)> did_update;
34
36 di::Function<void(terminal::OSC52, bool)> did_selection;
37
39 di::Function<void(di::StringView)> apc_passthrough;
40
42 di::Function<void(di::StringView)> did_finish_output;
43
45 di::Function<void()> did_update_cwd;
46};
47
49 auto clone() const -> CreatePaneArgs {
50 // NOTE: the hooks aren't cloned.
51 return { command.clone(),
53 replay_path.clone(),
54 save_state_path.clone(),
55 pipe_input.clone(),
56 cwd.clone(),
57 terminfo_dir.clone(),
58 term,
60 mock,
61 {} };
62 }
63
64 auto with_cwd(di::Optional<di::Path> cwd) const& -> CreatePaneArgs {
65 auto result = clone();
66 result.cwd = di::move(cwd);
67 return result;
68 }
69
70 di::Vector<di::TransparentString> command {};
71 di::Optional<di::Path> capture_command_output_path {};
72 di::Optional<di::Path> replay_path {};
73 di::Optional<di::Path> save_state_path {};
74 di::Optional<di::String> pipe_input {};
75 di::Optional<di::Path> cwd {};
76 di::Optional<di::Path> terminfo_dir {};
77 di::TransparentStringView term { "xterm-ttx"_tsv };
78 bool pipe_output { false };
79 bool mock { false };
81};
82
83class Pane {
84public:
85 static auto create_from_replay(u64 id, di::Optional<di::Path> cwd, di::PathView replay_path,
86 di::Optional<di::Path> save_state_path, Size const& size, PaneHooks hooks)
87 -> di::Result<di::Box<Pane>>;
88 static auto create(u64 id, CreatePaneArgs args, Size const& size) -> di::Result<di::Box<Pane>>;
89
90 // For testing, create a mock pane. This doesn't actually create a psuedo terminal or a subprocess.
91 static auto create_mock(u64 id = 0, di::Optional<di::Path> cwd = {}) -> di::Box<Pane>;
92
93 explicit Pane(u64 id, di::Optional<di::Path> cwd, dius::SyncFile pty_controller, Size const& size,
94 dius::system::ProcessHandle process, PaneHooks hooks)
95 : m_id(id)
96 , m_pty_controller(di::move(pty_controller))
97 , m_terminal(di::in_place, id, m_pty_controller, size)
98 , m_process(process)
99 , m_cwd(di::move(cwd))
100 , m_hooks(di::move(hooks)) {}
101 ~Pane();
102
103 auto id() const { return m_id; }
104 auto draw(Renderer& renderer) -> RenderedCursor;
105
106 auto event(KeyEvent const& event) -> bool;
107 auto event(MouseEvent const& event) -> bool;
108 auto event(FocusEvent const& event) -> bool;
109 auto event(PasteEvent const& event) -> bool;
110
111 void invalidate_all();
112 void resize(Size const& size);
113 void scroll(Direction direction, i32 amount_in_cells);
114 auto save_state(di::PathView path) -> di::Result<>;
115 void send_clipboard(terminal::SelectionType selection_type, di::Vector<byte> data);
116 void stop_capture();
117 void soft_reset();
118 void exit();
119
125 auto current_working_directory() const -> di::Optional<di::PathView> { return m_cwd.transform(&di::Path::view); }
126
127private:
128 void update_cwd(terminal::OSC7&& path_with_hostname);
129 void reset_viewport_scroll();
130
131 u64 m_id { 0 };
132 di::Atomic<bool> m_done { false };
133 di::Atomic<bool> m_capture { true };
134 di::Optional<MousePosition> m_last_mouse_position;
135 di::Optional<terminal::SelectionPoint> m_pending_selection_start;
136 MouseClickTracker m_mouse_click_tracker { 3 };
137 dius::SyncFile m_pty_controller;
138 di::Function<void()> m_restore_termios;
139 di::Synchronized<Terminal> m_terminal;
140 dius::system::ProcessHandle m_process;
141
142 u32 m_vertical_scroll_offset { 0 };
143 u32 m_horizontal_scroll_offset { 0 };
144
145 di::Optional<di::Path> m_cwd;
146 PaneHooks m_hooks;
147
148 // These are declared last, for when dius::Thread calls join() in the destructor.
149 dius::Thread m_process_thread;
150 dius::Thread m_reader_thread;
151 dius::Thread m_pipe_writer_thread;
152 dius::Thread m_pipe_reader_thread;
153};
154}
Definition focus_event.h:7
Definition key_event.h:24
Definition mouse_event.h:23
Definition pane.h:83
void resize(Size const &size)
Definition pane.cpp:533
void exit()
Definition pane.cpp:650
void soft_reset()
Definition pane.cpp:622
void send_clipboard(terminal::SelectionType selection_type, di::Vector< byte > data)
Definition pane.cpp:609
void stop_capture()
Definition pane.cpp:618
auto save_state(di::PathView path) -> di::Result<>
Definition pane.cpp:601
static auto create_from_replay(u64 id, di::Optional< di::Path > cwd, di::PathView replay_path, di::Optional< di::Path > save_state_path, Size const &size, PaneHooks hooks) -> di::Result< di::Box< Pane > >
Definition pane.cpp:63
void invalidate_all()
Definition pane.cpp:527
~Pane()
Definition pane.cpp:289
static auto create(u64 id, CreatePaneArgs args, Size const &size) -> di::Result< di::Box< Pane > >
Definition pane.cpp:127
static auto create_mock(u64 id=0, di::Optional< di::Path > cwd={}) -> di::Box< Pane >
Definition pane.cpp:283
auto id() const
Definition pane.h:103
void scroll(Direction direction, i32 amount_in_cells)
Definition pane.cpp:540
auto current_working_directory() const -> di::Optional< di::PathView >
Get the pane's current working directory.
Definition pane.h:125
auto draw(Renderer &renderer) -> RenderedCursor
Definition pane.cpp:299
Pane(u64 id, di::Optional< di::Path > cwd, dius::SyncFile pty_controller, Size const &size, dius::system::ProcessHandle process, PaneHooks hooks)
Definition pane.h:93
auto event(KeyEvent const &event) -> bool
Definition pane.cpp:378
Definition paste_event.h:8
Definition renderer.h:23
SelectionType
Represents the type of selection being modifed by an OSC 52 sequence.
Definition osc_52.h:8
Definition clipboard.h:10
Direction
Definition direction.h:7
Definition pane.h:48
bool pipe_output
Definition pane.h:78
di::TransparentStringView term
Definition pane.h:77
di::Optional< di::Path > cwd
Definition pane.h:75
di::Optional< di::Path > capture_command_output_path
Definition pane.h:71
di::Optional< di::Path > replay_path
Definition pane.h:72
PaneHooks hooks
Definition pane.h:80
di::Vector< di::TransparentString > command
Definition pane.h:70
bool mock
Definition pane.h:79
auto with_cwd(di::Optional< di::Path > cwd) const &-> CreatePaneArgs
Definition pane.h:64
di::Optional< di::String > pipe_input
Definition pane.h:74
di::Optional< di::Path > terminfo_dir
Definition pane.h:76
di::Optional< di::Path > save_state_path
Definition pane.h:73
auto clone() const -> CreatePaneArgs
Definition pane.h:49
Definition pane.h:28
di::Function< void(di::StringView)> did_finish_output
Callback with the results on reading from the output pipe.
Definition pane.h:42
di::Function< void(terminal::OSC52, bool)> did_selection
Application controlled callback when a clipboard set/request is invoked.
Definition pane.h:36
di::Function< void()> did_update_cwd
Callback when the pane's current working directory changes.
Definition pane.h:45
di::Function< void(Pane &, di::Optional< dius::system::ProcessResult >)> did_exit
Application controlled callback when the internal process exits.
Definition pane.h:30
di::Function< void(di::StringView)> apc_passthrough
Application controlled callback when APC command is set.
Definition pane.h:39
di::Function< void(Pane &)> did_update
controlled callback when the terminal buffer has updated.
Definition pane.h:33
Definition renderer.h:14
Definition size.h:7
Represents an OSC 52 sequence, which allows for modifying or querying the clipboard.
Definition osc_52.h:51
Represents a application current working directory report.
Definition osc_7.h:14