@harryisfish/gitt 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/display.js +70 -8
- package/dist/index.js +30 -3
- package/package.json +1 -1
package/dist/display.js
CHANGED
|
@@ -4,35 +4,59 @@ exports.display = void 0;
|
|
|
4
4
|
const readline_1 = require("readline");
|
|
5
5
|
// ANSI 转义序列
|
|
6
6
|
const CLEAR_SCREEN = '\x1b[2J';
|
|
7
|
+
const CLEAR_SCREEN_AND_SCROLLBACK = '\x1b[2J\x1b[3J';
|
|
7
8
|
const MOVE_TO_TOP = '\x1b[H';
|
|
8
9
|
const SAVE_CURSOR = '\x1b[s';
|
|
9
10
|
const RESTORE_CURSOR = '\x1b[u';
|
|
10
11
|
const HIDE_CURSOR = '\x1b[?25l';
|
|
11
12
|
const SHOW_CURSOR = '\x1b[?25h';
|
|
13
|
+
const ALTERNATE_SCREEN_BUFFER = '\x1b[?1049h';
|
|
14
|
+
const NORMAL_SCREEN_BUFFER = '\x1b[?1049l';
|
|
12
15
|
class DisplayManager {
|
|
13
16
|
constructor() {
|
|
14
17
|
this.statusSection = [];
|
|
15
18
|
this.menuSection = [];
|
|
16
19
|
this.dividerLine = '';
|
|
17
20
|
this.isLoading = true;
|
|
21
|
+
this.isDetailedView = false;
|
|
18
22
|
// 获取终端大小
|
|
19
|
-
|
|
23
|
+
this.terminalSize = { rows: process.stdout.rows, columns: process.stdout.columns };
|
|
20
24
|
// 创建分隔线
|
|
21
|
-
this.
|
|
22
|
-
// 计算上下区域的大小
|
|
23
|
-
this.statusHeight =
|
|
24
|
-
this.menuHeight = rows - this.statusHeight - 1;
|
|
25
|
+
this.updateDividerLine();
|
|
26
|
+
// 计算上下区域的大小 - 状态区域只占一行
|
|
27
|
+
this.statusHeight = 1;
|
|
28
|
+
this.menuHeight = this.terminalSize.rows - this.statusHeight - 1;
|
|
29
|
+
// 监听终端大小变化
|
|
30
|
+
process.stdout.on('resize', () => {
|
|
31
|
+
this.terminalSize = { rows: process.stdout.rows, columns: process.stdout.columns };
|
|
32
|
+
this.updateDividerLine();
|
|
33
|
+
this.menuHeight = this.terminalSize.rows - this.statusHeight - 1;
|
|
34
|
+
if (!this.isDetailedView) {
|
|
35
|
+
this.redrawScreen();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
updateDividerLine() {
|
|
40
|
+
this.dividerLine = '─'.repeat(this.terminalSize.columns);
|
|
25
41
|
}
|
|
26
42
|
// 清屏并初始化显示区域
|
|
27
43
|
initDisplay() {
|
|
28
|
-
|
|
44
|
+
// 切换到备用屏幕缓冲区,实现全屏模式
|
|
45
|
+
process.stdout.write(ALTERNATE_SCREEN_BUFFER);
|
|
46
|
+
process.stdout.write(CLEAR_SCREEN_AND_SCROLLBACK + MOVE_TO_TOP);
|
|
47
|
+
process.stdout.write(HIDE_CURSOR);
|
|
29
48
|
this.drawDivider();
|
|
30
49
|
this.showLoadingStatus();
|
|
50
|
+
// 确保程序退出时恢复终端状态
|
|
51
|
+
process.on('exit', () => {
|
|
52
|
+
process.stdout.write(SHOW_CURSOR);
|
|
53
|
+
process.stdout.write(NORMAL_SCREEN_BUFFER);
|
|
54
|
+
});
|
|
31
55
|
}
|
|
32
56
|
// 绘制分隔线
|
|
33
57
|
drawDivider() {
|
|
34
58
|
process.stdout.write(SAVE_CURSOR);
|
|
35
|
-
process.stdout.write(`\x1b[${this.statusHeight}H${this.dividerLine}`);
|
|
59
|
+
process.stdout.write(`\x1b[${this.statusHeight + 1}H${this.dividerLine}`);
|
|
36
60
|
process.stdout.write(RESTORE_CURSOR);
|
|
37
61
|
}
|
|
38
62
|
// 显示加载状态
|
|
@@ -48,6 +72,29 @@ class DisplayManager {
|
|
|
48
72
|
this.statusSection = lines;
|
|
49
73
|
this.refreshStatus();
|
|
50
74
|
}
|
|
75
|
+
// 更新简洁状态栏
|
|
76
|
+
updateCompactStatus(branchName, uncommittedChanges, ahead, behind) {
|
|
77
|
+
this.isLoading = false;
|
|
78
|
+
const statusLine = `🌿 ${branchName} | 📝 ${uncommittedChanges} | ⬆️ ${ahead} | ⬇️ ${behind}`;
|
|
79
|
+
this.statusSection = [statusLine];
|
|
80
|
+
this.refreshStatus();
|
|
81
|
+
}
|
|
82
|
+
// 显示详细状态信息
|
|
83
|
+
showDetailedStatus(lines) {
|
|
84
|
+
this.isDetailedView = true;
|
|
85
|
+
process.stdout.write(CLEAR_SCREEN + MOVE_TO_TOP);
|
|
86
|
+
lines.forEach(line => {
|
|
87
|
+
process.stdout.write(line + '\n');
|
|
88
|
+
});
|
|
89
|
+
process.stdout.write('\n按任意键返回主菜单...');
|
|
90
|
+
// 监听一次按键事件
|
|
91
|
+
process.stdin.setRawMode(true);
|
|
92
|
+
process.stdin.once('data', () => {
|
|
93
|
+
process.stdin.setRawMode(false);
|
|
94
|
+
this.isDetailedView = false;
|
|
95
|
+
this.redrawScreen();
|
|
96
|
+
});
|
|
97
|
+
}
|
|
51
98
|
// 刷新状态区域显示
|
|
52
99
|
refreshStatus() {
|
|
53
100
|
process.stdout.write(SAVE_CURSOR);
|
|
@@ -64,9 +111,24 @@ class DisplayManager {
|
|
|
64
111
|
});
|
|
65
112
|
process.stdout.write(RESTORE_CURSOR);
|
|
66
113
|
}
|
|
114
|
+
// 重绘整个屏幕
|
|
115
|
+
redrawScreen() {
|
|
116
|
+
process.stdout.write(CLEAR_SCREEN + MOVE_TO_TOP);
|
|
117
|
+
this.drawDivider();
|
|
118
|
+
this.refreshStatus();
|
|
119
|
+
this.prepareForMenu();
|
|
120
|
+
}
|
|
67
121
|
// 准备菜单区域
|
|
68
122
|
prepareForMenu() {
|
|
69
|
-
|
|
123
|
+
// 将光标移动到分隔线下方
|
|
124
|
+
process.stdout.write(`\x1b[${this.statusHeight + 2}H`);
|
|
125
|
+
// 清除菜单区域
|
|
126
|
+
for (let i = this.statusHeight + 2; i < this.terminalSize.rows; i++) {
|
|
127
|
+
process.stdout.write(`\x1b[${i}H`);
|
|
128
|
+
(0, readline_1.clearLine)(process.stdout, 0);
|
|
129
|
+
}
|
|
130
|
+
// 重新定位到菜单开始位置
|
|
131
|
+
process.stdout.write(`\x1b[${this.statusHeight + 2}H`);
|
|
70
132
|
}
|
|
71
133
|
// 显示错误信息
|
|
72
134
|
showError(message) {
|
package/dist/index.js
CHANGED
|
@@ -53,6 +53,25 @@ async function checkGitRepo() {
|
|
|
53
53
|
}
|
|
54
54
|
// 异步获取并展示仓库状态信息
|
|
55
55
|
async function showRepoStatus() {
|
|
56
|
+
try {
|
|
57
|
+
// 获取当前分支信息
|
|
58
|
+
const currentBranch = await git.branch();
|
|
59
|
+
const currentBranchName = currentBranch.current;
|
|
60
|
+
// 获取最新的远程分支信息
|
|
61
|
+
await git.fetch(['--all']);
|
|
62
|
+
// 获取本地与远程的差异统计
|
|
63
|
+
const status = await git.status();
|
|
64
|
+
const uncommittedChanges = status.modified.length + status.not_added.length + status.deleted.length;
|
|
65
|
+
// 更新简洁状态栏
|
|
66
|
+
display_1.display.updateCompactStatus(currentBranchName, uncommittedChanges, status.ahead, status.behind);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const errorMessage = error instanceof Error ? error.message : '未知错误';
|
|
70
|
+
display_1.display.showError(`获取仓库状态信息时发生错误: ${errorMessage}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// 显示详细的仓库状态信息
|
|
74
|
+
async function showDetailedRepoStatus() {
|
|
56
75
|
try {
|
|
57
76
|
const statusLines = [];
|
|
58
77
|
// 获取当前分支信息
|
|
@@ -86,8 +105,8 @@ async function showRepoStatus() {
|
|
|
86
105
|
statusLines.push('🌳 分支信息:');
|
|
87
106
|
statusLines.push(`- 本地分支数: ${localBranches}`);
|
|
88
107
|
statusLines.push(`- 远程分支数: ${remoteBranches}`);
|
|
89
|
-
//
|
|
90
|
-
display_1.display.
|
|
108
|
+
// 显示详细状态
|
|
109
|
+
display_1.display.showDetailedStatus(statusLines);
|
|
91
110
|
}
|
|
92
111
|
catch (error) {
|
|
93
112
|
const errorMessage = error instanceof Error ? error.message : '未知错误';
|
|
@@ -133,6 +152,11 @@ async function showMenu() {
|
|
|
133
152
|
const action = await (0, prompts_1.select)({
|
|
134
153
|
message: '请选择要执行的操作:',
|
|
135
154
|
choices: [
|
|
155
|
+
{
|
|
156
|
+
name: '查看详细状态',
|
|
157
|
+
value: 'status',
|
|
158
|
+
description: '查看仓库的详细状态信息,包括提交记录和分支统计'
|
|
159
|
+
},
|
|
136
160
|
{
|
|
137
161
|
name: '清理远程已删除的分支',
|
|
138
162
|
value: 'clean',
|
|
@@ -169,7 +193,10 @@ async function main() {
|
|
|
169
193
|
console.log('再见!');
|
|
170
194
|
process.exit(0);
|
|
171
195
|
}
|
|
172
|
-
if (action === '
|
|
196
|
+
if (action === 'status') {
|
|
197
|
+
await showDetailedRepoStatus();
|
|
198
|
+
}
|
|
199
|
+
else if (action === 'clean') {
|
|
173
200
|
await cleanDeletedBranches();
|
|
174
201
|
}
|
|
175
202
|
console.log('\n');
|