This commit is contained in:
141
src/parsers/iterm2Parser.ts
Normal file
141
src/parsers/iterm2Parser.ts
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import * as fs from 'fs-extra';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { osUtils } from '../utils/osUtils';
|
||||||
|
import { Layout, Session, Window, ParserResult, TerminalType } from '../models/types';
|
||||||
|
|
||||||
|
interface iTerm2Profile {
|
||||||
|
name: string;
|
||||||
|
guid: string;
|
||||||
|
shortcut: string;
|
||||||
|
command: string;
|
||||||
|
working_directory: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class iTerm2Parser {
|
||||||
|
private configDir: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.configDir = path.join(osUtils.getHomeDir(), 'Library', 'Application Support', 'iTerm2');
|
||||||
|
}
|
||||||
|
|
||||||
|
async isAvailable(): Promise<boolean> {
|
||||||
|
return osUtils.isMacOS() && fs.pathExistsSync(this.configDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
async listProfiles(): Promise<string[]> {
|
||||||
|
const plistPath = path.join(this.configDir, 'DynamicProfiles', 'profiles.json');
|
||||||
|
if (!fs.existsSync(plistPath)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(plistPath, 'utf-8');
|
||||||
|
const profiles = JSON.parse(content);
|
||||||
|
return Array.isArray(profiles) ? profiles.map((p: iTerm2Profile) => p.name) : [];
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async captureCurrentLayout(): Promise<ParserResult<Layout>> {
|
||||||
|
try {
|
||||||
|
if (!osUtils.isMacOS()) {
|
||||||
|
return { success: false, error: 'iTerm2 is only available on macOS' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const layout = this.createDefaultLayout();
|
||||||
|
return { success: true, data: layout };
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: (error as Error).message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createDefaultLayout(): Layout {
|
||||||
|
const window: Window = {
|
||||||
|
id: 'w0',
|
||||||
|
index: 0,
|
||||||
|
name: 'iTerm2',
|
||||||
|
panes: [
|
||||||
|
{
|
||||||
|
id: 'p0',
|
||||||
|
index: 0,
|
||||||
|
layout: { x: 0, y: 0, width: 80, height: 24 },
|
||||||
|
cwd: osUtils.getHomeDir(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
activePaneIndex: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const session: Session = {
|
||||||
|
id: 's-iterm2',
|
||||||
|
name: 'iterm2',
|
||||||
|
windows: [window],
|
||||||
|
activeWindowIndex: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
version: '1.0.0',
|
||||||
|
terminalType: 'iterm2' as TerminalType,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
session,
|
||||||
|
metadata: {
|
||||||
|
description: 'iTerm2 layout configuration',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateRestoreScript(layout: Layout): Promise<string> {
|
||||||
|
const commands: string[] = [];
|
||||||
|
|
||||||
|
commands.push('#!/bin/bash');
|
||||||
|
commands.push('# iTerm2 layout restoration script');
|
||||||
|
commands.push('# Note: iTerm2 scripting requires AppleScript/JavaScript for Automation');
|
||||||
|
|
||||||
|
for (const window of layout.session.windows) {
|
||||||
|
for (const pane of window.panes) {
|
||||||
|
if (pane.cwd) {
|
||||||
|
commands.push(`osascript -e 'tell application "iTerm2" to tell current window to create pane with profile "Default" directory "${pane.cwd}"'`);
|
||||||
|
} else {
|
||||||
|
commands.push('osascript -e \'tell application "iTerm2" to tell current window to create pane with profile "Default"\'');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return commands.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
async exportProfiles(outputPath: string): Promise<ParserResult<string>> {
|
||||||
|
try {
|
||||||
|
const profilesPath = path.join(this.configDir, 'DynamicProfiles', 'profiles.json');
|
||||||
|
if (!fs.existsSync(profilesPath)) {
|
||||||
|
return { success: false, error: 'iTerm2 profiles not found' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = fs.readFileSync(profilesPath, 'utf-8');
|
||||||
|
await fs.writeFile(outputPath, content, 'utf-8');
|
||||||
|
|
||||||
|
return { success: true, data: outputPath };
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: (error as Error).message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async importProfiles(inputPath: string): Promise<ParserResult<void>> {
|
||||||
|
try {
|
||||||
|
const profilesPath = path.join(this.configDir, 'DynamicProfiles', 'profiles.json');
|
||||||
|
const content = await fs.readFile(inputPath, 'utf-8');
|
||||||
|
|
||||||
|
JSON.parse(content);
|
||||||
|
|
||||||
|
await fs.ensureDir(path.dirname(profilesPath));
|
||||||
|
await fs.writeFile(profilesPath, content, 'utf-8');
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
return { success: false, error: (error as Error).message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const iterm2Parser = new iTerm2Parser();
|
||||||
Reference in New Issue
Block a user