inline values as decorators when debugging #16129

Merged
merged 1 commit into from Jan 13, 2017

Projects

None yet

7 participants

@nojvek
Member
nojvek commented Nov 28, 2016 edited
  1. Write Tests.
  2. Figure out how to get words from lines.
  3. Figure out how to stop flashing on stepping because onDidContinue passes in null stack frame everytime
  4. Figure out how to registerDecorator from public API.
  5. setDecorators afterText doesn't work in python on lines with trailing ':'
  6. Merge as single commit
  7. Add screenshot

image

@nojvek
Member
nojvek commented Nov 28, 2016

@isidorn Please take a look at the first iteration.

@isidorn isidorn was assigned by bpasero Nov 28, 2016
@isidorn isidorn added this to the November 2016 milestone Nov 28, 2016
@isidorn isidorn referenced this pull request Nov 28, 2016
Closed

inline values #16067

@isidorn
Contributor
isidorn commented Nov 28, 2016

I will do a code review and provide feedback in the code a bit later today, let me first try to answer your questions

  1. Awesome - might be a bit tricky though
  2. Just checked and yes there is no nice API to get you all words on a line. As you figured out already you need to use a regex, however you should use a word regex for the particular language you are in. You should get the regex using this method. Here is a sample usage
  3. Instead of using editor.removeDecorations and editor.addDecorations you need to use editor.deltaDecorations and probably keep track on your side of all the decorations from a previous state. DebugEditorModelManager is doing something similar now with breakpoints here
  4. Why do you want to register a decorator from a public api? This feature will live in the vsccode core repo
  5. No clue about that, we can investigate if it is a bug in the editor
@isidorn
Contributor
isidorn commented Nov 28, 2016
  1. However if your name regex is more precise than the language word regex then we should probably use that

  2. Here is a public api to set decorations in case you need it for some other use case

@isidorn
Contributor
isidorn commented Nov 29, 2016

@nojvek just to let you know that next week we have an endgame week - which means we take no new features. So it would be cool if we would try to land this feature together sometime this week. I have time on Thursday european time so I could try to wrap it up if something is still needed to be done then. Hope that works for you.

@nojvek
Member
nojvek commented Nov 29, 2016
@nojvek
Member
nojvek commented Nov 29, 2016
@isidorn
Contributor
isidorn commented Nov 29, 2016

Not sure if we can use it in the core
@jrieken is the right person to answer this

@jrieken
Member
jrieken commented Nov 29, 2016

re #16129 (comment) - Where do you need those? In an extension and the main-body of source code?

@isidorn
Contributor
isidorn commented Nov 29, 2016

@jrieken main-body of source code

@nojvek
Member
nojvek commented Nov 29, 2016
@jrieken
Member
jrieken commented Nov 29, 2016

For time being I've added a map-set.d.ts in the typings folder.

That is not allowed πŸ™…β€β™‚οΈ We have some technical debt there but in essence it would make ES6 Maps/Sets also available in the editor/base layer which we program against older runtime targets that don't support ES6. You might have a local version of those definitions, we have done that in a few places but it is not nice. Also it seems you don't need that.

The reason why I'm having hard time with using {} as map is that, I can't
quite set hasOwnProtype or prototype as keys, since they are already
defined properties. A scope variable could be this special object keys.

The fix for that is to not use {} but Object.create(null) or the utils defined in collections.ts

@nojvek
Member
nojvek commented Nov 29, 2016
@nojvek
Member
nojvek commented Nov 29, 2016
@isidorn
Contributor
isidorn commented Nov 29, 2016

That sounds like a decent workaround for now. So +1
I believe tokenization is already dealing with words so it would be cool if you could just get tokens and not do any additional word magic on a line (which you are currently doing).

@nojvek
Member
nojvek commented Nov 29, 2016
@isidorn
Contributor
isidorn commented Nov 29, 2016

@nojvek I would not move that to the TextEditorModel before I check with @alexandrudima. Will talk to him tomorrow in the office.

You can add a listener to the editor on changeModel. Example

@isidorn
Contributor
isidorn commented Nov 30, 2016

Ok I have discussed this with @alexandrudima and there are concerns

  • The current implementation of putting decorations after text is suboptimal and can hurt performance
  • Going through each word on a line can be very performant for very long lines
  • What do we do for people that have word wrapping enabled. Via that setting they have specifically enabled lines not to overflow over some border.

Due to the above, this feature will be under a setting which by default is false. Once we have no more performance concerns we can lift this flag. @nojvek you do not have to worry about introducing this flag, I can just put it on top once we polish this pr.

Also we need to put a limit on the line size and just do not compute anything for very long lines. Since currently we are matching the words on a line to a set of variables, we could also do it the other way around - match variables across a line. However this strategey does not work best for short lines which are the most common in practice. Thus I believe for starters we should just ignore long line.

As for the word wrap issue - that is something we need to think about. Might not require immediate action.

In a perfect world the debug extension would have a better ast understanding of the file - this knowledge would come from a language server but we currently do not have this. @weinand might know better if we plan to investigate into this any time in the future

Due to all of the above we do not have to rush this feature in for November. But let's see how it goes.

@nojvek
Member
nojvek commented Nov 30, 2016
@isidorn
Contributor
isidorn commented Dec 1, 2016

All those constraints make sense but we should introduce another one - the length of the editor line that is being processed. Because if the lenght of that line is quite large you will still go through each word and try to find it in the variables view, so some constraint needs to be added there.
We can handle word wrapping later, not for version 1.

fyi I am on vacation on Friday but I plan to code review, merge this feature and try to wrap it up on Monday.

@nojvek
Member
nojvek commented Dec 1, 2016
@nojvek nojvek changed the base branch to Microsoft:master from Microsoft:isidorn/inlineValues Dec 2, 2016
@nojvek
Member
nojvek commented Dec 4, 2016

I've moved most of helper functions to debugInlineDecorators.ts where the core of logic really happens. Added 100% line, branch and function coverage for that file.

I've tested on a bunch of different project types and it looks good so far. I've added a screenshot.

Let me know if you need more changes. Its a nice sunny sunday, so I'll get back to this on Monday evening. Can't wait for this to get into nightly releases.

@nojvek nojvek changed the title from Initial working prototype of inline values to Working inline values as decorators when debugging Dec 4, 2016
@nojvek nojvek changed the title from Working inline values as decorators when debugging to inline values as decorators when debugging Dec 4, 2016
@isidorn
Contributor
isidorn commented Dec 5, 2016

@nojvek great work! And nice that you tested it in different projects!

I have added comments in the commit directly.

Let's move this feature out to the next release because there is no need for the rush and I would love the insiders to self host on this feature for a couple of weeks. This will also give us time to nicely adress the issues I brought up in the review.

@isidorn isidorn modified the milestone: January 2017, November 2016 Dec 5, 2016
@nojvek
Member
nojvek commented Dec 5, 2016

Hi Isidor,

No problems. I am not seeing any comments in the review though.

When do you think it will make insiders?

Regards.

@isidorn
Contributor
isidorn commented Dec 5, 2016

@nojvek ok that explains why you did not react on my previous comment from a couple of days ago.
Here is the direct link to my comments, you should be able to nicely see them
d36a042

It should make insiders in about 8, 9 days when we wrap up our endgame.

+ // TODO: This calls onStackFrame with null stack frame on every step causing all decorators to be re-drawn.
+ // onDidContinued also gets called for step-over causing flash in decorators due to removeDecorators and setDecorators call
+ // One idea is to use throttled onStackFrame, other is to only call onDidContinued only for continue
+ // this.transitionToRunningState(session, event.body.allThreadsContinued ? undefined : event.body.threadId);
}));
@isidorn
isidorn Dec 5, 2016 Contributor

Let's first try with the idea I mentioned in my comment - to use editor.deltaDecorations and keep track of our decorations.
Calling onDidContinued only for continue will not work because some step calls can take arbitrary long, so in essence they can be just like a continue.

If the decoraionts idea does not work then we will update decorations with a delay, similar to how the debug views in the debug viewlet have a delay to prevetn tree collapsing and flashing

import { BreakpointWidget } from 'vs/workbench/parts/debug/browser/breakpointWidget';
import { FloatingClickWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
+import { getNameValueMapFromScopeChildren, getDecorators, getEditorWordRangeMap } from 'vs/workbench/parts/debug/electron-browser/debugInlineDecorators';
+import { IStringDictionary } from 'vs/base/common/collections';
@isidorn
isidorn Dec 5, 2016 Contributor

We try to sort imports by first base, editor and at the end workbench.

@nojvek
nojvek Dec 6, 2016 Member

Fixed.

@@ -56,6 +60,12 @@ export class DebugEditorContribution implements IDebugEditorContribution {
this.hideHoverScheduler = new RunOnceScheduler(() => this.hoverWidget.hide(), HOVER_DELAY);
this.registerListeners();
this.breakpointWidgetVisible = CONTEXT_BREAKPOINT_WIDGET_VISIBLE.bindTo(contextKeyService);
+
+ // TODO: How do I register a new decoration type using exposed api ?
@isidorn
isidorn Dec 5, 2016 Contributor

You do not need to do any of this. Just by calling editor.deltaDecorations editor should register you decoration nicely.
When removing decorations you will also use ids of each of the added decorations by calling deltaDecoraitons.

+ // TODO: onFocusStackFrame isn't called for the first time when editor url changes due to source mapping
+ //console.log("onFocusStackFrame", this.editor.getModel().uri.toString(), this.editor.getModel().uri.toString(), stackFrame);
+
+ if (!stackFrame || stackFrame && stackFrame.source.uri.toString() !== this.editor.getModel().uri.toString()) {
@isidorn
isidorn Dec 5, 2016 Contributor

If the stackFrame is false the other part of this expression will not be evaluted so the other stackFrame truthfulness check is not needed

@nojvek
nojvek Dec 6, 2016 Member

It seems you commented on an older review. Does not apply to current the iteration .

+ // This means we'll get a null stackFrame followed quickly by a valid stackFrame.
+ // Removing all decorators and adding them again causes a noticeable UI flash due to relayout and paint.
+ // We want to only remove inline decorations if a null stackFrame isn't followed by a valid stackFrame in a short interval.
+ clearTimeout(this.removeDecorationsTimeoutId);
@isidorn
isidorn Dec 5, 2016 Contributor

Same as I already commented couple of days ago. Instead of using a timeout I would prefer that we have the decorations on our end and than only update the delta using deltaDecorations. Only if this approach does not work I would consider using timeouts which feels ugly to me.

@nojvek
nojvek Dec 6, 2016 Member

Explained the issue about deltaDecorators on other thread. We need the timeout anyway since setDecorators gives us a nice diff for free. We just need to debounce the null between the continues, otherwise we end up removing all decorators and creating them again rather than only changing the subset that actually are different.

@isidorn
isidorn Dec 9, 2016 Contributor

I understand that but this is still not a nice solution. Though it is fine for the first version and once we merge this in next week I can try to polish this if possible

+ this.setInlineDecoratorsFromLinesDecoratorText(linesDecoratorText, linesContent);
+ });
+ }
+
@isidorn
isidorn Dec 5, 2016 Contributor

Two dimensional expression array is ugly - maybe we first merge children across scopes so we get an 1 dimensional array

+ // Put ellipses in value if its too long. Preserve last char e.g "longstr…" or {a:true, b:true, …}
+ let value = expr.value;
+ if (value && value.length > MAX_INLINE_VALUE_LENGTH) {
+ value = value.substr(0, MAX_INLINE_VALUE_LENGTH - ELLIPSES.length) + ELLIPSES + value[value.length - 1];
@isidorn
isidorn Dec 5, 2016 Contributor

I woudl just inline the ELLIPSES it is only used here.
Also consider using the unicode elipses character, might look nicer

@nojvek
nojvek Dec 6, 2016 Member

It is using the utf-8 ellipses char. I'll inline it.

+
+ nameValueMap[expr.name] = value;
+
+ // Limit the size of map. Too large can have a perf impact
@isidorn
isidorn Dec 5, 2016 Contributor

I would not bother with limiting the size of the map for now. We can easily add perf limits later

+ private computeLinesDecoratorTextFromNameValueMap(nameValueMap: { [name: string]: string }, linesContent: string[]): string[] {
+ // Compose a single regex that matches any of the names as a whole word
+ // Single regex is much faster than multiple string matches
+ // TODO: This step could be optimized if we already have a pre-computed variableName to ranges map for editor
@isidorn
isidorn Dec 5, 2016 Contributor

Agree that this could be optimized as we do not need to compute all the words on each step. We just need to recompute them on editor model changed event.

+ const linesNames = linesContent.map(content => content.match(namesRegex));
+
+ // Compute text that will be shown after each line as decorators
+ return linesNames.map((names) => {
@isidorn
isidorn Dec 5, 2016 Contributor

First filter then map so we do not have falsy elements in the array. Thus you would not need the falsy check on line 272 in setInlineDecoratorfFromLinesDecoratorText

@@ -310,7 +310,7 @@ class DecorationRenderHelper {
cssTextArr.push(strings.format(this._CSS_MAP.contentIconPath, opts.contentIconPath.toString(true).replace(/'/g, '%27')));
@isidorn
isidorn Dec 5, 2016 Contributor

What is the reason for this change?
How can we be sure that we did not break any of the many use cases editor decorations have.

This PR should not touch anything in the editor land. A change in the editor land is only acceptable if there is no alternative.

@nojvek
nojvek Dec 6, 2016 edited Member

This was actually a VSCode bug that I discovered. You couldn't have after/before text decorators with a ' in them. _CSS_MAP.contentText is defined as contentText: 'content:\'{0}\';', . This means the escaping of " actually did nothing. It should have been escaping single quotes '. I'm fairly certain that this doesn't have side effects because its only escaping the contentText property and that's the only usage of it.

Without this fix, python string values won't show up. Since python strings show up as 'cat bat mat' in the watches view.

@isidorn
isidorn Dec 9, 2016 Contributor

Ok makes sense. But the best thing would be to provide a seperate PR that only fixes this issue.
That PR I will then assign to the editor people. As the description just copy this comment.

src/vs/editor/common/commonCodeEditor.ts
@@ -622,6 +622,10 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom
return this.model.deltaDecorations(oldDecorations, newDecorations, this.id);
}
@isidorn
isidorn Dec 5, 2016 Contributor

Same as my previous comment. This PR should not touch anything in the editor land.

As I commented earlier have you tried using editor.deltaDecoraitions which should automatically register a decoration. A nice use case of this api can be found here

@nojvek
nojvek Dec 6, 2016 Member

setDecorators actually uses deltaDecorators. Inline decorators need to use after.contentText which ends up translating to a css:after block. For each of the unique decorators we need to create the selectors. By not using setDecorators we'll have to do that manually which will duplicate the logic in two places.

setDecorators ends up calling provider = new DecorationSubTypeOptionsProvider(this._styleSheet, key, parentTypeKey, options); eventually.

setDecorators does the correct thing and provides the proper abstraction. Its just that before calling setDecorators, the decoratorTypeKey to be registered. That's why I added the registerDecoratorType api.

I've spent hours trying to figure out if there was a nicer way to register the decoratorType. This seemed like the least obtrusive way since this._registerDecorationType was already being used.

The other workaround I can think is for setDecorators to auto-register the key if it doesn't exist.

@isidorn
isidorn Dec 9, 2016 Contributor

Thanks for the explanation!
@aeschli how are you registering your folding end of line decorators? Can you provide a code pointer? Does it make sense to expose register editor decoration API as @nojvek is proposing here.

@aeschli
aeschli Dec 9, 2016 Contributor

https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/folding/common/foldingModel.ts#L71 is where folding defines its decorations. Note that it manages the CSS itself. It just passes in the name of the CSS in inlineClassName. You can also do before/after images & text the same way using beforeContentClassName/afterContentClassName
If you do that (manage your own CSS) all you need to use deltaDecorators.

setDecoration got added for our extension host API, where the CSS is managed by us (done in the CodeEditorService). If you want to use that API, register your decoration type on the ICodeEditorService. No new API should be required.

@@ -0,0 +1,212 @@
+/*---------------------------------------------------------------------------------------------
@isidorn
isidorn Dec 5, 2016 Contributor

Awesome that we have tests for this!

@nojvek
nojvek Dec 6, 2016 Member

πŸ‘

+}
+
+// Simple tokenizer that separates comments from words
+function mockLineTokens(lineContent: string): LineTokens {
@isidorn
isidorn Dec 5, 2016 Contributor

I do not think this method is needed. You could instead reuses model.createFromeString and then on that model get line tokens.
Here's an example usage

@nojvek
nojvek Dec 6, 2016 Member

I tried that. The issue is the tokens are whole line tokens since the tokenizerSupport is null I tried using model.setMode('javascript') but that needs the javascript tokenizersupport to be registered and I couldn't fit all of the pieces to test that comments are ignored. So I wrote a simple stub that mocks editor.getLineTokens().

Happy to change this if there is a way to plug in the javascript tokenizer.

@isidorn
isidorn Dec 9, 2016 Contributor

@aeschli do we have some mock tokenizer which we could reuse here?

+export const ELLIPSES = '…';
+// LanguageConfigurationRegistry.getWordDefinition() return regexes that allow spaces and punctuation characters for languages like python
+// Using that approach is not viable so we are using a simple regex to look for word tokens.
+export const WORD_REGEXP = /[\$\_A-Za-z][\$\_A-Za-z0-9]*/g;
@isidorn
isidorn Dec 5, 2016 Contributor

For simplicity can we just use the regex \b word boundary character?

@nojvek
nojvek Dec 6, 2016 Member

\b doesn't work since it doesn't consider $ and _ as word character. Powershell, php would break seriously. Javascript allows $ and _ in variable names so they would have quirks as well.

@isidorn
isidorn Dec 9, 2016 Contributor

Ok makes sense. Though I hate introducing new regexes. Once we merge this in I can investigate if we can reuse some other word logic we have

+// Using that approach is not viable so we are using a simple regex to look for word tokens.
+export const WORD_REGEXP = /[\$\_A-Za-z][\$\_A-Za-z0-9]*/g;
+
+export function getNameValueMapFromScopeChildren(scopeExpressions: IExpression[][]): IStringDictionary<string> {
@isidorn
isidorn Dec 5, 2016 edited Contributor

This as a 2 dimensional array makes things overly complicated. Please make this one dimensional. Caller of this method could just merge mutliple expression arrays into one

@nojvek
nojvek Dec 6, 2016 Member

Fixed.

+
+export function getDecoratorFromNames(lineNumber: number, names: string[], nameValueMap: IStringDictionary<string>, linesContent: string[]): IDecorationOptions {
+ const margin = '10px';
+ const backgroundColor = 'rgba(255,200,0,0.2)';
@isidorn
isidorn Dec 5, 2016 Contributor

Adding css here is ugly. Is it possible to just add a css class and then style the decorations in debug.contribution.css?

@nojvek
nojvek Dec 6, 2016 Member

The generated parent classname with registerDecorationType looks like ced-inlineDecorator-4 I could add the parent :after selector but it might look weird.

I think once the decorator apis use an underlying implementation using spans rather than css :after selectors, we can nicely add the chrome like syntax highlighting for the inline values and move this to css. wdyt?

@isidorn
isidorn Dec 9, 2016 Contributor

We would like to change the underlying implementation since it is already causing performance issues for folding. Though I will have to sync with @alexandrudima on this

+ const tokenStr = lineContent.substring(startOffset, endOffset);
+
+ // Token is a word and not a comment
+ if (lineTokens.getStandardTokenType(j) !== StandardTokenType.Comment) {
@isidorn
isidorn Dec 5, 2016 Contributor

Great that you are using getStandardTokenType() since that is the new recommanded way of handling tokens

@nojvek
nojvek Dec 6, 2016 Member

πŸ‘

@isidorn
Contributor
isidorn commented Dec 5, 2016

@nojvek my appologies - I did not click on submit review both times! I was used to using the old github UX which did not require an explict click on submit

@nojvek
Member
nojvek commented Dec 5, 2016
@isidorn
Contributor
isidorn commented Dec 5, 2016

@nojvek you should be able to see them now, I made a mistake of not publishing them. Sorry for the misunderstanding!

@nojvek

Fixed review feedback

@isidorn
Contributor
isidorn commented Dec 6, 2016

@nojvek thanks for your replies - we are in the middle of the endgame so I will reply to your comments in a couple of days once the bugfixing fuss is over. I also need to consult with @alexandrudima for the editor side of things concerning some of the questions you have raised.

@nojvek
Member
nojvek commented Dec 6, 2016
@isidorn
Contributor
isidorn commented Dec 6, 2016

@nojvek feel free to ignore my comments from couple of days ago which I accidently only released yesterday

@isidorn
Contributor
isidorn commented Dec 9, 2016

@nojvek added some comments. Seems like it is in a good state, I would lke to merge it in some time next week and then I can look into improving some of the issues we raised in the discussion (end of line decorations, using timeouts, creating a tokenizer for tests). Most of the team is still busy with the endgame so I will sync with them next week for input on improving implentation of decorations

@nojvek
Member
nojvek commented Dec 9, 2016
@nojvek
Member
nojvek commented Dec 9, 2016
@isidorn
Contributor
isidorn commented Dec 28, 2016

Hi @nojvek I was looking into mergin this in, the following would still be needed in order for me to do the merge

  • As @aeschli mentioned here no new editor api needs to be added. So please use existing API
  • Changes in the codeEditorServiceImpl.ts need to be moved to a seperate PR
  • merge your branch with latest from master and resolve conflicts

Other things I can polish up once we merge it in.

Thanks a lot!

@nojvek
Member
nojvek commented Dec 28, 2016
@aeschli
Contributor
aeschli commented Dec 30, 2016

My suggestion is that you register your decoration type using ICodeEditorService.registerDecorationType

@isidorn
Contributor
isidorn commented Jan 10, 2017

ping @nojvek just to check if there are some updates here? Just fyi If you are busy I can also work on this.

@nojvek nojvek added a commit to nojvek/vscode that referenced this pull request Jan 10, 2017
@nojvek nojvek Fix bug in decorationRenderHelper
getCSSTextForModelDecorationContentClassName will not escape ' in contentText since its escaping " rather than '

_CSS_MAPcontentText: 'content:\'{0}\';' uses single apostrophe so we need to escape ' rather than "

This is a bug that was always present and breaks inlineValueDebugging feature I am working on #16129
25eb362
@nojvek
Member
nojvek commented Jan 10, 2017

@aeschli , codeEditorService is a private variable of codeEditor. It is not exposed. This is exactly what I am trying to do. ICodeEditor.registerDecorationType ends up calling ICodeEditorService.registerDecorationType

Updated PR, as you recommend I am using ICodeEditorService.registerDecorationType (<any>this.editor)._codeEditorService.registerDecorationType. I get a feeling that you are very much against touching the code editor api.

I feel its worse solution than what we had before but gets the job done until vscode exposes a nicer api. I'm really not sure what you want me to do here. 😞

@aeschli
Contributor
aeschli commented Jan 11, 2017

@nojvek To get hold of the codeEditorService, use service injection in the class you are:
Add
@ICodeEditorService codeEditorService: ICodeEditorService
to the constructor of the DebugEditorContribution

@nojvek
Member
nojvek commented Jan 11, 2017
@isidorn
Contributor
isidorn commented Jan 11, 2017

@nojvek just checked the PR and no other major changes are needed - except the code injection Martin mentioned. Once that is in I will merge this in.
Some polish work will be needed on top (adding setting, some refactoring, trying not to use timeouts) but that we will handle on our side.

Great work! 🍻

@nojvek nojvek Inline values as decorators when debugging
For perf reasons we only process max 100 scopes, lines longer than 500 chars are not processed, maximum decorator length is 150 chars and we store a wordRangesMap for current editor model for fast lookup.

Since continue, step over, step in will send null stack frame followed quickly by a valid frame. We debounce removeDecorators.

100% LFB code coverage for debugInlineDecorators.ts.

Tested inline decorators with python and javascript projects.

Adding codeEditorService to debugEditorContribution through dependency injection.
4077947
@nojvek
Member
nojvek commented Jan 12, 2017

Done.

Just curious: Any chance someone can give me a brief overview of how vscode uses es6 decorators to make dependency injection work?

		@IDebugService private debugService: IDebugService,
		@IContextMenuService private contextMenuService: IContextMenuService,
		@IInstantiationService private instantiationService: IInstantiationService,
		@IContextKeyService contextKeyService: IContextKeyService,
		@ICommandService private commandService: ICommandService,
		@ICodeEditorService private codeEditorService: ICodeEditorService,
		@ITelemetryService private telemetryService: ITelemetryService

Am I correct to assume that the services are all singletons? i.e each of them is only instantiated once and then stored in a service registry somewhere ?

@editorContribution
export class DebugEditorContribution implements IDebugEditorContribution {

This is like adding the class instance to another registry as editor extensions/contributors ? In this sense if I create another class

@editorContribution
export class SyncEditorContribution implements IDebugEditorContribution {

vscode will instantiate my contribution, add to contributions registry and call its handler functions when editor change happens right? So with @editorContribution its possible to build functionality in vscode that syncs the editor with a peer or web browser for a collaborative interview?

@isidorn
Contributor
isidorn commented Jan 13, 2017

@nojvek thanks! I will merge it in today.
As for the code injection, yes every service is instantiated exactly once and more details can be found here

@isidorn isidorn merged commit df2d1d2 into Microsoft:master Jan 13, 2017

1 of 2 checks passed

continuous-integration/travis-ci/pr The Travis CI build could not complete due to an error
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
@isidorn
Contributor
isidorn commented Jan 13, 2017

@nojvek added setting, started using set & map (since it is now ok to do this - we no longer support IE10) and did some polish on top. I also plan to look into restructuring the debugInlineValues.ts so it is a class and not a bunch of helper methods. I am also considering not showing inline values for lines after the current line that is focussed.
6091d5d
24c9eba
db334b2

@nojvek
Member
nojvek commented Jan 13, 2017
@isidorn
Contributor
isidorn commented Jan 13, 2017 edited

This can be set in settings > "debug.inlineValues": true.
You can set it and try it out in the next insider build. And it will be a part of the january stable release

@luminaxster
luminaxster commented Feb 4, 2017 edited

Wow!! Awesome work!
Do you have some feedback(than can be shared) from the users that have used the feature? I highly recommend this reading, if you haven't already, it goes "inline" with this feature. Let me know if I can be help, we are working on researching on and developing programming tools, too.

@weinand
Member
weinand commented Feb 5, 2017

@luminaxster since this feature made its first appearance in VS Code 1.9 (3 days ago) we do not yet have statistics. In addition this feature is not enabled by default because we are still working on it, so we do not expect widespread acceptance in this release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment