"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtHostPseudoterminal = exports.Terminal = exports.EnvironmentVariableCollection = exports.ExtHostTerminal = void 0;
const os_1 = require("os");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const ide_terminal_next_1 = require("@opensumi/ide-terminal-next");
const environmentVariable_1 = require("@opensumi/ide-terminal-next/lib/common/environmentVariable");
const common_1 = require("../../../common");
const vscode_1 = require("../../../common/vscode");
const ext_types_1 = require("../../../common/vscode/ext-types");
let nextLinkId = 1;
class ExtHostTerminal {
    get terminals() {
        return Array.from(this.terminalsMap.values());
    }
    constructor(rpcProtocol) {
        this.changeActiveTerminalEvent = new ide_core_common_1.Emitter();
        this.closeTerminalEvent = new ide_core_common_1.Emitter();
        this.openTerminalEvent = new ide_core_common_1.Emitter();
        this.terminalStateChangeEvent = new ide_core_common_1.Emitter();
        this.onDidChangeShellEvent = new ide_core_common_1.Emitter();
        this.terminalsMap = new Map();
        this._terminalDeferreds = new Map();
        this._linkProviders = new Set();
        this._terminalLinkCache = new Map();
        this._terminalLinkCancellationSource = new Map();
        this._profileProviders = new Map();
        this.environmentVariableCollections = new ide_core_common_1.MultiKeyMap(2);
        this.disposables = new ide_core_common_1.DisposableStore();
        this._terminalProcesses = new Map();
        this._terminalProcessDisposables = {};
        this._extensionTerminalAwaitingStart = {};
        this._terminalStartDeferreds = new Map();
        this.proxy = rpcProtocol.getProxy(vscode_1.MainThreadAPIIdentifier.MainThreadTerminal);
        this._bufferer = new ide_terminal_next_1.TerminalDataBufferer(this.proxy.$sendProcessData);
    }
    getTerminal(id) {
        if (this.terminalsMap.has(id)) {
            return this.terminalsMap.get(id);
        }
        return this.terminalsMap.get(this.getTerminalShortId(id));
    }
    getTerminalShortId(id) {
        // 插件进程创建的 Terminal 可能会在前端被拼接为 `${clientId}${TERMINAL_ID_SEPARATOR}${shortId}` 的形式
        if (id.includes(ide_terminal_next_1.TERMINAL_ID_SEPARATOR)) {
            return id.split(ide_terminal_next_1.TERMINAL_ID_SEPARATOR)[1];
        }
        return id;
    }
    /**
     * FIXME：由于前端对于 id 的拼接逻辑，需要通过 terminalsMap 是否存在对应 terminal 实例来获取真实 id
     */
    getRealTerminalId(id) {
        let terminalId = '';
        const shortId = this.getTerminalShortId(id);
        if (this.terminalsMap.has(id)) {
            terminalId = id;
        }
        else if (this.terminalsMap.has(shortId)) {
            terminalId = shortId;
        }
        return terminalId;
    }
    $onDidChangeActiveTerminal(id) {
        const terminal = this.getTerminal(id);
        const original = this.activeTerminal;
        // 当激活的终端为 Task 终端时，同样需要将 activeTerminal 置为 undefined
        this.activeTerminal = terminal;
        if (original !== this.activeTerminal) {
            this.changeActiveTerminalEvent.fire(this.activeTerminal);
        }
    }
    get onDidChangeActiveTerminal() {
        return this.changeActiveTerminalEvent.event;
    }
    $onDidCloseTerminal(e) {
        const terminalId = this.getRealTerminalId(e.id);
        const terminal = this.terminalsMap.get(terminalId);
        if (!terminal) {
            // 说明此时收到的可能为 Task 终端关闭事件，直接忽略即可
            return;
        }
        // 目前 OpenSumi 不是很好打通完整的 Terminal 关闭原因，先用 Unknown 打通接口
        terminal.setExitStatus(e.code, ext_types_1.TerminalExitReason.Unknown);
        this.closeTerminalEvent.fire(terminal);
        this.terminalsMap.delete(terminalId);
    }
    get onDidCloseTerminal() {
        return this.closeTerminalEvent.event;
    }
    $onDidOpenTerminal(info) {
        let terminal = this.getTerminal(info.id);
        if (!terminal) {
            terminal = new Terminal(info.name, info, this.proxy, info.id);
            this.terminalsMap.set(info.id, terminal);
            const deferred = this._terminalDeferreds.get(info.id);
            deferred === null || deferred === void 0 ? void 0 : deferred.resolve(terminal);
        }
        this.openTerminalEvent.fire(terminal);
    }
    $onDidTerminalTitleChange(id, name) {
        const terminal = this.getTerminal(id);
        if (terminal) {
            if (name !== terminal.name) {
                terminal.setName(name);
            }
        }
    }
    get onDidOpenTerminal() {
        return this.openTerminalEvent.event;
    }
    get onDidChangeShell() {
        return this.onDidChangeShellEvent.event;
    }
    get shellPath() {
        var _a;
        return ((_a = this._defaultProfile) === null || _a === void 0 ? void 0 : _a.path) || process.env.SHELL || (0, os_1.userInfo)().shell;
    }
    get onDidChangeTerminalState() {
        return this.terminalStateChangeEvent.event;
    }
    $setShell(shell) {
        if (this.shell !== shell) {
            this.shell = shell;
            this.onDidChangeShellEvent.fire(shell);
        }
    }
    createTerminal(name, shellPath, shellArgs) {
        const shortId = (0, ide_core_common_1.uuid)();
        const terminal = new Terminal(name || '', { name, shellPath, shellArgs }, this.proxy);
        terminal.create({
            name,
            shellPath,
            shellArgs,
        }, shortId);
        this.terminalsMap.set(shortId, terminal);
        return terminal;
    }
    createTerminalFromOptions(options) {
        // 插件 API 同步提供 terminal 实例
        const shortId = (0, ide_core_common_1.uuid)();
        const terminal = new Terminal(options.name, options, this.proxy);
        terminal.create(options, shortId);
        this.terminalsMap.set(shortId, terminal);
        return terminal;
    }
    createExtensionTerminal(options) {
        const shortId = (0, ide_core_common_1.uuid)();
        const terminal = new Terminal(options.name, options, this.proxy);
        const p = new ExtHostPseudoterminal(options.pty);
        terminal.createExtensionTerminal(shortId, options.iconPath, options.color);
        this.terminalsMap.set(shortId, terminal);
        this._terminalStartDeferreds.set(shortId, new ide_core_common_1.Deferred());
        const disposable = this._setupExtHostProcessListeners(shortId, p);
        this._terminalProcessDisposables[shortId] = disposable;
        this.disposables.add(p.onProcessExit((e) => {
            terminal.setExitStatus(e, ext_types_1.TerminalExitReason.Process);
        }));
        return terminal;
    }
    attachPtyToTerminal(id, pty) {
        const terminal = this._getTerminalByIdEventually(id);
        if (!terminal) {
            throw new Error(`Cannot resolve terminal with id ${id} for virtual process`);
        }
        const p = new ExtHostPseudoterminal(pty);
        this._setupExtHostProcessListeners(id, p);
    }
    $setTerminals(idList) {
        this.terminalsMap.clear();
        this.activeTerminal = undefined;
        idList.forEach((info) => {
            if (this.getTerminal(info.id)) {
                return;
            }
            const terminal = new Terminal(info.name, info, this.proxy, info.id);
            if (info.isActive) {
                this.activeTerminal = terminal;
            }
            // 终端恢复时，id 为前端创建，故不需要处理 id 信息
            this.terminalsMap.set(info.id, terminal);
        });
    }
    registerLinkProvider(provider) {
        this._linkProviders.add(provider);
        if (this._linkProviders.size === 1) {
            this.proxy.$startLinkProvider();
        }
        return ide_core_common_1.Disposable.create(() => {
            this._linkProviders.delete(provider);
            if (this._linkProviders.size === 0) {
                this.proxy.$stopLinkProvider();
            }
        });
    }
    async $provideLinks(id, line) {
        const terminalId = this.getRealTerminalId(id);
        const terminal = this.getTerminal(terminalId);
        if (!terminal) {
            return [];
        }
        // Discard any cached links the terminal has been holding, currently all links are released
        // when new links are provided.
        this._terminalLinkCache.delete(terminalId);
        const oldToken = this._terminalLinkCancellationSource.get(terminalId);
        if (oldToken) {
            oldToken.dispose(true);
        }
        const cancellationSource = new ide_core_common_1.CancellationTokenSource();
        this._terminalLinkCancellationSource.set(terminalId, cancellationSource);
        const result = [];
        const context = { terminal, line };
        const promises = [];
        for (const provider of this._linkProviders) {
            promises.push(new Promise(async (r) => {
                cancellationSource.token.onCancellationRequested(() => r({ provider, links: [] }));
                const links = (await provider.provideTerminalLinks(context, cancellationSource.token)) || [];
                if (!cancellationSource.token.isCancellationRequested) {
                    r({ provider, links });
                }
            }));
        }
        const provideResults = await Promise.all(promises);
        if (cancellationSource.token.isCancellationRequested) {
            return [];
        }
        const cacheLinkMap = new Map();
        for (const provideResult of provideResults) {
            if (provideResult && provideResult.links.length > 0) {
                result.push(...provideResult.links.map((providerLink) => {
                    const link = {
                        id: nextLinkId++,
                        startIndex: providerLink.startIndex,
                        length: providerLink.length,
                        label: providerLink.tooltip,
                    };
                    cacheLinkMap.set(link.id, {
                        provider: provideResult.provider,
                        link: providerLink,
                    });
                    return link;
                }));
            }
        }
        this._terminalLinkCache.set(terminalId, cacheLinkMap);
        return result;
    }
    $activateLink(id, linkId) {
        var _a;
        const terminalId = this.getRealTerminalId(id);
        const cachedLink = (_a = this._terminalLinkCache.get(terminalId)) === null || _a === void 0 ? void 0 : _a.get(linkId);
        if (!cachedLink) {
            return;
        }
        cachedLink.provider.handleTerminalLink(cachedLink.link);
    }
    dispose() {
        this.changeActiveTerminalEvent.dispose();
        this.closeTerminalEvent.dispose();
        this.openTerminalEvent.dispose();
        this.disposables.dispose();
    }
    registerTerminalProfileProvider(extension, id, provider) {
        if (this._profileProviders.has(id)) {
            throw new Error(`Terminal profile provider "${id}" already registered`);
        }
        this._profileProviders.set(id, provider);
        this.proxy.$registerProfileProvider(id, extension.identifier.value);
        return ide_core_common_1.Disposable.create(() => {
            this._profileProviders.delete(id);
            this.proxy.$unregisterProfileProvider(id);
        });
    }
    /**
     * @deprecated this function is useless, will removed in 2.17.0
     */
    $acceptDefaultShell(shellPath) {
        // will remove
    }
    $acceptDefaultProfile(profile, automationProfile) {
        const oldProfile = this._defaultProfile;
        this._defaultProfile = profile;
        // 还不知道这个 automation 有啥用
        this._defaultAutomationProfile = automationProfile;
        if ((oldProfile === null || oldProfile === void 0 ? void 0 : oldProfile.path) !== profile.path) {
            this.onDidChangeShellEvent.fire(profile.path);
        }
    }
    async $createContributedProfileTerminal(id, options) {
        var _a;
        const token = new ide_core_common_1.CancellationTokenSource().token;
        let profile = await ((_a = this._profileProviders.get(id)) === null || _a === void 0 ? void 0 : _a.provideTerminalProfile(token));
        if (token.isCancellationRequested) {
            return;
        }
        if (profile && !('options' in profile)) {
            profile = { options: profile };
        }
        if (!profile || !('options' in profile)) {
            throw new Error(`No terminal profile options provided for id "${id}"`);
        }
        if ('pty' in profile.options) {
            // TODO: 传入第二个参数
            // this.createExtensionTerminal(profile.options, options);
            this.createExtensionTerminal(profile.options);
            return;
        }
        // TODO: 传入第二个参数
        // this.createTerminalFromOptions(profile.options, options);
        this.createTerminalFromOptions(profile.options);
    }
    async _getTerminalByIdEventually(id, timeout = 1000) {
        let terminal = this.getTerminal(id);
        if (!terminal) {
            const deferred = this._terminalDeferreds.get(id) || new ide_core_common_1.Deferred();
            setTimeout(() => {
                deferred.resolve(terminal);
            }, timeout);
            this._terminalDeferreds.set(id, deferred);
            terminal = await deferred.promise;
            this._terminalDeferreds.delete(id);
        }
        return terminal;
    }
    async $startExtensionTerminal(id, initialDimensions) {
        var _a;
        // Make sure the ExtHostTerminal exists so onDidOpenTerminal has fired before we call
        // Pseudoterminal.start
        const terminal = await this._getTerminalByIdEventually(id);
        if (!terminal) {
            return { message: `Could not find the terminal with id ${id} on the extension host` };
        }
        // TerminalController::_createClient 会立即触发 onDidOpenTerminal，所以无需等待
        const terminalProcess = this._terminalProcesses.get(this.getTerminalShortId(id));
        if (terminalProcess) {
            terminalProcess.startSendingEvents(initialDimensions);
        }
        else {
            // Defer startSendingEvents call to when _setupExtHostProcessListeners is called
            this._extensionTerminalAwaitingStart[this.getTerminalShortId(id)] = { initialDimensions };
        }
        (_a = this._terminalStartDeferreds.get(this.getTerminalShortId(id))) === null || _a === void 0 ? void 0 : _a.resolve(undefined);
        return undefined;
    }
    _setupExtHostProcessListeners(shortId, p) {
        var _a;
        const disposables = new ide_core_common_1.DisposableStore();
        disposables.add(p.onProcessReady((e) => this.proxy.$sendProcessReady(shortId, e.pid, e.cwd)));
        disposables.add(p.onProcessTitleChanged((title) => {
            this.proxy.$sendProcessTitle(shortId, title);
            this._getTerminalByIdEventually(shortId).then((terminal) => {
                if (terminal) {
                    terminal.setName(title);
                }
            });
        }));
        // Buffer data events to reduce the amount of messages going to the renderer
        this._bufferer.startBuffering(shortId, p.onProcessData);
        disposables.add(p.onProcessExit((exitCode) => this._onProcessExit(shortId, exitCode)));
        if (p.onProcessOverrideDimensions) {
            disposables.add(p.onProcessOverrideDimensions((e) => this.proxy.$sendOverrideDimensions(shortId, e)));
        }
        this._terminalProcesses.set(shortId, p);
        (_a = this._terminalStartDeferreds.get(shortId)) === null || _a === void 0 ? void 0 : _a.promise.then(() => {
            const awaitingStart = this._extensionTerminalAwaitingStart[shortId];
            if (awaitingStart && p instanceof ExtHostPseudoterminal) {
                p.startSendingEvents(awaitingStart.initialDimensions);
                delete this._extensionTerminalAwaitingStart[shortId];
            }
        });
        return disposables;
    }
    _onProcessExit(id, exitCode) {
        this._bufferer.stopBuffering(id);
        // Remove process reference
        this._terminalProcesses.delete(id);
        delete this._extensionTerminalAwaitingStart[id];
        // Clean up process disposables
        const processDiposable = this._terminalProcessDisposables[id];
        if (processDiposable) {
            processDiposable.dispose();
            delete this._terminalProcessDisposables[id];
        }
        // Send exit event to main side
        this.proxy.$sendProcessExit(id, exitCode);
    }
    $acceptProcessInput(id, data) {
        var _a;
        (_a = this._terminalProcesses.get(this.getTerminalShortId(id))) === null || _a === void 0 ? void 0 : _a.input(data);
    }
    $acceptProcessShutdown(id, immediate) {
        var _a;
        (_a = this._terminalProcesses.get(this.getTerminalShortId(id))) === null || _a === void 0 ? void 0 : _a.shutdown(immediate);
    }
    $acceptProcessRequestInitialCwd(id) {
        var _a;
        (_a = this._terminalProcesses
            .get(id)) === null || _a === void 0 ? void 0 : _a.getInitialCwd().then((initialCwd) => this.proxy.$sendProcessInitialCwd(id, initialCwd));
    }
    $acceptProcessRequestCwd(id) {
        var _a;
        (_a = this._terminalProcesses
            .get(id)) === null || _a === void 0 ? void 0 : _a.getCwd().then((cwd) => this.proxy.$sendProcessCwd(id, cwd));
    }
    $acceptTerminalTitleChange(terminalId, name) {
        const terminal = this.getTerminal(terminalId);
        if (terminal) {
            terminal.setName(name);
        }
    }
    $acceptTerminalInteraction(terminalId) {
        const terminal = this.getTerminal(terminalId);
        if (terminal === null || terminal === void 0 ? void 0 : terminal.setInteractedWith()) {
            this.terminalStateChangeEvent.fire(terminal);
        }
    }
    getEnvironmentVariableCollection(extension, rootUri = common_1.NO_ROOT_URI) {
        // eslint-disable-next-line @typescript-eslint/no-this-alias
        const that = this;
        let collection = this.environmentVariableCollections.get([extension.id, rootUri]);
        if (!collection) {
            collection = new (class extends EnvironmentVariableCollection {
                getScoped(scope) {
                    var _a;
                    return that.getEnvironmentVariableCollection(extension, (_a = scope.workspaceFolder) === null || _a === void 0 ? void 0 : _a.uri.toString());
                }
            })();
            this._setEnvironmentVariableCollection(extension.id, rootUri, collection);
        }
        return collection;
    }
    syncEnvironmentVariableCollection(extensionIdentifier, collection) {
        const serialized = [...collection.map.entries()];
        this.proxy.$setEnvironmentVariableCollection(extensionIdentifier, collection.persistent, serialized.length === 0 ? undefined : serialized);
    }
    _setEnvironmentVariableCollection(extensionIdentifier, rootUri, collection) {
        this.environmentVariableCollections.set([extensionIdentifier, rootUri], collection);
        collection.onDidChangeCollection(() => {
            // When any collection value changes send this immediately, this is done to ensure
            // following calls to createTerminal will be created with the new environment. It will
            // result in more noise by sending multiple updates when called but collections are
            // expected to be small.
            this.syncEnvironmentVariableCollection(extensionIdentifier, collection);
        });
    }
}
exports.ExtHostTerminal = ExtHostTerminal;
/**
 * EnvironmentVariableCollection
 * Some code copied and modified from
 * https://github.com/microsoft/vscode/blob/1.55.0/src/vs/workbench/api/common/extHostTerminalService.ts#L696
 */
class EnvironmentVariableCollection {
    get onDidChangeCollection() {
        return this._onDidChangeCollection && this._onDidChangeCollection.event;
    }
    constructor(serialized) {
        this.map = new Map();
        this._onDidChangeCollection = new ide_core_common_1.Emitter();
        this._persistent = true;
        this.map = new Map(serialized);
    }
    get persistent() {
        return this._persistent;
    }
    set persistent(value) {
        this._persistent = value;
        this._onDidChangeCollection.fire();
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    getScoped(_scope) {
        throw new Error('Cannot get scoped from a regular env var collection');
    }
    _setIfDiffers(variable, mutator) {
        const current = this.map.get(variable);
        if (!current || current.value !== mutator.value || current.type !== mutator.type) {
            this.map.set(variable, mutator);
            this._onDidChangeCollection.fire();
        }
    }
    replace(variable, value, options) {
        this._setIfDiffers(variable, {
            value,
            type: environmentVariable_1.EnvironmentVariableMutatorType.Replace,
            options: options !== null && options !== void 0 ? options : { applyAtProcessCreation: true },
        });
    }
    append(variable, value, options) {
        this._setIfDiffers(variable, {
            value,
            type: environmentVariable_1.EnvironmentVariableMutatorType.Append,
            options: options !== null && options !== void 0 ? options : { applyAtProcessCreation: true },
        });
    }
    prepend(variable, value, options) {
        this._setIfDiffers(variable, {
            value,
            type: environmentVariable_1.EnvironmentVariableMutatorType.Prepend,
            options: options !== null && options !== void 0 ? options : { applyAtProcessCreation: true },
        });
    }
    get(variable) {
        return this.map.get(variable);
    }
    forEach(callback, thisArg) {
        this.map.forEach((value, key) => callback.call(thisArg, key, value, this));
    }
    delete(variable) {
        this.map.delete(variable);
        this._onDidChangeCollection.fire();
    }
    clear() {
        this.map.clear();
        this._onDidChangeCollection.fire();
    }
}
exports.EnvironmentVariableCollection = EnvironmentVariableCollection;
class Terminal {
    constructor(_name = '', _creationOptions, proxy, id) {
        this._name = _name;
        this._creationOptions = _creationOptions;
        this.proxy = proxy;
        this._state = { isInteractedWith: false };
        this.when = new Promise((resolve) => {
            this.createdPromiseResolve = resolve;
        });
        this.shellIntegration = undefined;
        if (!(0, ide_core_common_1.isUndefined)(id)) {
            this.created(id);
        }
    }
    get name() {
        return this._name;
    }
    get state() {
        return this._state;
    }
    get exitStatus() {
        return this._exitStatus;
    }
    get processId() {
        return this.when.then(() => this.proxy.$getProcessId(this.id));
    }
    get creationOptions() {
        return this._creationOptions;
    }
    sendText(text, addNewLine) {
        this.when.then(() => {
            this.proxy.$sendText(this.id, text, addNewLine);
        });
    }
    show(preserveFocus) {
        this.when.then(() => {
            this.proxy.$show(this.id, preserveFocus);
        });
    }
    hide() {
        this.when.then(() => {
            this.proxy.$hide(this.id);
        });
    }
    /**
     * 所有插件进程的终端调用都需要指定 id
     * 该逻辑用于保障依赖 `vscode.window.onDidOpenTerminal` 获取 terminal 实例的相关逻辑
     * 让相关 terminal 的值引用一致
     * 如 vscode-js-debug 中的 https://github.com/microsoft/vscode-js-debug/blob/a201e735c94b9aeb1e13d8c586b91a1fe1ab62b3/src/ui/debugTerminalUI.ts#L198
     */
    async create(options, shortId) {
        await this.proxy.$createTerminal(options, shortId);
        this.created(shortId);
    }
    created(shortId) {
        this.id = shortId;
        this.__id = shortId;
        this.createdPromiseResolve();
    }
    dispose() {
        this.proxy.$dispose(this.id);
    }
    async createExtensionTerminal(id, iconPath, color) {
        await this.proxy.$createTerminal({ name: this.name, isExtensionTerminal: true, iconPath, color, isTransient: true }, id);
        this.created(id);
    }
    setExitStatus(code, reason) {
        this._exitStatus = Object.freeze({ code, reason });
    }
    setName(name) {
        this._name = name;
    }
    setInteractedWith() {
        if (!this._state.isInteractedWith) {
            this._state.isInteractedWith = true;
            return true;
        }
        return false;
    }
}
exports.Terminal = Terminal;
class ExtHostPseudoterminal {
    get onProcessReady() {
        return this._onProcessReady.event;
    }
    get onProcessOverrideDimensions() {
        return this._onProcessOverrideDimensions.event;
    }
    constructor(_pty) {
        this._pty = _pty;
        this._onProcessData = new ide_core_common_1.Emitter();
        this.onProcessData = this._onProcessData.event;
        this._onProcessExit = new ide_core_common_1.Emitter();
        this.onProcessExit = this._onProcessExit.event;
        this._onProcessReady = new ide_core_common_1.Emitter();
        this._onProcessTitleChanged = new ide_core_common_1.Emitter();
        this.onProcessTitleChanged = this._onProcessTitleChanged.event;
        this._onProcessOverrideDimensions = new ide_core_common_1.Emitter();
    }
    async start() {
        return undefined;
    }
    shutdown() {
        this._pty.close();
    }
    input(data) {
        if (this._pty.handleInput) {
            this._pty.handleInput(data);
        }
    }
    resize(cols, rows) {
        if (this._pty.setDimensions) {
            this._pty.setDimensions({ columns: cols, rows });
        }
    }
    getInitialCwd() {
        return Promise.resolve('');
    }
    getCwd() {
        return Promise.resolve('');
    }
    getLatency() {
        return Promise.resolve(0);
    }
    startSendingEvents(initialDimensions) {
        // Attach the listeners
        this._pty.onDidWrite((e) => {
            this._onProcessData.fire(e);
        });
        if (this._pty.onDidClose) {
            this._pty.onDidClose((e = undefined) => {
                this._onProcessExit.fire(e === void 0 ? undefined : e);
            });
        }
        if (this._pty.onDidOverrideDimensions) {
            this._pty.onDidOverrideDimensions((e) => this._onProcessOverrideDimensions.fire(e ? { cols: e.columns, rows: e.rows } : e));
        }
        if (this._pty.onDidChangeName) {
            this._pty.onDidChangeName((title) => this._onProcessTitleChanged.fire(title));
        }
        this._pty.open(initialDimensions ? initialDimensions : undefined);
        this._onProcessReady.fire({ pid: -1, cwd: '' });
    }
}
exports.ExtHostPseudoterminal = ExtHostPseudoterminal;
//# sourceMappingURL=ext.host.terminal.js.map