Skip to content

Commit ebf1214

Browse files
authored
fix: diff isn't copied (#30)
1 parent a99d1b1 commit ebf1214

File tree

5 files changed

+1258
-93
lines changed

5 files changed

+1258
-93
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "diff-merge",
33
"displayName": "Diff & Merge",
44
"description": "Show diffs and merge",
5-
"version": "0.4.1",
5+
"version": "0.4.2",
66
"repository": {
77
"type": "git",
88
"url": "https://github.com/moshfeu/vscode-diff-merge"

resources/monaco/src/index.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ import './style.css';
33

44
import * as monaco from 'monaco-editor';
55

6-
import {render, addDiffActions, swap} from './utils';
6+
import { render, addDiffActions, swap, layoutDiffContainer } from './utils';
77

88
const diffEditor = monaco.editor.createDiffEditor(
99
document.getElementById('container'),
1010
{
11-
originalEditable: true
11+
originalEditable: true,
1212
}
1313
);
1414

1515
self.addEventListener('resize', () => {
1616
if (diffEditor) {
1717
diffEditor.layout();
18+
layoutDiffContainer();
1819
}
1920
});
2021

21-
self.addEventListener('message', e => {
22+
self.addEventListener('message', (e) => {
2223
const { diffNavigator } = window;
2324
const {
24-
data: { key, payload }
25+
data: { key, payload },
2526
} = e;
2627
switch (key) {
2728
case 'data':
@@ -40,9 +41,9 @@ self.addEventListener('message', e => {
4041
});
4142

4243
self.vscode.postMessage({
43-
command: 'load'
44+
command: 'load',
4445
});
4546

4647
diffEditor.onDidUpdateDiff(() => {
4748
addDiffActions(diffEditor);
48-
});
49+
});

resources/monaco/src/style.css

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
html, body {
1+
html,
2+
body {
23
margin: 0;
34
padding: 0;
45
width: 100vw;
@@ -12,9 +13,11 @@ html, body {
1213

1314
.diffActions {
1415
position: absolute;
15-
top:0;
16+
top: 0;
1617
left: 0;
17-
width: 20px;
18+
width: 15px;
19+
padding: 0 2px;
20+
box-sizing: border-box;
1821
}
1922

2023
.diffAction {
@@ -31,4 +34,4 @@ html, body {
3134

3235
.diffAction:hover {
3336
opacity: 1;
34-
}
37+
}

resources/monaco/src/utils.js

+121-82
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
let cacheActionsLines = [];
2-
let diffActionsNode, diffEditor, ignoreChange = false;
2+
let diffActionsNode,
3+
diffEditor,
4+
ignoreChange = false;
35

4-
export function render(_diffEditor, { rightPath, notSupportedFile, leftContent, rightContent, theme, tabSize }) {
6+
export function render(
7+
_diffEditor,
8+
{ rightPath, notSupportedFile, leftContent, rightContent, theme, tabSize }
9+
) {
510
diffEditor = _diffEditor;
611
window.diffEditor = _diffEditor;
712
diffEditor.setModel({
8-
original: monaco.editor.createModel(leftContent, null, generateMonacoFakeUri(rightPath, 'org')),
9-
modified: monaco.editor.createModel(rightContent, null, generateMonacoFakeUri(rightPath, 'mod'))
13+
original: monaco.editor.createModel(
14+
leftContent,
15+
null,
16+
generateMonacoFakeUri(rightPath, 'org')
17+
),
18+
modified: monaco.editor.createModel(
19+
rightContent,
20+
null,
21+
generateMonacoFakeUri(rightPath, 'mod')
22+
),
1023
});
1124
diffActionsNode = createDiffActionsContainer(diffEditor);
1225
window.diffNavigator = monaco.editor.createDiffNavigator(diffEditor);
@@ -18,10 +31,11 @@ export function render(_diffEditor, { rightPath, notSupportedFile, leftContent,
1831
}
1932

2033
function setTabSize(tabSize) {
21-
const { originalEditor, modifiedEditor } = diffEditor;
22-
const updateTabSize = model => model.updateOptions({ tabSize, detectIndentation: false });
23-
updateTabSize(originalEditor.getModel());
24-
updateTabSize(modifiedEditor.getModel());
34+
const { originalEditor, modifiedEditor } = diffEditor;
35+
const updateTabSize = (model) =>
36+
model.updateOptions({ tabSize, detectIndentation: false });
37+
updateTabSize(originalEditor.getModel());
38+
updateTabSize(modifiedEditor.getModel());
2539
}
2640

2741
function setEditorValue(editor, value) {
@@ -40,7 +54,7 @@ export function swap() {
4054
function generateMonacoFakeUri(path, qs) {
4155
if (path) {
4256
const prefixPath = path.startsWith('/') ? '' : '/';
43-
return monaco.Uri.parse(`vscode://${prefixPath}${path}?${qs}`)
57+
return monaco.Uri.parse(`vscode://${prefixPath}${path}?${qs}`);
4458
}
4559
return null;
4660
}
@@ -51,115 +65,134 @@ function onDidUpdateDiff() {
5165
return;
5266
}
5367
vscode.postMessage({
54-
command: 'change'
68+
command: 'change',
5569
});
5670
}
5771

5872
export function addDiffActions(diffEditor) {
59-
const changes = diffEditor.getLineChanges();
60-
waitForChangesDecorations()
61-
.then(() => {
62-
const changesData = changes.map(change => ({
63-
change,
64-
...getStrategy(change)
65-
}));
66-
const actionsLines = changesData.map(({top}) => top);
67-
const actions = Array.from(diffActionsNode.querySelectorAll('.diffAction'));
68-
69-
changesData.forEach(({change, top, replacer}) => {
70-
createOrUpdateDiffAction(diffActionsNode, top, () => {
71-
const originalLines = getChangeOriginalValue(change, diffEditor);
72-
applyOriginalLines(originalLines, replacer, diffEditor);
73-
});
74-
});
75-
cacheActionsLines.forEach(actionLine => {
76-
if (!actionsLines.includes(actionLine)) {
77-
diffActionsNode.removeChild(actions.find(action => action.style.top === `${actionLine}px`));
78-
}
73+
waitForChangesDecorations().then(() => {
74+
const changes = diffEditor.getLineChanges();
75+
const changesData = changes.map((change) => ({
76+
change,
77+
...getStrategy(change),
78+
}));
79+
const actionsLines = changesData.map(({ top }) => top);
80+
const actions = Array.from(diffActionsNode.querySelectorAll('.diffAction'));
81+
82+
changesData.forEach(({ change, top, replacer }) => {
83+
createOrUpdateDiffAction(diffActionsNode, top, () => {
84+
const originalLines = getChangeOriginalValue(change, diffEditor);
85+
applyOriginalLines(originalLines, replacer, diffEditor);
7986
});
80-
cacheActionsLines = actionsLines;
8187
});
88+
cacheActionsLines.forEach((actionLine) => {
89+
if (!actionsLines.includes(actionLine)) {
90+
diffActionsNode.removeChild(
91+
actions.find((action) => action.style.top === `${actionLine}px`)
92+
);
93+
}
94+
});
95+
cacheActionsLines = actionsLines;
96+
});
8297
}
8398

8499
function getStrategy(change) {
85100
const isChangeInOriginalSide = change.modifiedEndLineNumber === 0;
86101
const isChangeInModifiedSide = change.originalEndLineNumber === 0;
87102
if (isChangeInModifiedSide) {
88103
return {
89-
top: diffEditor.modifiedEditor.getTopForLineNumber(change.modifiedStartLineNumber),
104+
top: diffEditor.modifiedEditor.getTopForLineNumber(
105+
change.modifiedStartLineNumber
106+
),
90107
replacer: () => {
91108
const startLine = change.modifiedStartLineNumber - 1;
92109
return {
93110
startLine,
94111
linesToRemove: change.modifiedEndLineNumber - startLine,
95-
}
96-
}
97-
}
112+
};
113+
},
114+
};
98115
} else if (isChangeInOriginalSide) {
99116
return {
100-
top: diffEditor.originalEditor.getTopForLineNumber(change.originalStartLineNumber),
117+
top: diffEditor.originalEditor.getTopForLineNumber(
118+
change.originalStartLineNumber
119+
),
101120
replacer: () => {
102121
const startLine = change.modifiedStartLineNumber;
103122
return {
104123
startLine,
105124
linesToRemove: 0,
106-
}
107-
}
108-
}
125+
};
126+
},
127+
};
109128
}
110129
return {
111-
top: diffEditor.originalEditor.getTopForLineNumber(change.originalStartLineNumber),
130+
top: diffEditor.originalEditor.getTopForLineNumber(
131+
change.originalStartLineNumber
132+
),
112133
replacer: () => {
113134
const startLine = change.modifiedStartLineNumber - 1;
114135
return {
115136
startLine,
116-
linesToRemove: (change.modifiedEndLineNumber - change.modifiedStartLineNumber) + 1,
117-
}
118-
}
119-
}
137+
linesToRemove:
138+
change.modifiedEndLineNumber - change.modifiedStartLineNumber + 1,
139+
};
140+
},
141+
};
120142
}
121143

122144
function applyOriginalLines(originalLines, replacer, diffEditor) {
123-
let {startLine, linesToRemove} = replacer();
145+
let { startLine, linesToRemove } = replacer();
124146
const diff = {
125-
range: new monaco.Range(++startLine, 0, startLine + linesToRemove, 0),
126-
text: originalLines
127-
};
147+
range: new monaco.Range(++startLine, 0, startLine + linesToRemove, 0),
148+
text: originalLines,
149+
};
128150
diffEditor.modifiedEditor.executeEdits('diff-merge', [diff]);
129151
}
130152

131153
function getChangeOriginalValue(change, diffEditor) {
132-
return diffEditor.originalEditor.getValue()
133-
.split(/(?<=[\n\r])/gm)
134-
.slice(change.originalStartLineNumber - 1, change.originalEndLineNumber)
135-
.join('');
154+
return diffEditor.originalEditor
155+
.getValue()
156+
.split(/(?<=[\n\r])/gm)
157+
.slice(change.originalStartLineNumber - 1, change.originalEndLineNumber)
158+
.join('');
136159
}
137160

138161
function createOrUpdateDiffAction(diffActionsNode, top, onCopy) {
139162
// action is already in place
140163
if (cacheActionsLines.includes(top)) {
141-
const action = diffActionsNode.querySelector(`.diffAction[data-top="${top}"]`);
164+
const action = diffActionsNode.querySelector(
165+
`.diffAction[data-top="${top}"]`
166+
);
142167
action.onclick = onCopy;
143168
} else {
144169
const action = document.createElement('div');
145170
action.className = 'diffAction';
146171
action.dataset.top = top;
147172
action.innerHTML = '→';
148173
action.style.top = `${top}px`;
149-
action.onclick = onCopy;
174+
action.onclick = onCopy;
150175
diffActionsNode.appendChild(action);
151176
}
152177
}
153178

154-
function createDiffActionsContainer(diffEditor) {
179+
export function layoutDiffContainer(diffActions = diffActionsNode) {
155180
const modifedEditorNode = diffEditor.modifiedEditor.getDomNode();
181+
diffActions.style.left = `${
182+
modifedEditorNode.getBoundingClientRect().left
183+
}px`;
184+
}
185+
186+
function createDiffActionsContainer(diffEditor) {
156187
const diffActions = document.createElement('div');
157188
diffActions.className = 'diffActions diffOverview';
158-
diffActions.style.height = `${diffEditor.originalEditor.getScrollHeight()}px`
159-
modifedEditorNode.appendChild(diffActions);
160-
diffEditor.modifiedEditor.onDidScrollChange(({scrollTop}) => {
189+
diffActions.style.height = `${diffEditor.originalEditor.getScrollHeight()}px`;
190+
document.querySelector('#container').appendChild(diffActions);
191+
192+
diffEditor.modifiedEditor.onDidScrollChange(({ scrollTop }) => {
161193
diffActions.style.top = `-${scrollTop}px`;
162194
});
195+
layoutDiffContainer(diffActions);
163196
return diffActions;
164197
}
165198

@@ -180,31 +213,35 @@ function waitForChangesDecorations() {
180213
}
181214

182215
function isSaveShortcut(e) {
183-
return (window.navigator.platform.match('Mac') ?
184-
e.metaKey :
185-
e.ctrlKey) &&
186-
e.keyCode == 83;
216+
return (
217+
(window.navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey) &&
218+
e.keyCode == 83
219+
);
187220
}
188221

189222
function bindSaveShortcut() {
190-
document.addEventListener('keydown', e => {
191-
if (isSaveShortcut(e)) {
192-
e.preventDefault();
193-
vscode.postMessage({
194-
command: 'save',
195-
contents: {
196-
left: diffEditor.originalEditor.getValue(),
197-
right: diffEditor.modifiedEditor.getValue()
198-
}
199-
});
200-
}
201-
},
202-
false
223+
document.addEventListener(
224+
'keydown',
225+
(e) => {
226+
if (isSaveShortcut(e)) {
227+
e.preventDefault();
228+
vscode.postMessage({
229+
command: 'save',
230+
contents: {
231+
left: diffEditor.originalEditor.getValue(),
232+
right: diffEditor.modifiedEditor.getValue(),
233+
},
234+
});
235+
}
236+
},
237+
false
203238
);
204239
}
205240

206241
function extractEditorStyles(diffEditor) {
207-
const lineHeight = diffEditor.modifiedEditor.getOption(monaco.editor.EditorOption.lineHeight);
242+
const lineHeight = diffEditor.modifiedEditor.getOption(
243+
monaco.editor.EditorOption.lineHeight
244+
);
208245
document.body.style.setProperty('--diff-merge-lineheight', `${lineHeight}px`);
209246
}
210247

@@ -217,13 +254,15 @@ function setTheme(theme) {
217254
}
218255

219256
function retrieveCssVariables() {
220-
const isNumber = s => !isNaN(Number(s));
257+
const isNumber = (s) => !isNaN(Number(s));
221258

222259
const htmlTag = document.querySelector('html');
223260
const compotedStyle = getComputedStyle(htmlTag);
224261

225-
return Object.keys(htmlTag.style).filter(isNumber).reduce((ol, ne) => {
226-
ol[htmlTag.style[ne]] = compotedStyle.getPropertyValue(htmlTag.style[ne])
227-
return ol;
228-
}, {})
229-
}
262+
return Object.keys(htmlTag.style)
263+
.filter(isNumber)
264+
.reduce((ol, ne) => {
265+
ol[htmlTag.style[ne]] = compotedStyle.getPropertyValue(htmlTag.style[ne]);
266+
return ol;
267+
}, {});
268+
}

0 commit comments

Comments
 (0)