From 3fda3ad3f4abdccf601ef4764f01b977beba083a Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 15:47:24 -0400 Subject: [PATCH 1/9] Specs for the do-nothing case. --- lib/editor-decorator.coffee | 3 +++ spec/editor-marker-spec.coffee | 37 +++++++++++++++++++++++++++++ spec/fixtures/bottom.rb | 14 +++++++++++ spec/fixtures/middle.rb | 43 ++++++++++++++++++++++++++++++++++ spec/fixtures/top.rb | 38 ++++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+) create mode 100644 lib/editor-decorator.coffee create mode 100644 spec/editor-marker-spec.coffee create mode 100644 spec/fixtures/bottom.rb create mode 100644 spec/fixtures/middle.rb create mode 100644 spec/fixtures/top.rb diff --git a/lib/editor-decorator.coffee b/lib/editor-decorator.coffee new file mode 100644 index 0000000..29d4414 --- /dev/null +++ b/lib/editor-decorator.coffee @@ -0,0 +1,3 @@ +# Decorate any lines within an {Editor} that correspond to an active {Stacktrace}. + +module.exports = (editor) -> diff --git a/spec/editor-marker-spec.coffee b/spec/editor-marker-spec.coffee new file mode 100644 index 0000000..13a1db6 --- /dev/null +++ b/spec/editor-marker-spec.coffee @@ -0,0 +1,37 @@ +path = require 'path' +{Editor, WorkspaceView} = require 'atom' + +{Stacktrace, Frame} = require '../lib/stacktrace' +editorDecorator = require '../lib/editor-decorator' + +framePath = (fname) -> path.join __dirname, 'fixtures', fname + +frames = [ + new Frame('raw0', framePath('bottom.rb'), 12, 'botfunc') + new Frame('raw1', framePath('middle.rb'), 42, 'midfunc') + new Frame('raw2', framePath('top.rb'), 37, 'topfunc') + new Frame('raw3', framePath('middle.rb'), 5, 'otherfunc') +] +trace = new Stacktrace(frames, 'Boom') + +describe 'editorMarker', -> + [editor, editorView] = [] + + beforeEach -> + atom.workspaceView = new WorkspaceView + + withEditorOn = (fname, callback) -> + waitsForPromise -> + atom.workspace.open(framePath fname) + + runs -> + editorView = atom.workspaceView.getActiveView() + editor = editorView.getEditor() + callback() + + it 'does nothing if there is no active trace', -> + expect(Stacktrace.getActivated()).toBeNull() + + withEditorOn 'bottom.rb', -> + editorDecorator(editor) + expect(editorView.find '.line.line-stackframe').toHaveLength 0 diff --git a/spec/fixtures/bottom.rb b/spec/fixtures/bottom.rb new file mode 100644 index 0000000..fb32573 --- /dev/null +++ b/spec/fixtures/bottom.rb @@ -0,0 +1,14 @@ +# This isn't a real Ruby file. It's a test fixture I can reference in other places. + + + + + + + + +def botfunc + before = true + puts 'this is the stack line' + after = false +end diff --git a/spec/fixtures/middle.rb b/spec/fixtures/middle.rb new file mode 100644 index 0000000..d8d7ee3 --- /dev/null +++ b/spec/fixtures/middle.rb @@ -0,0 +1,43 @@ +# This isn't a real Ruby file. It's a test fixture I can reference in other places. +# This one has two lines in the "stack trace". + +def otherfunc + puts 'this is the line' + # and more stuff +end + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +def botfunc + # more things + puts 'this is the line' +end diff --git a/spec/fixtures/top.rb b/spec/fixtures/top.rb new file mode 100644 index 0000000..d0c6839 --- /dev/null +++ b/spec/fixtures/top.rb @@ -0,0 +1,38 @@ +# This isn't a real Ruby file. It's a test fixture I can reference in other places. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +def topfunc + # things + puts 'this is the line' +end From c6e469e203f552f3f44e10b6445736e7e2efe532 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 15:51:57 -0400 Subject: [PATCH 2/9] More do-nothing cases. --- spec/editor-marker-spec.coffee | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spec/editor-marker-spec.coffee b/spec/editor-marker-spec.coffee index 13a1db6..474260a 100644 --- a/spec/editor-marker-spec.coffee +++ b/spec/editor-marker-spec.coffee @@ -14,12 +14,15 @@ frames = [ ] trace = new Stacktrace(frames, 'Boom') -describe 'editorMarker', -> +describe 'editorDecorator', -> [editor, editorView] = [] beforeEach -> atom.workspaceView = new WorkspaceView + afterEach -> + Stacktrace.getActivated()?.deactivate() + withEditorOn = (fname, callback) -> waitsForPromise -> atom.workspace.open(framePath fname) @@ -35,3 +38,10 @@ describe 'editorMarker', -> withEditorOn 'bottom.rb', -> editorDecorator(editor) expect(editorView.find '.line.line-stackframe').toHaveLength 0 + + it "does nothing if the file doesn't appear in the active trace", -> + trace.activate() + + withEditorOn 'context.txt', -> + editorDecorator(editor) + expect(editorView.find '.line.line-stackframe').toHaveLength 0 From 0244de32f31cfa63ddc1c5ab333e0f1e102f59df Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 15:55:01 -0400 Subject: [PATCH 3/9] Test for a single decoration. --- spec/editor-marker-spec.coffee | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/spec/editor-marker-spec.coffee b/spec/editor-marker-spec.coffee index 474260a..68ea49e 100644 --- a/spec/editor-marker-spec.coffee +++ b/spec/editor-marker-spec.coffee @@ -39,9 +39,18 @@ describe 'editorDecorator', -> editorDecorator(editor) expect(editorView.find '.line.line-stackframe').toHaveLength 0 - it "does nothing if the file doesn't appear in the active trace", -> - trace.activate() + describe 'with an active trace', -> - withEditorOn 'context.txt', -> - editorDecorator(editor) - expect(editorView.find '.line.line-stackframe').toHaveLength 0 + beforeEach -> trace.activate() + + it "does nothing if the file doesn't appear in the active trace", -> + withEditorOn 'context.txt', -> + editorDecorator(editor) + expect(editorView.find '.line.line-stackframe').toHaveLength 0 + + it 'decorates stackframe lines in applicable editors', -> + withEditorOn 'bottom.rb', -> + editorDecorator(editor) + decorated = editorView.find '.line.line-stackframe' + expect(decorated).toHaveLength 1 + expect(decorated.text()).toEqual(" puts 'this is the stack line'") From b81d7fb82da88416ac34db3c98a926fb66f976d5 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 16:11:44 -0400 Subject: [PATCH 4/9] Decorate matching Editor lines. --- lib/editor-decorator.coffee | 11 +++++++++++ lib/stacktrace.coffee | 4 ++++ spec/editor-marker-spec.coffee | 1 + 3 files changed, 16 insertions(+) diff --git a/lib/editor-decorator.coffee b/lib/editor-decorator.coffee index 29d4414..876667d 100644 --- a/lib/editor-decorator.coffee +++ b/lib/editor-decorator.coffee @@ -1,3 +1,14 @@ # Decorate any lines within an {Editor} that correspond to an active {Stacktrace}. +{Stacktrace} = require './stacktrace' + module.exports = (editor) -> + active = Stacktrace.getActivated() + return unless active? + + for frame in active.frames + if frame.realPath is editor.getPath() + range = editor.getBuffer().rangeForRow frame.bufferLineNumber() + marker = editor.markBufferRange range + console.log "Decorating #{editor.getPath()} range #{range}" + editor.decorateMarker marker, type: 'line', class: 'line-stackframe' diff --git a/lib/stacktrace.coffee b/lib/stacktrace.coffee index 413f38e..14aaf8e 100644 --- a/lib/stacktrace.coffee +++ b/lib/stacktrace.coffee @@ -92,6 +92,10 @@ class Frame constructor: (@rawLine, @rawPath, @lineNumber, @functionName) -> @realPath = @rawPath + # Public: Return the zero-indexed line number. + # + bufferLineNumber: -> @lineNumber - 1 + # Public: Asynchronously collect n lines of context around the specified line number in this # frame's source file. # diff --git a/spec/editor-marker-spec.coffee b/spec/editor-marker-spec.coffee index 68ea49e..5db13e0 100644 --- a/spec/editor-marker-spec.coffee +++ b/spec/editor-marker-spec.coffee @@ -28,6 +28,7 @@ describe 'editorDecorator', -> atom.workspace.open(framePath fname) runs -> + atom.workspaceView.attachToDom() editorView = atom.workspaceView.getActiveView() editor = editorView.getEditor() callback() From 4b1f5eeb675150010a392db869224bf205aec53b Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 16:18:45 -0400 Subject: [PATCH 5/9] Decorate each Editor as it's opened. --- lib/main.coffee | 3 +++ stylesheets/stacktrace.less | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/lib/main.coffee b/lib/main.coffee index cf64fba..99a5024 100644 --- a/lib/main.coffee +++ b/lib/main.coffee @@ -1,6 +1,7 @@ EnterDialog = require './enter-dialog' {Stacktrace} = require './stacktrace' {StacktraceView} = require './stacktrace-view' +editorDecorator = require './editor-decorator' module.exports = @@ -13,6 +14,8 @@ module.exports = text = (s.getText() for s in (selections or [])).join '' atom.emit 'stacktrace:accept-trace', trace: text + atom.workspace.eachEditor editorDecorator + StacktraceView.registerIn(atom.workspace) atom.on 'stacktrace:accept-trace', ({trace}) => diff --git a/stylesheets/stacktrace.less b/stylesheets/stacktrace.less index 282fe3c..71c6705 100644 --- a/stylesheets/stacktrace.less +++ b/stylesheets/stacktrace.less @@ -45,3 +45,9 @@ } } + +.editor { + .line.line-stackframe { + background: @background-color-info; + } +} From 5a77576026c99589f5f825085a328156b64ec9ce Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 16:19:23 -0400 Subject: [PATCH 6/9] Now with one fewer debugging line. --- lib/editor-decorator.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/editor-decorator.coffee b/lib/editor-decorator.coffee index 876667d..c1b4577 100644 --- a/lib/editor-decorator.coffee +++ b/lib/editor-decorator.coffee @@ -10,5 +10,4 @@ module.exports = (editor) -> if frame.realPath is editor.getPath() range = editor.getBuffer().rangeForRow frame.bufferLineNumber() marker = editor.markBufferRange range - console.log "Decorating #{editor.getPath()} range #{range}" editor.decorateMarker marker, type: 'line', class: 'line-stackframe' From 7d2c7ed1da76fc5064b95fc1e71b352641a90d23 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 16:38:27 -0400 Subject: [PATCH 7/9] Decorate the gutter, too. --- lib/editor-decorator.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/editor-decorator.coffee b/lib/editor-decorator.coffee index c1b4577..59de55b 100644 --- a/lib/editor-decorator.coffee +++ b/lib/editor-decorator.coffee @@ -11,3 +11,4 @@ module.exports = (editor) -> range = editor.getBuffer().rangeForRow frame.bufferLineNumber() marker = editor.markBufferRange range editor.decorateMarker marker, type: 'line', class: 'line-stackframe' + editor.decorateMarker marker, type: 'gutter', class: 'gutter-stackframe' From fb25a0ddf7aebfcc21174c96e0c5daa1d675faf7 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 16:38:42 -0400 Subject: [PATCH 8/9] Derive the stackframe color from the syntax theme. --- stylesheets/stacktrace.less | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/stylesheets/stacktrace.less b/stylesheets/stacktrace.less index 71c6705..5bfc3c8 100644 --- a/stylesheets/stacktrace.less +++ b/stylesheets/stacktrace.less @@ -3,6 +3,10 @@ // See https://github.com/atom/atom-dark-ui/blob/master/stylesheets/ui-variables.less // for a full listing of what's available. @import "ui-variables"; +@import "syntax-variables"; + +@stackframe-background: mix(@background-color-info, @syntax-background-color, 40%); +@stackframe-gutter-background: mix(@background-color-info, @syntax-gutter-background-color, 40%); .stacktrace { &.enter-dialog .editor { @@ -48,6 +52,10 @@ .editor { .line.line-stackframe { - background: @background-color-info; + background: @stackframe-background; + } + + .gutter .gutter-stackframe { + background: @stackframe-gutter-background; } } From 774497a977f190fdddf2959737ad2485b60418f8 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 16:46:26 -0400 Subject: [PATCH 9/9] Re-mark everything when the active trace changes. --- lib/editor-decorator.coffee | 6 ++++++ lib/main.coffee | 3 +++ spec/editor-marker-spec.coffee | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/lib/editor-decorator.coffee b/lib/editor-decorator.coffee index 59de55b..e2d242f 100644 --- a/lib/editor-decorator.coffee +++ b/lib/editor-decorator.coffee @@ -2,7 +2,12 @@ {Stacktrace} = require './stacktrace' +markers = [] + module.exports = (editor) -> + m.destroy() for m in markers + markers = [] + active = Stacktrace.getActivated() return unless active? @@ -12,3 +17,4 @@ module.exports = (editor) -> marker = editor.markBufferRange range editor.decorateMarker marker, type: 'line', class: 'line-stackframe' editor.decorateMarker marker, type: 'gutter', class: 'gutter-stackframe' + markers.push marker diff --git a/lib/main.coffee b/lib/main.coffee index 99a5024..f24b80c 100644 --- a/lib/main.coffee +++ b/lib/main.coffee @@ -15,6 +15,8 @@ module.exports = atom.emit 'stacktrace:accept-trace', trace: text atom.workspace.eachEditor editorDecorator + Stacktrace.on 'active-changed', -> + editorDecorator(e) for e in atom.workspace.getEditors() StacktraceView.registerIn(atom.workspace) @@ -24,6 +26,7 @@ module.exports = atom.workspace.open trace.getUrl() deactivate: -> + Stacktrace.off 'active-changed' atom.off 'stacktrace:accept-trace' serialize: -> diff --git a/spec/editor-marker-spec.coffee b/spec/editor-marker-spec.coffee index 5db13e0..425a769 100644 --- a/spec/editor-marker-spec.coffee +++ b/spec/editor-marker-spec.coffee @@ -55,3 +55,10 @@ describe 'editorDecorator', -> decorated = editorView.find '.line.line-stackframe' expect(decorated).toHaveLength 1 expect(decorated.text()).toEqual(" puts 'this is the stack line'") + + it 'removes prior decorations when deactivated', -> + withEditorOn 'bottom.rb', -> + editorDecorator(editor) + trace.deactivate() + editorDecorator(editor) + expect(editorView.find '.line.line-stackframe').toHaveLength 0