UNPKG

@harryisfish/gitt

Version:

这是一个命令行工具,用于帮助你管理 Git 仓库与远端仓库,如保持同步、推送、拉取等。

140 lines (139 loc) 5.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.display = void 0; const readline_1 = require("readline"); // ANSI 转义序列 const CLEAR_SCREEN = '\x1b[2J'; const CLEAR_SCREEN_AND_SCROLLBACK = '\x1b[2J\x1b[3J'; const MOVE_TO_TOP = '\x1b[H'; const SAVE_CURSOR = '\x1b[s'; const RESTORE_CURSOR = '\x1b[u'; const HIDE_CURSOR = '\x1b[?25l'; const SHOW_CURSOR = '\x1b[?25h'; const ALTERNATE_SCREEN_BUFFER = '\x1b[?1049h'; const NORMAL_SCREEN_BUFFER = '\x1b[?1049l'; class DisplayManager { constructor() { this.statusSection = []; this.menuSection = []; this.dividerLine = ''; this.isLoading = true; this.isDetailedView = false; // 获取终端大小 this.terminalSize = { rows: process.stdout.rows, columns: process.stdout.columns }; // 创建分隔线 this.updateDividerLine(); // 计算上下区域的大小 - 状态区域只占一行 this.statusHeight = 1; this.menuHeight = this.terminalSize.rows - this.statusHeight - 1; // 监听终端大小变化 process.stdout.on('resize', () => { this.terminalSize = { rows: process.stdout.rows, columns: process.stdout.columns }; this.updateDividerLine(); this.menuHeight = this.terminalSize.rows - this.statusHeight - 1; if (!this.isDetailedView) { this.redrawScreen(); } }); } updateDividerLine() { this.dividerLine = '─'.repeat(this.terminalSize.columns); } // 清屏并初始化显示区域 initDisplay() { // 切换到备用屏幕缓冲区,实现全屏模式 process.stdout.write(ALTERNATE_SCREEN_BUFFER); process.stdout.write(CLEAR_SCREEN_AND_SCROLLBACK + MOVE_TO_TOP); process.stdout.write(HIDE_CURSOR); this.drawDivider(); this.showLoadingStatus(); // 确保程序退出时恢复终端状态 process.on('exit', () => { process.stdout.write(SHOW_CURSOR); process.stdout.write(NORMAL_SCREEN_BUFFER); }); } // 绘制分隔线 drawDivider() { process.stdout.write(SAVE_CURSOR); process.stdout.write(`\x1b[${this.statusHeight + 1}H${this.dividerLine}`); process.stdout.write(RESTORE_CURSOR); } // 显示加载状态 showLoadingStatus() { if (this.isLoading) { process.stdout.write(MOVE_TO_TOP); process.stdout.write('正在获取仓库信息...\n'); } } // 更新状态区域内容 updateStatus(lines) { this.isLoading = false; this.statusSection = lines; this.refreshStatus(); } // 更新简洁状态栏 updateCompactStatus(branchName, uncommittedChanges, ahead, behind) { this.isLoading = false; const statusLine = `🌿 ${branchName} | 📝 ${uncommittedChanges} | ⬆️ ${ahead} | ⬇️ ${behind}`; this.statusSection = [statusLine]; this.refreshStatus(); } // 显示详细状态信息 showDetailedStatus(lines) { this.isDetailedView = true; process.stdout.write(CLEAR_SCREEN + MOVE_TO_TOP); lines.forEach(line => { process.stdout.write(line + '\n'); }); process.stdout.write('\n按任意键返回主菜单...'); // 监听一次按键事件 process.stdin.setRawMode(true); process.stdin.once('data', () => { process.stdin.setRawMode(false); this.isDetailedView = false; this.redrawScreen(); }); } // 刷新状态区域显示 refreshStatus() { process.stdout.write(SAVE_CURSOR); process.stdout.write(MOVE_TO_TOP); // 清空状态区域 for (let i = 0; i < this.statusHeight; i++) { (0, readline_1.clearLine)(process.stdout, 0); process.stdout.write('\n'); } // 重新显示状态信息 process.stdout.write(MOVE_TO_TOP); this.statusSection.forEach(line => { process.stdout.write(line + '\n'); }); process.stdout.write(RESTORE_CURSOR); } // 重绘整个屏幕 redrawScreen() { process.stdout.write(CLEAR_SCREEN + MOVE_TO_TOP); this.drawDivider(); this.refreshStatus(); this.prepareForMenu(); } // 准备菜单区域 prepareForMenu() { // 将光标移动到分隔线下方 process.stdout.write(`\x1b[${this.statusHeight + 2}H`); // 清除菜单区域 for (let i = this.statusHeight + 2; i < this.terminalSize.rows; i++) { process.stdout.write(`\x1b[${i}H`); (0, readline_1.clearLine)(process.stdout, 0); } // 重新定位到菜单开始位置 process.stdout.write(`\x1b[${this.statusHeight + 2}H`); } // 显示错误信息 showError(message) { const currentPos = process.stdout.rows; process.stdout.write(`\x1b[${currentPos}H\x1b[31m${message}\x1b[0m\n`); } } exports.display = new DisplayManager();