Overview
Opening this issue up as a discussion point for the current work around notebook formatting. As a way to accomplish this without the introduction of new API, the thought is to introduce a new Code Action Kind notebook.format.extensionID. Looping in some relevant notebook formatting people.
cc: @rebornix @karthiknadig @charliermarsh
Proposed Plan
- Extension authors will provide a Code Action that wraps all of their formatting into a single action, with the kind
notebook.format.xyz
- We recommend that the
xyz is unique to your extension, but this is not a restriction
- We require that you have a complete
DocumentFilter that contains notebookType
- Only one formatting Code Action will be used against the notebook.
- If more than one extension registers a provider for this type, users will be prompted to choose between them and define a setting
"notebook.defaultFormatter": "extensionID" (mirrors the editor setting)
- If an extension registers multiple
notebook.format.xyz providers, only the first will be used.
- If a
notebook.format Code Action is applied on save, the standard provideDocumentFormatting flow will be skipped
- The
notebook.format Code Action can be applied in the following ways:
- Setting
"notebook.formatOnSave.enabled": true (this means that there will only be explicit triggering of this for saves, due to formatOnSave requiring the file to NOT be saved after a delay)
- Command palette
Format Notebook
- Notebook Context Menu (🔜)
Rough Example
export async function activate(context: vscode.ExtensionContext) {
registerCodeActionsProvider(DocumentFilter, new ProviderName(), providedKinds);
}
class ProviderName {
static readonly kind = "notebook.format.extensionID";
public provideCodeActions(
document: vscode.TextDocument,
_range: vscode.Range | vscode.Selection,
_context: vscode.CodeActionContext,
_token: vscode.CancellationToken
): vscode.CodeAction[] | undefined {
const nbEdits: NotebookEdit[] | TextEdit[] = {
// wrap all formatting edits here
}
const fix = new vscode.CodeAction(
'Apply Notebook Formatting',
ProviderName.kind,
);
fix.edit = new vscode.WorkspaceEdit();
fix.edit.set(notebookDocument.uri, nbEdits);
return [fix];
}
}
{
"notebook.defaultFormatter": "extensionID", // extensionID
"notebook.formatOnSave.enabled": true,
"notebook.codeActionsOnSave": { // these will occur BEFORE the formatter
"source.xyz": "explicit",
}
}
Other relevant notes
- Code Action Kind prefix rules
- Code Action Providers that return a kind prefixed with
notebook. will only ever be called against the 0th cell of the notebook. Additionally, the provided TextDocument will always correspond to the 0th cell in the notebook and contain a uri that can retrieve the notebook. It is the responsibility of the provider to extract the NotebookDocument from this (an example will be provided in a sample extension, coming 🔜).
- If a Code Action is added to settings under
notebook.codeActionsOnSave without the notebook. prefix, the codeaction will be applied to every valid cell asynchronously, in parallel.
- Using
NotebookEdit.replaceCells() is less performant than simply using TextEdit.replace() against that document. Additionally, using NotebookEdit.replaceCells() will fully replace cells, including output. When possible, use TextEdits for editing just the content of a cell.
Questions
- Feel free to leave any and all thoughts below 👍
Overview
Opening this issue up as a discussion point for the current work around notebook formatting. As a way to accomplish this without the introduction of new API, the thought is to introduce a new Code Action Kind
notebook.format.extensionID. Looping in some relevant notebook formatting people.cc: @rebornix @karthiknadig @charliermarsh
Proposed Plan
notebook.format.xyzxyzis unique to your extension, but this is not a restrictionDocumentFilterthat containsnotebookType"notebook.defaultFormatter": "extensionID"(mirrors the editor setting)notebook.format.xyzproviders, only the first will be used.notebook.formatCode Action is applied on save, the standardprovideDocumentFormattingflow will be skippednotebook.formatCode Action can be applied in the following ways:"notebook.formatOnSave.enabled": true(this means that there will only be explicit triggering of this for saves, due toformatOnSaverequiring the file to NOT be saved after a delay)Format NotebookRough Example
settings.json:Other relevant notes
notebook.will only ever be called against the 0th cell of the notebook. Additionally, the providedTextDocumentwill always correspond to the 0th cell in the notebook and contain aurithat can retrieve the notebook. It is the responsibility of the provider to extract theNotebookDocumentfrom this (an example will be provided in a sample extension, coming 🔜).notebook.codeActionsOnSavewithout thenotebook.prefix, the codeaction will be applied to every valid cell asynchronously, in parallel.NotebookEdit.replaceCells()is less performant than simply usingTextEdit.replace()against that document. Additionally, usingNotebookEdit.replaceCells()will fully replace cells, including output. When possible, useTextEditsfor editing just the content of a cell.Questions