desktopmerge
bunsenstraat 1 year ago
parent 69c81b992f
commit f544187d8c
  1. 4
      libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
  2. 16
      libs/remix-ui/workspace/src/lib/actions/events.ts
  3. 2
      libs/remix-ui/workspace/src/lib/contexts/index.ts
  4. 32
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterm.tsx
  5. 376
      libs/remix-ui/xterm/src/lib/components/remix-ui-xterminals.tsx
  6. 252
      libs/remix-ui/xterm/src/lib/components/xterm-wrap.tsx

@ -59,8 +59,8 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {
<div className="px-2 pl-3 justify-content-start d-flex border-right flex-column" id="remixUIHTLeft" style={{width: 'inherit'}}>
<HomeTabTitle />
{!isElectron()?
<HomeTabFile plugin={plugin} />:
<HomeTabFileElectron plugin={plugin}></HomeTabFileElectron>}
<HomeTabFile plugin={plugin} />:
<HomeTabFileElectron plugin={plugin}></HomeTabFileElectron>}
<HomeTabLearn plugin={plugin} />
</div>
<div className="pl-2 pr-3 justify-content-start d-flex flex-column" style={{width: '65%'}} id="remixUIHTRight">

@ -123,14 +123,14 @@ export const listenOnProviderEvents = (provider) => (reducerDispatch: React.Disp
if (config.get('currentFile') === path) {
// if it's the current file and the content is different:
if(showAlert){
dispatch(displayNotification(
path + ' changed',
'This file has been changed outside of Remix IDE.',
'Replace by the new content', 'Keep the content displayed in Remix',
() => {
editor.setText(path, content)
}
))}else{
dispatch(displayNotification(
path + ' changed',
'This file has been changed outside of Remix IDE.',
'Replace by the new content', 'Keep the content displayed in Remix',
() => {
editor.setText(path, content)
}
))}else{
editor.setText(path, content)
}
} else {

@ -49,6 +49,6 @@ export const FileSystemContext = createContext<{
dispatchOpenElectronFolder: (path: string) => Promise<void>
dispatchGetElectronRecentFolders: () => Promise<void>
dispatchRemoveRecentFolder: (path: string) => Promise<void>
}>(null)
}>(null)

@ -19,29 +19,29 @@ export interface RemixUiXtermProps {
}
const RemixUiXterm = (props: RemixUiXtermProps) => {
const { plugin, pid, send, timeStamp } = props
const xtermRef = React.useRef(null)
const { plugin, pid, send, timeStamp } = props
const xtermRef = React.useRef(null)
useEffect(() => {
props.setTerminalRef(pid, xtermRef.current)
}, [xtermRef.current])
useEffect(() => {
props.setTerminalRef(pid, xtermRef.current)
}, [xtermRef.current])
const onKey = (event: { key: string; domEvent: KeyboardEvent }) => {
send(event.key, pid)
}
const onKey = (event: { key: string; domEvent: KeyboardEvent }) => {
send(event.key, pid)
}
return (
return (
<Xterm
addons={[fitAddon]}
options={{ theme: { background: props.theme.backgroundColor, foreground: props.theme.textColor } }}
onRender={() => fitAddon.fit()}
ref={xtermRef}
onKey={onKey}></Xterm>
<Xterm
addons={[fitAddon]}
options={{ theme: { background: props.theme.backgroundColor, foreground: props.theme.textColor } }}
onRender={() => fitAddon.fit()}
ref={xtermRef}
onKey={onKey}></Xterm>
)
)
}

@ -19,216 +19,216 @@ export interface xtermState {
}
export const RemixUiXterminals = (props: RemixUiXterminalsProps) => {
const [terminals, setTerminals] = useState<xtermState[]>([])
const [workingDir, setWorkingDir] = useState<string>('')
const [showOutput, setShowOutput] = useState<boolean>(true)
const [theme, setTheme] = useState<any>(themeCollection[0])
const [terminalsEnabled, setTerminalsEnabled] = useState<boolean>(false)
const [shells, setShells] = useState<string[]>([])
const { plugin } = props
useEffect(() => {
setTimeout(async () => {
plugin.on('xterm', 'loaded', async () => {
console.log('xterm loaded')
})
plugin.on('xterm', 'data', async (data: string, pid: number) => {
writeToTerminal(data, pid)
})
plugin.on('xterm', 'close', async (pid: number) => {
setTerminals(prevState => {
const removed = prevState.filter(xtermState => xtermState.pid !== pid)
if (removed.length > 0)
removed[removed.length - 1].hidden = false
if(removed.length === 0)
setShowOutput(true)
return [...removed]
})
})
plugin.on('fs', 'workingDirChanged', (path: string) => {
setWorkingDir(path)
setTerminalsEnabled(true)
})
plugin.on('theme', 'themeChanged', async (theme) => {
handleThemeChange(theme)
})
const theme = await plugin.call('theme', 'currentTheme')
handleThemeChange(theme)
const shells = await plugin.call('xterm', 'getShells')
setShells(shells)
}, 2000)
}, [])
const handleThemeChange = (theme: any) => {
themeCollection.forEach((themeItem) => {
if (themeItem.themeName === theme.name) {
setTheme(themeItem)
}
})
}
const writeToTerminal = (data: string, pid: number) => {
setTerminals(prevState => {
const terminal = prevState.find(xtermState => xtermState.pid === pid)
if (terminal.ref && terminal.ref.terminal) {
terminal.ref.terminal.write(data)
} else {
terminal.queue += data
}
return [...prevState]
})
}
const send = (data: string, pid: number) => {
plugin.call('xterm', 'keystroke', data, pid)
}
const createTerminal = async (shell?: string) => {
const pid = await plugin.call('xterm', 'createTerminal', workingDir, shell)
setShowOutput(false)
setTerminals(prevState => {
// set all to hidden
prevState.forEach(xtermState => {
xtermState.hidden = true
})
return [...prevState, {
pid: pid,
queue: '',
timeStamp: Date.now(),
ref: null,
hidden: false
}]
})
}
const setTerminalRef = (pid: number, ref: any) => {
setTerminals(prevState => {
const terminal = prevState.find(xtermState => xtermState.pid === pid)
terminal.ref = ref
if (terminal.queue) {
ref.terminal.write(terminal.queue)
terminal.queue = ''
}
return [...prevState]
})
}
const selectTerminal = (state: xtermState) => {
const [terminals, setTerminals] = useState<xtermState[]>([])
const [workingDir, setWorkingDir] = useState<string>('')
const [showOutput, setShowOutput] = useState<boolean>(true)
const [theme, setTheme] = useState<any>(themeCollection[0])
const [terminalsEnabled, setTerminalsEnabled] = useState<boolean>(false)
const [shells, setShells] = useState<string[]>([])
const { plugin } = props
useEffect(() => {
setTimeout(async () => {
plugin.on('xterm', 'loaded', async () => {
console.log('xterm loaded')
})
plugin.on('xterm', 'data', async (data: string, pid: number) => {
writeToTerminal(data, pid)
})
plugin.on('xterm', 'close', async (pid: number) => {
setTerminals(prevState => {
// set all to hidden
prevState.forEach(xtermState => {
xtermState.hidden = true
})
const terminal = prevState.find(xtermState => xtermState.pid === state.pid)
terminal.hidden = false
return [...prevState]
const removed = prevState.filter(xtermState => xtermState.pid !== pid)
if (removed.length > 0)
removed[removed.length - 1].hidden = false
if(removed.length === 0)
setShowOutput(true)
return [...removed]
})
}
const closeTerminal = () => {
const pid = terminals.find(xtermState => xtermState.hidden === false).pid
if (pid)
plugin.call('xterm', 'close', pid)
}
const selectOutput = () => {
setShowOutput(true)
}
const showTerminal = () => {
setShowOutput(false)
if (terminals.length === 0) createTerminal()
}
return (<>
<div className='xterm-panel'>
<div className='xterm-panel-header bg-light'>
<div className='xterm-panel-header-left p-1'>
<button className={`btn btn-sm btn-secondary mr-2 ${!showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={selectOutput}>ouput</button>
<button className={`btn btn-sm btn-secondary ${terminalsEnabled ? '' : 'd-none'} ${showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={showTerminal}><span className="far fa-terminal border-0 ml-1"></span></button>
</div>
<div className={`xterm-panel-header-right ${showOutput ? 'd-none' : ''}`}>
})
plugin.on('fs', 'workingDirChanged', (path: string) => {
setWorkingDir(path)
setTerminalsEnabled(true)
})
plugin.on('theme', 'themeChanged', async (theme) => {
handleThemeChange(theme)
})
const theme = await plugin.call('theme', 'currentTheme')
handleThemeChange(theme)
const shells = await plugin.call('xterm', 'getShells')
setShells(shells)
}, 2000)
}, [])
const handleThemeChange = (theme: any) => {
themeCollection.forEach((themeItem) => {
if (themeItem.themeName === theme.name) {
setTheme(themeItem)
}
})
}
const writeToTerminal = (data: string, pid: number) => {
setTerminals(prevState => {
const terminal = prevState.find(xtermState => xtermState.pid === pid)
if (terminal.ref && terminal.ref.terminal) {
terminal.ref.terminal.write(data)
} else {
terminal.queue += data
}
return [...prevState]
})
}
const send = (data: string, pid: number) => {
plugin.call('xterm', 'keystroke', data, pid)
}
const createTerminal = async (shell?: string) => {
const pid = await plugin.call('xterm', 'createTerminal', workingDir, shell)
setShowOutput(false)
setTerminals(prevState => {
// set all to hidden
prevState.forEach(xtermState => {
xtermState.hidden = true
})
return [...prevState, {
pid: pid,
queue: '',
timeStamp: Date.now(),
ref: null,
hidden: false
}]
})
}
const setTerminalRef = (pid: number, ref: any) => {
setTerminals(prevState => {
const terminal = prevState.find(xtermState => xtermState.pid === pid)
terminal.ref = ref
if (terminal.queue) {
ref.terminal.write(terminal.queue)
terminal.queue = ''
}
return [...prevState]
})
}
const selectTerminal = (state: xtermState) => {
setTerminals(prevState => {
// set all to hidden
prevState.forEach(xtermState => {
xtermState.hidden = true
})
const terminal = prevState.find(xtermState => xtermState.pid === state.pid)
terminal.hidden = false
return [...prevState]
})
}
const closeTerminal = () => {
const pid = terminals.find(xtermState => xtermState.hidden === false).pid
if (pid)
plugin.call('xterm', 'close', pid)
}
const selectOutput = () => {
setShowOutput(true)
}
const showTerminal = () => {
setShowOutput(false)
if (terminals.length === 0) createTerminal()
}
return (<>
<div className='xterm-panel'>
<div className='xterm-panel-header bg-light'>
<div className='xterm-panel-header-left p-1'>
<button className={`btn btn-sm btn-secondary mr-2 ${!showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={selectOutput}>ouput</button>
<button className={`btn btn-sm btn-secondary ${terminalsEnabled ? '' : 'd-none'} ${showOutput ? 'xterm-btn-none' : 'xterm-btn-active'}`} onClick={showTerminal}><span className="far fa-terminal border-0 ml-1"></span></button>
</div>
<div className={`xterm-panel-header-right ${showOutput ? 'd-none' : ''}`}>
<Dropdown as={ButtonGroup}>
<button className="btn btn-sm btn-secondary" onClick={async() => createTerminal()}><span className="far fa-plus border-0 p-0 m-0"></span></button>
<Dropdown as={ButtonGroup}>
<button className="btn btn-sm btn-secondary" onClick={async() => createTerminal()}><span className="far fa-plus border-0 p-0 m-0"></span></button>
<Dropdown.Toggle split variant="secondary" id="dropdown-split-basic" />
<Dropdown.Toggle split variant="secondary" id="dropdown-split-basic" />
<Dropdown.Menu className='custom-dropdown-items remixui_menuwidth'>
{shells.map((shell, index) => {
return (<Dropdown.Item key={index} onClick={async() => await createTerminal(shell)}>{shell}</Dropdown.Item>)
})}
</Dropdown.Menu>
</Dropdown>
<button className="btn ml-2 btn-sm btn-secondary" onClick={closeTerminal}><span className="far fa-trash border-0 ml-1"></span></button>
<Dropdown.Menu className='custom-dropdown-items remixui_menuwidth'>
{shells.map((shell, index) => {
return (<Dropdown.Item key={index} onClick={async() => await createTerminal(shell)}>{shell}</Dropdown.Item>)
})}
</Dropdown.Menu>
</Dropdown>
<button className="btn ml-2 btn-sm btn-secondary" onClick={closeTerminal}><span className="far fa-trash border-0 ml-1"></span></button>
</div>
</div>
<div className='remix-ui-xterminals-container'>
<>
<div className={`${!showOutput ? 'd-none' : 'd-block w-100'} `}>
<RemixUiTerminal
plugin={props.plugin}
onReady={props.onReady} />
</div>
<div className={`remix-ui-xterminals-section ${showOutput ? 'd-none' : 'd-flex'} `}>
{terminals.map((xtermState) => {
return (
<div className={`h-100 xterm-terminal ${xtermState.hidden ? 'hide-xterm' : 'show-xterm'}`} key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>
<RemixUiXterm theme={theme} setTerminalRef={setTerminalRef} timeStamp={xtermState.timeStamp} send={send} pid={xtermState.pid} plugin={plugin}></RemixUiXterm>
</div>
)
})}
<div className='remix-ui-xterminals-buttons border-left'>
{terminals.map((xtermState, index) => {
return (<button key={index} onClick={async () => selectTerminal(xtermState)} className={`btn btn-sm mt-2 btn-secondary ${xtermState.hidden ? 'xterm-btn-none' : 'xterm-btn-active'}`}><span className="fa fa-terminal border-0 p-0 m-0"></span></button>)
})}
</div>
</div>
</>
</div>
</div>
<div className='remix-ui-xterminals-container'>
<>
<div className={`${!showOutput ? 'd-none' : 'd-block w-100'} `}>
<RemixUiTerminal
plugin={props.plugin}
onReady={props.onReady} />
</div>
<div className={`remix-ui-xterminals-section ${showOutput ? 'd-none' : 'd-flex'} `}>
{terminals.map((xtermState) => {
return (
<div className={`h-100 xterm-terminal ${xtermState.hidden ? 'hide-xterm' : 'show-xterm'}`} key={xtermState.pid} data-id={`remixUIXT${xtermState.pid}`}>
<RemixUiXterm theme={theme} setTerminalRef={setTerminalRef} timeStamp={xtermState.timeStamp} send={send} pid={xtermState.pid} plugin={plugin}></RemixUiXterm>
</div>
)
})}
<div className='remix-ui-xterminals-buttons border-left'>
{terminals.map((xtermState, index) => {
return (<button key={index} onClick={async () => selectTerminal(xtermState)} className={`btn btn-sm mt-2 btn-secondary ${xtermState.hidden ? 'xterm-btn-none' : 'xterm-btn-active'}`}><span className="fa fa-terminal border-0 p-0 m-0"></span></button>)
})}
</div>
</div>
</>
</div>
</div>
</>)
</>)
}
const themeCollection = [
{ themeName: 'HackerOwl', backgroundColor: '#011628', textColor: '#babbcc',
{ themeName: 'HackerOwl', backgroundColor: '#011628', textColor: '#babbcc',
shapeColor: '#8694a1',fillColor: '#011C32'},
{ themeName: 'Cerulean', backgroundColor: '#ffffff', textColor: '#343a40',
{ themeName: 'Cerulean', backgroundColor: '#ffffff', textColor: '#343a40',
shapeColor: '#343a40',fillColor: '#f8f9fa'},
{ themeName: 'Cyborg', backgroundColor: '#060606', textColor: '#adafae',
{ themeName: 'Cyborg', backgroundColor: '#060606', textColor: '#adafae',
shapeColor: '#adafae', fillColor: '#222222'},
{ themeName: 'Dark', backgroundColor: '#222336', textColor: '#babbcc',
{ themeName: 'Dark', backgroundColor: '#222336', textColor: '#babbcc',
shapeColor: '#babbcc',fillColor: '#2a2c3f'},
{ themeName: 'Flatly', backgroundColor: '#ffffff', textColor: '#343a40',
{ themeName: 'Flatly', backgroundColor: '#ffffff', textColor: '#343a40',
shapeColor: '#7b8a8b',fillColor: '#ffffff'},
{ themeName: 'Black', backgroundColor: '#1a1a1a', textColor: '#babbcc',
{ themeName: 'Black', backgroundColor: '#1a1a1a', textColor: '#babbcc',
shapeColor: '#b5b4bc',fillColor: '#1f2020'},
{ themeName: 'Light', backgroundColor: '#eef1f6', textColor: '#3b445e',
{ themeName: 'Light', backgroundColor: '#eef1f6', textColor: '#3b445e',
shapeColor: '#343a40',fillColor: '#ffffff'},
{ themeName: 'Midcentury', backgroundColor: '#DBE2E0', textColor: '#11556c',
{ themeName: 'Midcentury', backgroundColor: '#DBE2E0', textColor: '#11556c',
shapeColor: '#343a40',fillColor: '#eeede9'},
{ themeName: 'Spacelab', backgroundColor: '#ffffff', textColor: '#343a40',
{ themeName: 'Spacelab', backgroundColor: '#ffffff', textColor: '#343a40',
shapeColor: '#333333', fillColor: '#eeeeee'},
{ themeName: 'Candy', backgroundColor: '#d5efff', textColor: '#11556c',
{ themeName: 'Candy', backgroundColor: '#d5efff', textColor: '#11556c',
shapeColor: '#343a40',fillColor: '#fbe7f8' },
{ themeName: 'Violet', backgroundColor: '#f1eef6', textColor: '#3b445e',
{ themeName: 'Violet', backgroundColor: '#f1eef6', textColor: '#3b445e',
shapeColor: '#343a40',fillColor: '#f8fafe' },
{ themeName: 'Pride', backgroundColor: '#f1eef6', textColor: '#343a40',
{ themeName: 'Pride', backgroundColor: '#f1eef6', textColor: '#343a40',
shapeColor: '#343a40',fillColor: '#f8fafe' },
]
]

@ -103,135 +103,135 @@ interface IProps {
}
export class Xterm extends React.Component<IProps> {
/**
/**
* The ref for the containing element.
*/
terminalRef: React.RefObject<HTMLDivElement>
terminalRef: React.RefObject<HTMLDivElement>
/**
/**
* XTerm.js Terminal object.
*/
terminal!: Terminal // This is assigned in the setupTerminal() which is called from the constructor
static propTypes = {
className: PropTypes.string,
options: PropTypes.object,
addons: PropTypes.array,
onBinary: PropTypes.func,
onCursorMove: PropTypes.func,
onData: PropTypes.func,
onKey: PropTypes.func,
onLineFeed: PropTypes.func,
onScroll: PropTypes.func,
onSelectionChange: PropTypes.func,
onRender: PropTypes.func,
onResize: PropTypes.func,
onTitleChange: PropTypes.func,
customKeyEventHandler: PropTypes.func,
}
constructor(props: IProps) {
super(props)
this.terminalRef = React.createRef()
// Bind Methods
this.onData = this.onData.bind(this)
this.onCursorMove = this.onCursorMove.bind(this)
this.onKey = this.onKey.bind(this)
this.onBinary = this.onBinary.bind(this)
this.onLineFeed = this.onLineFeed.bind(this)
this.onScroll = this.onScroll.bind(this)
this.onSelectionChange = this.onSelectionChange.bind(this)
this.onRender = this.onRender.bind(this)
this.onResize = this.onResize.bind(this)
this.onTitleChange = this.onTitleChange.bind(this)
this.setupTerminal()
}
setupTerminal() {
// Setup the XTerm terminal.
this.terminal = new Terminal(this.props.options)
// Load addons if the prop exists.
if (this.props.addons) {
this.props.addons.forEach((addon) => {
this.terminal.loadAddon(addon)
})
}
// Create Listeners
this.terminal.onBinary(this.onBinary)
this.terminal.onCursorMove(this.onCursorMove)
this.terminal.onData(this.onData)
this.terminal.onKey(this.onKey)
this.terminal.onLineFeed(this.onLineFeed)
this.terminal.onScroll(this.onScroll)
this.terminal.onSelectionChange(this.onSelectionChange)
this.terminal.onRender(this.onRender)
this.terminal.onResize(this.onResize)
this.terminal.onTitleChange(this.onTitleChange)
// Add Custom Key Event Handler
if (this.props.customKeyEventHandler) {
this.terminal.attachCustomKeyEventHandler(this.props.customKeyEventHandler)
}
}
componentDidMount() {
if (this.terminalRef.current) {
// Creates the terminal within the container element.
this.terminal.open(this.terminalRef.current)
}
}
componentWillUnmount() {
// When the component unmounts dispose of the terminal and all of its listeners.
this.terminal.dispose()
}
private onBinary(data: string) {
if (this.props.onBinary) this.props.onBinary(data)
}
private onCursorMove() {
if (this.props.onCursorMove) this.props.onCursorMove()
}
private onData(data: string) {
if (this.props.onData) this.props.onData(data)
}
private onKey(event: { key: string; domEvent: KeyboardEvent }) {
if (this.props.onKey) this.props.onKey(event)
}
private onLineFeed() {
if (this.props.onLineFeed) this.props.onLineFeed()
}
private onScroll(newPosition: number) {
if (this.props.onScroll) this.props.onScroll(newPosition)
}
private onSelectionChange() {
if (this.props.onSelectionChange) this.props.onSelectionChange()
}
private onRender(event: { start: number; end: number }) {
if (this.props.onRender) this.props.onRender(event)
}
private onResize(event: { cols: number; rows: number }) {
if (this.props.onResize) this.props.onResize(event)
}
private onTitleChange(newTitle: string) {
if (this.props.onTitleChange) this.props.onTitleChange(newTitle)
}
render() {
return <div className={this.props.className} ref={this.terminalRef} />
}
terminal!: Terminal // This is assigned in the setupTerminal() which is called from the constructor
static propTypes = {
className: PropTypes.string,
options: PropTypes.object,
addons: PropTypes.array,
onBinary: PropTypes.func,
onCursorMove: PropTypes.func,
onData: PropTypes.func,
onKey: PropTypes.func,
onLineFeed: PropTypes.func,
onScroll: PropTypes.func,
onSelectionChange: PropTypes.func,
onRender: PropTypes.func,
onResize: PropTypes.func,
onTitleChange: PropTypes.func,
customKeyEventHandler: PropTypes.func,
}
constructor(props: IProps) {
super(props)
this.terminalRef = React.createRef()
// Bind Methods
this.onData = this.onData.bind(this)
this.onCursorMove = this.onCursorMove.bind(this)
this.onKey = this.onKey.bind(this)
this.onBinary = this.onBinary.bind(this)
this.onLineFeed = this.onLineFeed.bind(this)
this.onScroll = this.onScroll.bind(this)
this.onSelectionChange = this.onSelectionChange.bind(this)
this.onRender = this.onRender.bind(this)
this.onResize = this.onResize.bind(this)
this.onTitleChange = this.onTitleChange.bind(this)
this.setupTerminal()
}
setupTerminal() {
// Setup the XTerm terminal.
this.terminal = new Terminal(this.props.options)
// Load addons if the prop exists.
if (this.props.addons) {
this.props.addons.forEach((addon) => {
this.terminal.loadAddon(addon)
})
}
// Create Listeners
this.terminal.onBinary(this.onBinary)
this.terminal.onCursorMove(this.onCursorMove)
this.terminal.onData(this.onData)
this.terminal.onKey(this.onKey)
this.terminal.onLineFeed(this.onLineFeed)
this.terminal.onScroll(this.onScroll)
this.terminal.onSelectionChange(this.onSelectionChange)
this.terminal.onRender(this.onRender)
this.terminal.onResize(this.onResize)
this.terminal.onTitleChange(this.onTitleChange)
// Add Custom Key Event Handler
if (this.props.customKeyEventHandler) {
this.terminal.attachCustomKeyEventHandler(this.props.customKeyEventHandler)
}
}
componentDidMount() {
if (this.terminalRef.current) {
// Creates the terminal within the container element.
this.terminal.open(this.terminalRef.current)
}
}
componentWillUnmount() {
// When the component unmounts dispose of the terminal and all of its listeners.
this.terminal.dispose()
}
private onBinary(data: string) {
if (this.props.onBinary) this.props.onBinary(data)
}
private onCursorMove() {
if (this.props.onCursorMove) this.props.onCursorMove()
}
private onData(data: string) {
if (this.props.onData) this.props.onData(data)
}
private onKey(event: { key: string; domEvent: KeyboardEvent }) {
if (this.props.onKey) this.props.onKey(event)
}
private onLineFeed() {
if (this.props.onLineFeed) this.props.onLineFeed()
}
private onScroll(newPosition: number) {
if (this.props.onScroll) this.props.onScroll(newPosition)
}
private onSelectionChange() {
if (this.props.onSelectionChange) this.props.onSelectionChange()
}
private onRender(event: { start: number; end: number }) {
if (this.props.onRender) this.props.onRender(event)
}
private onResize(event: { cols: number; rows: number }) {
if (this.props.onResize) this.props.onResize(event)
}
private onTitleChange(newTitle: string) {
if (this.props.onTitleChange) this.props.onTitleChange(newTitle)
}
render() {
return <div className={this.props.className} ref={this.terminalRef} />
}
}
Loading…
Cancel
Save