diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 2d17230b72..0029802c1e 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -91,6 +91,18 @@ class Terminal extends Plugin { } onActivation () { + this.on('scriptRunner', 'log', (msg) => { + this.commands.log.apply(this.commands, msg.data) + }) + this.on('scriptRunner', 'info', (msg) => { + this.commands.info.apply(this.commands, msg.data) + }) + this.on('scriptRunner', 'warn', (msg) => { + this.commands.warn.apply(this.commands, msg.data) + }) + this.on('scriptRunner', 'error', (msg) => { + this.commands.error.apply(this.commands, msg.data) + }) this.renderComponent() } @@ -108,7 +120,9 @@ class Terminal extends Plugin { options = {this.opts} data = {this.data} cmdInterpreter = {this._components.cmdInterpreter} - autoCompletePopup = {this._components.autoCompletePopup}/>, + autoCompletePopup = {this._components.autoCompletePopup} + registerCommand = {this.registerCommand} + />, this.element ) } diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx index 60249b4193..282bc073b4 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react' // eslint-disable-line +import React, { useState, useEffect, useRef, SyntheticEvent } from 'react' // eslint-disable-line import './remix-ui-terminal.css' @@ -13,12 +13,38 @@ export interface RemixUiTerminalProps { options: any data: any cmdInterpreter: any + registerCommand: any +} + +export interface ClipboardEvent extends SyntheticEvent { + clipboardData: DataTransfer; } export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') const [inserted, setInserted] = useState(false) + + const [state, setState] = useState({ + data: { + // lineLength: props.options.lineLength || 80, + session: [], + activeFilters: { commands: {}, input: '' }, + filterFns: {} + }, + _commands: {}, + commands: {}, + _JOURNAL: [], + _jobs: [], + _INDEX: {}, + _INDEXall: [], + _INDEXallMain: [], + _INDEXcommands: {}, + _INDEXcommandsMain: {} + }) + + // terminal inputRef + const inputEl = useRef(null) // events useEffect(() => { // window.addEventListener('resize', function () { @@ -33,6 +59,25 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // } }, []) + // handle events + const handlePaste = (event: ClipboardEvent) => { + // Do something + const selection = window.getSelection() + if (!selection.rangeCount) return false + event.preventDefault() + event.stopPropagation() + var clipboard = (event.clipboardData) // || window.clipboardData + var text = clipboard.getData('text/plain') + text = text.replace(/[^\x20-\xFF]/gi, '') // remove non-UTF-8 characters + var temp = document.createElement('div') + temp.innerHTML = text + var textnode = document.createTextNode(temp.textContent) + selection.getRangeAt(0).insertNode(textnode) + selection.empty() + // self.scroll2bottom() + // placeCaretAtEnd(event.currentTarget) + } + const handleMinimizeTerminal = (event) => { console.log('clikced', props.event) if (toggleDownUp === 'fa-angle-double-down') { @@ -47,14 +92,76 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { console.log(props.event, 'event.trigger') } - const reattached = (event) => { - let el = event.currentTarget - var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 - if (isBottomed) { + // const reattached = (event) => { + // let el = event.currentTarget + // var isBottomed = el.scrollHeight - el.scrollTop - el.clientHeight < 30 + // if (isBottomed) { + + // } else { + // // if (!inserted) + // } + // } + + const registerCommand = (name, command, opts) => { + const { _commands, _INDEXcommands, _INDEXallMain, _INDEXcommandsMain, _INDEXall, commands } = state + // TODO if no _commands[name] throw an error + + // TODO if typeof command !== 'function' throw error + _commands[name] = command + _INDEXcommands[name] = [] + _INDEXallMain[name] = [] + + // TODO _command function goes here + commands[name] = function _command () { + const steps = [] + const args = [...arguments] + const gidx = 0 + const idx = 0 + const step = 0 + const root = { steps, cmd: name, gidx, idx } + const ITEM = { root, cmd: name, el: {} } + root.gidx = _INDEXallMain.push(ITEM) - 1 + root.idx = _INDEXcommandsMain[name].push(ITEM) - 1 + function append (cmd, params, el) { + let item = { el, cmd, root, gidx, idx, step, args: [...arguments] } + if (cmd) { + item = { el, cmd, root, gidx, idx, step, args } + } else { + // item = ITEM + item.el = el + cmd = name + } + item.gidx = _INDEXall.push(item) - 1 + item.idx = _INDEXcommands[cmd].push(item) - 1 + item.step = steps.push(item) - 1 + item.args = params + _appendItem(item) + } } + + return commands[name] } + const _appendItem = (item: any) => { + let { _JOURNAL, _jobs, data } = state + const self = props + const { el, gidx } = item + _JOURNAL[gidx] = item + if (!_jobs.length) { + // requestAnimationFrame(function updateTerminal () { + // self._jobs.forEach(el => self._view.journal.appendChild(el)) + // self.scroll2bottom() + _jobs = [] + } + if (data.activeFilters.commands[item.cmd]) _jobs.push(el) + } + + const focusinput = () => { + inputEl.current.focus() + } + + return (
@@ -114,6 +221,16 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { }}>
+
+ {/* ${background} */} +
+ {/* ${text} */} +
+
+
+
+ {'>'} +
diff --git a/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts b/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts new file mode 100644 index 0000000000..e4846cfb10 --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/types/terminalTypes.ts @@ -0,0 +1,7 @@ + +export interface ROOTS { + steps: any, + cmd: string, + gidx: number, + idx: number +}