- This topic has 6 replies, 3 voices, and was last updated 7 years, 7 months ago by Fedor Losev.
-
AuthorPosts
-
Fedor LosevParticipantTerminal js/ts source references should be highlighted and open source location on click or double click, similar to stack traces in Java console. Otherwise what is the value? We already have built-in terminal in Neon, Terminal+ doesn’t add a lot.
Ideally this will:
– on click or double click of ts/js/etc source open editor
– highlight current project sources in one color and other sources in anotherTrue that webpack://xx references can be ambiguous, but it is quite possible to make some reasonable and sane assumptions.
It took me just a couple hours to make a quick and dirty but completely working double click implementation in Eclipse EASE using tm.terminal to invoke ng test / ng serve, so shouldn’t be complicated:
If line contains an absolute path this is trivial – find a parent project and open editor. If no parent project, open editor for external resource.
If line contains webpack:///, find a project which contains such file (starting lookup from current project) and go to the above step.
For webpack:/// there may be corner cases and false positives (extremely rare) but it will do the work 99% of time and will make the Genuitec terminal much more useful.
support-piotrParticipantFedor,
Can you provide few examples of console output, which you would like to see underlined?
Best regards,
Piotr Tomiak
Fedor LosevParticipantI mean source file references in the common output of ng test and ng serve (also ng build but this is less critical since we have better navigation in Problems view).
Highlighting will be very nice but it is less critical, most important is navigation to source editor line/column in tests.
Here are few most common cases:
Karma/Chrome:
$ ng test --single-run 24 04 2017 20:21:49.212:INFO [karma]: Karma v1.4.1 server started at http://0.0.0.0:9876/ 24 04 2017 20:21:49.213:INFO [launcher]: Launching browser Chrome with unlimited concurrency 24 04 2017 20:21:49.216:INFO [launcher]: Starting browser Chrome 24 04 2017 20:21:50.002:INFO [Chrome 57.0.2987 (Windows 10 0.0.0)]: Connected on socket imWpvfbiu6jh3jGkAAAA with id 53807319 Chrome 57.0.2987 (Windows 10 0.0.0) AppComponent Failed test FAILED Expected false to be truthy. at Object.<anonymous> (webpack:///src/app/app.component.spec.ts:15:18 <- src/test.ts:51176:23) [ProxyZone] at AsyncTestZoneSpec.Array.concat.AsyncTestZoneSpec.onInvoke (webpack:///~/zone.js/dist/async-test.js:49:0 <- src/test.ts:51458:39) [ProxyZone] at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:76:0 <- src/test.ts:52161:39) [ProxyZone] at runInTestZone (webpack:///~/@angular/core/@angular/core/testing.es5.js:110:0 <- src/test.ts:14850:25) [ProxyZone] at Object.<anonymous> (webpack:///~/@angular/core/@angular/core/testing.es5.js:49:0 <- src/test.ts:14789:13) [ProxyZone]
The for example
webpack:///src/app/app.component.spec.ts:15:18 -> click opens ./src/app/app.component.spec.ts on line 15 column 18
(nice to have: if there is no such file in current project, try to locate in other workspace projects and if few matches select latest file by date)webpack:///~/@angular/core/@angular/core/testing.es5.js:110:0 -> click opens ./node_modules/@angular/core/@angular/core/testing.es5.js line 110
(nice to have: if there is no such file in current project, try to locate mimicking node lookup in node_modules)Karma/PhantomJS:
$ ng test --single-run 24 04 2017 20:45:18.338:INFO [karma]: Karma v1.4.1 server started at http://0.0.0.0:9876/ 24 04 2017 20:45:18.339:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency 24 04 2017 20:45:18.358:INFO [launcher]: Starting browser PhantomJS 24 04 2017 20:45:21.314:INFO [PhantomJS 2.1.1 (Windows 8 0.0.0)]: Connected on socket 1Efl2E2hJ3Ye8zFaAAAA with id 96480012 PhantomJS 2.1.1 (Windows 8 0.0.0) AppComponent Failed test FAILED Expected false to be truthy. webpack:///src/app/app.component.spec.ts:15:28 <- src/test.ts:51188:33 invoke@webpack:///~/zone.js/dist/zone.js:365:0 <- src/polyfills.ts:3280:31 onInvoke@webpack:///~/zone.js/dist/async-test.js:49:0 <- src/test.ts:51479:45 onInvoke@webpack:///~/zone.js/dist/proxy.js:76:0 <- src/test.ts:52186:47 invoke@webpack:///~/zone.js/dist/zone.js:364:0 <- src/polyfills.ts:3279:40 .....
Same links, but note there are no surrounding () the source and there is @ before webpack:///
ng serve
ERROR in C:/dv/src/angcheck/src/app/app.component.ts (10,3): Type '"1"' is not assignable to type 'number'.
C:/dv/src/angcheck/src/app/app.component.ts (10,3) -> click opens editor ./src/app/app.component.ts on line 10 column 3
(nice to have: if it is not a subpath of current project, opens corresponding Eclipse editor for external resource)
Fedor LosevParticipantIdeally it should be some generic functionality of Terminal+. similar to Grep Console plugin with editor hyperlink support that we have for standard Eclipse console. Then users can define specific cases and there is no need for Genuitec to implement every case format.
But just a support for webpack:// links and absolute paths for me will more than enough.
Fedor LosevParticipantIf you are interested here is the link detection excerpt from EASE javascript that I wrote to mock this (and this) quickly, just in standard Eclipse terminal.
I create tm.terminal console, copy karma.conf.js and test.ts to local.karma.conf.js and local.test.ts, patching with desired configuration (single spec file, es5/es6, Chrome/PhantomJS, junit report) and run ng test –config local.karma.conf.js in terminal. I also open internal browser view once karma is serving.
On double click in terminal I run the code below to process links.
It is quite dirty and fragile, I’m sure there are uncovered cases, but meantime it serves well. Hope we’ll have this as part of IDE soon, to focus on our business and not IDE enhancements : )
const srcMatch = /(?:(?:\()|(?:\(?(?=webpack:\/)))(.*?(?:(?:\.js(?![\/\\]))|(?:\.ts(?![\/\\]))))(?:\:(\d+))?(?:\:(\d+))?(?: <- .*?)?\)?/; function getProjectMatch(project, srcFile, isRelative) { var projPath = getPathStr(project); srcFile = getPathStr(srcFile); if (!isRelative) { if (srcFile.indexOf(projPath) == 0) { return { project : project, src : srcFile.substring(projPath.length) }; } } else { if (new java.io.File(projPath, srcFile).exists()) { return { project : project, src : srcFile }; } } } function processLineClick(terminalText, line, column, button) { if (button == 1) { const lineText = getLineText(terminalText, line, column); if (lineText) { runOnUiLater(function() { const matches = lineText.match(srcMatch); if (matches && matches.length > 1) { var srcFile = getPathStr(matches[1]); var isRelative = false; if (srcFile.indexOf("webpack:///") == 0) { srcFile = srcFile.substring("webpack:///".length); if (srcFile.indexOf('~/') == 0) { srcFile = "node_modules/" + srcFile.substring(2) } isRelative = true; } const line = matches.length > 2 ? parseInt(matches[2]) || 0 : 0; const col = matches.length > 3 ? parseInt(matches[3]) || 0 : 0; var projectMatch = getProjectMatch(selectedProject, srcFile, isRelative); if (!projectMatch) { const projects = org.eclipse.core.resources.ResourcesPlugin.getWorkspace().getRoot().getProjects(); for (var i = 0; !projectMatch && i < projects.length; i++) { projectMatch = getProjectMatch(projects[i], srcFile, isRelative); } } var editor; if (projectMatch) { const page = org.eclipse.ui.PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); const srcRes = projectMatch.project.getFile(projectMatch.src); const markerAttr = new java.util.HashMap(); markerAttr.put(org.eclipse.core.resources.IMarker.LINE_NUMBER, new java.lang.Integer(line)); marker = srcRes.createMarker(org.eclipse.core.resources.IMarker.TEXT); marker.setAttributes(markerAttr); editor = org.eclipse.ui.ide.IDE.openEditor(page, marker, true); const selection = editor.getSelectionProvider().getSelection(); editor.selectAndReveal(selection.getOffset() + col - 1, 0); } else { // TODO open editor for external location //IFileStore fileStore = EFS.getLocalFileSystem().getStore( .. ); //... //IDE.openEditorOnFileStore(page, fileStore); print("TBD: external file open not implemented yet"); } } }, 50); } } }
support-swapnaModeratorFedor,
Thank you for the detailed explanations. I have filed an enhancement request for the dev team and they are looking into it.
Please let us know if you see any other issues.
–Swapna
MyEclipse Support
Fedor LosevParticipantSome fixes to regex
const srcMatch = /([^\( @]*(?:(?:\.js(?![\/\\]))|(?:\.ts(?![\/\\]))))(?:(?:(?:\:| \()(\d+))?(?:[:,](\d+))?)?(?: <- .*?)?\)?/;
Sample lines with test:
const lines = [ " at webpack:///src/local.test.ts:53:2 <- src/local.test.ts:57060", " at Object.it (webpack:///src/app/studio/creative/model/creative.vo.spec.ts:26:17 <- src/local.test.ts:123:22) [ProxyZone]", " at ProxyZoneSpec.283.ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/local.test.ts:54668:39) [ProxyZone]", " at ProxyZoneSpec.283.ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79 <- src/local.test.ts:54668:39) [ProxyZone]", " webpack:///src/app/studio/creative/model/creative.vo.spec.ts:26:22 <- src/local.test.ts:126:26", " invoke@webpack:///~/zone.js/dist/zone.js:365:0 <- src/polyfills.ts:3281:31", " ERROR in C:/dv/src/angtest/src/app/studio/creative/model/creative.vo.spec.ts (22,17): Property 'getOwnPopertySymbols' does not exist on type 'X'.'", ]; const expMatches = [ ['webpack:///src/local.test.ts', '53', '2'], ['webpack:///src/app/studio/creative/model/creative.vo.spec.ts', '26', '17'], ["webpack:///~/zone.js/dist/proxy.js", "79", "0"], ["webpack:///~/zone.js/dist/proxy.js", "79"], ["webpack:///src/app/studio/creative/model/creative.vo.spec.ts", "26", "22"], ["webpack:///~/zone.js/dist/zone.js", "365", "0"], ["C:/dv/src/angtest/src/app/studio/creative/model/creative.vo.spec.ts", "22", "17"] ]; lines.forEach(function(testLine, testIdx) { const matches = testLine.match(srcMatch); expect(matches).toBeTruthy(); expect(matches.length).toBeTruthy(); expMatches[testIdx].forEach(function(expMatch, i) { //print(matches[i+1]); expect(i+1<matches.length).toBeTruthy(); expect(matches[i+1]).toBeEqual(expMatch, " for " + matches.reduce(function(sum, elt, i, array) { return i>0 ? sum + elt + "," : ""; })); }) })
-
AuthorPosts