mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
added autocompletion to console
This commit is contained in:
parent
88a0ba0895
commit
eccf1f76b3
5 changed files with 171 additions and 5 deletions
|
|
@ -28,6 +28,8 @@ import (
|
||||||
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common/docserver"
|
"github.com/ethereum/go-ethereum/common/docserver"
|
||||||
re "github.com/ethereum/go-ethereum/jsre"
|
re "github.com/ethereum/go-ethereum/jsre"
|
||||||
|
|
@ -73,6 +75,54 @@ type jsre struct {
|
||||||
prompter
|
prompter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
loadedModulesMethods map[string][]string
|
||||||
|
)
|
||||||
|
|
||||||
|
func loadAutoCompletion(js *jsre, ipcpath string) {
|
||||||
|
modules, err := js.suportedApis(ipcpath)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Unable to determine supported modules - %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("load autocompletion %v", modules)
|
||||||
|
|
||||||
|
loadedModulesMethods = make(map[string][]string)
|
||||||
|
for module, _ := range modules {
|
||||||
|
loadedModulesMethods[module] = api.AutoCompletion[module]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func apiWordCompleter(line string) []string {
|
||||||
|
results := make([]string, 0)
|
||||||
|
|
||||||
|
if strings.Contains(line, ".") {
|
||||||
|
elements := strings.Split(line, ".")
|
||||||
|
if len(elements) == 2 {
|
||||||
|
module := elements[0]
|
||||||
|
partialMethod := elements[1]
|
||||||
|
if methods, found := loadedModulesMethods[module]; found {
|
||||||
|
for _, method := range methods {
|
||||||
|
if strings.HasPrefix(method, partialMethod) { // e.g. debug.se
|
||||||
|
results = append(results, module+"."+method)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for module, methods := range loadedModulesMethods {
|
||||||
|
if line == module { // user typed in full module name, show all methods
|
||||||
|
for _, method := range methods {
|
||||||
|
results = append(results, module+"."+method)
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(module, line) { // partial method name, e.g. admi
|
||||||
|
results = append(results, module)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
func newJSRE(libPath, ipcpath string) *jsre {
|
func newJSRE(libPath, ipcpath string) *jsre {
|
||||||
js := &jsre{ps1: "> "}
|
js := &jsre{ps1: "> "}
|
||||||
js.wait = make(chan *big.Int)
|
js.wait = make(chan *big.Int)
|
||||||
|
|
@ -87,6 +137,9 @@ func newJSRE(libPath, ipcpath string) *jsre {
|
||||||
lr := liner.NewLiner()
|
lr := liner.NewLiner()
|
||||||
js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
|
js.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
|
||||||
lr.SetCtrlCAborts(true)
|
lr.SetCtrlCAborts(true)
|
||||||
|
loadAutoCompletion(js, ipcpath)
|
||||||
|
lr.SetCompleter(apiWordCompleter)
|
||||||
|
lr.SetTabCompletionStyle(liner.TabPrints)
|
||||||
js.prompter = lr
|
js.prompter = lr
|
||||||
js.atexit = func() {
|
js.atexit = func() {
|
||||||
js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) })
|
js.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) })
|
||||||
|
|
@ -242,11 +295,13 @@ func (self *jsre) welcome(ipcpath string) {
|
||||||
+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`)
|
+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`)
|
||||||
|
|
||||||
if modules, err := self.suportedApis(ipcpath); err == nil {
|
if modules, err := self.suportedApis(ipcpath); err == nil {
|
||||||
modulesVersionString := ""
|
loadedModules := make([]string, 0)
|
||||||
for api, version := range modules {
|
for api, version := range modules {
|
||||||
modulesVersionString += fmt.Sprintf("%s:%s ", api, version)
|
loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version))
|
||||||
}
|
}
|
||||||
self.re.Eval(fmt.Sprintf("var modules = '%s';", modulesVersionString))
|
sort.Strings(loadedModules)
|
||||||
|
|
||||||
|
self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " ")))
|
||||||
self.re.Eval(`console.log(" modules: " + modules);`)
|
self.re.Eval(`console.log(" modules: " + modules);`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ func (self *debugApi) DumpBlock(req *shared.Request) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return stateDb.Dump(), nil
|
return stateDb.RawDump(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *debugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
|
func (self *debugApi) GetBlockRlp(req *shared.Request) (interface{}, error) {
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,13 @@ web3._extend({
|
||||||
params: 1,
|
params: 1,
|
||||||
inputFormatter: [web3._extend.formatters.formatInputInt],
|
inputFormatter: [web3._extend.formatters.formatInputInt],
|
||||||
outputFormatter: web3._extend.formatters.formatOutputString
|
outputFormatter: web3._extend.formatters.formatOutputString
|
||||||
|
}) ,
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'dumpBlock',
|
||||||
|
call: 'debug_dumpBlock',
|
||||||
|
params: 1,
|
||||||
|
inputFormatter: [web3._extend.formatters.formatInputInt],
|
||||||
|
outputFormatter: function(obj) { return obj; }
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
properties:
|
properties:
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ web3._extend({
|
||||||
properties:
|
properties:
|
||||||
[
|
[
|
||||||
new web3._extend.Property({
|
new web3._extend.Property({
|
||||||
name: 'accounts',
|
name: 'listAccounts',
|
||||||
getter: 'personal_listAccounts',
|
getter: 'personal_listAccounts',
|
||||||
outputFormatter: function(obj) { return obj; }
|
outputFormatter: function(obj) { return obj; }
|
||||||
})
|
})
|
||||||
|
|
|
||||||
104
rpc/api/utils.go
104
rpc/api/utils.go
|
|
@ -10,6 +10,110 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/xeth"
|
"github.com/ethereum/go-ethereum/xeth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Mapping between the different methods each api supports
|
||||||
|
AutoCompletion = map[string][]string{
|
||||||
|
"admin": []string{
|
||||||
|
"addPeer",
|
||||||
|
"peers",
|
||||||
|
"nodeInfo",
|
||||||
|
"exportChain",
|
||||||
|
"importChain",
|
||||||
|
"verbosity",
|
||||||
|
"chainSyncStatus",
|
||||||
|
"setSolc",
|
||||||
|
"datadir",
|
||||||
|
},
|
||||||
|
"debug": []string{
|
||||||
|
"dumpBlock",
|
||||||
|
"getBlockRlp",
|
||||||
|
"printBlock",
|
||||||
|
"processBlock",
|
||||||
|
"seedHash",
|
||||||
|
"setHead",
|
||||||
|
},
|
||||||
|
"eth": []string{
|
||||||
|
"accounts",
|
||||||
|
"blockNumber",
|
||||||
|
"getBalance",
|
||||||
|
"protocolVersion",
|
||||||
|
"coinbase",
|
||||||
|
"mining",
|
||||||
|
"gasPrice",
|
||||||
|
"getStorage",
|
||||||
|
"storageAt",
|
||||||
|
"getStorageAt",
|
||||||
|
"getTransactionCount",
|
||||||
|
"getBlockTransactionCountByHash",
|
||||||
|
"getBlockTransactionCountByNumber",
|
||||||
|
"getUncleCountByBlockHash",
|
||||||
|
"getUncleCountByBlockNumber",
|
||||||
|
"getData",
|
||||||
|
"getCode",
|
||||||
|
"sign",
|
||||||
|
"sendTransaction",
|
||||||
|
"transact",
|
||||||
|
"estimateGas",
|
||||||
|
"call",
|
||||||
|
"flush",
|
||||||
|
"getBlockByHash",
|
||||||
|
"getBlockByNumber",
|
||||||
|
"getTransactionByHash",
|
||||||
|
"getTransactionByBlockHashAndIndex",
|
||||||
|
"getUncleByBlockHashAndIndex",
|
||||||
|
"getUncleByBlockNumberAndIndex",
|
||||||
|
"getCompilers",
|
||||||
|
"compileSolidity",
|
||||||
|
"newFilter",
|
||||||
|
"newBlockFilter",
|
||||||
|
"newPendingTransactionFilter",
|
||||||
|
"uninstallFilter",
|
||||||
|
"getFilterChanges",
|
||||||
|
"getFilterLogs",
|
||||||
|
"getLogs",
|
||||||
|
"hashrate",
|
||||||
|
"getWork",
|
||||||
|
"submitWork",
|
||||||
|
},
|
||||||
|
"miner": []string{
|
||||||
|
"hashrate",
|
||||||
|
"makeDAG",
|
||||||
|
"setExtra",
|
||||||
|
"setGasPrice",
|
||||||
|
"startAutoDAG",
|
||||||
|
"start",
|
||||||
|
"stopAutoDAG",
|
||||||
|
"stop",
|
||||||
|
},
|
||||||
|
"net": []string{
|
||||||
|
"peerCount",
|
||||||
|
"listening",
|
||||||
|
},
|
||||||
|
"personal": []string{
|
||||||
|
"listAccounts",
|
||||||
|
"newAccount",
|
||||||
|
"deleteAccount",
|
||||||
|
"unlockAccount",
|
||||||
|
},
|
||||||
|
"shh": []string{
|
||||||
|
"version",
|
||||||
|
"post",
|
||||||
|
"hasIdentity",
|
||||||
|
"newIdentity",
|
||||||
|
"newFilter",
|
||||||
|
"uninstallFilter",
|
||||||
|
"getFilterChanges",
|
||||||
|
},
|
||||||
|
"txpool": []string{
|
||||||
|
"status",
|
||||||
|
},
|
||||||
|
"web3": []string{
|
||||||
|
"sha3",
|
||||||
|
"version",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Parse a comma separated API string to individual api's
|
// Parse a comma separated API string to individual api's
|
||||||
func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]EthereumApi, error) {
|
func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]EthereumApi, error) {
|
||||||
if len(strings.TrimSpace(apistr)) == 0 {
|
if len(strings.TrimSpace(apistr)) == 0 {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue