@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 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
- const { rows, columns } = process.stdout;
23
+ this.terminalSize = { rows: process.stdout.rows, columns: process.stdout.columns };
20
24
  // 创建分隔线
21
- this.dividerLine = '─'.repeat(columns);
22
- // 计算上下区域的大小
23
- this.statusHeight = Math.floor(rows / 2) - 1;
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
- process.stdout.write(CLEAR_SCREEN + MOVE_TO_TOP);
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
- process.stdout.write(`\x1b[${this.statusHeight + 1}H\n`);
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.updateStatus(statusLines);
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 === 'clean') {
196
+ if (action === 'status') {
197
+ await showDetailedRepoStatus();
198
+ }
199
+ else if (action === 'clean') {
173
200
  await cleanDeletedBranches();
174
201
  }
175
202
  console.log('\n');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harryisfish/gitt",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "这是一个命令行工具,用于帮助你管理 Git 仓库与远端仓库,如保持同步、推送、拉取等。",
5
5
  "main": "dist/index.js",
6
6
  "bin": {