Skip to content
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

Custom Editor API #3961

Merged
merged 9 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1420,14 +1420,16 @@
"browser",
"tab",
"singleton",
"external"
"external",
"customEditor"
],
"markdownDescription": "The default PDF viewer.",
"enumDescriptions": [
"Open PDF with the default web browser.",
"Open PDF with the built-in tab viewer.",
"Open PDF with the built-in tab viewer, reveal existing one if possible.",
"[Experimental] Open PDF with the external viewer set in \"View > Pdf > External: command\"."
"[Experimental] Open PDF with the external viewer set in \"View > Pdf > External: command\".",
"Open PDF with the built-in tab viewer, treating it as a custom editor."
ManuelHentschel marked this conversation as resolved.
Show resolved Hide resolved
]
},
"latex-workshop.view.pdf.tab.editorGroup": {
Expand All @@ -1450,11 +1452,32 @@
"Put the viewer tab in a new group below the current one"
]
},
"latex-workshop.view.pdf.tab.viewColumn": {
"scope": "window",
"type": "string",
"default": "Beside",
"markdownDescription": "The view column in which to open the tab viewer, if treating it as a custom editor.",
"enum": [
"Active",
"Beside",
"One",
"Two",
"Three"
],
"enumDescriptions": [
"Use the currently active editor group",
"Use the column next to the current editor",
"Use the first editor column",
"Use the second editor column",
"Use the third editor column"
]
},
ManuelHentschel marked this conversation as resolved.
Show resolved Hide resolved
"latex-workshop.view.pdf.tab.openDelay": {
"scope": "window",
"type": "number",
"default": 1000,
"markdownDescription": "Defines the delay in milliseconds to wait for a tab opening. Please increase the value if you encounter a focus issue after opening a tab."
"markdownDescription": "Defines the delay in milliseconds to wait for a tab opening. Please increase the value if you encounter a focus issue after opening a tab.",
"markdownDeprecationMessage": "Deprecated, does not have any effect."
ManuelHentschel marked this conversation as resolved.
Show resolved Hide resolved
},
"latex-workshop.view.pdf.ref.viewer": {
"type": "string",
Expand Down
28 changes: 26 additions & 2 deletions src/components/viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { moveActiveEditor } from '../utils/webview'

const logger = getLogger('Viewer')

export type ViewerLocation = 'tab' | 'browser' | 'singleton' | 'external' | 'customEditor'
ManuelHentschel marked this conversation as resolved.
Show resolved Hide resolved

export { pdfViewerHookProvider } from './viewerlib/pdfviewerhook'
export { pdfViewerPanelSerializer } from './viewerlib/pdfviewerpanel'

Expand Down Expand Up @@ -97,13 +99,19 @@ export class Viewer {
async open(pdfFile: string, mode?: string): Promise<void> {
const configuration = vscode.workspace.getConfiguration('latex-workshop')
const tabEditorGroup = configuration.get('view.pdf.tab.editorGroup') as string
const viewer = mode ?? configuration.get<'tab' | 'browser' | 'singleton' | 'external'>('view.pdf.viewer', 'tab')
const viewerLocation = configuration.get<ViewerLocation>('view.pdf.viewer', 'tab')
if(mode === 'tab' && (viewerLocation === 'customEditor' || viewerLocation === 'singleton')) {
ManuelHentschel marked this conversation as resolved.
Show resolved Hide resolved
mode = viewerLocation
}
const viewer = mode ?? viewerLocation
if (viewer === 'browser') {
return lw.viewer.openBrowser(pdfFile)
} else if (viewer === 'tab' || viewer === 'singleton') {
return lw.viewer.openTab(pdfFile, tabEditorGroup, true)
} else if (viewer === 'external') {
return lw.viewer.openExternal(pdfFile)
} else if (viewer === 'customEditor') {
return lw.viewer.openCustomEditor(pdfFile)
}
}

Expand Down Expand Up @@ -149,9 +157,25 @@ export class Viewer {
return this.openPdfInTab(pdfUri, tabEditorGroup, preserveFocus)
}

async openCustomEditor(pdfFile: string): Promise<void> {
const url = await this.checkViewer(pdfFile)
if (!url) {
return
}
const configuration = vscode.workspace.getConfiguration('latex-workshop')
const viewColumnName = configuration.get<keyof typeof vscode.ViewColumn>('view.pdf.tab.viewColumn', 'Active')
const viewColumn = vscode.ViewColumn[viewColumnName]
const pdfUri = vscode.Uri.file(pdfFile)
const showOptions: vscode.TextDocumentShowOptions = {
viewColumn,
preserveFocus: true
}
await vscode.commands.executeCommand('vscode.openWith', pdfUri, 'latex-workshop-pdf-hook', showOptions)
}

async openPdfInTab(pdfUri: vscode.Uri, tabEditorGroup: string, preserveFocus: boolean): Promise<void> {
const configuration = vscode.workspace.getConfiguration('latex-workshop')
const singleton = configuration.get<'tab' | 'browser' | 'singleton' | 'external'>('view.pdf.viewer', 'tab') === 'singleton'
const singleton = configuration.get<ViewerLocation>('view.pdf.viewer', 'tab') === 'singleton'
if (singleton) {
const panels = viewerManager.getPanelSet(pdfUri)
if (panels && panels.size > 0) {
Expand Down
26 changes: 20 additions & 6 deletions src/components/viewerlib/pdfviewerhook.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type * as vscode from 'vscode'
import * as vscode from 'vscode'
import * as lw from '../../lw'
import { ViewerLocation } from '../viewer'
import { viewerManager } from './pdfviewermanager'
import { populatePdfViewerPanel } from './pdfviewerpanel'

class PdfViewerHookProvider implements vscode.CustomReadonlyEditorProvider {
openCustomDocument(uri: vscode.Uri) {
Expand All @@ -9,12 +12,23 @@ class PdfViewerHookProvider implements vscode.CustomReadonlyEditorProvider {
}
}

resolveCustomEditor(document: vscode.CustomDocument, webviewPanel: vscode.WebviewPanel) {
webviewPanel.onDidChangeViewState(e => { e.webviewPanel.dispose() })
if (document.uri === undefined || !document.uri.fsPath.toLocaleLowerCase().endsWith('.pdf')) {
return
async resolveCustomEditor(document: vscode.CustomDocument, webviewPanel: vscode.WebviewPanel) {
const configuration = vscode.workspace.getConfiguration('latex-workshop')
const viewerLocation = configuration.get<ViewerLocation>('view.pdf.viewer', 'tab')
if(viewerLocation === 'customEditor'){
webviewPanel.webview.options = {
...webviewPanel.webview.options,
enableScripts: true
}
const pdfPanel = await populatePdfViewerPanel(document.uri, webviewPanel)
void viewerManager.initiatePdfViewerPanel(pdfPanel)
} else{
ManuelHentschel marked this conversation as resolved.
Show resolved Hide resolved
webviewPanel.onDidChangeViewState(e => { e.webviewPanel.dispose() })
if (document.uri === undefined || !document.uri.fsPath.toLocaleLowerCase().endsWith('.pdf')) {
return
}
void lw.viewer.openPdfInTab(document.uri, 'current', false)
}
void lw.viewer.openPdfInTab(document.uri, 'current', false)
}
}

Expand Down
11 changes: 9 additions & 2 deletions src/components/viewerlib/pdfviewerpanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,23 @@ async function patchCodespaces(url: vscode.Uri) {
codespacesPatched = true
}

// Create a new vscode.WebviewPanel and in it a PdfViewerPanel
export async function createPdfViewerPanel(pdfUri: vscode.Uri, preserveFocus: boolean): Promise<PdfViewerPanel> {
await lw.server.serverStarted
const htmlContent = await getPDFViewerContent(pdfUri)
const panel = vscode.window.createWebviewPanel('latex-workshop-pdf', path.basename(pdfUri.path), {
viewColumn: vscode.ViewColumn.Active,
preserveFocus
}, {
enableScripts: true,
retainContextWhenHidden: true
})
const pdfPanel = await populatePdfViewerPanel(pdfUri, panel)
return pdfPanel
ManuelHentschel marked this conversation as resolved.
Show resolved Hide resolved
}

// Create a PdfViewerPanel inside an existing vscode.WebviewPanel
export async function populatePdfViewerPanel(pdfUri: vscode.Uri, panel: vscode.WebviewPanel): Promise<PdfViewerPanel>{
await lw.server.serverStarted
const htmlContent = await getPDFViewerContent(pdfUri)
panel.webview.html = htmlContent
const pdfPanel = new PdfViewerPanel(pdfUri, panel)
return pdfPanel
Expand Down