/ packages / git-diff / lib / diff-list-view.js
diff-list-view.js
 1  const SelectListView = require('atom-select-list');
 2  const { repositoryForPath } = require('./helpers');
 3  
 4  module.exports = class DiffListView {
 5    constructor() {
 6      this.selectListView = new SelectListView({
 7        emptyMessage: 'No diffs in file',
 8        items: [],
 9        filterKeyForItem: diff => diff.lineText,
10        elementForItem: diff => {
11          const li = document.createElement('li');
12          li.classList.add('two-lines');
13  
14          const primaryLine = document.createElement('div');
15          primaryLine.classList.add('primary-line');
16          primaryLine.textContent = diff.lineText;
17          li.appendChild(primaryLine);
18  
19          const secondaryLine = document.createElement('div');
20          secondaryLine.classList.add('secondary-line');
21          secondaryLine.textContent = `-${diff.oldStart},${diff.oldLines} +${
22            diff.newStart
23          },${diff.newLines}`;
24          li.appendChild(secondaryLine);
25  
26          return li;
27        },
28        didConfirmSelection: diff => {
29          this.cancel();
30          const bufferRow = diff.newStart > 0 ? diff.newStart - 1 : diff.newStart;
31          this.editor.setCursorBufferPosition([bufferRow, 0], {
32            autoscroll: true
33          });
34          this.editor.moveToFirstCharacterOfLine();
35        },
36        didCancelSelection: () => {
37          this.cancel();
38        }
39      });
40      this.selectListView.element.classList.add('diff-list-view');
41      this.panel = atom.workspace.addModalPanel({
42        item: this.selectListView,
43        visible: false
44      });
45    }
46  
47    attach() {
48      this.previouslyFocusedElement = document.activeElement;
49      this.selectListView.reset();
50      this.panel.show();
51      this.selectListView.focus();
52    }
53  
54    cancel() {
55      this.panel.hide();
56      if (this.previouslyFocusedElement) {
57        this.previouslyFocusedElement.focus();
58        this.previouslyFocusedElement = null;
59      }
60    }
61  
62    destroy() {
63      this.cancel();
64      this.panel.destroy();
65      return this.selectListView.destroy();
66    }
67  
68    async toggle() {
69      const editor = atom.workspace.getActiveTextEditor();
70      if (this.panel.isVisible()) {
71        this.cancel();
72      } else if (editor) {
73        this.editor = editor;
74        const repository = repositoryForPath(this.editor.getPath());
75        let diffs = repository
76          ? repository.getLineDiffs(this.editor.getPath(), this.editor.getText())
77          : [];
78        if (!diffs) diffs = [];
79        for (let diff of diffs) {
80          const bufferRow = diff.newStart > 0 ? diff.newStart - 1 : diff.newStart;
81          const lineText = this.editor.lineTextForBufferRow(bufferRow);
82          diff.lineText = lineText ? lineText.trim() : '';
83        }
84  
85        await this.selectListView.update({ items: diffs });
86        this.attach();
87      }
88    }
89  };