jsir 1.2.9 → 1.3.1

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.
package/cmd/ooa.js CHANGED
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  const {
3
- run, getLibDataDir, trim, regEach, getConfig, mkdir, requireG, reget,
3
+ run, getLibDataDir, trim, regEach, getConfig, mkdir, reget,
4
4
  getCbText, e, sleep, objDataFile, setConfig, vl, md5, BigNumber,
5
- info, warn, error, arrayDataFile, infoStr, warnStr, errorStr, errorStack,
6
- getInfo, ei, pad, msg, msgStr, isError, getType, tableStr, nableStr, objProfileRows
5
+ info, warn, error, arrayDataFile, infoStr, warnStr, errorStack,
6
+ getInfo, ei, pad, msgStr, getType,
7
+ errorTag, isArgsMatch, draftQuery
7
8
  } = require('../util')
9
+ const evalCode = require('../evalCode')
8
10
 
9
11
  const _types = {
10
12
  'e': "exe",
@@ -19,12 +21,15 @@ const _args = process.argv.slice(2).map(trim)
19
21
  const _history9 = []
20
22
  const _tipsOnRm = {}
21
23
  const _setting = require('../setting')
24
+ const readline = require("readline");
22
25
  const _fileWatcherMap = {}
23
26
 
24
27
  let _cmdMap = {}
25
28
  let _rl
29
+ let _rlHistory = []
26
30
  let _haveWrapperInput = true
27
31
  let _repos = arrayDataFile('repos.json')
32
+ let _exit = false
28
33
 
29
34
  const $data = {}
30
35
 
@@ -38,27 +43,12 @@ try {
38
43
  error(e)
39
44
  }
40
45
 
41
- console.table = (...args) => {
42
- console.log(tableStr(...args))
43
- }
44
- console.nable = (rows) => {
45
- console.log(nableStr(rows))
46
- }
47
-
48
46
  let _noAppendNextLine = true
49
47
 
50
48
  const _mainCmdMap = {
51
49
  repl: {
52
50
  comment: "交互界面",
53
51
  },
54
- ls: {
55
- comment: "模糊搜索脚本",
56
- cmd: ['']
57
- },
58
- run: {
59
- comment: "执行脚本",
60
- cmd: ['']
61
- },
62
52
  add: {
63
53
  comment: "新增脚本",
64
54
  cmd: ['@e ']
@@ -128,10 +118,8 @@ function isMainCmd(mainList) {
128
118
  return mainList.indexOf(_args[0]) !== -1;
129
119
  }
130
120
 
131
- async function initRuntime() {
132
- global.$lib = {...require('../util'), ...require('../ethWeb'),
133
- evalText
134
- }
121
+ function initRuntime() {
122
+ global.$lib = {...require('../util')}
135
123
  }
136
124
 
137
125
  function getFileOpenExe(fileName) {
@@ -154,28 +142,27 @@ run(async () => {
154
142
  if (isMainCmd(['config'])) {
155
143
  let fileName = 'config.json';
156
144
  let configFile = getLibDataDir() + '/' + fileName;
157
- await e(`"${getFileOpenExe(fileName)}" "${configFile}"`)
145
+ ei('vi', [configFile])
158
146
  return
159
147
  }
160
148
 
161
149
  dealSourceCmds()
162
150
 
163
151
  if (isMainCmd(['repl'])) {
164
- await initRuntime()
152
+ initRuntime()
165
153
  _noAppendNextLine = false
166
- nextLine()
167
154
  } else if (isMainCmd()){
168
155
  if (_noAppendNextLine) {
169
156
  _cmdMap = objDataFile('ooaCmdMap.json')
170
157
  }
171
158
 
172
- if (isMainCmd(['run', 'edit', 'rm', 'diff', 'push', 'pull', 'deps'])
159
+ if (isMainCmd(['edit', 'rm', 'diff', 'push', 'pull', 'deps'])
173
160
  && _args[1] && !/^\d+$/.test(_args[1])) {
174
161
  warn('wrong args')
175
162
  return
176
163
  }
177
164
  if (isMainCmd(['lib'])) {
178
- await initRuntime()
165
+ initRuntime()
179
166
  }
180
167
  if (isMainCmd(['add', 'note', 'init'])
181
168
  && (!_args[1] || /^\d+$/.test(_args[1]))) {
@@ -183,25 +170,17 @@ run(async () => {
183
170
  return
184
171
  }
185
172
 
186
- if (isMainCmd(['ls']) && _args[1] && /^\d+$/.test(_args[1])) {
187
- warn('wrong args')
188
- return
189
- }
190
-
191
173
  let argStr = _args.slice(1).map(i => {
192
174
  if (/\s+/.test(i) || !i) {
193
175
  i = `"${i}"`
194
176
  }
195
177
  return i
196
178
  }).join(' ').replace(/^@/, '')
197
- if (isMainCmd(['run', 'edit', 'rm', 'diff', 'push', 'pull', 'deps']) && !trim(argStr)) {
179
+ if (isMainCmd(['edit', 'rm', 'diff', 'push', 'pull', 'deps']) && !trim(argStr)) {
198
180
  _args[0] = '@'
199
181
  }
200
- if (isMainCmd(['ls']) && !trim(argStr)) {
201
- argStr = ','
202
- }
203
182
  if (isMainCmd(['file'])) {
204
- await initRuntime()
183
+ initRuntime()
205
184
  }
206
185
  let info = _mainCmdMap[_args[0]]
207
186
  if (info) {
@@ -211,7 +190,7 @@ run(async () => {
211
190
  } else {
212
191
  await wrapperInput(`${_args[0]}${argStr}`)
213
192
  }
214
- } else if (isMainCmd(['help'])) {
193
+ } else if (_args[0] && _args[0].startsWith('-')) {
215
194
  let cols = []
216
195
  for (let key of Object.keys(_mainCmdMap)) {
217
196
  cols.push({
@@ -232,7 +211,7 @@ run(async () => {
232
211
  }).join(' ').replace(/^@/, '')
233
212
  if (/^\d+$/.test(_args[0])) {
234
213
  if (_args[0] === '0' || (_cmdMap[_args[0]] && ['e ', 'f '].filter(i => _cmdMap[_args[0]].startsWith(i)).length > 0)) {
235
- await initRuntime()
214
+ initRuntime()
236
215
  }
237
216
  }
238
217
  await wrapperInput(line)
@@ -244,97 +223,112 @@ run(async () => {
244
223
  }
245
224
  })
246
225
 
247
- async function getFileWatcher(fileName, workFile, text) {
248
- info("fileLine open " + workFile)
249
- if (!_fileWatcherMap[workFile]) {
250
- _fs.unlinkSync(workFile)
226
+ async function getFileWatcher(fileName, workFilePath, text) {
227
+ info("workFile open " + workFilePath)
228
+ if (!_fileWatcherMap[workFilePath]) {
229
+ _fs.unlinkSync(workFilePath)
251
230
  await sleep(1000)
252
- _fs.writeFileSync(workFile, text)
253
- let watcher = _chokidar.watch([workFile]);
254
- _fileWatcherMap[workFile] = watcher;
231
+ _fs.writeFileSync(workFilePath, text)
232
+ let watcher = _chokidar.watch([workFilePath]);
233
+ _fileWatcherMap[workFilePath] = watcher;
234
+ setTips("FILE", "FILE", () => {
235
+ Object.keys(_fileWatcherMap).forEach(closeFileWatcher);
236
+ })
255
237
  return watcher
256
238
  }
257
239
  }
258
- async function fileLine(name) {
240
+
241
+ function closeFileWatcher(workFilePath) {
242
+ let watcher = _fileWatcherMap[workFilePath]
243
+ info("workFile close " + workFilePath)
244
+ watcher.unwatch([workFilePath])
245
+ watcher.close()
246
+ delete _fileWatcherMap[workFilePath]
247
+ }
248
+
249
+ async function workFile(name) {
259
250
  name = trim(name)
260
251
  if (!name) {
261
- name = 'lineWorkFile'
252
+ name = 'workFile'
262
253
  }
263
254
  let fileName = `f ${toJsirFileName(name)}`
264
- let workFile = `${_home}/${fileName}`;
265
- if (!_fs.existsSync(workFile)) {
266
- _fs.writeFileSync(workFile, '');
255
+ await watchFile(fileName)
256
+ }
257
+
258
+ async function watchFile(fileName) {
259
+ let workFilePath = `${_home}/${fileName}`;
260
+ if (!_fs.existsSync(workFilePath)) {
261
+ _fs.writeFileSync(workFilePath, '');
267
262
  }
268
- let text = String(_fs.readFileSync(workFile))
269
- let watcher = await getFileWatcher(fileName, workFile, text)
270
- text = trim(text)
271
- let line = trim(getExeLine(text))
263
+ let text = String(_fs.readFileSync(workFilePath))
264
+ let watcher = await getFileWatcher(fileName, workFilePath, text)
265
+
272
266
  if (watcher) {
273
267
  watcher.on('change', async () => {
274
- let newText = trim(String(_fs.readFileSync(workFile)))
275
- let newLine = trim(getExeLine(newText))
276
- let tmpLine = line
277
- line = newLine
278
- if (newLine && newLine !== tmpLine) {
279
- let exeStrs
280
- if (newLine.startsWith('/*')) {
281
- exeStrs = newLine.split('\n').slice(1, -1).map(trim).filter(i => i)
282
- } else {
283
- exeStrs = ["#" + newLine]
284
- }
285
- for(let exeStr of exeStrs) {
286
- await wrapperInput(trim(exeStr))
268
+ let newText = String(_fs.readFileSync(workFilePath));
269
+ let exeStr = getExeStr(text, newText);
270
+ text = newText;
271
+ if (trim(exeStr)) {
272
+ try {
273
+ console.log("\n" + infoStr("------ workFile run ------"))
274
+ await wrapperInput("# " + exeStr)
275
+ } catch (e) {
276
+ error(e)
287
277
  }
288
278
  }
289
279
  }).on("unlink", () => {
290
- info("fileLine close " + workFile)
291
- watcher.unwatch([workFile])
292
- watcher.close()
293
- delete _fileWatcherMap[workFile]
280
+ closeFileWatcher(workFilePath);
294
281
  });
295
282
  }
296
- await e(`"${getFileOpenExe(fileName)}" "${workFile}"`)
283
+ await e(`"${getFileOpenExe(fileName)}" "${workFilePath}"`)
297
284
  }
298
285
 
299
- function getExeLine(text) {
300
- let lines = []
301
- let nLine = []
302
- let cLine = []
303
- for (let line of text.split("\n")
304
- .map(i => trim(i))
305
- .filter(i => i)) {
306
- if (lines.length > 1) {
307
- break
308
- }
309
- if (nLine.length > 0) {
310
- nLine.push(line)
311
- if (line.endsWith('*/')) {
312
- lines.push(nLine.join('\n'))
313
- nLine = []
314
- }
315
- continue
286
+ function getExeStr(oldText, newText) {
287
+ let olds = oldText.split(/\n/).filter(i => trim(i));
288
+ let news = newText.split(/\n/).filter(i => trim(i));
289
+
290
+ if (olds.length !== news.length) {
291
+ return ;
292
+ }
293
+
294
+ let reg = /^\/\/\s*jsir(\s+.+)?$/;
295
+
296
+ let lineChange = false
297
+ let flagChange = false
298
+ let currText = []
299
+ for (let i = 0; i < news.length; i++) {
300
+ if (!flagChange && lineChange) {
301
+ break;
316
302
  }
303
+ let oldLine = olds[i];
304
+ let newLine = news[i];
317
305
 
318
- if (line.startsWith('/*')) {
319
- if (cLine.length > 0) {
320
- lines.push(cLine.join('\n'))
321
- cLine = []
306
+ if (reg.test(trim(newLine))) {
307
+ if (flagChange) {
308
+ break;
322
309
  }
323
-
324
- if (!line.endsWith('*/')) {
325
- nLine.push(line)
310
+ if (reg.test(trim(oldLine))) {
311
+ if (trim(oldLine).split(/jsir/)[0] !== trim(newLine).split(/jsir/)[0]) {
312
+ flagChange = true
313
+ }
326
314
  } else {
327
- lines.push("")
315
+ break;
316
+ }
317
+ currText = []
318
+ } else {
319
+ currText.push(newLine)
320
+ if (flagChange && trim(newLine).endsWith(";;")) {
321
+ break;
328
322
  }
329
- continue
330
323
  }
331
324
 
332
- cLine.push(line)
325
+ if (oldLine !== newLine) {
326
+ lineChange = true;
327
+ }
333
328
  }
334
- if (cLine.length > 0) {
335
- lines.push(cLine.join('\n'))
329
+ if (flagChange) {
330
+ return currText.join("\n")
336
331
  }
337
- return lines[1]
338
332
  }
339
333
 
340
334
  async function nextLine(callback, preStr, hidden) {
@@ -343,13 +337,8 @@ async function nextLine(callback, preStr, hidden) {
343
337
  })
344
338
  }
345
339
 
346
- function _nextLine(callback, preStr, hidden, resolve, end) {
347
- end = trim(end)
348
- if (!_haveWrapperInput) {
349
- return
350
- }
340
+ function initRl(callback, preStr, hidden) {
351
341
  if (!_rl) {
352
- let readline = require('readline')
353
342
  _rl = readline.createInterface({
354
343
  input: process.stdin,
355
344
  output: process.stdout
@@ -363,23 +352,49 @@ function _nextLine(callback, preStr, hidden, resolve, end) {
363
352
  nextLine();
364
353
  }
365
354
  });
355
+ _rl.history = _rlHistory
366
356
  }
367
- _haveWrapperInput = false
368
357
 
369
- _rl._writeToOutput = function _writeToOutput(stringToWrite){
370
- if(hidden && stringToWrite.indexOf("\n") === -1 && stringToWrite !== promitStr){
371
- if (stringToWrite.indexOf(promitStr) === -1) {
372
- _rl.output.write("*");
358
+ let repoTip = trim(trim(getConfig("jsLibSource")).split('/').map(trim).reverse().filter(i => i)[0])
359
+ let promptStr = preStr
360
+ if (promptStr !== '') {
361
+ promptStr = (preStr
362
+ || ((callback && callback !== wrapperInput) ? "-> ":"")
363
+ || [Object.values(global.$tips).filter(i => String(i)).join(','), repoTip].filter(i => i).join(':') + `> `)
364
+ promptStr = infoStr(promptStr)
365
+ }
366
+ if (hidden) {
367
+ _rl._writeToOutput = function _writeToOutput(stringToWrite){
368
+ if(hidden && stringToWrite.indexOf("\n") === -1 && stringToWrite !== promptStr){
369
+ if (stringToWrite.indexOf(promptStr) === -1) {
370
+ _rl.output.write("*");
371
+ } else {
372
+ _rl.output.write(promptStr + stringToWrite.replace(promptStr, '').replace(/[\s\S]/g, '*'));
373
+ }
373
374
  } else {
374
- _rl.output.write(promitStr + stringToWrite.replace(promitStr, '').replace(/[\s\S]/g, '*'));
375
+ _rl.output.write(stringToWrite);
375
376
  }
376
- } else {
377
- _rl.output.write(stringToWrite);
378
377
  }
379
378
  }
380
- _rl.removeAllListeners('line')
379
+
380
+ _rl.setPrompt(promptStr);
381
+ }
382
+
383
+ function closeRl() {
384
+ _rlHistory = _rl.history;
385
+ _rl.close();
386
+ _rl = null;
387
+ }
388
+
389
+ function _nextLine(callback, preStr, hidden, resolve, end) {
390
+ end = trim(end)
391
+ if (!_haveWrapperInput) {
392
+ return
393
+ }
394
+ initRl(callback, preStr, hidden);
395
+ _haveWrapperInput = false
381
396
  let inputStr = ''
382
- _rl.on('line', async line => {
397
+ let lineHander = async line => {
383
398
  let textLine = line
384
399
  line = trim(line)
385
400
  if (end) {
@@ -388,37 +403,40 @@ function _nextLine(callback, preStr, hidden, resolve, end) {
388
403
  }
389
404
  } else {
390
405
  inputStr = line
406
+ if (/^\s+$/.test(textLine) && (!callback || wrapperInput === callback)) {
407
+ console.clear();
408
+ listCmd();
409
+ }
391
410
  }
392
411
  if (line && (hidden || (callback && callback !== wrapperInput))) {
393
412
  _rl.history = _rl.history.slice(1)
394
413
  }
395
414
  if (!end || line === end) {
396
415
  _haveWrapperInput = true;
397
- if (_noAppendNextLine && _rl) {
398
- _rl.close()
399
- _rl = null
400
- }
416
+ closeRl()
401
417
  inputStr = inputStr.replace(/\s+$/, '');
402
418
 
403
419
  let pro = (callback || wrapperInput)(inputStr);
404
420
 
405
421
  resolve && resolve(inputStr);
422
+ let currCallback = callback;
406
423
  callback = null;
407
424
  hidden = false;
408
425
  end = null;
409
426
  inputStr = '';
410
- await pro;
427
+
428
+ try {
429
+ await pro;
430
+ } finally {
431
+ if ((currCallback || wrapperInput) === wrapperInput) {
432
+ _noAppendNextLine || nextLine()
433
+ }
434
+ }
411
435
  }
412
- })
413
- let repoTip = trim(trim(getConfig("jsLibSource")).split('/').map(trim).reverse().filter(i => i)[0])
414
- let promitStr = preStr
415
- if (promitStr !== '') {
416
- promitStr = (preStr
417
- || ((callback && callback !== wrapperInput) ? "-> ":"")
418
- || [Object.values(global.$tips).filter(i => String(i)).join(','), repoTip].filter(i => i).join(':') + `> `)
419
- promitStr = infoStr(promitStr)
420
436
  }
421
- _rl.setPrompt(promitStr);
437
+
438
+ _rl.removeAllListeners('line')
439
+ _rl.on('line', lineHander)
422
440
  _rl.prompt()
423
441
  }
424
442
 
@@ -556,7 +574,10 @@ function listCmd(prefixKey, inputCmdMap) {
556
574
  }
557
575
  }
558
576
  let items = Object.values(currCmdMap)
559
- .filter(item => _fs.existsSync(_home + "/" + item) && (!prefixKey || prefixMap[item].indexOf(prefixKey) !== -1))
577
+ .filter(item => _fs.existsSync(_home + "/" + item)
578
+ && ((prefixKey === '' && prefixMap[item].filter(i => trim(i)).length <= 0)
579
+ || (trim(prefixKey) && prefixMap[item].indexOf(trim(prefixKey)) !== -1)
580
+ || (!prefixKey && prefixKey !== '')))
560
581
  .sort((a,b) => {
561
582
  let typeKeys = Object.keys(_types);
562
583
  let orderA = typeKeys.indexOf(a.split(/\s+/)[0]);
@@ -598,7 +619,7 @@ function listCmd(prefixKey, inputCmdMap) {
598
619
  if (!text) {
599
620
  text = String(_fs.readFileSync(_home + "/" + currCmdMap[i]))
600
621
  }
601
- getComments(currCmdMap[i], text, items, item)
622
+ getComments(i, currCmdMap[i], text, items, item)
602
623
  }
603
624
  if (Object.keys(items).length === 0) {
604
625
  warn("no items")
@@ -616,48 +637,6 @@ function listCmd(prefixKey, inputCmdMap) {
616
637
  }
617
638
  }
618
639
 
619
- function draftQuery(fLine) {
620
- let lines = []
621
- let text = String(_fs.readFileSync(getLibDataDir() + "/log/draft.log"))
622
- let temp = []
623
- for (let line of text.split("\n")) {
624
- if (!trim(line)) {
625
- continue
626
- }
627
- if (line.startsWith("---------")) {
628
- if (temp.length > 0) {
629
- lines.push(temp.join('\n'))
630
- }
631
- temp = []
632
- temp.push(warnStr(line))
633
- } else {
634
- temp.push(line)
635
- }
636
- }
637
- if (temp.length > 0) {
638
- lines.push(temp.join('\n'))
639
- }
640
-
641
- let results = []
642
- if (!/^\d+$/.test(fLine)) {
643
- let ss = fLine.split(/\s+/)
644
- fLine = ss[0]
645
- for (let line of lines) {
646
- if (new RegExp(fLine, 'i').test(line)) {
647
- results.push(line)
648
- }
649
- }
650
- fLine = ss[1]
651
- lines = results
652
- results = []
653
- }
654
- if (fLine && /^\d+$/.test(fLine)) {
655
- let index = Math.abs(parseInt(fLine));
656
- results.push(...lines.slice(- index))
657
- }
658
- console.log(results.join("\n"))
659
- }
660
-
661
640
  async function wrapperInput(str) {
662
641
  try {
663
642
  await _wrapperInput(str);
@@ -672,31 +651,23 @@ async function _wrapperInput(str) {
672
651
 
673
652
  str = trim(str)
674
653
  if (!str) {
675
- _noAppendNextLine || nextLine()
676
654
  return;
677
655
  }
678
- if (/^[&]/.test(str)) {
679
- _rl.removeAllListeners('line');
680
- try {
681
- let cmdStr = trim(str.substr(1));
682
- if (/^\d+$/.test(cmdStr) && _cmdMap[cmdStr]) {
683
- if (_cmdMap[cmdStr]) {
684
- ei('vi', [getLibDataDir() + '/ooa/' + _cmdMap[cmdStr]])
685
- } else {
686
- warn("no items")
687
- }
688
- } else if (cmdStr) {
689
- ei(cmdStr.split(/\s+/)[0],
690
- enrichArgs(trim(cmdStr.replace(/^\S+/, ''))).map(trim));
656
+ if (/^&/.test(str)) {
657
+ let cmdStr = trim(str.substr(1));
658
+ if (/^\d+$/.test(cmdStr) && _cmdMap[cmdStr]) {
659
+ if (_cmdMap[cmdStr]) {
660
+ ei('vi', [getLibDataDir() + '/ooa/' + _cmdMap[cmdStr]])
691
661
  } else {
692
- ei('vi', ['-n'])
662
+ warn("no items")
693
663
  }
694
- return;
695
- } finally {
696
- _noAppendNextLine || nextLine()
664
+ } else if (cmdStr) {
665
+ ei(cmdStr.split(/\s+/)[0],
666
+ enrichArgs(trim(cmdStr.replace(/^\S+/, ''))).map(trim));
667
+ } else {
668
+ ei('vi', ['-n'])
697
669
  }
698
- }
699
- if (/^[`'"]/.test(str)) {
670
+ } else if (/^[`'"]/.test(str)) {
700
671
  let fstr = str.substr(0, 1);
701
672
  if (fstr === '`') {
702
673
  let text = str.substr(1) + "\n" + await nextText(line => line, fstr)
@@ -704,27 +675,18 @@ async function _wrapperInput(str) {
704
675
  } else {
705
676
  let fLine = trim(str.substr(1))
706
677
  if (fLine) {
707
- draftQuery(fLine)
678
+ console.log(draftQuery(fLine).join("\n"))
708
679
  } else {
709
680
  let text = str.substr(1) + "\n" + await nextText(line => line, fstr)
710
681
  $draft(text)
711
682
  }
712
- _noAppendNextLine || nextLine()
713
683
  }
714
- return;
715
- }
716
-
717
- if (/^[$#*]/.test(str)) {
684
+ } else if (/^[$#*]/.test(str)) {
718
685
  let is$ = str.startsWith('$')
719
686
  let isStar = str.startsWith('*')
720
687
  let text = trim(str.replace(/^[$#*]/, ''))
721
688
  if (is$) {
722
- let result = await evalText('return ' + text)
723
- if (result === $lib) {
724
- console.table(objProfileRows(result))
725
- } else {
726
- console.log(result)
727
- }
689
+ console.log(await evalText('return ' + text))
728
690
  } else if (isStar) {
729
691
  let items = text.split(/\s+/).map(trim).filter(i => i)
730
692
  let result = await evalText('return ' + items[0])
@@ -756,11 +718,9 @@ async function _wrapperInput(str) {
756
718
  } else {
757
719
  listCmd()
758
720
  }
759
- _noAppendNextLine || nextLine()
760
721
  } else if (!str.split(/\s+/)[0].match(/^\d+$/)) {
761
722
  _cmdMap = filterCmd(str.split(/\s+/))
762
723
  listCmd()
763
- _noAppendNextLine || nextLine()
764
724
  } else {
765
725
  let strs = str.split(/\s+/)
766
726
  if (_cmdMap[strs[0]]) {
@@ -769,10 +729,9 @@ async function _wrapperInput(str) {
769
729
  let fileName = trim(_cmdMap[strs[0]]);
770
730
  let firstName = fileName.split(/\s+/)[0]
771
731
  if (firstName === 'f') {
772
- await fileLine(fileName.replace(/^\s*f\s*/, ''))
732
+ await workFile(fileName.replace(/^\s*f\s*/, ''))
773
733
  } else if (firstName !== 'e') {
774
734
  console.log(String(_fs.readFileSync(path)));
775
- _noAppendNextLine || nextLine()
776
735
  } else {
777
736
  await runCmd(str)
778
737
  }
@@ -782,8 +741,29 @@ async function _wrapperInput(str) {
782
741
  }
783
742
  }
784
743
 
744
+ function delTipsByIndex(idxs) {
745
+ let keys = Object.keys($tips)
746
+ let indexKeyMap = {}
747
+ for(let i = 1;i<=keys.length;i++) {
748
+ indexKeyMap[i] = keys[i - 1]
749
+ }
750
+ let params = []
751
+ for (const index of idxs) {
752
+ if ($tips.hasOwnProperty(index)) {
753
+ params.push(index)
754
+ } else if (indexKeyMap[Number(index)]) {
755
+ params.push(indexKeyMap[Number(index)])
756
+ } else if (indexKeyMap[keys.length + 1 + Number(index)]) {
757
+ params.push(indexKeyMap[keys.length + 1 + Number(index)])
758
+ }
759
+ }
760
+ delTips(...params)
761
+ }
762
+
785
763
  async function dealKeyword(str, strs, fstr, ostr) {
786
- if (/^\d+$/.test(fstr)) {
764
+ if (fstr.startsWith("<")) {
765
+ delTipsByIndex([fstr, ...ostr].join(" ").replace(/^</, '').split(/\s+/).filter(i => i))
766
+ } else if (/^\d+$/.test(fstr)) {
787
767
  if (!_cmdMap[fstr]) {
788
768
  warn("no items")
789
769
  } else {
@@ -904,6 +884,8 @@ async function dealKeyword(str, strs, fstr, ostr) {
904
884
  warn('require config.jsLibSource')
905
885
  }
906
886
  }
887
+ }else if (fstr === '!') {
888
+ listCmd('')
907
889
  } else if (/^w\d*$/.test(fstr)) {
908
890
  let name = _cmdMap[trim(fstr.replace(/^w/, ''))]
909
891
  if (!name) {
@@ -940,8 +922,17 @@ async function dealKeyword(str, strs, fstr, ostr) {
940
922
  } else if (fstr === 'e' && ostr.length === 0) {
941
923
  hisToCmdMap()
942
924
  listCmd()
943
- } else if (fstr === 'f') {
944
- await fileLine(trim(ostr.join(' ')))
925
+ } else if (/^f\d*$/.test(fstr)) {
926
+ if (fstr === 'f' ) {
927
+ await workFile(trim(ostr.join(' ')))
928
+ return;
929
+ }
930
+ let name = _cmdMap[trim(fstr.replace(/^f/, ''))]
931
+ if (!name) {
932
+ warn("no items")
933
+ } else {
934
+ await watchFile(name)
935
+ }
945
936
  } else if (fstr === '%') {
946
937
  let newRepo = trim(ostr[0])
947
938
  let currRepo = getConfig('jsLibSource');
@@ -969,9 +960,9 @@ async function dealKeyword(str, strs, fstr, ostr) {
969
960
  warn(`repo ${newRepo} not exist`)
970
961
  }
971
962
  }
972
- _noAppendNextLine || nextLine()
973
963
  } else if (fstr === 'q') {
974
964
  console.log("Bye!")
965
+ _exit = true;
975
966
  process.exit(0)
976
967
  } else {
977
968
  await save(strs)
@@ -1017,8 +1008,8 @@ function getScriptRequires(scriptName) {
1017
1008
  return md5Keys
1018
1009
  }
1019
1010
 
1020
- function getComments(cmdName, text, cols = [], col) {
1021
- let docLines = [infoStr('0x' + md5(cmdName).substr(0, 8))]
1011
+ function getComments(i, cmdName, text, cols = [], col) {
1012
+ let docLines = [infoStr('0x' + md5(cmdName).substr(0, 8)) + " - " + infoStr(i)]
1022
1013
  text = trim(text)
1023
1014
  if (text.startsWith("/*")) {
1024
1015
  for (let line of text.split("\n")) {
@@ -1103,28 +1094,6 @@ function filterCmd(args){
1103
1094
  return cmdMap
1104
1095
  }
1105
1096
 
1106
- function isArgsMatch(text, args, callback, useMd5) {
1107
- let match = false
1108
- for (let arg of args) {
1109
- let r = true
1110
- for (let str of arg.split(',').filter(item => trim(item) !== '')) {
1111
- let reg = new RegExp(str, 'i')
1112
- if (!reg.test(text) && !(useMd5 && ('0x' + md5(text).substr(0, 8)) === str)) {
1113
- r = false
1114
- break
1115
- }
1116
- }
1117
- if (r) {
1118
- match = true
1119
- break
1120
- }
1121
- }
1122
- if (match && callback) {
1123
- callback()
1124
- }
1125
- return match
1126
- }
1127
-
1128
1097
  function getArgComments(argDef) {
1129
1098
  let comments = []
1130
1099
  let keys = Object.keys(argDef)
@@ -1160,7 +1129,6 @@ async function runCmd(str = '', scriptName = '', text = '') {
1160
1129
  if (!scriptName) {
1161
1130
  if (!_cmdMap[strs[0]] && strs[0] !== '0') {
1162
1131
  warn('no items')
1163
- _noAppendNextLine || nextLine()
1164
1132
  return
1165
1133
  }
1166
1134
  if (_cmdMap[strs[0]]) {
@@ -1191,9 +1159,9 @@ async function runCmd(str = '', scriptName = '', text = '') {
1191
1159
  let arg = oriArgs[i]
1192
1160
  let needTrans
1193
1161
  let pair
1194
- if (arg.endsWith(":")) {
1195
- arg = arg.replace(/:$/, '')
1196
- if (oriArgs[i+1] && !oriArgs[i+1].endsWith(":")) {
1162
+ if (arg.startsWith(":") || arg.startsWith("_")) {
1163
+ arg = arg.replace(/^:/, '')
1164
+ if (oriArgs[i+1] && !(oriArgs[i+1].startsWith(":") || oriArgs[i+1].startsWith("_"))) {
1197
1165
  pair = [arg, oriArgs[i+1]]
1198
1166
  i++
1199
1167
  } else {
@@ -1362,6 +1330,10 @@ async function _requireSource(cmdMatchStr, ignoreLog = false) {
1362
1330
  nullable = true;
1363
1331
  cmdMatchStr = trim(cmdMatchStr.substr(1));
1364
1332
  }
1333
+ if (_fs.existsSync(_home + '/' + cmdMatchStr)) {
1334
+ cmdMatchStr = '0x' + md5(cmdMatchStr).substr(0, 8);
1335
+ }
1336
+
1365
1337
  let cmdMap = filterCmd(cmdMatchStr.split(/\s+/))
1366
1338
  if (Object.keys(cmdMap).length !== 1) {
1367
1339
  if (nullable) {
@@ -1397,18 +1369,18 @@ async function _requireSource(cmdMatchStr, ignoreLog = false) {
1397
1369
  }
1398
1370
  throw `invalid returned: ${cmdMatchStr}`
1399
1371
  }
1400
- if (typeof result === 'function') {
1372
+ if (getType(result) === 'Function' || getType(result) === 'AsyncFunction') {
1401
1373
  let tmp = result;
1402
1374
  result = (...args) => {
1403
1375
  let resp
1404
1376
  try {
1405
1377
  resp = tmp(...args)
1406
1378
  } catch (e) {
1407
- throw _errorAppend(e, cmdName);
1379
+ throw errorTag(e, cmdName);
1408
1380
  }
1409
1381
  if (getType(resp) === 'Promise') {
1410
1382
  return resp.catch(e => {
1411
- return Promise.reject(_errorAppend(e, cmdName))
1383
+ return Promise.reject(errorTag(e, cmdName))
1412
1384
  })
1413
1385
  } else {
1414
1386
  return resp;
@@ -1439,46 +1411,14 @@ async function _requireSources(...matchItem) {
1439
1411
  return result
1440
1412
  }
1441
1413
 
1442
- function _errorAppend(e, $cmdName) {
1443
- if (!$cmdName) {
1444
- return e;
1445
- }
1446
- if (!isError(e)) {
1447
- e = new Error(e)
1448
- e.stack = e.stack.split(/\n/)[0]
1449
- }
1450
- e.stack = e.stack + `\n at ${$cmdName}`
1451
- return e
1452
- }
1453
-
1454
- function evalText($text = '', $cmdName = '', $args = []) {
1455
- const require = requireG;
1456
- const $nextLine = nextLine;
1457
- const $nextText = nextText;
1458
- const $setTips = setTips;
1459
- const $delTips = delTips;
1460
- const $info = info;
1461
- const $msg = msg;
1462
- const $warn = warn;
1463
- const $error = error;
1464
- const $infoStr = infoStr;
1465
- const $msgStr = msgStr;
1466
- const $warnStr = warnStr;
1467
- const $errorStr = errorStr;
1468
- const $cmdDir = _home;
1469
- const $cmdMap = _cmdMap;
1470
- const $defArgs = () => $args;
1471
- const $require = _requireSources;
1472
- const $tableStr = tableStr;
1473
- const $nableStr = nableStr;
1474
- const $table = console.table;
1475
- const $nable = console.nable;
1476
-
1477
- return eval(`(async ()=>{try {${$text};
1414
+ async function evalText($text = '', $cmdName = '', $args = []) {
1415
+ try {
1416
+ return await evalCode($text, $cmdName, $args,
1417
+ _home, _cmdMap, _requireSources, $data,
1418
+ nextLine, nextText, setTips, delTips, wrapperInput, filterCmd)
1478
1419
  } catch(e) {
1479
- throw _errorAppend(e, $cmdName);
1420
+ throw errorTag(e, $cmdName);
1480
1421
  }
1481
- })()`)
1482
1422
  }
1483
1423
 
1484
1424
  process.on('uncaughtException',function(err){
@@ -1493,3 +1433,15 @@ process.on('rejectionHandled',function(err){
1493
1433
  error(err, 'rejectionHandled')
1494
1434
  _noAppendNextLine || nextLine()
1495
1435
  })
1436
+ process.on('SIGINT', function () {
1437
+ if (_noAppendNextLine) {
1438
+ process.exit();
1439
+ } else {
1440
+ nextLine();
1441
+ }
1442
+ });
1443
+ process.on('beforeExit', function () {
1444
+ if (!_exit) {
1445
+ _noAppendNextLine || nextLine();
1446
+ }
1447
+ });