Merge pull request #1774 from ethereum/solidityCompilerTerminal

Push the `appStore` to the terminal and add autocompletion support
pull/3094/head
yann300 6 years ago committed by GitHub
commit d3fd7a9ba0
  1. 3
      src/app/panels/editor-panel.js
  2. 26
      src/app/panels/terminal.js
  3. 30
      src/app/ui/auto-complete-popup.js
  4. 4
      src/lib/cmdInterpreterAPI.js

@ -100,7 +100,8 @@ class EditorPanel {
self._components.contextView = contextView self._components.contextView = contextView
self._components.terminal = new Terminal({ self._components.terminal = new Terminal({
udapp: self._deps.udapp, udapp: self._deps.udapp,
compilers: {} appStore: self.appStore,
appManager: self.appManager
}, },
{ {
getPosition: (event) => { getPosition: (event) => {

@ -17,6 +17,7 @@ var AutoCompletePopup = require('../ui/auto-complete-popup')
var csjs = require('csjs-inject') var csjs = require('csjs-inject')
var css = require('./styles/terminal-styles') var css = require('./styles/terminal-styles')
import { BaseApi } from 'remix-plugin'
var packageV = require('../../../package.json') var packageV = require('../../../package.json')
@ -26,8 +27,18 @@ function register (api) { KONSOLES.push(api) }
var ghostbar = yo`<div class=${css.ghostbar} bg-secondary></div>` var ghostbar = yo`<div class=${css.ghostbar} bg-secondary></div>`
class Terminal { const profile = {
displayName: 'Terminal',
name: 'terminal',
methods: [],
events: [],
description: ' - ',
required: false
}
class Terminal extends BaseApi {
constructor (opts, api) { constructor (opts, api) {
super(profile)
var self = this var self = this
self.event = new EventManager() self.event = new EventManager()
self._api = api self._api = api
@ -62,12 +73,12 @@ class Terminal {
self.updateJournal({ type: 'select', value: label }) self.updateJournal({ type: 'select', value: label })
} }
}) })
self._components.autoCompletePopup = new AutoCompletePopup() self._components.autoCompletePopup = new AutoCompletePopup(self._opts)
self._components.autoCompletePopup.event.register('handleSelect', function (input) { self._components.autoCompletePopup.event.register('handleSelect', function (input) {
let textList = self._view.input.innerText.split(' ') let textList = self._view.input.innerText.split(' ')
textList.pop() textList.pop()
textList.push(input) textList.push(input)
self._view.input.innerText = `${textList}`.replace(/,/g, ' ') self._view.input.innerText = textList
self._view.input.focus() self._view.input.focus()
self.putCursor2End(self._view.input) self.putCursor2End(self._view.input)
}) })
@ -103,14 +114,18 @@ class Terminal {
self._jsSandboxContext = {} self._jsSandboxContext = {}
self._jsSandboxRegistered = {} self._jsSandboxRegistered = {}
self.externalApi = this.api()
self.externalApi.notifs = {'theme': ['switchTheme']}
opts.appManager.init([self.externalApi])
opts.appManager.activateRequestAndNotification(self.externalApi)
if (opts.shell) self._shell = opts.shell if (opts.shell) self._shell = opts.shell
register(self) register(self)
} }
focus () { focus () {
if (this._view.input) this._view.input.focus() if (this._view.input) this._view.input.focus()
} }
render () { render () {
var self = this var self = this
if (self._view.el) return self._view.el if (self._view.el) return self._view.el
@ -649,7 +664,6 @@ class Terminal {
function domTerminalFeatures (self, scopedCommands) { function domTerminalFeatures (self, scopedCommands) {
return { return {
compilers: self._opts.compilers,
swarmgw, swarmgw,
ethers, ethers,
remix: self._components.cmdInterpreter, remix: self._components.cmdInterpreter,

@ -23,8 +23,9 @@ class AutoCompletePopup {
var self = this var self = this
self.event = new EventManager() self.event = new EventManager()
self.isOpen = false self.isOpen = false
self.opts = opts
self.data = { self.data = {
_options: opts.options || [] _options: []
} }
self._components = { self._components = {
modal: null modal: null
@ -33,7 +34,9 @@ class AutoCompletePopup {
self._startingElement = 0 self._startingElement = 0
self._elementsToShow = 4 self._elementsToShow = 4
self._selectedElement = 0 self._selectedElement = 0
this.extraCommands = []
this.render() this.render()
this.extendAutocompletion()
} }
render () { render () {
@ -149,18 +152,24 @@ class AutoCompletePopup {
this.isOpen = true this.isOpen = true
this.data._options = [] this.data._options = []
Commands.allPrograms.forEach(item => { Commands.allPrograms.forEach(item => {
let program = getKeyOf(item) const program = getKeyOf(item)
if (program.substring(0, program.length - 1).includes(autoCompleteInput.trim())) { if (program.substring(0, program.length - 1).includes(autoCompleteInput.trim())) {
this.data._options.push(item) this.data._options.push(item)
} else if (autoCompleteInput.trim().includes(program) || (program === autoCompleteInput.trim())) { } else if (autoCompleteInput.trim().includes(program) || (program === autoCompleteInput.trim())) {
Commands.allCommands.forEach(item => { Commands.allCommands.forEach(item => {
let command = getKeyOf(item) const command = getKeyOf(item)
if (command.includes(autoCompleteInput.trim())) { if (command.includes(autoCompleteInput.trim())) {
this.data._options.push(item) this.data._options.push(item)
} }
}) })
} }
}) })
this.extraCommands.forEach(item => {
const command = getKeyOf(item)
if (command.includes(autoCompleteInput.trim())) {
this.data._options.push(item)
}
})
if (this.data._options.length === 1 && event.which === 9) { if (this.data._options.length === 1 && event.which === 9) {
// if only one option and tab is pressed, we resolve it // if only one option and tab is pressed, we resolve it
@ -188,6 +197,21 @@ class AutoCompletePopup {
this._selectedElement = 0 this._selectedElement = 0
yo.update(this._view, this.render()) yo.update(this._view, this.render())
} }
extendAutocompletion () {
// TODO: this is not using the appManager interface. Terminal should be put as module
this.opts.appStore.event.on('activate', (id) => {
const profile = this.opts.appStore.getOne(id).profile
if (!profile.methods) return
profile.methods.forEach((method) => {
const key = `remix.call({name: '${id}', key:'${method}', payload: []}).then((result) => { console.log(result) }).catch((error) => { console.log(error) })`
const keyValue = {}
keyValue[key] = `call ${id} - ${method}`
if (this.extraCommands.includes(keyValue)) return
this.extraCommands.push(keyValue)
})
})
}
} }
function getKeyOf (item) { function getKeyOf (item) {

@ -28,6 +28,7 @@ class CmdInterpreterAPI {
offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api
} }
self.commandHelp = { self.commandHelp = {
'remix.call(message: {name, key, payload})': 'Call a registered plugins',
'remix.getFile(path)': 'Returns the content of the file located at the given path', 'remix.getFile(path)': 'Returns the content of the file located at the given path',
'remix.setFile(path, content)': 'set the content of the file located at the given path', 'remix.setFile(path, content)': 'set the content of the file located at the given path',
'remix.debug(hash)': 'Start debugging a transaction.', 'remix.debug(hash)': 'Start debugging a transaction.',
@ -40,6 +41,9 @@ class CmdInterpreterAPI {
'remix.debugHelp()': 'Display help message for debugging' 'remix.debugHelp()': 'Display help message for debugging'
} }
} }
call (message) {
return this._components.terminal.externalApi.request(message)
}
log () { arguments[0] != null ? this._components.terminal.commands.html(arguments[0]) : this._components.terminal.commands.html(arguments[1]) } log () { arguments[0] != null ? this._components.terminal.commands.html(arguments[0]) : this._components.terminal.commands.html(arguments[1]) }
highlight (rawLocation) { highlight (rawLocation) {
var self = this var self = this

Loading…
Cancel
Save