Skip to content

Commit 7bcf470

Browse files
committed
Open editor to exact column from build error overlay
1 parent bd682de commit 7bcf470

File tree

4 files changed

+37
-9
lines changed

4 files changed

+37
-9
lines changed

packages/react-dev-utils/errorOverlayMiddleware.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ const launchEditorEndpoint = require('./launchEditorEndpoint');
1212
module.exports = function createLaunchEditorMiddleware() {
1313
return function launchEditorMiddleware(req, res, next) {
1414
if (req.url.startsWith(launchEditorEndpoint)) {
15-
launchEditor(req.query.fileName, req.query.lineNumber);
15+
launchEditor(
16+
req.query.fileName,
17+
req.query.lineNumber,
18+
req.query.colNumber
19+
);
1620
res.end();
1721
} else {
1822
next();

packages/react-dev-utils/launchEditor.js

+24-6
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,13 @@ function addWorkspaceToArgumentsIfExists(args, workspace) {
9595
return args;
9696
}
9797

98-
function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) {
98+
function getArgumentsForLineNumber(
99+
editor,
100+
fileName,
101+
lineNumber,
102+
colNumber,
103+
workspace
104+
) {
99105
const editorBasename = path.basename(editor).replace(/\.(exe|cmd|bat)$/i, '');
100106
switch (editorBasename) {
101107
case 'atom':
@@ -104,25 +110,27 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) {
104110
case 'subl':
105111
case 'sublime':
106112
case 'sublime_text':
113+
return [fileName + ':' + lineNumber + ':' + colNumber];
107114
case 'wstorm':
108115
case 'charm':
109116
return [fileName + ':' + lineNumber];
110117
case 'notepad++':
111-
return ['-n' + lineNumber, fileName];
118+
return ['-n' + lineNumber, '-c' + colNumber, fileName];
112119
case 'vim':
113120
case 'mvim':
114121
case 'joe':
122+
return ['+' + lineNumber, fileName];
115123
case 'emacs':
116124
case 'emacsclient':
117-
return ['+' + lineNumber, fileName];
125+
return ['+' + lineNumber + ':' + colNumber, fileName];
118126
case 'rmate':
119127
case 'mate':
120128
case 'mine':
121129
return ['--line', lineNumber, fileName];
122130
case 'code':
123131
case 'Code':
124132
return addWorkspaceToArgumentsIfExists(
125-
['-g', fileName + ':' + lineNumber],
133+
['-g', fileName + ':' + lineNumber + ':' + colNumber],
126134
workspace
127135
);
128136
case 'appcode':
@@ -245,7 +253,7 @@ function printInstructions(fileName, errorMessage) {
245253
}
246254

247255
let _childProcess = null;
248-
function launchEditor(fileName, lineNumber) {
256+
function launchEditor(fileName, lineNumber, colNumber) {
249257
if (!fs.existsSync(fileName)) {
250258
return;
251259
}
@@ -256,6 +264,10 @@ function launchEditor(fileName, lineNumber) {
256264
return;
257265
}
258266

267+
// colNumber is optional, but should be a number
268+
// default is 1
269+
colNumber = parseInt(colNumber, 10) || 1;
270+
259271
let [editor, ...args] = guessEditor();
260272
if (!editor) {
261273
printInstructions(fileName, null);
@@ -279,7 +291,13 @@ function launchEditor(fileName, lineNumber) {
279291
let workspace = null;
280292
if (lineNumber) {
281293
args = args.concat(
282-
getArgumentsForLineNumber(editor, fileName, lineNumber, workspace)
294+
getArgumentsForLineNumber(
295+
editor,
296+
fileName,
297+
lineNumber,
298+
colNumber,
299+
workspace
300+
)
283301
);
284302
} else {
285303
args.push(fileName);

packages/react-dev-utils/webpackHotDevClient.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ ErrorOverlay.setEditorHandler(function editorHandler(errorLocation) {
3030
'?fileName=' +
3131
window.encodeURIComponent(errorLocation.fileName) +
3232
'&lineNumber=' +
33-
window.encodeURIComponent(errorLocation.lineNumber || 1)
33+
window.encodeURIComponent(errorLocation.lineNumber || 1) +
34+
'&colNumber=' +
35+
window.encodeURIComponent(errorLocation.colNumber || 1)
3436
);
3537
});
3638

packages/react-error-overlay/src/utils/parseCompileError.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Anser from 'anser';
44
export type ErrorLocation = {|
55
fileName: string,
66
lineNumber: number,
7+
colNumber?: number,
78
|};
89

910
const filePathRegex = /^\.(\/[^/\n ]+)+\.[^/\n ]+$/;
@@ -25,6 +26,7 @@ function parseCompileError(message: string): ?ErrorLocation {
2526
const lines: Array<string> = message.split('\n');
2627
let fileName: string = '';
2728
let lineNumber: number = 0;
29+
let colNumber: number = 0;
2830

2931
for (let i = 0; i < lines.length; i++) {
3032
const line: string = Anser.ansiToText(lines[i]).trim();
@@ -41,6 +43,8 @@ function parseCompileError(message: string): ?ErrorLocation {
4143
const match: ?Array<string> = line.match(lineNumberRegexes[k]);
4244
if (match) {
4345
lineNumber = parseInt(match[1], 10);
46+
// colNumber starts with 0 and hence add 1
47+
colNumber = parseInt(match[2], 10) + 1 || 1;
4448
break;
4549
}
4650
k++;
@@ -51,7 +55,7 @@ function parseCompileError(message: string): ?ErrorLocation {
5155
}
5256
}
5357

54-
return fileName && lineNumber ? { fileName, lineNumber } : null;
58+
return fileName && lineNumber ? { fileName, lineNumber, colNumber } : null;
5559
}
5660

5761
export default parseCompileError;

0 commit comments

Comments
 (0)