1 |
|
2 | (function() {
|
3 | var CoffeeScript, addMultilineHandler, merge, nodeREPL, replDefaults, vm;
|
4 |
|
5 | vm = require('vm');
|
6 |
|
7 | nodeREPL = require('repl');
|
8 |
|
9 | CoffeeScript = require('./coffee-script');
|
10 |
|
11 | merge = require('./helpers').merge;
|
12 |
|
13 | replDefaults = {
|
14 | prompt: 'coffee> ',
|
15 | "eval": function(input, context, filename, cb) {
|
16 | var js;
|
17 | input = input.replace(/\uFF00/g, '\n');
|
18 | input = input.replace(/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, '$1$2$3');
|
19 | if (/^(\s*|\(\s*\))$/.test(input)) {
|
20 | return cb(null);
|
21 | }
|
22 | try {
|
23 | js = CoffeeScript.compile("_=(" + input + "\n)", {
|
24 | filename: filename,
|
25 | bare: true
|
26 | });
|
27 | return cb(null, vm.runInContext(js, context, filename));
|
28 | } catch (err) {
|
29 | return cb(err);
|
30 | }
|
31 | }
|
32 | };
|
33 |
|
34 | addMultilineHandler = function(repl) {
|
35 | var inputStream, multiline, nodeLineListener, outputStream, rli;
|
36 | rli = repl.rli, inputStream = repl.inputStream, outputStream = repl.outputStream;
|
37 | multiline = {
|
38 | enabled: false,
|
39 | initialPrompt: repl.prompt.replace(/^[^> ]*/, function(x) {
|
40 | return x.replace(/./g, '-');
|
41 | }),
|
42 | prompt: repl.prompt.replace(/^[^> ]*>?/, function(x) {
|
43 | return x.replace(/./g, '.');
|
44 | }),
|
45 | buffer: ''
|
46 | };
|
47 | nodeLineListener = rli.listeners('line')[0];
|
48 | rli.removeListener('line', nodeLineListener);
|
49 | rli.on('line', function(cmd) {
|
50 | if (multiline.enabled) {
|
51 | multiline.buffer += "" + cmd + "\n";
|
52 | rli.setPrompt(multiline.prompt);
|
53 | rli.prompt(true);
|
54 | } else {
|
55 | nodeLineListener(cmd);
|
56 | }
|
57 | });
|
58 | return inputStream.on('keypress', function(char, key) {
|
59 | if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'v')) {
|
60 | return;
|
61 | }
|
62 | if (multiline.enabled) {
|
63 | if (!multiline.buffer.match(/\n/)) {
|
64 | multiline.enabled = !multiline.enabled;
|
65 | rli.setPrompt(repl.prompt);
|
66 | rli.prompt(true);
|
67 | return;
|
68 | }
|
69 | if ((rli.line != null) && !rli.line.match(/^\s*$/)) {
|
70 | return;
|
71 | }
|
72 | multiline.enabled = !multiline.enabled;
|
73 | rli.line = '';
|
74 | rli.cursor = 0;
|
75 | rli.output.cursorTo(0);
|
76 | rli.output.clearLine(1);
|
77 | multiline.buffer = multiline.buffer.replace(/\n/g, '\uFF00');
|
78 | rli.emit('line', multiline.buffer);
|
79 | multiline.buffer = '';
|
80 | } else {
|
81 | multiline.enabled = !multiline.enabled;
|
82 | rli.setPrompt(multiline.initialPrompt);
|
83 | rli.prompt(true);
|
84 | }
|
85 | });
|
86 | };
|
87 |
|
88 | module.exports = {
|
89 | start: function(opts) {
|
90 | var repl;
|
91 | if (opts == null) {
|
92 | opts = {};
|
93 | }
|
94 | opts = merge(replDefaults, opts);
|
95 | repl = nodeREPL.start(opts);
|
96 | repl.on('exit', function() {
|
97 | return repl.outputStream.write('\n');
|
98 | });
|
99 | addMultilineHandler(repl);
|
100 | return repl;
|
101 | }
|
102 | };
|
103 |
|
104 | }).call(this);
|