diff --git a/src/commands/restore.ts b/src/commands/restore.ts new file mode 100644 index 0000000..ade7973 --- /dev/null +++ b/src/commands/restore.ts @@ -0,0 +1,110 @@ +import inquirer from 'inquirer'; +import { fileUtils } from '../utils/fileUtils'; +import { tmuxParser, screenParser, iterm2Parser } from '../parsers'; +import { Layout } from '../models/types'; + +interface RestoreOptions { + name: string; + session?: string; + attach?: boolean; + dryRun?: boolean; +} + +export async function restoreLayout(options: RestoreOptions): Promise { + await fileUtils.initialize(); + + let layoutName = options.name; + if (!layoutName) { + const layouts = await fileUtils.listLayouts(); + if (layouts.length === 0) { + throw new Error('No layouts found. Use "save" command first.'); + } + + const { selectedLayout } = await inquirer.prompt([ + { + type: 'list', + name: 'selectedLayout', + message: 'Select a layout to restore:', + choices: layouts, + }, + ]); + layoutName = selectedLayout; + } + + let layout: Layout; + try { + layout = await fileUtils.readLayout(layoutName) as Layout; + } catch (error) { + throw new Error(`Failed to read layout: ${(error as Error).message}`); + } + + const sessionName = options.session || layout.session.name; + console.log(`Restoring layout "${layoutName}" to session "${sessionName}"...`); + + if (options.dryRun) { + const commands = await generateRestoreCommands(layout, sessionName); + console.log('\nGenerated commands (dry run):'); + for (const cmd of commands) { + console.log(` ${cmd}`); + } + return; + } + + let result: { success: boolean; error?: string }; + + switch (layout.terminalType) { + case 'tmux': + result = await tmuxParser.restoreLayout(layout, sessionName); + break; + case 'screen': + result = await screenParser.restoreLayout(layout, sessionName); + break; + case 'iterm2': { + const script = await iterm2Parser.generateRestoreScript(layout); + console.log('iTerm2 restore script:'); + console.log(script); + result = { success: true }; + break; + } + default: + result = await restoreGeneric(layout, sessionName); + } + + if (!result.success) { + throw new Error(`Failed to restore layout: ${result.error}`); + } + + console.log(`Layout restored successfully to session "${sessionName}".`); + + if (options.attach) { + console.log(`To attach to the session, run: tmux attach-session -t ${sessionName}`); + } +} + +async function generateRestoreCommands(layout: Layout, sessionName: string): Promise { + switch (layout.terminalType) { + case 'tmux': + return tmuxParser.generateRestoreCommands(layout, sessionName); + case 'screen': + return screenParser.generateRestoreCommands(layout, sessionName); + default: + return [`# Unknown terminal type: ${layout.terminalType}`]; + } +} + +async function restoreGeneric(layout: Layout, sessionName: string): Promise<{ success: boolean; error?: string }> { + try { + const commands = [`# Generic restore for ${layout.terminalType}`, `session_name="${sessionName}"`]; + for (const window of layout.session.windows) { + commands.push(`# Window: ${window.name}`); + for (const pane of window.panes) { + if (pane.command) { + commands.push(`# Execute in pane: ${pane.command}`); + } + } + } + return { success: true }; + } catch (error) { + return { success: false, error: (error as Error).message }; + } +}