-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
Markdown Static Preview Scrolling Fixes #123727
Markdown Static Preview Scrolling Fixes #123727
Conversation
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 like the right direction but I think the implementation could be cleaned up a little. Let me know if you have any questions about the comments
@@ -160,14 +160,18 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview | |||
document: vscode.TextDocument, | |||
webview: vscode.WebviewPanel | |||
): Promise<void> { | |||
const lineNumber = this._topmostLineMonitor.previousMDTextEditor?.document.uri.toString() === document.uri.toString() ? this._topmostLineMonitor.previousMDTextEditor?.visibleRanges[0].start.line : undefined; |
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.
Instead of exposing previousMDTextEditor
, can you hide this behind a method that gets the line for a given uri?
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.
previousMDTextEditor
changed to an internal map with public functions for access.
|
||
// When at a markdown file, apply existing scroll settings from static preview if applicable. | ||
// Also save reference to text editor for line number reference later | ||
if (textEditor && isMarkdownFile(textEditor.document!)) { |
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.
[nit] Avoid using !
where 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.
Should be fixed now.
|
||
if (this.previousStaticEditorInfo.uri?.toString() === textEditor.document.uri.toString()) { | ||
const line = this.previousStaticEditorInfo.line ? this.previousStaticEditorInfo.line : 0; | ||
scrollEditorToLine(line, textEditor); |
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.
Should the TopMostLineMonitor being scrolling editors or can this live somewhere else?
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.
Moved to MarkdownPreviewManager
export class TopmostLineMonitor extends Disposable { | ||
|
||
private readonly pendingUpdates = new Map<string, number>(); | ||
private readonly throttle = 50; | ||
public previousMDTextEditor: vscode.TextEditor | undefined; |
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.
Are there cases where you can more than one markdown file that we need to track the scroll position of? Try seeing if you can hit this using multiple editors and editor groups with different files
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.
Changed the previous text editors to be indexed via string URI so that multiple editor instances can be accessed. This might get populated if the user has a lot of markdown files open (?)
@@ -220,6 +224,11 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview | |||
this._staticPreviews.delete(preview); | |||
}); | |||
|
|||
// Continuously update the scroll info in case user changes the editor. | |||
preview.onScroll((scrollInfo) => { | |||
this._topmostLineMonitor.previousStaticEditorInfo = scrollInfo; |
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.
Should this live in the preview itself?
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.
Yup, accidentally forgot that I passed an instance of the topmost line monitor into the preview. Preview should now do this.
@@ -7,13 +7,21 @@ import * as vscode from 'vscode'; | |||
import { Disposable } from '../util/dispose'; | |||
import { isMarkdownFile } from './file'; | |||
|
|||
export interface LastScrollLocation { | |||
readonly line: number; | |||
readonly uri: vscode.Uri | undefined; |
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.
What are the cases where uri can be undefined? Is this something we'd expect to happen?
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.
Originally allowed for undefined for initialization; removed undefined.
I noticed another bug where all other open text editors for a markdown file disappear when one instance enters static preview. It seems that this bug isn't caused by this PR's changes because it also occurs on |
When running the debugger, it seems that the other text editors are removed prior to entering the |
Regarding this, I created #124134 |
|
||
public setPreviousMDTextEditorLine(editor: vscode.TextEditor) { | ||
const uri = editor.document.uri; | ||
this.previousMDTextEditors.set(uri.toString(), 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.
The TextEditor
object becomes invalid as soon as that editor is closed, so it's kind of dangerous to keep a reference to it around
Instead you can use window.visibleTextEditors
to get all current editors
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 we need to keep information about closed text editors to get the scroll info when we switch editors. Since keeping text editors won't work, we can just keep the last scroll location as with the static preview scroll locations.
this.previousMDTextEditors.set(uri.toString(), editor); | ||
} | ||
|
||
public getPreviousMDTextEditorLineByUri(resource: vscode.Uri) { |
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.
[nit] Add an explicit return types
this.setPreviousMDTextEditorLine(textEditor); | ||
} | ||
|
||
this.isPrevEditorCustom = (textEditor === undefined); |
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.
isPrevCustomEditor
will up being true when you do anything that causes there not to be an active text editor, such as switching to an extension page or maximizing the panel
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.
Ok, will link isPrevCustomEditor
to PreviewManager._activePreview
== undefined
return editor?.visibleRanges[0].start.line; | ||
} | ||
|
||
public setPreviousStaticEditorLine(scrollLocation: LastScrollLocation) { |
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.
Is this used anywhere?
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.
used in preview.ts
.
this.previousStaticEditorInfo.set(scrollLocation.uri.toString(), scrollLocation); | ||
} | ||
|
||
public getPreviousStaticEditorLineByUri(resource: vscode.Uri) { |
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.
Is this used outside of this class?
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.
nope, will change to private
if (this.isPrevEditorCustom) { | ||
const line = this.getPreviousStaticEditorLineByUri(textEditor.document.uri); | ||
if (line) { | ||
this._onEditorNeedsScrolling.fire({ line: line, editor: textEditor }); |
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.
Would it make sense to have the previewManager instead monitor onDidChangeActiveTextEditor
and then ask the TopMostLineMonitor
if it need to scroll somewhere?
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.
Sure, that would also functionally work. I can make that change.
@@ -284,6 +286,8 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { | |||
}); | |||
} | |||
|
|||
|
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.
[nit] Remove extra spaces
export class TopmostLineMonitor extends Disposable { | ||
|
||
private readonly pendingUpdates = new Map<string, number>(); | ||
private readonly throttle = 50; | ||
private previousEditorInfo = new Map<string, LastScrollLocation>(); |
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.
Unlike the previous commits, line numbers from static previews and text editors are both tracked in this object. I believe that they were tracked in different objects before because text editors used the reference to the editor object to find line number, but both editors now update using the same way.
This PR addresses two bugs with scrolling in markdown static preview:
Steps to test:
Issue 1:
View - Reopen Editor With...
>Markdown Preview (Experimental)
Issue 2:
View - Reopen Editor With...
>Markdown Preview (Experimental)
in command palette).This PR addresses #84520