From d8877a9b9cc8cd93f1c0c5dced7724437d24c5e5 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 15:11:46 -0400 Subject: [PATCH 1/4] Calculate the actual frame line. --- lib/stacktrace.coffee | 19 ++++++++++++---- spec/stacktrace-spec.coffee | 44 ++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/lib/stacktrace.coffee b/lib/stacktrace.coffee index 913f222..17df444 100644 --- a/lib/stacktrace.coffee +++ b/lib/stacktrace.coffee @@ -144,9 +144,9 @@ class Frame # Public: Asynchronously collect n lines of context around the specified line number in this # frame's source file. # - # n - The number of lines of context to collect on *each* side of the error line. The error - # line will always be `lines[n]` and `lines.length` will be `n * 2 + 1`. - # callback - Invoked with any errors or an Array containing the relevant lines. + # n - The number of lines of context to collect on *each* side of the error line. + # callback - Invoked with any errors, or an Array containing the relevant lines and the index of + # the line in the Array that corresponds to the actual frame. # getContext: (n, callback) -> # Notice that @lineNumber is one-indexed, not zero-indexed. @@ -155,7 +155,18 @@ class Frame toLine: @lineNumber + n trim: false keepLastEmptyLine: true - chomp fs.createReadStream(@realPath), range, callback + chomp fs.createReadStream(@realPath), range, (err, lines) => + if err? + callback(err) + else + # Determine which line is the actual trace line. + if lines.length < (2 * n + 1) and range.fromLine < 0 + # The front is cut off. + traceLine = @lineNumber - 1 + else + traceLine = n + + callback(null, lines, traceLine) navigateTo: -> position = [@lineNumber - 1, 0] diff --git a/spec/stacktrace-spec.coffee b/spec/stacktrace-spec.coffee index 3f03c24..afcae2d 100644 --- a/spec/stacktrace-spec.coffee +++ b/spec/stacktrace-spec.coffee @@ -152,14 +152,15 @@ describe 'Frame', -> beforeEach -> fixturePath = path.join __dirname, 'fixtures', 'context.txt' - frame = new Frame('five', fixturePath, 5, 'something') it 'acquires n lines of context asynchronously', -> - lines = null + [lines, traceLine] = [] + frame = new Frame('five', fixturePath, 5, 'something') - frame.getContext 2, (err, ls) -> + frame.getContext 2, (err, ls, lnum) -> throw err if err? lines = ls + traceLine = lnum waitsFor -> lines? @@ -170,6 +171,7 @@ describe 'Frame', -> expect(lines[2]).toEqual('five') expect(lines[3]).toEqual('six') expect(lines[4]).toEqual('') + expect(traceLine).toBe(2) describe 'recognizes itself in an Editor', -> it 'is on a cursor', -> @@ -180,3 +182,39 @@ describe 'Frame', -> it 'is on a different file', -> expect(frame.isOn(position: Point.fromObject([4, 0]), path: 'some/other/path.rb')).toBeFalsy() + + it 'identifies the trace line if the beginning is cut off', -> + [lines, traceLine] = [] + frame = new Frame('two', fixturePath, 2, 'something') + + frame.getContext 3, (err, ls, lnum) -> + throw err if err? + lines = ls + traceLine = lnum + + waitsFor -> lines? + + runs -> + expect(lines.length).toBe(5) + expect(lines[0]).toEqual('one') + expect(lines[4]).toEqual('five') + expect(traceLine).toBe(1) + expect(lines[1]).toEqual('two') + + it 'identifies the trace line if the end is cut off', -> + [lines, traceLine] = [] + frame = new Frame('nine', fixturePath, 9, 'something') + + frame.getContext 3, (err, ls, lnum) -> + throw err if err? + lines = ls + traceLine = lnum + + waitsFor -> lines? + + runs -> + expect(lines.length).toBe(6) + expect(lines[0]).toEqual('six') + expect(lines[5]).toEqual('') + expect(traceLine).toBe(3) + expect(lines[3]).toEqual('nine') From 2f69e3e952374e69b6c492fd5a09775218a43619 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sun, 27 Jul 2014 15:26:43 -0400 Subject: [PATCH 2/4] Decorate lines within the mini-Editors. --- lib/stacktrace-view.coffee | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/stacktrace-view.coffee b/lib/stacktrace-view.coffee index bfed2f3..dd5e4e0 100644 --- a/lib/stacktrace-view.coffee +++ b/lib/stacktrace-view.coffee @@ -81,11 +81,17 @@ class FrameView extends View grammar = atom.syntax.selectGrammar @frame.realPath, lines.join("\n") @source.getEditor().setGrammar grammar - @frame.getContext 3, (err, lines) => + @frame.getContext 3, (err, lines, traceLine) => if err? console.error err else - @source.getEditor().setText lines.join("\n") + editor = @source.getEditor() + editor.setText lines.join("\n") + @marker = editor.markBufferRange [[traceLine, 0], [traceLine + 1, 0]], persistent: false + editor.decorateMarker @marker, type: 'line', class: 'trace-line' + + beforeRemove: -> + @marker.destroy() if @marker? navigate: -> @navCallback() From 4287b994056d6eff7cda69c1bb870e442d854675 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sat, 30 Aug 2014 12:33:17 -0400 Subject: [PATCH 3/4] Fix up unit tests. --- spec/stacktrace-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/stacktrace-spec.coffee b/spec/stacktrace-spec.coffee index afcae2d..b2ffe25 100644 --- a/spec/stacktrace-spec.coffee +++ b/spec/stacktrace-spec.coffee @@ -152,10 +152,10 @@ describe 'Frame', -> beforeEach -> fixturePath = path.join __dirname, 'fixtures', 'context.txt' + frame = new Frame('five', fixturePath, 5, 'something') it 'acquires n lines of context asynchronously', -> [lines, traceLine] = [] - frame = new Frame('five', fixturePath, 5, 'something') frame.getContext 2, (err, ls, lnum) -> throw err if err? From d488f8892192fa32b83f70d6ad67c57213a11f25 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Sat, 30 Aug 2014 13:08:15 -0400 Subject: [PATCH 4/4] Mini editors still don't like decorations! --- lib/stacktrace-view.coffee | 5 +++-- spec/stacktrace-view-spec.coffee | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/stacktrace-view.coffee b/lib/stacktrace-view.coffee index dd5e4e0..603ad80 100644 --- a/lib/stacktrace-view.coffee +++ b/lib/stacktrace-view.coffee @@ -87,8 +87,9 @@ class FrameView extends View else editor = @source.getEditor() editor.setText lines.join("\n") - @marker = editor.markBufferRange [[traceLine, 0], [traceLine + 1, 0]], persistent: false - editor.decorateMarker @marker, type: 'line', class: 'trace-line' + range = editor.getBuffer().rangeForRow traceLine + @marker = editor.markBufferRange range + console.log editor.decorateMarker @marker, type: 'line', class: 'line-stackframe' beforeRemove: -> @marker.destroy() if @marker? diff --git a/spec/stacktrace-view-spec.coffee b/spec/stacktrace-view-spec.coffee index 131965b..dc43700 100644 --- a/spec/stacktrace-view-spec.coffee +++ b/spec/stacktrace-view-spec.coffee @@ -59,3 +59,6 @@ describe 'FrameView', -> it 'shows the function name', -> text = view.find('.function-name').text() expect(text).toEqual('midfunc') + + it 'decorates the active line', -> + expect(view.find('.editor .line-stacktrace')).toHaveLength(1)