UNPKG

git-suggest

Version:

A lightweight command-line tool that automatically generates contextual, high-quality Git commit messages based on your staged code changes. Powered by GitHub Copilot CLI, it helps you write smarter commits with less typing.

207 lines (200 loc) 7.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupShellIntegration = setupShellIntegration; const fs_1 = require("fs"); const path_1 = require("path"); const chalk_1 = __importDefault(require("chalk")); const inquirer_1 = __importDefault(require("inquirer")); async function setupShellIntegration(options) { console.log(chalk_1.default.blue('Setting up shell integration for git-suggest...')); const shell = options.shell === 'auto' ? await detectShell() : options.shell; console.log(chalk_1.default.gray(`Detected shell: ${shell}`)); try { switch (shell) { case 'bash': await setupBashIntegration(); break; case 'zsh': await setupZshIntegration(); break; case 'fish': await setupFishIntegration(); break; default: throw new Error(`Unsupported shell: ${shell}`); } console.log(chalk_1.default.green('✓ Shell integration setup complete!')); console.log(chalk_1.default.blue('\nRestart your terminal or run:')); console.log(chalk_1.default.white(`source ~/.${shell}rc`)); console.log(chalk_1.default.blue('\nThen try typing: git commit -m "feat(')); } catch (error) { console.error(chalk_1.default.red('Failed to setup shell integration:'), error); throw error; } } async function detectShell() { const shell = process.env.SHELL || ''; if (shell.includes('zsh')) return 'zsh'; if (shell.includes('fish')) return 'fish'; if (shell.includes('bash')) return 'bash'; // Default to bash if we can't detect return 'bash'; } async function setupBashIntegration() { const bashrcPath = (0, path_1.join)(process.env.HOME || '', '.bashrc'); const profilePath = (0, path_1.join)(process.env.HOME || '', '.bash_profile'); const integrationScript = ` # git-suggest integration _git_suggest_complete() { local cur prev COMPREPLY=() cur="\${COMP_WORDS[COMP_CWORD]}" prev="\${COMP_WORDS[COMP_CWORD-1]}" if [[ "\${COMP_WORDS[1]}" == "commit" && "\${prev}" == "-m" ]]; then # Generate suggestions when user types git commit -m local suggestions suggestions=$(git-suggest generate --no-interactive 2>/dev/null | grep -o '".*"' | tr -d '"' 2>/dev/null || echo "") if [[ -n "\$suggestions" ]]; then COMPREPLY=( $(compgen -W "\$suggestions" -- "\$cur") ) fi fi } # Enable git-suggest completion for git command complete -F _git_suggest_complete git `; await appendToShellConfig(bashrcPath, integrationScript, 'bash'); // Also try .bash_profile for macOS if (process.platform === 'darwin') { try { await appendToShellConfig(profilePath, integrationScript, 'bash'); } catch { // Ignore if .bash_profile doesn't exist or can't be written } } } async function setupZshIntegration() { const zshrcPath = (0, path_1.join)(process.env.HOME || '', '.zshrc'); const integrationScript = ` # git-suggest integration _git_suggest_complete() { local context state line typeset -A opt_args _arguments -C \\ '1:command:->command' \\ '*::arg:->args' && return 0 case \$state in command) _values 'git command' \\ 'commit[Record changes to the repository]' ;; args) case \$line[1] in commit) if [[ \$words[CURRENT-1] == "-m" ]]; then # Generate suggestions when user types git commit -m local suggestions suggestions=($(git-suggest generate --no-interactive 2>/dev/null | grep -o '".*"' | tr -d '"' 2>/dev/null || echo "")) if [[ \${#suggestions[@]} -gt 0 ]]; then _describe 'commit messages' suggestions fi else _git-commit fi ;; esac ;; esac } # Enable git-suggest completion compdef _git_suggest_complete git `; await appendToShellConfig(zshrcPath, integrationScript, 'zsh'); } async function setupFishIntegration() { const fishConfigDir = (0, path_1.join)(process.env.HOME || '', '.config', 'fish'); const completionsDir = (0, path_1.join)(fishConfigDir, 'completions'); // Ensure completions directory exists try { await fs_1.promises.mkdir(completionsDir, { recursive: true }); } catch { // Directory might already exist } const completionScript = ` # git-suggest completion for fish shell function __git_suggest_complete set -l cmd (commandline -opc) if test (count $cmd) -ge 3 if test $cmd[2] = "commit"; and test $cmd[3] = "-m" # Generate suggestions when user types git commit -m set -l suggestions (git-suggest generate --no-interactive 2>/dev/null | grep -o '".*"' | tr -d '"' 2>/dev/null) if test -n "$suggestions" for suggestion in $suggestions echo $suggestion end end end end end # Register completion for git commit -m complete -c git -n '__fish_git_using_command commit' -s m -l message -a '(__git_suggest_complete)' `; const completionPath = (0, path_1.join)(completionsDir, 'git-suggest.fish'); await fs_1.promises.writeFile(completionPath, completionScript); } async function appendToShellConfig(configPath, script, shellName) { const marker = '# git-suggest integration'; try { // Check if file exists and read it let content = ''; try { content = await fs_1.promises.readFile(configPath, 'utf8'); } catch { // File doesn't exist, that's okay } // Check if integration is already present if (content.includes(marker)) { console.log(chalk_1.default.yellow(`⚠ git-suggest integration already exists in ${configPath}`)); const { overwrite } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'overwrite', message: 'Overwrite existing integration?', default: false } ]); if (!overwrite) { return; } // Remove existing integration const lines = content.split('\n'); const startIndex = lines.findIndex(line => line.includes(marker)); if (startIndex !== -1) { const endIndex = lines.findIndex((line, index) => index > startIndex && line.trim() === '' && !lines[index + 1]?.startsWith('#') && !lines[index + 1]?.trim().startsWith('_')); if (endIndex !== -1) { lines.splice(startIndex, endIndex - startIndex + 1); content = lines.join('\n'); } } } // Append new integration const newContent = content + '\n' + script + '\n'; await fs_1.promises.writeFile(configPath, newContent); console.log(chalk_1.default.green(`✓ Added integration to ${configPath}`)); } catch (error) { throw new Error(`Failed to update ${shellName} configuration: ${error instanceof Error ? error.message : error}`); } } //# sourceMappingURL=setup.js.map