1 | vm = require 'vm'
|
2 | nodeREPL = require 'repl'
|
3 | CoffeeScript = require './module'
|
4 | {merge} = require './helpers'
|
5 |
|
6 | addMultilineHandler = (repl) ->
|
7 | {rli, inputStream, outputStream} = repl
|
8 | initialPrompt = repl.prompt.replace /^[^> ]*/, (x) -> x.replace /./g, '-'
|
9 | continuationPrompt = repl.prompt.replace /^[^> ]*>?/, (x) -> x.replace /./g, '.'
|
10 |
|
11 | enabled = no
|
12 | buffer = ''
|
13 |
|
14 |
|
15 | nodeLineListener = (rli.listeners 'line')[0]
|
16 | rli.removeListener 'line', nodeLineListener
|
17 | rli.on 'line', (cmd) ->
|
18 | if enabled
|
19 | buffer += "#{cmd}\n"
|
20 | rli.setPrompt continuationPrompt
|
21 | rli.prompt true
|
22 | else
|
23 | nodeLineListener cmd
|
24 | return
|
25 |
|
26 |
|
27 | inputStream.on 'keypress', (char, key) ->
|
28 | return unless key and key.ctrl and not key.meta and not key.shift and key.name is 'v'
|
29 | if enabled
|
30 |
|
31 | unless buffer.match /\n/
|
32 | enabled = not enabled
|
33 | rli.setPrompt repl.prompt
|
34 | rli.prompt true
|
35 | return
|
36 |
|
37 | return if rli.line? and not rli.line.match /^\s*$/
|
38 |
|
39 | enabled = not enabled
|
40 | rli.line = ''
|
41 | rli.cursor = 0
|
42 | rli.output.cursorTo 0
|
43 | rli.output.clearLine 1
|
44 |
|
45 | buffer = buffer.replace /\n/g, '\uFF00'
|
46 | rli.emit 'line', buffer
|
47 | buffer = ''
|
48 | else
|
49 | enabled = not enabled
|
50 | rli.setPrompt initialPrompt
|
51 | rli.prompt true
|
52 | return
|
53 |
|
54 | module.exports =
|
55 | start: (opts = {}) ->
|
56 |
|
57 | opts.prompt or= 'coffee> '
|
58 | opts.eval or= (input, context, filename, cb) ->
|
59 |
|
60 | input = input.replace /\uFF00/g, '\n'
|
61 |
|
62 | input = input.replace /(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, '$1$2$3'
|
63 |
|
64 | return cb null if /^(\s*|\(\s*\))$/.test input
|
65 |
|
66 | try
|
67 | js = CoffeeScript.cs2js "_=(#{input}\n)", {filename, bare: yes}
|
68 | cb null, vm.runInContext js, context, filename
|
69 | catch err
|
70 | cb "\x1B[0;31m#{err.constructor.name}: #{err.message}\x1B[0m"
|
71 |
|
72 | repl = nodeREPL.start opts
|
73 | repl.on 'exit', -> repl.outputStream.write '\n'
|
74 | addMultilineHandler repl
|
75 | repl
|