-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtool_progress.cpp
More file actions
103 lines (86 loc) · 3.55 KB
/
Copy pathtool_progress.cpp
File metadata and controls
103 lines (86 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "tool_progress.hpp"
#include "tui/text_style.hpp"
#include "tui/theme_palette.hpp"
#include "tui/tool_row_format.hpp"
#include "tui/tool_row_presentation.hpp"
#include <ftxui/dom/elements.hpp>
#include <ftxui/screen/terminal.hpp>
#include <chrono>
#include <string>
namespace acecode {
namespace {
std::string format_bytes(size_t n) {
if (n < 1024) return std::to_string(n) + "B";
if (n < 1024 * 1024) return std::to_string(n / 1024) + "KB";
return std::to_string(n / (1024 * 1024)) + "MB";
}
long elapsed_seconds(std::chrono::steady_clock::time_point start) {
return std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::steady_clock::now() - start).count();
}
} // namespace
ftxui::Element render_tool_progress(const TuiState& state) {
using namespace ftxui;
if (!state.tool_running) return text("");
const auto& p = state.tool_progress;
const long secs = elapsed_seconds(p.start_time);
const int term_cols = Terminal::Size().dimx;
const bool narrow = term_cols > 0 && term_cols < 40;
// Header line:默认 "● Bash",Ctrl+O verbose 时才显示参数预览。
// 执行中指示灯为灰(与配对前的 Pending 态一致)。
std::string preview = p.command_preview;
if (narrow && preview.size() > 20) preview = preview.substr(0, 19) + "\xE2\x80\xA6";
const auto& th = tui::theme();
Elements header_segs;
header_segs.push_back(text(" \xE2\x97\x8F ") | color(th.ui.text_dim)); // "●"
header_segs.push_back(text(tui::pascal_case_tool_name(p.tool_name))
| bold | color(tui::tool_call_name_color(th)));
if (tui::tool_call_arguments_visible(state.transcript_expanded) &&
!preview.empty()) {
const auto arg_color = tui::tool_call_argument_color(th);
header_segs.push_back(text("(") | color(arg_color));
header_segs.push_back(text(preview) | color(arg_color));
header_segs.push_back(text(")") | color(arg_color));
}
Element header = hbox(std::move(header_segs));
// No output yet → single "Running…" line
if (p.tail_lines.empty() && p.current_partial.empty()) {
return vbox({
header,
hbox({
text(" Running\xE2\x80\xA6 ") | dim,
text(std::to_string(secs) + "s") | dim | color(th.ui.accent_alt),
}),
});
}
// Tail lines (up to 5) + current partial
Elements rows;
rows.push_back(header);
for (const auto& line : p.tail_lines) {
rows.push_back(text(" " + line) | dim | color(th.ui.text_muted));
}
if (!p.current_partial.empty()) {
rows.push_back(text(" " + p.current_partial) | dim | color(th.ui.text_muted));
}
// Status line
int shown = static_cast<int>(p.tail_lines.size()) + (p.current_partial.empty() ? 0 : 1);
int extra = std::max(0, p.total_lines - static_cast<int>(p.tail_lines.size()));
std::string status_left;
if (extra > 0) status_left = "+" + std::to_string(extra) + " lines";
Elements status_row;
if (!status_left.empty()) {
status_row.push_back(text(" " + status_left) |
tui::readable_secondary());
} else {
status_row.push_back(text(" ") | dim);
}
status_row.push_back(filler());
status_row.push_back(text(std::to_string(secs) + "s") | dim | color(th.ui.accent_alt));
if (p.total_bytes > 0) {
status_row.push_back(text(" " + format_bytes(p.total_bytes)) | dim);
}
rows.push_back(hbox(std::move(status_row)));
(void)shown;
return vbox(std::move(rows));
}
} // namespace acecode