-
Notifications
You must be signed in to change notification settings - Fork 4
/
seeing-is-believing.coffee
146 lines (126 loc) · 6.36 KB
/
seeing-is-believing.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
# http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
spawn = require('child_process').spawn
# https://atom.io/docs/api/v1.7.2/CompositeDisposable
# An object that aggregates multiple Disposable instances together into a single disposable, so they can all be disposed as a group.
{CompositeDisposable} = require 'atom'
# might be cool to use the -j option to split into a second or third pane
# would be like:
# if there are multiple panes open that SIB did not create
# then just run with magic comment style
# if there is only one pane that SIB did not open
# run with --json flag
# find or open 2nd pane to the right, add metadata to it so we know it is "sib-results"
# print results there
# if there is stdout/stderr
# find or open 3rd & 4th panes under them, print results there
# if there is not stderr or stdout
# close the stdout / stderr panes if they are open
module.exports = SeeingIsBelieving =
config:
sibCommand:
title: 'Seeing is believing command'
description: '
This is the absolute path to your `seeing_is_believing` command. You may need to run
`which seeing_is_believing` or `rbenv which seeing_is_believing` to find this. Examples:
`/home/USERNAME/.gem/ruby/2.3.0/bin/seeing_is_believing` or `/usr/local/bin/bundle exec seeing_is_believing`.
Alternatively, you could set it to a file containing a script that runs it in a custom environment.
'
type: 'string'
default: 'seeing_is_believing'
flags:
description: 'You can get a full list of flags by running seeing_is_believing --help'
type: 'array'
default: ['--alignment-strategy', 'chunk',
'--number-of-captures', '300',
'--line-length', '1000',
'--timeout', '12']
items:
type: 'string'
activate: ->
@notifications = []
@subscriptions = new CompositeDisposable
# The snippets package subscribes to "atom-text-editor"
# what's the difference? Sounds like it's what we actually want and would let
# us get rid fo teh `return unless editor` check down below
@subscriptions.add atom.commands.add 'atom-workspace',
'seeing-is-believing:annotate-document': => @run [],
'seeing-is-believing:annotate-magic-comments': => @run ['--xmpfilter-style'],
'seeing-is-believing:remove-annotations': => @run ['--clean']
@subscriptions.add atom.commands.onDidDispatch (event) =>
return unless event.type == "snippets:expand"
editor = atom.workspace.getActiveTextEditor() # I think we can assume this since snippets:expand did dispatch, note they use @getModel, to do this, but a quick glance around didn't locate it, so maybe look for it if I keep this
scope = editor.getLastCursor().getScopeDescriptor()
scopes = scope?.getScopesArray?() # IDK if I need the ?s, just cargo culting their work: https://github.com/atom/snippets/blob/c93956cc7306632beede152d77a7d4f757bc70a9/lib/snippets.coffee#L193
return unless scopes && scopes.includes("source.ruby")
didExpand = false
editor.getCursors().forEach (cursor) =>
{row, column} = cursor.getBufferPosition()
text = editor.getTextInRange([{row, column: column-5}, {row, column: column}])
console.log(text)
@run ['--xmpfilter-style'] if text == "# => "
deactivate: ->
@subscriptions.dispose()
run: (args) ->
editor = atom.workspace.getActiveTextEditor()
# Ideally we figure out whether this can happen,
# and if so, update the scope on our subscription.
return unless editor
# Here, we intentionally avoid using a subscription to scope this as there's
# no feedback about why it's not working, so it just seems broken. Eg #26
if @isntRuby editor
@dismissOurErrors()
@notifyError "Seeing Is Believing expects a Ruby file",
description: @expectedRubyError(editor, atom.keymaps),
dismissable: true
return
sibCommand = atom.config.get('seeing-is-believing.sibCommand')
args = args.concat atom.config.get('seeing-is-believing.flags')
@invokeSib sibCommand, args, editor.getText(), editor.getPath(), (code, stdout, stderr) =>
@dismissOurErrors()
if code == 2 # nondisplayable error
@notifyError 'Seeing Is Believing', detail: "exec error: #{stderr}", dismissable: true
else
@withoutMovingScreenOrCursors editor, -> editor.setText(stdout + stderr)
# https://atom.io/docs/api/v1.13.1/NotificationManager#instance-addError
notifyError: (message, options) ->
@notifications.push atom.notifications.addError(message, options)
dismissOurErrors: ->
@notifications.shift().dismiss() while 0 < @notifications.length
invokeSib: (sibCommand, args, body, filename, onClose) ->
args.push('--as', filename) if filename
[stdout, stderr] = ["", ""]
sib = spawn(sibCommand, args)
sib.stdout.on 'data', (output) -> stdout += output
sib.stderr.on 'data', (output) -> stderr += output
sib.on 'close', (code) -> onClose(code, stdout, stderr)
sib.stdin.write(body)
sib.stdin.end()
withoutMovingScreenOrCursors: (editor, f) ->
element = editor.element
cursors = editor.getSelectedBufferRanges()
scrollTop = element.getScrollTop()
scrollLeft = element.getScrollLeft()
f()
editor.setSelectedBufferRanges(cursors)
element.setScrollLeft(scrollLeft)
element.setScrollTop(scrollTop)
isntRuby: (editor) ->
"ruby" != editor.getGrammar().name.toLowerCase()
expectedRubyError: (editor, keymaps) ->
grammarName = editor.getGrammar().name
grammarKeys = @keystrokesFor editor, keymaps, "grammar-selector:show"
howToOpenGrammarSelector =
if grammarKeys?
"`#{grammarKeys}` or click `#{grammarName}` in the bottom right of the window"
else
"click `#{grammarName}` in the bottom right of the window"
"""
Atom thinks your file is `#{grammarName}`.
To tell Atom that this is a `Ruby` file, use the Grammar Selector
(#{howToOpenGrammarSelector}).
The syntax highlighting will change and you'll see `Ruby` in the bottom-right.
"""
keystrokesFor: (editor, keymaps, name) ->
keymaps.findKeyBindings(command: name, target: editor.element)
.map((cmd) -> cmd.keystrokes)
.filter((ks) -> ks)[0]