jsir 1.0.8 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (7) hide show
  1. package/cmd/ooa.js +248 -159
  2. package/ethWeb.js +114 -54
  3. package/index.js +23 -11
  4. package/package.json +1 -2
  5. package/sol.js +2 -1
  6. package/util.js +159 -65
  7. package/sql.js +0 -11
package/cmd/ooa.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  const {
3
3
  run, getLibDataDir, trim, regEach, getConfig, mkdir, requireG, reget,
4
- getCbText, setCbText, e, getOr, sleep, objDataFile, setConfig, vl
4
+ getCbText, setCbText, e, getOr, sleep, objDataFile, setConfig, vl, wrapRows,
5
+ info, warn, error, arrayDataFile
5
6
  } = require('../index')
6
7
 
7
8
  const _types = {
@@ -11,8 +12,9 @@ const _types = {
11
12
  }
12
13
  const _Chokidar = require('chokidar');
13
14
  const _fs = require('fs')
14
- const _home = getLibDataDir() + '/ooa'
15
- const _args = process.argv.slice(2)
15
+ const _libDataDir = getLibDataDir()
16
+ const _home = _libDataDir + '/ooa'
17
+ const _args = process.argv.slice(2).map(trim)
16
18
  const _history9 = []
17
19
  const _tipsOnRm = {}
18
20
  const _setting = require('../setting')
@@ -20,6 +22,7 @@ let _cmdMap = {}
20
22
  let _rl
21
23
  let _haveWrapperInput = false
22
24
  let _haveStartRead = false;
25
+ let _repos = arrayDataFile('repos.json')
23
26
 
24
27
  const lib = require('../index')
25
28
 
@@ -37,6 +40,9 @@ const _table = require('console.table')
37
40
  console.table = (...args) => {
38
41
  console.log(trim(_table.getTable(...args)))
39
42
  }
43
+ console.nable = (rows) => {
44
+ console.table(wrapRows(rows))
45
+ }
40
46
 
41
47
  let _noAppendNextLine = true
42
48
 
@@ -93,11 +99,12 @@ const _mainCmdMap = {
93
99
  cmd: ['@*']
94
100
  },
95
101
  repo: {
96
- comment: "设置本地仓库目录"
102
+ comment: "设置本地仓库目录",
103
+ cmd: ['% ']
97
104
  },
98
105
  lib: {
99
106
  comment: "查看内置资源",
100
- cmd: ['$lib']
107
+ cmd: ['*lib ']
101
108
  }
102
109
  }
103
110
 
@@ -106,14 +113,6 @@ run(async () => {
106
113
  _fs.mkdirSync(_home)
107
114
  } catch (e) {}
108
115
 
109
- if (_args[0] === 'repo') {
110
- if (_args[1]) {
111
- setConfig('jsLibSource', _args[1])
112
-
113
- }
114
- console.log(`jsLibSource: ${getConfig('jsLibSource')}`)
115
- return
116
- }
117
116
  if (_args[0] === 'config') {
118
117
  let configFile = getLibDataDir() + '/config.json';
119
118
  e(`idea "${configFile}"`)
@@ -121,7 +120,7 @@ run(async () => {
121
120
  }
122
121
 
123
122
  dealSourceCmds()
124
- dealInitData()
123
+ await dealInitData()
125
124
 
126
125
  if (_args[0] === 'repl') {
127
126
  _noAppendNextLine = false
@@ -134,7 +133,7 @@ run(async () => {
134
133
 
135
134
  if (['run', 'edit', 'rm', 'diff', 'push', 'pull'].indexOf(_args[0]) !== -1
136
135
  && _args[1] && !/^\d+$/.test(_args[1])) {
137
- let name = `e ${_args[1]}.js`
136
+ let name = toJsirFileName(`e ${_args[1]}`)
138
137
  let path = _home + '/' + name
139
138
  if (_fs.existsSync(path)) {
140
139
  _cmdMap = {
@@ -165,7 +164,7 @@ run(async () => {
165
164
  }
166
165
 
167
166
  let argStr = _args.slice(1).map(i => {
168
- if (/\s+/.test(i)) {
167
+ if (/\s+/.test(i) || !i) {
169
168
  i = `"${i}"`
170
169
  }
171
170
  return i
@@ -176,14 +175,6 @@ run(async () => {
176
175
  if (['ls'].indexOf(_args[0]) !== -1 && !trim(argStr)) {
177
176
  argStr = ','
178
177
  }
179
- if (['lib'].indexOf(_args[0]) !== -1 && trim(argStr)) {
180
- argStr = trim(argStr)
181
- if (typeof lib[argStr] === "function") {
182
- argStr = '.' + argStr + '.toString()'
183
- } else {
184
- argStr = '.' + argStr
185
- }
186
- }
187
178
 
188
179
  let info = _mainCmdMap[_args[0]]
189
180
  if (info) {
@@ -213,7 +204,7 @@ async function fileLine(name) {
213
204
  }
214
205
  let tempDir = getLibDataDir() + "/ooa"
215
206
  mkdir(tempDir)
216
- let workFile = `${tempDir}/f ${name}.js`;
207
+ let workFile = `${tempDir}/f ${toJsirFileName(name)}`;
217
208
  if (!_fs.existsSync(workFile)) {
218
209
  _fs.writeFileSync(workFile, '');
219
210
  }
@@ -238,14 +229,13 @@ async function fileLine(name) {
238
229
  && newLine !== line) {
239
230
  let exeStrs
240
231
  if (newLine.startsWith("//")) {
241
- exeStrs = newLine.split('\n').map(i => trim(trim(i).replace(/^\/\//, '')))
242
- .filter(i => i)
232
+ exeStrs = []
243
233
  } else if (newLine.startsWith('/*')) {
244
234
  exeStrs = newLine.replace(/^\/\*|\*\/$/g, '').split('\n')
245
235
  .map(i => trim(trim(i).replace(/^\*/, '')))
246
236
  .filter(i => i)
247
237
  } else {
248
- exeStrs = ["$" + newLine]
238
+ exeStrs = ["#" + newLine]
249
239
  }
250
240
  for(let exeStr of exeStrs) {
251
241
  await wrapperInput(trim(exeStr))
@@ -305,10 +295,10 @@ function getLines(text) {
305
295
  lines.push(cLine.join('\n'))
306
296
  }
307
297
 
308
- return lines.reverse()
298
+ return lines.slice(1).reverse()
309
299
  }
310
300
 
311
- function dealInitData() {
301
+ async function dealInitData() {
312
302
  if (!global.$i) {
313
303
  global.$i = {}
314
304
  }
@@ -317,26 +307,28 @@ function dealInitData() {
317
307
  continue;
318
308
  }
319
309
  let filePath = _home + "/" + file;
320
- let initDataName = file.replace(/^i\s+/, '')
321
- .replace(/\.js$/, '')
310
+ let initDataName = trimJsirFileName(file.replace(/^i\s+/, ''))
322
311
  .split(/\s+/).filter(item => item).join("_");
323
312
  let text = String(_fs.readFileSync(filePath))
313
+ $i[initDataName] = null
324
314
  try {
325
- $i[initDataName] = evalText(text)
315
+ $i[initDataName] = await evalText(text)
326
316
  } catch (e) {
327
- error(e, `$i.${initDataName} loading failed`)
317
+ $log(`$i.${initDataName} loading failed\n${e.stack}`);
328
318
  }
329
319
  if (!vl($i[initDataName])) {
330
320
  warn(`$i.${initDataName} loading failed`)
331
321
  }
332
-
333
- if (!text.match(/\s+\$nextLine\s*\(\s*\)/)) {
334
- _noAppendNextLine || nextLine()
335
- }
336
322
  }
337
323
  }
338
324
 
339
- function nextLine(callback, preStr, hidden) {
325
+ async function nextLine(callback, preStr, hidden) {
326
+ return new Promise(resolve => {
327
+ _nextLine(callback, preStr, hidden, resolve)
328
+ })
329
+ }
330
+
331
+ function _nextLine(callback, preStr, hidden, resolve) {
340
332
  if (_haveStartRead && !_haveWrapperInput) {
341
333
  return
342
334
  }
@@ -358,9 +350,10 @@ function nextLine(callback, preStr, hidden) {
358
350
  }
359
351
  }
360
352
  _rl.removeAllListeners('line')
361
- _rl.on('line', line => {
353
+ _rl.on('line', async line => {
354
+ line = trim(line)
362
355
  _haveWrapperInput = true;
363
- if (hidden) {
356
+ if (line && (hidden || (callback && callback !== wrapperInput))) {
364
357
  _rl.history = _rl.history.slice(1)
365
358
  }
366
359
  if (_noAppendNextLine && _rl) {
@@ -368,31 +361,44 @@ function nextLine(callback, preStr, hidden) {
368
361
  _rl = null
369
362
  }
370
363
  try {
371
- (callback || wrapperInput)(trim(line))
364
+ await (callback || wrapperInput)(line)
372
365
  } finally {
366
+ resolve && resolve(line)
373
367
  callback = null
368
+ hidden = false
374
369
  }
375
370
  })
371
+ let repoTip = trim(trim(getConfig("jsLibSource")).split('/').map(trim).reverse().filter(i => i)[0])
376
372
  let promitStr = (preStr
377
373
  || ((callback && callback !== wrapperInput) ? "-> ":"")
378
- || Object.values(global.$tips).filter(i => String(i)).join(',') + "> ")
374
+ || [Object.values(global.$tips).filter(i => String(i)).join(','), repoTip].filter(i => i).join('-') + `> `)
379
375
  _rl.setPrompt(promitStr)
380
376
  process.stdout.write('\x1B[32m')
381
377
  _rl.prompt()
382
378
  process.stdout.write('\x1B[39m')
383
379
  }
384
380
 
385
- function nextText(callback, preStr, hidden) {
381
+ async function nextText(callback, preStr, hidden) {
382
+ return new Promise(resolve => {
383
+ _nextText(callback, preStr, hidden, resolve)
384
+ })
385
+ }
386
+
387
+ async function _nextText(callback, preStr, hidden, resolve) {
386
388
  preStr = preStr || "#"
387
389
  let text = ''
388
- let fn = line => {
389
- if (line === preStr) {
390
- callback(trim(text))
391
- }
390
+ let line = await nextLine(line => line, preStr, hidden)
391
+ while (line !== trim(preStr)) {
392
392
  text += line + "\n"
393
- nextLine(fn, preStr, hidden)
393
+ line = await nextLine(line => line, preStr, hidden)
394
+ }
395
+
396
+ text = trim(text)
397
+ try {
398
+ await callback(text)
399
+ } finally {
400
+ resolve && resolve(text)
394
401
  }
395
- nextLine(fn, preStr, hidden)
396
402
  }
397
403
 
398
404
  function dealSourceCmds() {
@@ -401,24 +407,24 @@ function dealSourceCmds() {
401
407
  mkdir(source)
402
408
  }
403
409
  if (source && _fs.existsSync(source)) {
404
- _fs.readdirSync(source).filter(item => item.endsWith('.js')).forEach(item => {
410
+ _fs.readdirSync(source).filter(isJsirFileName).forEach(item => {
405
411
  if (!_fs.existsSync(_home + "/" + item)) {
406
412
  _fs.writeFileSync(_home + "/" + item, String(_fs.readFileSync(source + "/" + item)))
407
413
  }
408
414
  })
409
415
  } else {
410
- warn(`config.jsLibSource not found, run [${_setting.name} repo dirPath]`)
416
+ warn(`config.jsLibSource undefined, run [${_setting.name} repo]`)
411
417
  }
412
418
  }
413
419
 
414
420
  async function save(args) {
415
- let path = `${_home}/${args.join(' ')}.js`
421
+ let path = `${_home}/${toJsirFileName(args.join(' '))}`
416
422
  if (_fs.existsSync(path)) {
417
423
  warn('already exist')
418
424
  return
419
425
  }
420
426
  let resp = `/*
421
- test
427
+ A test script
422
428
  */
423
429
 
424
430
  $defArgs({
@@ -429,9 +435,7 @@ $defArgs({
429
435
  let {} = $lib // 引用内置资源
430
436
  let {} = $i // 引用初始资源
431
437
 
432
- // your code
433
-
434
- console.log($args.arg)`;
438
+ console.log($args)`;
435
439
 
436
440
  if (args[0] !== 'e') {
437
441
  resp = await getCbText();
@@ -447,28 +451,7 @@ function rename(old, _new) {
447
451
  return
448
452
  }
449
453
  _fs.rename(old, _new, ()=>{})
450
- info(`${_new} renamed`)
451
- }
452
-
453
- function info(msg) {
454
- process.stdout.write('\x1B[32m')
455
- process.stdout.write('[info] ')
456
- process.stdout.write('\x1B[39m')
457
- console.log(msg)
458
- }
459
-
460
- function warn(msg) {
461
- process.stdout.write('\x1B[33m')
462
- process.stdout.write('[warn] ')
463
- process.stdout.write('\x1B[39m')
464
- console.log(msg)
465
- }
466
-
467
- function error(e, msg) {
468
- process.stdout.write('\x1B[35m')
469
- process.stdout.write(`[${msg || 'error'}] `)
470
- process.stdout.write('\x1B[39m')
471
- console.log(e)
454
+ return true
472
455
  }
473
456
 
474
457
  function putHis(x) {
@@ -524,11 +507,12 @@ function listCmd() {
524
507
 
525
508
  text = text1
526
509
  }
527
- let name = _cmdMap[i].replace(/\.js$/, '')
510
+ let name = trimJsirFileName(_cmdMap[i])
511
+ let suffix = getJsirFileSuffix(_cmdMap[i])
528
512
  let item = {
529
513
  key: prefix.join('') + i,
530
- type: _types[name.split(/\s+/)[0]] || 'note',
531
- name: name.replace(/^[eif]\s+/, '')
514
+ name: name.replace(/^[eif]\s+/, ''),
515
+ type: [_types[name.split(/\s+/)[0]] || 'note', suffix].map(trim).join(".")
532
516
  }
533
517
  items.push(item)
534
518
 
@@ -544,6 +528,35 @@ function listCmd() {
544
528
  }
545
529
  }
546
530
 
531
+ function printObjProfile(result) {
532
+ result = Object.keys(result).map(key => {
533
+ return {
534
+ key,
535
+ type: typeof result[key]
536
+ }})
537
+ .sort((a,b) => {
538
+ return a.type >= b.type ? 1:-1
539
+ })
540
+
541
+ let temp = []
542
+ for(let i = 0; i< Object.keys(result).length; i+=3) {
543
+ let item = {}
544
+ temp.push(item)
545
+
546
+ item['type'] = result[i].type
547
+ item['name']= result[i].key
548
+ if (result[i+1]) {
549
+ item['type '] = result[i+1].type
550
+ item['name ']= result[i+1].key
551
+ }
552
+ if (result[i+2]) {
553
+ item['type '] = result[i+2].type
554
+ item['name ']= result[i+2].key
555
+ }
556
+ }
557
+ console.table(temp)
558
+ }
559
+
547
560
  async function wrapperInput(str) {
548
561
  global.$newInput = true;
549
562
 
@@ -552,46 +565,51 @@ async function wrapperInput(str) {
552
565
  _noAppendNextLine || nextLine()
553
566
  return;
554
567
  }
555
- if (/^\$/.test(str)) {
556
- let text = trim(str.replace(/^\$/, ''))
568
+ if (/^[$#*]/.test(str)) {
569
+ let is$ = str.startsWith('$')
570
+ let isStar = str.startsWith('*')
571
+ let text = trim(str.replace(/^[$#*]/, ''))
557
572
  try {
558
- let result = evalText(text)
559
- if (result === $i || result === $lib) {
560
- result = Object.keys(result).map(key => {
561
- return {
562
- key,
563
- type: typeof result[key]
564
- }})
565
- .sort((a,b) => {
566
- return a.type >= b.type ? 1:-1
567
- })
568
-
569
- let temp = []
570
- for(let i = 0; i< Object.keys(result).length; i+=3) {
571
- let item = {}
572
- temp.push(item)
573
-
574
- item['type'] = result[i].type
575
- item['name']= result[i].key
576
- if (result[i+1]) {
577
- item['type '] = result[i+1].type
578
- item['name ']= result[i+1].key
579
- }
580
- if (result[i+2]) {
581
- item['type '] = result[i+2].type
582
- item['name ']= result[i+2].key
573
+ if (is$) {
574
+ let result = await evalText('return ' + text)
575
+ if (result === $i || result === $lib) {
576
+ printObjProfile(result)
577
+ } else {
578
+ console.log(result)
579
+ }
580
+ return
581
+ }
582
+ if (isStar) {
583
+ let items = text.split(/\s+/).map(trim).filter(i => i)
584
+ let result = await evalText('return ' + items[0])
585
+ if (!result || Object.keys(result).length === 0) {
586
+ console.log(result)
587
+ return
588
+ }
589
+ let rows = []
590
+ let matchs = items.slice(1)
591
+ for (let key of Object.keys(result)) {
592
+ if (matchs.length === 0 || isArgsMatch(key, matchs)){
593
+ let type = typeof result[key]
594
+ let str = String(result[key])
595
+ rows.push({
596
+ key: key,
597
+ value: type === 'function' ? str.split('\n')[0].replace(/\s*{\s*$/, '')
598
+ : (str.length <= 64 ? str:type)
599
+ })
583
600
  }
584
601
  }
585
- console.table(temp)
586
- } else {
587
- console.log(result)
602
+ if (rows.length === 0) {
603
+ warn("no items")
604
+ } else {
605
+ console.table(rows)
606
+ }
607
+ return
588
608
  }
609
+ await evalText(text)
589
610
  } catch (e) {
590
611
  error(e)
591
612
  }
592
- if (!text.match(/\s+\$nextLine\s*\(\s*\)/)) {
593
- _noAppendNextLine || nextLine()
594
- }
595
613
  return;
596
614
  }
597
615
 
@@ -604,6 +622,31 @@ async function wrapperInput(str) {
604
622
  } else {
605
623
  listCmd()
606
624
  }
625
+ _noAppendNextLine || nextLine()
626
+ } else if (str.match(/^%/)) {
627
+ let newRepo = trim(str.substring(1))
628
+ if (!newRepo) {
629
+ console.log(`current: ${getConfig('jsLibSource')}`)
630
+ _repos = _repos.filter(i => _fs.existsSync(i))
631
+ for(let i = 0; i<_repos.length; i++) {
632
+ console.log(`${i+1}: ${_repos[i]}`)
633
+ }
634
+ let repoStr = trim(await nextLine(line => line, 'reset(or blank): '))
635
+ if (/^\d+$/.test(repoStr)) {
636
+ repoStr = _repos[Number(repoStr) - 1]
637
+ }
638
+ newRepo = repoStr
639
+ }
640
+ if (newRepo) {
641
+ setConfig('jsLibSource', newRepo)
642
+ if (_repos.indexOf(newRepo) === -1) {
643
+ _repos.push(newRepo)
644
+ }
645
+ }
646
+ arrayDataFile('repos.json', () => _repos)
647
+ dealSourceCmds()
648
+ await dealInitData()
649
+
607
650
  _noAppendNextLine || nextLine()
608
651
  } else if (!str.split(/\s+/)[0].match(/^\d+$/)) {
609
652
  _cmdMap = filterCmd(str.split(/\s+/))
@@ -614,7 +657,7 @@ async function wrapperInput(str) {
614
657
  if (_cmdMap[strs[0]]) {
615
658
  putHis(_cmdMap[strs[0]])
616
659
  let path = _home + '/' + _cmdMap[strs[0]]
617
- let fileName = _cmdMap[strs[0]].replace(/\.js$/, '');
660
+ let fileName = trimJsirFileName(_cmdMap[strs[0]]);
618
661
  let firstName = trim(fileName).split(/\s+/)[0]
619
662
  if (firstName === 'f') {
620
663
  await fileLine(fileName.replace(/^\s*f\s*/, ''))
@@ -692,8 +735,10 @@ async function dealKeyword(str, strs, fstr, ostr) {
692
735
  } else {
693
736
  let newName =trim(ostr.join(" "))
694
737
  if (newName) {
695
- newName = newName + ".js"
696
- rename(_home + '/' + name, _home + '/' + newName)
738
+ newName = toJsirFileName(newName)
739
+ if (rename(_home + '/' + name, _home + '/' + newName)) {
740
+ info(`${_home + '/' + newName} renamed`)
741
+ }
697
742
  let jsLibDir = trim(getConfig("jsLibSource"))
698
743
  if (jsLibDir && _fs.existsSync(jsLibDir)) {
699
744
  let cmdsDir = jsLibDir
@@ -793,9 +838,9 @@ async function dealKeyword(str, strs, fstr, ostr) {
793
838
  }
794
839
  }
795
840
 
796
-
797
841
  function getComments(text, cols = [], col) {
798
842
  let docLines = []
843
+ text = trim(text)
799
844
  if (text.startsWith("/*")) {
800
845
  for (let line of text.split("\n")) {
801
846
  let aLine = line
@@ -816,45 +861,92 @@ function getComments(text, cols = [], col) {
816
861
  docLines.push(...comments)
817
862
  }
818
863
  if (docLines.length > 0) {
819
- col.doc = docLines[0]
864
+ col.doc = '-\x1B[32m' + docLines[0] + '\x1B[39m'
820
865
  if (docLines.length > 1) {
821
866
  for (let line of docLines.slice(1)) {
822
867
  cols.push({
823
- doc: line
868
+ doc: ' ' + line
824
869
  })
825
870
  }
826
871
  }
827
872
  }
828
873
  }
829
874
 
875
+ function toJsirFileName(name) {
876
+ name = trim(name)
877
+ if (isJsirFileName(name)) {
878
+ return name;
879
+ }
880
+ name = name + '.js'
881
+ if (!isJsirFileName(name)) {
882
+ throw `invalid name`
883
+ }
884
+ return name
885
+ }
886
+
887
+ function isJsirFileName(name) {
888
+ name = trim(name)
889
+ return /^[^.]*[^.\s]\.[^.\s]+$/.test(name)
890
+ }
891
+
892
+ function trimJsirFileName(name) {
893
+ name = trim(name)
894
+ if (isJsirFileName(name)) {
895
+ return trim(name.replace(/\.[^.\s]+$/, ''))
896
+ }
897
+ return name
898
+ }
899
+
900
+ function getJsirFileSuffix(name) {
901
+ name = trim(name)
902
+ if (isJsirFileName(name)) {
903
+ return trim(name.split('.').slice(-1))
904
+ }
905
+ return ''
906
+ }
907
+
830
908
  function filterCmd(args){
831
909
  let cmdMap = {}
832
910
  let files = _fs.readdirSync(_home)
833
911
  let i = 1
834
912
  for (let file of files) {
835
913
  file = trim(file)
836
- let fileName = file.replace(/\.js$/, '')
837
- if (!file.endsWith('.js') || !fileName) {
914
+ if (!isJsirFileName(file)) {
838
915
  continue
839
916
  }
840
- for (let arg of args) {
841
- let r = true
842
- for (let str of arg.split(',').filter(item => trim(item) !== '')) {
843
- let reg = new RegExp(str, 'i')
844
- if (!reg.test(fileName)) {
845
- r = false
846
- break
847
- }
848
- }
849
- if (r && Object.values(cmdMap).indexOf(file) === -1) {
917
+ let fileName = trimJsirFileName(file)
918
+ isArgsMatch(fileName, args, () => {
919
+ if (Object.values(cmdMap).indexOf(file) === -1) {
850
920
  cmdMap[i] = file
851
921
  i ++
852
922
  }
853
- }
923
+ })
854
924
  }
855
925
  return cmdMap
856
926
  }
857
927
 
928
+ function isArgsMatch(text, args, callback) {
929
+ let match = false
930
+ for (let arg of args) {
931
+ let r = true
932
+ for (let str of arg.split(',').filter(item => trim(item) !== '')) {
933
+ let reg = new RegExp(str, 'i')
934
+ if (!reg.test(text)) {
935
+ r = false
936
+ break
937
+ }
938
+ }
939
+ if (r) {
940
+ match = true
941
+ break
942
+ }
943
+ }
944
+ if (match && callback) {
945
+ callback()
946
+ }
947
+ return match
948
+ }
949
+
858
950
  function getArgComments(argDef) {
859
951
  let comments = []
860
952
  let keys = Object.keys(argDef)
@@ -865,15 +957,15 @@ function getArgComments(argDef) {
865
957
  comments.push(aLine.join(", ") + ", ")
866
958
  aLine = []
867
959
  }
868
- aLine.push(`${k}` + (argDef[k] ? `(${argDef[k]})`:''))
960
+ aLine.push(`\x1B[33m${k}\x1B[39m` + (argDef[k] ? ` <${argDef[k]}>`:''))
869
961
  }
870
962
  if (aLine.length > 0) {
871
963
  comments.push(aLine.join(", "))
872
964
  }
873
- comments[0] = 'ARGS: ' + comments[0]
965
+ comments[0] = '$args: ' + comments[0]
874
966
  if (comments.length > 1) {
875
967
  for(let i = 1; i< comments.length; i++) {
876
- comments[i] = ' ' + comments[i]
968
+ comments[i] = ' ' + comments[i]
877
969
  }
878
970
  }
879
971
  }
@@ -906,7 +998,7 @@ async function runCmd(str) {
906
998
  }
907
999
  if (argDef.hasOwnProperty(pair[0])) {
908
1000
  args[i] = argVal
909
- args[argNames[i]] = argVal
1001
+ delete args[argNames[i]]
910
1002
  args[pair[0]] = argVal
911
1003
  }
912
1004
  }
@@ -917,14 +1009,9 @@ async function runCmd(str) {
917
1009
  continue
918
1010
  }
919
1011
  if (args[name] === undefined || args[name] === null) {
920
- if (!exit) {
921
- let comments = getArgComments(argDef)
922
- if (comments.length > 0) {
923
- console.log(comments.join('\n'))
924
- }
925
- }
926
1012
  exit = true
927
- warn(`require ${name}`)
1013
+ let comment = trim(argDef[name]);
1014
+ warn(`require \x1B[33m${name}\x1B[39m` + (comment ? ` <${comment}>`:''))
928
1015
  }
929
1016
  }
930
1017
  if (exit) {
@@ -934,13 +1021,10 @@ async function runCmd(str) {
934
1021
 
935
1022
  process.argv = [process.argv[0], path, ...args]
936
1023
  try {
937
- evalText(text, strs[0], _cmdMap[strs[0]], args)
1024
+ await evalText(text, strs[0], _cmdMap[strs[0]], args)
938
1025
  } catch (e) {
939
1026
  error(e)
940
1027
  }
941
- if (!text.match(/\s+\$nextLine\s*\(\s*\)/)) {
942
- _noAppendNextLine || nextLine()
943
- }
944
1028
  }
945
1029
 
946
1030
  function enrichArgs(str) {
@@ -968,8 +1052,9 @@ function enrichArgs(str) {
968
1052
  }
969
1053
  i ++
970
1054
  })
971
- return args
1055
+ return args.map(trim)
972
1056
  }
1057
+
973
1058
  function translateArgs(arg) {
974
1059
  let rpStr = s => {
975
1060
  let ori = s;
@@ -988,24 +1073,29 @@ function translateArgs(arg) {
988
1073
  }
989
1074
 
990
1075
  function getArgDef(text) {
991
- let exeStr = trim(reget(text, /\$defArgs\(([^()]*)\)/))
1076
+ let exeStr = trim(reget(text, /\$defArgs\(\s*(\{[\s\S]*?\})\s*\)/))
992
1077
  let argDef = {}
993
1078
  try {
994
1079
  argDef = eval(`(${exeStr || '{}'})`) || {}
995
1080
  } catch (e) {
996
- warn('wrong $defArgs')
1081
+ $log(e.stack)
997
1082
  }
998
1083
  if (typeof argDef !== 'object') {
999
1084
  argDef = {}
1000
1085
  }
1001
1086
  let temp = {}
1087
+ let tempOpt = {}
1002
1088
  for (let key of Object.keys(argDef)) {
1003
1089
  let vlKey = trim(key)
1004
1090
  if (vlKey) {
1005
- temp[vlKey] = argDef[key]
1091
+ if (vlKey.startsWith('_')) {
1092
+ tempOpt[vlKey] = argDef[key]
1093
+ } else {
1094
+ temp[vlKey] = argDef[key]
1095
+ }
1006
1096
  }
1007
1097
  }
1008
- return temp
1098
+ return Object.assign(temp, tempOpt)
1009
1099
  }
1010
1100
 
1011
1101
  function setTips(key, value, onRm) {
@@ -1045,15 +1135,14 @@ function evalText($text, $cmdIndex, $cmdName, $args) {
1045
1135
  const $nextText = nextText;
1046
1136
  const $setTips = setTips;
1047
1137
  const $delTips = delTips;
1138
+ const $info = info;
1139
+ const $warn = warn;
1140
+ const $error = error;
1048
1141
  const $cmdDir = _home + '/';
1049
1142
  const $cmdMap = _cmdMap;
1050
1143
  const $defArgs = () => $args
1051
1144
 
1052
- if ($cmdIndex) {
1053
- return eval(`(async ()=>{${$text}})()`)
1054
- } else {
1055
- return eval(`${$text}`)
1056
- }
1145
+ return eval(`(async ()=>{${$text}\n})()`)
1057
1146
  }
1058
1147
 
1059
1148
  process.on('uncaughtException',function(err){