Skip to content

Commit

Permalink
fix a bug that breaks shell config (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kun Chen committed Apr 30, 2023
1 parent fa51973 commit e7d6854
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 73 deletions.
12 changes: 9 additions & 3 deletions apps/app/src/nativeBridge/modules/terminalModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { IPty } from 'node-pty';
import os from 'os';

import { moduleEvent, moduleFunction, NativeBridgeModule, nativeBridgeModule } from '../module';
import { Logger } from './common/logger';

class PTYInstance {
private ptyProcess: IPty;
Expand All @@ -13,9 +14,9 @@ class PTYInstance {
this.id = id;

const shell =
shellCommand || process.env[process.platform === 'win32' ? 'COMSPEC' : 'SHELL'] || process.platform === 'win32'
? 'cmd.exe'
: '/bin/bash';
shellCommand ||
process.env[process.platform === 'win32' ? 'COMSPEC' : 'SHELL'] ||
(process.platform === 'win32' ? 'cmd.exe' : '/bin/bash');

this.ptyProcess = require('node-pty').spawn(shell, [], {
name: 'xterm-color',
Expand Down Expand Up @@ -55,6 +56,8 @@ export class TerminalModule extends NativeBridgeModule {
shellCommand: string,
startupDirectory: string,
): Promise<void> {
Logger.getInstance().log('info', `creating new terminal with id: ${id}, shell: ${shellCommand}`);

const ptyInstance = new PTYInstance(id, cols, rows, shellCommand, startupDirectory);
ptyInstance.onData((data: string) => {
this.onData(_mainWindow, ptyInstance.id, data);
Expand All @@ -77,6 +80,9 @@ export class TerminalModule extends NativeBridgeModule {
if (ptyInstance) {
ptyInstance.kill();
delete this.ptyInstances[id];
Logger.getInstance().log('info', `killed terminal with id: ${id}`);
} else {
Logger.getInstance().log('warn', `could not find terminal with id: ${id}`);
}
}

Expand Down
35 changes: 23 additions & 12 deletions apps/terminal/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { DEFAULT_CONFIG } from '@terminalone/types';
import _ from 'lodash';
import dynamic from 'next/dynamic';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { FiMenu, FiMinus, FiPlus } from 'react-icons/fi';

import SettingsPage from '../components/SettingsPage';
Expand All @@ -23,15 +23,26 @@ type UserTab = {
};

const Page = () => {
const { config } = useConfigContext();
const { config, loading } = useConfigContext();

const [tabId, setTabId] = useState<number>(1);
const [userTabs, setUserTabs] = useState<UserTab[]>([
{
tabId: 1,
shellName: config.defaultShellName,
},
]);
const [tabId, setTabId] = useState<number>(0);
const [userTabs, setUserTabs] = useState<UserTab[]>([]);

useEffect(() => {
if (!loading && userTabs.length === 0) {
setTabId(1);
setUserTabs([
{
tabId: 1,
shellName: config.defaultShellName,
},
]);
}
}, [loading, config, userTabs]);

if (loading) {
return <div />;
}

const activeShellName = userTabs.find((t) => t.tabId === tabId)?.shellName || config.defaultShellName;
const activeShellConfig = config.shells.find((s) => s.name === activeShellName) || DEFAULT_CONFIG.shells[0];
Expand Down Expand Up @@ -110,9 +121,9 @@ const Page = () => {
>
<div className="flex-1 relative overflow-hidden">
{tabId === 0 && <SettingsPage />}
{userTabs.map((userTab) => (
<Terminal key={userTab.tabId} active={tabId === userTab.tabId} shellName={userTab.shellName} />
))}
{userTabs.map((userTab) => {
return <Terminal key={userTab.tabId} active={tabId === userTab.tabId} shellName={userTab.shellName} />;
})}
</div>
</div>
</>
Expand Down
76 changes: 40 additions & 36 deletions apps/terminal/components/Terminal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import { Terminal as XTerm } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import { WebglAddon } from 'xterm-addon-webgl';

import { useConfigContext } from '../../hooks/ConfigContext';

let nextId = 0;

const Terminal = ({ active, shellName }: { active: boolean; shellName: string }) => {
const { config, loading } = useConfigContext();
const terminalRef = useRef<HTMLDivElement>(null);

useEffect(() => {
Expand All @@ -18,6 +21,9 @@ const Terminal = ({ active, shellName }: { active: boolean; shellName: string })
if (!window || !window.TerminalOne) {
return;
}
if (loading) {
return;
}

const terminalDiv = terminalRef.current;

Expand All @@ -32,42 +38,40 @@ const Terminal = ({ active, shellName }: { active: boolean; shellName: string })
fitAddon.fit();

const terminalId = (nextId++).toString();
window.TerminalOne.config.getConfig().then((config) => {
const activeShellConfig = config.shells.find((s) => s.name === shellName) || DEFAULT_CONFIG.shells[0];
// when the following values are empty, they will be auto determined based on system defaults
const shellCommand = activeShellConfig.command;
const startupDirectory = activeShellConfig.startupDirectory;
const theme = config.themes.find((t) => t.name === activeShellConfig.themeName) || DEFAULT_CONFIG.themes[0];

terminal.options.cursorBlink = config.cursorBlink;
terminal.options.cursorStyle = config.cursorStyle;
terminal.options.cursorWidth = config.cursorWidth;
terminal.options.scrollback = config.scrollback;
terminal.options.fontSize = config.fontSize;
terminal.options.fontFamily = config.fontFamily;
terminal.options.fontWeight = config.fontWeight;
terminal.options.fontWeightBold = config.fontWeightBold;
terminal.options.theme = theme;

window.TerminalOne?.terminal
.newTerminal(terminalId, terminal.cols, terminal.rows, shellCommand, startupDirectory)
.then(() => {
fitAddon.fit();

terminal.onData((data) => {
window.TerminalOne?.terminal?.writeTerminal(terminalId, data);
});
terminal.onResize(({ cols, rows }) => {
window.TerminalOne?.terminal?.resizeTerminal(terminalId, cols, rows);
});
window.TerminalOne?.terminal?.onData((_e, id: string, data: string) => {
if (id !== terminalId) {
return;
}
terminal.write(data);
});
const activeShellConfig = config.shells.find((s) => s.name === shellName) || DEFAULT_CONFIG.shells[0];
// when the following values are empty, they will be auto determined based on system defaults
const shellCommand = activeShellConfig.command;
const startupDirectory = activeShellConfig.startupDirectory;
const theme = config.themes.find((t) => t.name === activeShellConfig.themeName) || DEFAULT_CONFIG.themes[0];

terminal.options.cursorBlink = config.cursorBlink;
terminal.options.cursorStyle = config.cursorStyle;
terminal.options.cursorWidth = config.cursorWidth;
terminal.options.scrollback = config.scrollback;
terminal.options.fontSize = config.fontSize;
terminal.options.fontFamily = config.fontFamily;
terminal.options.fontWeight = config.fontWeight;
terminal.options.fontWeightBold = config.fontWeightBold;
terminal.options.theme = theme;

window.TerminalOne?.terminal
.newTerminal(terminalId, terminal.cols, terminal.rows, shellCommand, startupDirectory)
.then(() => {
fitAddon.fit();

terminal.onData((data) => {
window.TerminalOne?.terminal?.writeTerminal(terminalId, data);
});
terminal.onResize(({ cols, rows }) => {
window.TerminalOne?.terminal?.resizeTerminal(terminalId, cols, rows);
});
window.TerminalOne?.terminal?.onData((_e, id: string, data: string) => {
if (id !== terminalId) {
return;
}
terminal.write(data);
});
});
});

const resizeListener = () => {
fitAddon.fit();
Expand All @@ -87,7 +91,7 @@ const Terminal = ({ active, shellName }: { active: boolean; shellName: string })
window.TerminalOne?.terminal?.killTerminal(terminalId);
terminal.dispose();
};
}, [terminalRef, shellName]);
}, [terminalRef, shellName, config, loading]);

useEffect(() => {
if (!terminalRef.current) {
Expand Down
39 changes: 18 additions & 21 deletions apps/terminal/hooks/ConfigContext.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,38 @@
'use client';

import { DEFAULT_CONFIG, ResolvedConfig } from '@terminalone/types';
import React, { createContext, useContext, useEffect, useState } from 'react';

interface IConfigContextData {
config: ResolvedConfig;
configPath: string;
loading?: boolean;
}

const ConfigContext = createContext<IConfigContextData>({
const DEFAULT_CONFIG_CONTEXT_DATA: IConfigContextData = {
config: DEFAULT_CONFIG,
configPath: '',
});
loading: true,
};

const ConfigContext = createContext<IConfigContextData>(DEFAULT_CONFIG_CONTEXT_DATA);

export const ConfigContextProvider = (props: React.PropsWithChildren<{}>) => {
const [config, setConfig] = useState<ResolvedConfig>(DEFAULT_CONFIG);
const [configPath, setConfigPath] = useState<string>('');
const [data, setData] = useState<IConfigContextData>(DEFAULT_CONFIG_CONTEXT_DATA);

useEffect(() => {
if (window && window.TerminalOne) {
window.TerminalOne.config.getConfig().then((cfg) => {
setConfig(cfg);
});
window.TerminalOne.config.getConfigPath().then((path) => {
setConfigPath(path);
window.TerminalOne?.config.getConfig().then((cfg) => {
window.TerminalOne?.config.getConfigPath().then((path) => {
setData({
config: cfg,
configPath: path,
loading: false,
});
});
}
});
}, []);

return (
<ConfigContext.Provider
value={{
config: config,
configPath: configPath,
}}
>
{props.children}
</ConfigContext.Provider>
);
return <ConfigContext.Provider value={data}>{props.children}</ConfigContext.Provider>;
};

export const useConfigContext = () => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@terminalone/monorepo",
"version": "0.1.1",
"version": "0.1.2",
"description": "A fast, elegant and intelligent cross-platform terminal.",
"author": "Kun Chen",
"license": "MIT",
Expand Down

0 comments on commit e7d6854

Please sign in to comment.