support vscode.dev link generation in notebook editor (#154183)

* support vscode.dev link generation in notebook editor

* Update comments.
This commit is contained in:
Peng Lyu 2022-07-06 08:53:12 -07:00 committed by GitHub
parent 6624aea0d0
commit f9f353c90b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 6 deletions

View file

@ -22,14 +22,50 @@ export function getRepositoryForFile(gitAPI: GitAPI, file: vscode.Uri): Reposito
return undefined;
}
function getFileAndPosition(): { uri: vscode.Uri | undefined; range: vscode.Range | undefined } {
enum LinkType {
File = 1,
Notebook = 2
}
interface IFilePosition {
type: LinkType.File;
uri: vscode.Uri;
range: vscode.Range | undefined;
}
interface INotebookPosition {
type: LinkType.Notebook;
uri: vscode.Uri;
cellIndex: number;
range: vscode.Range | undefined;
}
function getFileAndPosition(): IFilePosition | INotebookPosition | undefined {
let uri: vscode.Uri | undefined;
let range: vscode.Range | undefined;
if (vscode.window.activeTextEditor) {
uri = vscode.window.activeTextEditor.document.uri;
range = vscode.window.activeTextEditor.selection;
if (uri.scheme === 'vscode-notebook-cell' && vscode.window.activeNotebookEditor?.notebook.uri.fsPath === uri.fsPath) {
// if the active editor is a notebook editor and the focus is inside any a cell text editor
// generate deep link for text selection for the notebook cell.
const cell = vscode.window.activeNotebookEditor.notebook.getCells().find(cell => cell.document.uri.fragment === uri?.fragment);
const cellIndex = cell?.index ?? vscode.window.activeNotebookEditor.selection.start;
const range = cell !== undefined ? vscode.window.activeTextEditor.selection : undefined;
return { type: LinkType.Notebook, uri, cellIndex, range };
} else {
// the active editor is a text editor
range = vscode.window.activeTextEditor.selection;
return { type: LinkType.File, uri, range };
}
}
return { uri, range };
if (vscode.window.activeNotebookEditor) {
// if the active editor is a notebook editor but the focus is not inside any cell text editor, generate deep link for the cell selection in the notebook document.
return { type: LinkType.Notebook, uri: vscode.window.activeNotebookEditor.notebook.uri, cellIndex: vscode.window.activeNotebookEditor.selection.start, range: undefined };
}
return undefined;
}
function rangeString(range: vscode.Range | undefined) {
@ -43,9 +79,30 @@ function rangeString(range: vscode.Range | undefined) {
return hash;
}
export function notebookCellRangeString(index: number | undefined, range: vscode.Range | undefined) {
if (index === undefined) {
return '';
}
if (!range) {
return `#C${index + 1}`;
}
let hash = `#C${index + 1}:L${range.start.line + 1}`;
if (range.start.line !== range.end.line) {
hash += `-L${range.end.line + 1}`;
}
return hash;
}
export function getPermalink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?: string): string | undefined {
hostPrefix = hostPrefix ?? 'https://github.com';
const { uri, range } = getFileAndPosition();
const fileAndPosition = getFileAndPosition();
if (!fileAndPosition) {
return;
}
const uri = fileAndPosition.uri;
// Use the first repo if we cannot determine a repo from the uri.
const gitRepo = (uri ? getRepositoryForFile(gitAPI, uri) : gitAPI.repositories[0]) ?? gitAPI.repositories[0];
if (!gitRepo) {
@ -69,7 +126,9 @@ export function getPermalink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?:
}
const commitHash = gitRepo.state.HEAD?.commit;
const fileSegments = (useSelection && uri) ? `${uri.path.substring(gitRepo.rootUri.path.length)}${rangeString(range)}` : '';
const fileSegments = fileAndPosition.type === LinkType.File
? (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${rangeString(fileAndPosition.range)}` : '')
: (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${notebookCellRangeString(fileAndPosition.cellIndex, fileAndPosition.range)}` : '');
return `${hostPrefix}/${repo.owner}/${repo.repo}/blob/${commitHash
}${fileSegments}`;

View file

@ -42,7 +42,8 @@ export const enum CellToolbarOrder {
export const enum CellOverflowToolbarGroups {
Copy = '1_copy',
Insert = '2_insert',
Edit = '3_edit'
Edit = '3_edit',
Share = '4_share'
}
export interface INotebookActionContext {
@ -427,3 +428,9 @@ MenuRegistry.appendMenuItem(MenuId.EditorContext, {
group: CellOverflowToolbarGroups.Insert,
when: NOTEBOOK_EDITOR_FOCUSED
});
MenuRegistry.appendMenuItem(MenuId.NotebookCellTitle, {
title: localize('miShare', "Share"),
submenu: MenuId.EditorContextShare,
group: CellOverflowToolbarGroups.Share
});