Skip to content

Commit c905165

Browse files
tharakawjPavel Zhytko
authored and
Pavel Zhytko
committed
Open editor to exact column from build error overlay (facebook#3465)
* Open editor to exact column from build error overlay * Update launch editor validations
1 parent 4c9022e commit c905165

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

packages/react-dev-utils/errorOverlayMiddleware.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ 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+
const lineNumber = parseInt(req.query.lineNumber, 10) || 1;
16+
const colNumber = parseInt(req.query.colNumber, 10) || 1;
17+
launchEditor(req.query.fileName, lineNumber, colNumber);
1618
res.end();
1719
} else {
1820
next();

packages/react-dev-utils/launchEditor.js

+28-7
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,13 @@ function addWorkspaceToArgumentsIfExists(args, workspace) {
103103
return args;
104104
}
105105

106-
function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) {
106+
function getArgumentsForLineNumber(
107+
editor,
108+
fileName,
109+
lineNumber,
110+
colNumber,
111+
workspace
112+
) {
107113
const editorBasename = path.basename(editor).replace(/\.(exe|cmd|bat)$/i, '');
108114
switch (editorBasename) {
109115
case 'atom':
@@ -112,17 +118,19 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) {
112118
case 'subl':
113119
case 'sublime':
114120
case 'sublime_text':
121+
return [fileName + ':' + lineNumber + ':' + colNumber];
115122
case 'wstorm':
116123
case 'charm':
117124
return [fileName + ':' + lineNumber];
118125
case 'notepad++':
119-
return ['-n' + lineNumber, fileName];
126+
return ['-n' + lineNumber, '-c' + colNumber, fileName];
120127
case 'vim':
121128
case 'mvim':
122129
case 'joe':
130+
return ['+' + lineNumber, fileName];
123131
case 'emacs':
124132
case 'emacsclient':
125-
return ['+' + lineNumber, fileName];
133+
return ['+' + lineNumber + ':' + colNumber, fileName];
126134
case 'rmate':
127135
case 'mate':
128136
case 'mine':
@@ -132,7 +140,7 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, workspace) {
132140
case 'code-insiders':
133141
case 'Code - Insiders':
134142
return addWorkspaceToArgumentsIfExists(
135-
['-g', fileName + ':' + lineNumber],
143+
['-g', fileName + ':' + lineNumber + ':' + colNumber],
136144
workspace
137145
);
138146
case 'appcode':
@@ -255,17 +263,24 @@ function printInstructions(fileName, errorMessage) {
255263
}
256264

257265
let _childProcess = null;
258-
function launchEditor(fileName, lineNumber) {
266+
function launchEditor(fileName, lineNumber, colNumber) {
259267
if (!fs.existsSync(fileName)) {
260268
return;
261269
}
262270

263271
// Sanitize lineNumber to prevent malicious use on win32
264272
// via: https://github.com/nodejs/node/blob/c3bb4b1aa5e907d489619fb43d233c3336bfc03d/lib/child_process.js#L333
265-
if (lineNumber && isNaN(lineNumber)) {
273+
// and it should be a positive integer
274+
if (!(Number.isInteger(lineNumber) && lineNumber > 0)) {
266275
return;
267276
}
268277

278+
// colNumber is optional, but should be a positive integer too
279+
// default is 1
280+
if (!(Number.isInteger(colNumber) && colNumber > 0)) {
281+
colNumber = 1;
282+
}
283+
269284
let [editor, ...args] = guessEditor();
270285

271286
if (!editor) {
@@ -294,7 +309,13 @@ function launchEditor(fileName, lineNumber) {
294309
let workspace = null;
295310
if (lineNumber) {
296311
args = args.concat(
297-
getArgumentsForLineNumber(editor, fileName, lineNumber, workspace)
312+
getArgumentsForLineNumber(
313+
editor,
314+
fileName,
315+
lineNumber,
316+
colNumber,
317+
workspace
318+
)
298319
);
299320
} else {
300321
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)