-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
generalize code and markdown code lenses to be used with multiple languages #4876
Conversation
language = 'python'; | ||
} | ||
|
||
let codeLens = settings?.codeLensExpressions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linter should have flagged this I believe. The 'let' should be a 'const'
constructor(settings?: IJupyterSettings) { | ||
constructor(settings?: IJupyterSettings, language?: string) { | ||
|
||
if (language) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd rewrite this like so:
if (language) { | |
if (!language) { | |
language = python | |
} |
And don't use the active text editor here. It should be used in the caller. Otherwise this code has an implicit dependency on the window namespace that isn't necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you know that you want to use the active editor? There are cases where this is called on a non active editor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that's why I'd pass in the language only. Let the caller decided what the language is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah so you're saying, don't pass in a default value for language
, just let language
be an argument in the method and end it there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it the responsibility of the caller to determine it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you know that you want to use the active editor? There are cases where this is called on a non active editor
that wasn't done for any good reason, just don't know the best way to get the TextDocument
object in each situation, so i defaulted to that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries. The calling code should be able to make a better decision I think about whether or not to use the active editor to determine the language. You might have to trace back a few levels though (in the callers) to determine what they're actually doing. I think some of the code in cellFactory.ts has some intermediary functions that you might need to pass the language through as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, sorry for the hand holding, but youre asking that I look through all instances of CellMatcher and see where a language argument is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well all of them should need one, but each caller will get it in different ways. So yes, you'd have to look for all callers of CellMatcher (you should be able to use the same go to references for the constructor to find them).
@@ -105,7 +105,9 @@ export class JupyterImporter implements INotebookImporter { | |||
}; | |||
|
|||
private get defaultCellMarker(): string { | |||
return this.configuration.getSettings().defaultCellMarker || Identifiers.DefaultCodeCellMarker; | |||
const language = window.activeTextEditor?.document.languageId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We actually have an abstraction around the VScode 'window' namepace called IDocumentManager
. You'd inject an IDocumentManager
into the constructor of the importer and use that here instead of the window namespace.
This abstraction allows us to have tests that can run without VS code being involved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, do I call the active text editor:
const language = this.DocumentManager.activeTextEditor?.document.languageId
where the constructor now has:
@inject(IDocumentManager) private readonly DocumentManager: IDocumentManager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes something like that. The importer may be called for things other than the active document though. It would be good to check where defaultCellMarker is used (under what circumstances). The caller of defaultCellMarker may have a file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where can I find the caller of defaultCellMarker?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good except for the cell matcher part with passing the language in. Thanks for the PR. |
Oh it seems you need to update .eslintrc.js. The linter step is giving this error:
That means remove those files from the linter ignore list. You'll probably get linter errors then. You can run lint on those files if you install the eslint extension (not sure if contributing.md mentions that or not. I'll go fix it if it doesn't) |
The 'VSCode' tests are expected to fail until we can catch up to the new notebook APIs that VS code has been changing (we run our tests with insiders) (See this bug: #4796) However the other tests should be passing pretty close to 100%. After you fix the build errors, they should go green. |
Getting a private onSettingsChanged = () => {
const settings = this.configuration.getSettings(undefined);
const ownsSelection = settings.sendSelectionToInteractiveWindow;
const editorContext = new ContextKey(EditorContexts.OwnsSelection, this.commandManager);
**editorContext.set(ownsSelection).catch();**
};
private onChangedActiveTextEditor() {
// Setup the editor context for the cells
const editorContext = new ContextKey(EditorContexts.HasCodeCells, this.commandManager);
const activeEditor = this.documentManager.activeTextEditor;
if (activeEditor && activeEditor.document.languageId === PYTHON_LANGUAGE) {
// Inform the editor context that we have cells, fire and forget is ok on the promise here
// as we don't care to wait for this context to be set and we can't do anything if it fails
**editorContext.set(hasCells(activeEditor.document, this.configuration.getSettings())).catch();**
} else {
**editorContext.set(false).catch();**
}
} |
have to fix a few more things as it turns out... |
I think should be fixable using |
…ode-jupyter into codelens-multiple-languages
Perfect. Another issue, I just noticed is that the code cell expressions are sent to the interactive window as well, leading to python syntax error. I think it needs to be commented before being sent. |
Last merge fixed the issue with Now there's an issue with public async store(service: string, key: string, value: string | undefined): Promise<void> {
// On CI we don't need to use keytar for testing (else it hangs).
if (IS_REMOTE_NATIVE_TEST && this.extensionContext.extensionMode !== ExtensionMode.Production) {
this.testingState.set(`${service}#${key}`, value || '');
return;
}
if (!value) {
await this.extensionContext.secrets.delete(`${service}.${key}`);
} else {
await this.extensionContext.secrets.store(`${service}.${key}`, value);
}
}
public async retrieve(service: string, key: string): Promise<string | undefined> {
// On CI we don't need to use keytar for testing (else it hangs).
if (IS_REMOTE_NATIVE_TEST && this.extensionContext.extensionMode !== ExtensionMode.Production) {
return this.testingState.get(`${service}#${key}`);
}
// eslint-disable-next-line
const val = await this.extensionContext.secrets.get(`${service}.${key}`);
return val;
} |
This one is likely a merge required from main. We updated our version of VS code's API that we're using. |
Sorry for not getting to this for a long time. I got side tracked by grad school and couldn't get to it. I'll try to get to this ASAP, but would also be completely open to having someone push this over the finish line! |
@amichuda I merged from main and it now builds again but I'm not sure the behavior is correct. If I have markdown like so: '```python'
print('foo') It sends the code lens lines along with the python code. The interactive window shows this as an error: I'll try debugging it later. |
Had some time to debug. The code here was not stripping your delimiter so it was failing to be valid python code.
I made it so it could pick up the language id |
Codecov Report
@@ Coverage Diff @@
## main #4876 +/- ##
======================================
Coverage 71% 72%
======================================
Files 399 401 +2
Lines 26938 27085 +147
Branches 3964 3998 +34
======================================
+ Hits 19374 19599 +225
+ Misses 6188 5833 -355
- Partials 1376 1653 +277
|
@@ -44,6 +44,7 @@ | |||
], | |||
"activationEvents": [ | |||
"onLanguage:python", | |||
"onLanguage:markdown", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks pretty reasonable. But one more thing popping out here. The code expressions are added on activation via the lens manager. But it's only activating on python and markdown files loading. The languages that we add to codeExpressions would need to also register here as activation events. But that feels like it would have to be a dynamic list here. Not sure if that is possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something to ask VS code then. Can a user add activation events to their settings.json for an extension.
There's still work to do here. We need some sort of 'end' marker for markdown cells or it won't get the correct cell ranges (nor have executable code) |
Sorry about getting back to this SUPER LATE. What's the best way to continue on this, rebase to master and finish the pull request? |
Yeah a rebase would be the starting point. I don't think it works correctly yet though. At least if my memory is correct, markdown code isn't working because it doesn't have a way to match the 'end' for the markdown code. Normal code cells work because the end is the next cell divider. Markdown code is kinda in the middle of other stuff, so it needs a begin/end pair. I don't think it should be too hard to match on |
I'm going to close this PR as its been around for a while. |
For #1238
This is still rough, but I wanted to make sure that things were being done correctly (pretty new at typescript)
Please let me know and I can make any changes
Thank you so much for your patience!
Features
codeLensExpression
in the config to allow for both.py
and.md
files to be used in interactive windowdefaultCellMarker
Problems
cellhashprovider.unit.test
datascience.unit.test
fail for `dataScience.activate() because of this line:package-lock.json
has been regenerated by runningnpm install
(if dependencies have changed).