repl.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // Generated by CoffeeScript 1.12.6
  2. (function() {
  3. var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, ref, replDefaults, runInContext, updateSyntaxError, vm;
  4. fs = require('fs');
  5. path = require('path');
  6. vm = require('vm');
  7. nodeREPL = require('repl');
  8. CoffeeScript = require('./coffee-script');
  9. ref = require('./helpers'), merge = ref.merge, updateSyntaxError = ref.updateSyntaxError;
  10. replDefaults = {
  11. prompt: 'coffee> ',
  12. historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0,
  13. historyMaxInputSize: 10240,
  14. "eval": function(input, context, filename, cb) {
  15. var Assign, Block, Literal, Value, ast, err, js, ref1, referencedVars, token, tokens;
  16. input = input.replace(/\uFF00/g, '\n');
  17. input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1');
  18. input = input.replace(/^\s*try\s*{([\s\S]*)}\s*catch.*$/m, '$1');
  19. ref1 = require('./nodes'), Block = ref1.Block, Assign = ref1.Assign, Value = ref1.Value, Literal = ref1.Literal;
  20. try {
  21. tokens = CoffeeScript.tokens(input);
  22. referencedVars = (function() {
  23. var i, len, results;
  24. results = [];
  25. for (i = 0, len = tokens.length; i < len; i++) {
  26. token = tokens[i];
  27. if (token[0] === 'IDENTIFIER') {
  28. results.push(token[1]);
  29. }
  30. }
  31. return results;
  32. })();
  33. ast = CoffeeScript.nodes(tokens);
  34. ast = new Block([new Assign(new Value(new Literal('_')), ast, '=')]);
  35. js = ast.compile({
  36. bare: true,
  37. locals: Object.keys(context),
  38. referencedVars: referencedVars
  39. });
  40. return cb(null, runInContext(js, context, filename));
  41. } catch (error) {
  42. err = error;
  43. updateSyntaxError(err, input);
  44. return cb(err);
  45. }
  46. }
  47. };
  48. runInContext = function(js, context, filename) {
  49. if (context === global) {
  50. return vm.runInThisContext(js, filename);
  51. } else {
  52. return vm.runInContext(js, context, filename);
  53. }
  54. };
  55. addMultilineHandler = function(repl) {
  56. var inputStream, multiline, nodeLineListener, origPrompt, outputStream, ref1, rli;
  57. rli = repl.rli, inputStream = repl.inputStream, outputStream = repl.outputStream;
  58. origPrompt = (ref1 = repl._prompt) != null ? ref1 : repl.prompt;
  59. multiline = {
  60. enabled: false,
  61. initialPrompt: origPrompt.replace(/^[^> ]*/, function(x) {
  62. return x.replace(/./g, '-');
  63. }),
  64. prompt: origPrompt.replace(/^[^> ]*>?/, function(x) {
  65. return x.replace(/./g, '.');
  66. }),
  67. buffer: ''
  68. };
  69. nodeLineListener = rli.listeners('line')[0];
  70. rli.removeListener('line', nodeLineListener);
  71. rli.on('line', function(cmd) {
  72. if (multiline.enabled) {
  73. multiline.buffer += cmd + "\n";
  74. rli.setPrompt(multiline.prompt);
  75. rli.prompt(true);
  76. } else {
  77. rli.setPrompt(origPrompt);
  78. nodeLineListener(cmd);
  79. }
  80. });
  81. return inputStream.on('keypress', function(char, key) {
  82. if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'v')) {
  83. return;
  84. }
  85. if (multiline.enabled) {
  86. if (!multiline.buffer.match(/\n/)) {
  87. multiline.enabled = !multiline.enabled;
  88. rli.setPrompt(origPrompt);
  89. rli.prompt(true);
  90. return;
  91. }
  92. if ((rli.line != null) && !rli.line.match(/^\s*$/)) {
  93. return;
  94. }
  95. multiline.enabled = !multiline.enabled;
  96. rli.line = '';
  97. rli.cursor = 0;
  98. rli.output.cursorTo(0);
  99. rli.output.clearLine(1);
  100. multiline.buffer = multiline.buffer.replace(/\n/g, '\uFF00');
  101. rli.emit('line', multiline.buffer);
  102. multiline.buffer = '';
  103. } else {
  104. multiline.enabled = !multiline.enabled;
  105. rli.setPrompt(multiline.initialPrompt);
  106. rli.prompt(true);
  107. }
  108. });
  109. };
  110. addHistory = function(repl, filename, maxSize) {
  111. var buffer, fd, lastLine, readFd, size, stat;
  112. lastLine = null;
  113. try {
  114. stat = fs.statSync(filename);
  115. size = Math.min(maxSize, stat.size);
  116. readFd = fs.openSync(filename, 'r');
  117. buffer = new Buffer(size);
  118. fs.readSync(readFd, buffer, 0, size, stat.size - size);
  119. fs.closeSync(readFd);
  120. repl.rli.history = buffer.toString().split('\n').reverse();
  121. if (stat.size > maxSize) {
  122. repl.rli.history.pop();
  123. }
  124. if (repl.rli.history[0] === '') {
  125. repl.rli.history.shift();
  126. }
  127. repl.rli.historyIndex = -1;
  128. lastLine = repl.rli.history[0];
  129. } catch (error) {}
  130. fd = fs.openSync(filename, 'a');
  131. repl.rli.addListener('line', function(code) {
  132. if (code && code.length && code !== '.history' && code !== '.exit' && lastLine !== code) {
  133. fs.writeSync(fd, code + "\n");
  134. return lastLine = code;
  135. }
  136. });
  137. repl.on('exit', function() {
  138. return fs.closeSync(fd);
  139. });
  140. return repl.commands[getCommandId(repl, 'history')] = {
  141. help: 'Show command history',
  142. action: function() {
  143. repl.outputStream.write((repl.rli.history.slice(0).reverse().join('\n')) + "\n");
  144. return repl.displayPrompt();
  145. }
  146. };
  147. };
  148. getCommandId = function(repl, commandName) {
  149. var commandsHaveLeadingDot;
  150. commandsHaveLeadingDot = repl.commands['.help'] != null;
  151. if (commandsHaveLeadingDot) {
  152. return "." + commandName;
  153. } else {
  154. return commandName;
  155. }
  156. };
  157. module.exports = {
  158. start: function(opts) {
  159. var build, major, minor, ref1, repl;
  160. if (opts == null) {
  161. opts = {};
  162. }
  163. ref1 = process.versions.node.split('.').map(function(n) {
  164. return parseInt(n, 10);
  165. }), major = ref1[0], minor = ref1[1], build = ref1[2];
  166. if (major === 0 && minor < 8) {
  167. console.warn("Node 0.8.0+ required for CoffeeScript REPL");
  168. process.exit(1);
  169. }
  170. CoffeeScript.register();
  171. process.argv = ['coffee'].concat(process.argv.slice(2));
  172. opts = merge(replDefaults, opts);
  173. repl = nodeREPL.start(opts);
  174. if (opts.prelude) {
  175. runInContext(opts.prelude, repl.context, 'prelude');
  176. }
  177. repl.on('exit', function() {
  178. if (!repl.rli.closed) {
  179. return repl.outputStream.write('\n');
  180. }
  181. });
  182. addMultilineHandler(repl);
  183. if (opts.historyFile) {
  184. addHistory(repl, opts.historyFile, opts.historyMaxInputSize);
  185. }
  186. repl.commands[getCommandId(repl, 'load')].help = 'Load code from a file into this REPL session';
  187. return repl;
  188. }
  189. };
  190. }).call(this);