|
| 1 | +const { CompositeDisposable } = require('atom') |
| 2 | +const { repositoryForPath } = require('./helpers') |
| 3 | + |
| 4 | +class MinimapGitDiffBinding { |
| 5 | + constructor (minimap) { |
| 6 | + this.active = false |
| 7 | + this.updateDiffs = this.updateDiffs.bind(this) |
| 8 | + this.destroy = this.destroy.bind(this) |
| 9 | + this.minimap = minimap |
| 10 | + this.decorations = {} |
| 11 | + this.markers = null |
| 12 | + this.subscriptions = new CompositeDisposable() |
| 13 | + |
| 14 | + if (!this.minimap) { |
| 15 | + console.warn('minimap-git-diff binding created without a minimap') |
| 16 | + return |
| 17 | + } |
| 18 | + |
| 19 | + this.editor = this.minimap.getTextEditor() |
| 20 | + |
| 21 | + this.subscriptions.add(this.minimap.onDidDestroy(this.destroy)) |
| 22 | + |
| 23 | + this.getRepo().then(repo => { |
| 24 | + this.repository = repo |
| 25 | + if (repo) { |
| 26 | + this.subscriptions.add(this.editor.getBuffer().onDidStopChanging(this.updateDiffs)) |
| 27 | + this.subscriptions.add(this.repository.onDidChangeStatuses(() => { |
| 28 | + this.scheduleUpdate() |
| 29 | + })) |
| 30 | + this.subscriptions.add(this.repository.onDidChangeStatus(changedPath => { |
| 31 | + if (changedPath === this.editor.getPath()) { this.scheduleUpdate() } |
| 32 | + })) |
| 33 | + this.subscriptions.add(this.repository.onDidDestroy(() => { |
| 34 | + this.destroy() |
| 35 | + })) |
| 36 | + this.subscriptions.add(atom.config.observe('minimap-git-diff.useGutterDecoration', useGutterDecoration => { |
| 37 | + this.useGutterDecoration = useGutterDecoration |
| 38 | + this.scheduleUpdate() |
| 39 | + })) |
| 40 | + } |
| 41 | + }) |
| 42 | + |
| 43 | + this.scheduleUpdate() |
| 44 | + } |
| 45 | + |
| 46 | + cancelUpdate () { |
| 47 | + clearImmediate(this.immediateId) |
| 48 | + } |
| 49 | + |
| 50 | + scheduleUpdate () { |
| 51 | + this.cancelUpdate() |
| 52 | + this.immediateId = setImmediate(this.updateDiffs) |
| 53 | + } |
| 54 | + |
| 55 | + updateDiffs () { |
| 56 | + this.removeDecorations() |
| 57 | + if (this.getPath() && (this.diffs = this.getDiffs())) { |
| 58 | + this.addDecorations(this.diffs) |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + addDecorations (diffs) { |
| 63 | + for (const { newStart, oldLines, newLines } of Array.from(diffs)) { |
| 64 | + const startRow = newStart - 1 |
| 65 | + const endRow = (newStart + newLines) - 2 |
| 66 | + if ((oldLines === 0) && (newLines > 0)) { |
| 67 | + this.markRange(startRow, endRow, '.git-line-added') |
| 68 | + } else if ((newLines === 0) && (oldLines > 0)) { |
| 69 | + this.markRange(startRow, startRow, '.git-line-removed') |
| 70 | + } else { |
| 71 | + this.markRange(startRow, endRow, '.git-line-modified') |
| 72 | + } |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + removeDecorations () { |
| 77 | + if (!this.markers) { return } |
| 78 | + for (const marker of Array.from(this.markers)) { marker.destroy() } |
| 79 | + this.markers = null |
| 80 | + } |
| 81 | + |
| 82 | + markRange (startRow, endRow, scope) { |
| 83 | + if (this.editor.isDestroyed()) { return } |
| 84 | + const marker = this.editor.markBufferRange([[startRow, 0], [endRow, Infinity]], { invalidate: 'never' }) |
| 85 | + const type = this.useGutterDecoration ? 'gutter' : 'line' |
| 86 | + this.minimap.decorateMarker(marker, { type, scope: `.minimap .${type} ${scope}`, plugin: 'git-diff' }) |
| 87 | + if (!this.markers) { this.markers = [] } |
| 88 | + this.markers.push(marker) |
| 89 | + } |
| 90 | + |
| 91 | + destroy () { |
| 92 | + this.removeDecorations() |
| 93 | + this.subscriptions.dispose() |
| 94 | + this.diffs = null |
| 95 | + this.minimap = null |
| 96 | + } |
| 97 | + |
| 98 | + getPath () { |
| 99 | + const buffer = this.editor.getBuffer() |
| 100 | + if (buffer) { |
| 101 | + return buffer.getPath() |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + getRepo () { return repositoryForPath(this.editor.getPath()) } |
| 106 | + |
| 107 | + getDiffs () { |
| 108 | + try { |
| 109 | + const buffer = this.editor.getBuffer() |
| 110 | + if (this.repository && buffer) { |
| 111 | + return this.repository.getLineDiffs(this.getPath(), buffer.getText()) |
| 112 | + } |
| 113 | + } catch (e) {} |
| 114 | + |
| 115 | + return null |
| 116 | + } |
| 117 | +} |
| 118 | + |
| 119 | +module.exports = MinimapGitDiffBinding |
0 commit comments