forked from atom-community/atom-script
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript-view.coffee
205 lines (163 loc) · 5.99 KB
/
script-view.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
grammarMap = require './grammars'
{View, BufferedProcess} = require 'atom'
HeaderView = require './header-view'
ScriptOptionsView = require './script-options-view'
AnsiFilter = require 'ansi-to-html'
_ = require 'underscore'
# Runs a portion of a script through an interpreter and displays it line by line
module.exports =
class ScriptView extends View
@bufferedProcess: null
@content: ->
@div =>
@subview 'headerView', new HeaderView()
# Display layout and outlets
@div class: 'tool-panel panel panel-bottom padding script-view native-key-bindings', outlet: 'script', tabindex: -1, =>
@div class: 'panel-body padded output', outlet: 'output'
initialize: (serializeState, run_options) ->
# Bind commands
atom.workspaceView.command "script:run", => @start()
atom.workspaceView.command "script:close-view", => @close()
atom.workspaceView.command "script:kill-process", => @stop()
@ansiFilter = new AnsiFilter
@run_options = run_options
serialize: ->
updateOptions: (event) =>
console.log(event)
@run_options = event.run_options
start: ->
# Get current editor
editor = atom.workspace.getActiveEditor()
# No editor available, do nothing
if not editor?
return
@resetView()
commandContext = @setup(editor)
if commandContext then @run(commandContext.command, commandContext.args)
resetView: (title='Loading...') ->
# Display window and load message
# First run, create view
if not @hasParent()
atom.workspaceView.prependToBottom(this)
# Close any existing process and start a new one
@stop()
@headerView.title.text(title)
@headerView.setStatus("start")
# Get script view ready
@output.empty()
close: ->
# Stop any running process and dismiss window
@stop()
if @hasParent() then @detach()
getlang: (editor) ->
grammar = editor.getGrammar()
lang = grammar.name
return lang
setup: (editor) ->
# Store information about the run, including language
commandContext = {}
# Get language
lang = @getlang(editor)
err = null
# Determine if no language is selected
if lang == "Null Grammar" or lang == "Plain Text"
err =
"Must select a language in the lower left or " +
"save the file with an appropriate extension."
# Provide them a dialog to submit an issue on GH, prepopulated
# with their language of choice
else if ! (lang of grammarMap)
err =
"Command not configured for " + lang + "!\n\n" +
"Add an <a href='https://github.com/rgbkrk/atom-script/issues/" +
"new?title=Add%20support%20for%20" + lang + "'>issue on GitHub" +
"</a> or send your own Pull Request"
if err?
@handleError(err)
return false
if not @run_options.cmd? or @run_options.cmd is ''
# Precondition: lang? and lang of grammarMap
commandContext.command = grammarMap[lang].command
else
commandContext.command = @run_options.cmd
filename = editor.getTitle()
# Get selected text
selectedText = editor.getSelectedText()
filepath = editor.getPath()
# If no text was selected, either use the file
# or select ALL the code in the editor
# Brand new file, text not selected, "select" ALL the text
if (not selectedText? or not selectedText) and not filepath?
selectedText = editor.getText()
# No selected text on a file that does exist, use filepath
if (not selectedText? or not selectedText) and filepath?
argType = "File Based"
arg = filepath
else
argType = "Selection Based"
arg = selectedText
makeargs = grammarMap[lang][argType]
try
args = makeargs(arg)
commandContext.args = args
catch error
err = argType + " Runner not available for " + lang + "\n\n" +
"If it should exist add an " +
"<a href='https://github.com/rgbkrk/atom-script/issues/" +
"new?title=Add%20support%20for%20" + lang + "'>issue on GitHub" +
"</a> or send your own Pull Request"
@handleError(err)
return false
# Update header
@headerView.title.text(lang + " - " + filename)
# Return setup information
return commandContext
handleError: (err) ->
# Display error and kill process
@headerView.title.text("Error")
@headerView.setStatus("err")
@display("error", err)
@stop()
run: (command, args) ->
atom.emit("achievement:unlock", {msg: "Homestar Runner"})
# Prepend the user defined path
path_prefix = atom.config.get('script.path_prefix')
if path_prefix
process.env.PATH = [path_prefix, process.env.PATH].join(':')
# Default to where the user opened atom
options =
cwd: @getCwd()
env: process.env
args = (@run_options.cmd_args.concat args).concat @run_options.script_args
stdout = (output) => @display("stdout", output)
stderr = (output) => @display("stderr", output)
exit = (return_code) =>
if return_code is 0
@headerView.setStatus("stop")
else
@headerView.setStatus("err")
console.log "Exited with #{return_code}"
# Run process
@bufferedProcess = new BufferedProcess({command, args, options,
stdout, stderr, exit})
@bufferedProcess.process.on('error', (node_error) =>
@output.append("<h1>Unable to run</h1>")
@output.append("<pre>#{_.escape(command)}</pre>")
@output.append("<h2>Is it on your path?</h2>")
@output.append("<pre>PATH: #{_.escape(process.env.PATH)}</pre>")
)
getCwd: ->
if not @run_options.cmd_cwd? or @run_options.cmd_cwd is ''
atom.project.getPath()
else
@run_options.cmd_cwd
stop: ->
# Kill existing process if available
if @bufferedProcess? and @bufferedProcess.process?
@display("stdout", "^C")
@headerView.setStatus("kill")
@bufferedProcess.kill()
display: (css, line) ->
line = _.escape(line)
line = @ansiFilter.toHtml(line)
@output.append("<pre class='line #{css}'>#{line}</pre>")