Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 729c93e

Browse files
committed
Add open function to open the file from the diff
1 parent 6c4f1f5 commit 729c93e

File tree

5 files changed

+77
-4
lines changed

5 files changed

+77
-4
lines changed

lib/diff-component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export default class DiffComponent {
3131
'core:confirm': () => this.diffViewModel.toggleSelectedLinesStageStatus(),
3232
'git:expand-selection-up': () => this.diffViewModel.expandSelectionUp(),
3333
'git:expand-selection-down': () => this.diffViewModel.expandSelectionDown(),
34-
'git:toggle-selection-mode': () => this.diffViewModel.toggleSelectionMode()
34+
'git:toggle-selection-mode': () => this.diffViewModel.toggleSelectionMode(),
35+
'git:open-file-to-line': () => this.diffViewModel.openFileAtSelection()
3536
})
3637
}
3738

lib/diff-hunk.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ export default class DiffHunk {
4444
this.didChange()
4545
}
4646

47+
getFirstChangedLine() {
48+
for (const line of this.lines)
49+
if (line.isChanged())
50+
return line
51+
return null
52+
}
53+
4754
stage() {
4855
this.transactor.transact(() => {
4956
for (let line of this.lines)

lib/diff-view-model.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import {Emitter, CompositeDisposable} from 'atom'
44
import DiffSelection from './diff-selection'
5+
import DiffHunk from './diff-hunk'
56

67
export default class DiffViewModel {
78
constructor({fileList, uri, title}) {
@@ -237,4 +238,23 @@ export default class DiffViewModel {
237238
getFileDiffs() {
238239
return this.fileList.getFiles()
239240
}
241+
242+
openFileAtSelection() {
243+
// TODO: this is maybe a naive line-choosing approach. Basically picks the
244+
// first line of the most recent selection. It could look for an addition,
245+
// and if not found, it'll use the deleted line. Depends on how this feels
246+
const selection = this.getLastSelection()
247+
const [firstPosition, secondPosition] = selection.getRange()
248+
const pathName = this.getFileDiffs()[firstPosition[0]].getNewPathName()
249+
const lineOrHunk = this.fileList.getObjectAtPosition(firstPosition)
250+
251+
let lineObject
252+
if (lineOrHunk instanceof DiffHunk)
253+
lineObject = lineOrHunk.getFirstChangedLine()
254+
else
255+
lineObject = lineOrHunk
256+
257+
initialLine = (lineObject.getNewLineNumber() || lineObject.getOldLineNumber()) - 1
258+
atom.workspace.open(pathName, {initialLine})
259+
}
240260
}

lib/file-list.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,20 @@ export default class FileList {
3737
return this.files
3838
}
3939

40+
// position = [0, 2] will get you the third hunk in the first file.
41+
// position = [0, 2, 1] will get you the 2nd line in the third hunk in the first file.
42+
getObjectAtPosition(position) {
43+
let file, hunk, line
44+
const [fileIndex, hunkIndex, lineIndex] = position
45+
46+
file = this.getFiles()[fileIndex]
47+
hunk = file.getHunks()[hunkIndex]
48+
if (lineIndex != null)
49+
return hunk.getLines()[lineIndex]
50+
else
51+
return hunk
52+
}
53+
4054
toString() {
4155
return this.files.map((file) => { return file.toString() }).join('\n')
4256
}

spec/diff-view-model-spec.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ function expectLineToBeSelected(isSelected, viewModel, fileDiffIndex, diffHunkIn
2525
}
2626

2727
describe("DiffViewModel", function() {
28+
let viewModel
2829
describe("selecting diffs", function() {
29-
let viewModel
3030
beforeEach(function() {
3131
viewModel = createDiffs('fixtures/two-file-diff.txt')
3232
})
33+
3334
it("initially selects the first hunk", function() {
3435
expectHunkToBeSelected(true, viewModel, 0, 0)
3536
expectHunkToBeSelected(false, viewModel, 0, 1)
@@ -479,7 +480,6 @@ describe("DiffViewModel", function() {
479480
})
480481

481482
describe("staging diffs", function() {
482-
let viewModel
483483
beforeEach(function() {
484484
viewModel = createDiffs('fixtures/two-file-diff.txt')
485485
})
@@ -514,7 +514,6 @@ describe("DiffViewModel", function() {
514514
})
515515

516516
describe("handling events from the fileList", function() {
517-
let viewModel
518517
beforeEach(function() {
519518
viewModel = createDiffs('fixtures/two-file-diff.txt')
520519
})
@@ -528,6 +527,38 @@ describe("DiffViewModel", function() {
528527
expect(changeHandler).toHaveBeenCalled()
529528
})
530529
})
530+
531+
describe("opening the selected file", function() {
532+
beforeEach(function() {
533+
viewModel = createDiffs('fixtures/two-file-diff.txt')
534+
spyOn(atom.workspace, 'open')
535+
})
536+
537+
it("opens the file to the first line in the selected hunk when in hunk mode and ::openFileAtSelection() is called", function() {
538+
viewModel.moveSelectionDown()
539+
540+
viewModel.openFileAtSelection()
541+
expect(atom.workspace.open).toHaveBeenCalled()
542+
args = atom.workspace.open.mostRecentCall.args
543+
expect(args[0]).toBe('src/config.coffee')
544+
expect(args[1]).toEqual({initialLine: 433})
545+
})
546+
547+
it("opens the file to the first selected line in line mode when ::openFileAtSelection() is called", function() {
548+
let selection = new DiffSelection(viewModel, {
549+
mode: 'line',
550+
headPosition: [0, 2, 4],
551+
tailPosition: [0, 2, 5]
552+
})
553+
viewModel.setSelection(selection)
554+
555+
viewModel.openFileAtSelection()
556+
expect(atom.workspace.open).toHaveBeenCalled()
557+
args = atom.workspace.open.mostRecentCall.args
558+
expect(args[0]).toBe('src/config.coffee')
559+
expect(args[1]).toEqual({initialLine: 515})
560+
})
561+
})
531562
})
532563

533564
FileStr = `FILE src/config.coffee - modified - unstaged

0 commit comments

Comments
 (0)