diff --git a/lib/stacktrace-view.coffee b/lib/stacktrace-view.coffee index bfed2f3..603ad80 100644 --- a/lib/stacktrace-view.coffee +++ b/lib/stacktrace-view.coffee @@ -81,11 +81,18 @@ 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") + range = editor.getBuffer().rangeForRow traceLine + @marker = editor.markBufferRange range + console.log editor.decorateMarker @marker, type: 'line', class: 'line-stackframe' + + beforeRemove: -> + @marker.destroy() if @marker? navigate: -> @navCallback() 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..b2ffe25 100644 --- a/spec/stacktrace-spec.coffee +++ b/spec/stacktrace-spec.coffee @@ -155,11 +155,12 @@ describe 'Frame', -> frame = new Frame('five', fixturePath, 5, 'something') it 'acquires n lines of context asynchronously', -> - lines = null + [lines, traceLine] = [] - 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') 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)