I have some experience with Jupyter Notebook tweaking, but not with JupyterLab.
Basically, I want to add a subset of commands to a side tab. Let's say I've registered the command "sample" under the heading "DTLA"
function addCommands(app: JupyterLab, tracker: ICommandPalette): void {
const category = 'DTLA';
let command = CommandIDs.sample;
app.commands.addCommand(command, {
label: 'sample',
execute: () => { console.log('hellow!'); }
});
tracker.addItem({ command, category })
}
/**
* The command IDs used by the application plugin.
*/
namespace CommandIDs {
export
const sample: string = 'application:sample';
}
https://imgur.com/pHlTCLZ
now i want to put it into its own sidebar tab, which i can create just fine.
/**
* Activate the extension.
*/
function activateext(
app: JupyterLab,
docmanager: IDocumentManager,
editorTracker: IEditorTracker,
restorer: ILayoutRestorer,
notebookTracker: INotebookTracker,
rendermime: IRenderMimeRegistry,
palette: ICommandPalette,
): IExt {
// Create the ext widget.
const ext = new Ext({docmanager, rendermime, palette});
// Create the ext registry.
const registry = new ExtRegistry();
//add commands
addCommands(app, palette);
// Add the ext to the left area.
ext.title.label = 'DTLA';
ext.id = 'table-of-contents';
app.shell.addToLeftArea(ext, {rank: 700});
// Add the ext widget to the application restorer.
restorer.add(ext, 'juputerlab-ext');
return registry;
}
export default extension;
https://imgur.com/a/bQhZNOe
so, how do i attach commands to the new sidebar?
Related
I've tried so many variations of this from code I found on github using the provideInlineCompletionItems function but cannot seem to get it to work. Is there something I am doing wrong?
const vscode = require('vscode');
function activate(context) {
const provider = {
provideInlineCompletionItems: async (document, position, context, token) => {
const txt = 'hi'
return [
{
text: txt,
insertText: txt,
range:new vscode.Range(position.translate(0, txt.length), position)
}
]
},
};
vscode.languages.registerInlineCompletionItemProvider({pattern: "**"}, provider);
}
exports.activate = activate;
function deactivate() {}
module.exports = {
activate,
deactivate
};
Even with https://github.com/microsoft/vscode/issues/125663 and "editor.inlineSuggest.enabled": true, set to true it doesn't work. I know inline suggestions works since I have github copilot, I just can't seem to get it to work. Copilot is also disabled so they don't interfere
I rollbacked a version of VSCode and it works now. this is the debug code I used.
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require('vscode');
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
/**
* #param {vscode.ExtensionContext} context
*/
function activate(context) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "seven" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
let disposable = vscode.commands.registerCommand('seven.helloWorld', function () {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
vscode.window.showInformationMessage('Hello World from seven!');
});
const provider = {
provideInlineCompletionItems: async (document, position, context, token) => {
const line = document.lineAt(position.line);
console.log("420")
if (line.text.startsWith('if')) {
console.log("421")
let range = line.range;
if (line.text.indexOf(";") !== -1) {
console.log("423")
range = new vscode.Range(range.start, range.end.with(undefined, line.text.indexOf(";") + 1));
}
console.log("424")
return [{ text: 'if (hello) {\n};', insertText: "if (hello)", range }];
}
}
};
vscode.languages.registerInlineCompletionItemProvider({ pattern: '**' }, provider);
context.subscriptions.push(disposable);
}
// This method is called when your extension is deactivated
function deactivate() {}
module.exports = {
activate,
deactivate
}
I'm trying to create a simple vscode extension that will insert some default text into a newly created file. What I want is for the vscode.workspace.createFileSystemWatcher to call a function that gets the activeTextEditor and writes to the new file. Here is what I've tried:
import * as vscode from "vscode";
export function activate(context: vscode.ExtensionContext) {
let disposable = vscode.commands.registerCommand(
"default-text-generator.generate",
() => {
function _watcherChangeApplied(editor?: vscode.TextEditor) {
if (editor) {
editor.edit((editBuilder) => {
editBuilder.insert(editor.selection.active, "Hello World");
});
}
}
const editor = vscode.window.activeTextEditor;
let uri: vscode.Uri | undefined = editor?.document.uri;
if (uri) {
let watcher = vscode.workspace.createFileSystemWatcher(
new vscode.RelativePattern(
vscode.workspace.getWorkspaceFolder(uri)!,
"**/*.ts"
),
false,
false,
false
);
watcher.onDidCreate(() => _watcherChangeApplied(editor));
}
}
);
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
export function deactivate(): void {
//deactivate
}
Here's what's happening. The editor seems to insert the text, then immediately gets overwritten back to a blank page. I can't seem to figure out why.
The problem happens because the editor you are referring to is not what you think to be. It is not the newly created editor but instead, the editor that you are focused/active when the new .ts file is created.
The FileSystemWatcher.onDidCreate event provides you a Uri to the newly created file inside your workspace, but not necessarily opened in VS Code. Try creating a file via terminal and you will see what I mean. The file is created, the event is fired, but no editor is opened in VS Code.
So, you won't be able to use the editor.edit API to manipulate the file. Instead, you should edit the file using RAW/Node functions. But, in this case, maybe/probably you will clash with the external tool that is creating the .ts file (which may not be VS Code, if you use the FileWatcher). If only files created via VS Code must be detected, you should change to the workspace.onDidCreateFiles event instead. But yet, it also only provides you the Uri, not the Editor.
Hope this helps
This works:
let disposable2 = vscode.commands.registerCommand('yourCommand.here', async (...file) => {
async function _watcherChangeApplied(uri) {
if (uri) {
const editor = await vscode.window.showTextDocument(uri);
editor.edit((editBuilder) => {
editBuilder.insert(editor.selection.active, "Hello World");
});
await editor.document.save();
}
}
const editor = vscode.window.activeTextEditor;
let uri = editor?.document.uri;
if (uri) {
let watcher = vscode.workspace.createFileSystemWatcher(
new vscode.RelativePattern(
vscode.workspace.getWorkspaceFolder(uri),
"**/*.ts"
),
false,
false,
false
);
// watcher.onDidCreate(() => _watcherChangeApplied(editor));
watcher.onDidCreate((uri) => _watcherChangeApplied(uri));
}
}
The key point is that watcher.onDidCreate() will return the uri of the newly created file. You can pass that to your _watcherChangeApplied(uri) function.
In _watcherChangeApplied(uri) you can show the created file via await vscode.window.showTextDocument(uri) and that function returns an editor that you can use with its edit functions.
The code works whether you create the file within vscode (like the New File... icon button at the top of the explorer) or via the terminal (like touch test.ts).
If you want to enable creating new files through the terminal, for example, and NOT open them, try this _watcherChangeApplied(uri):
async function _watcherChangeApplied(uri) {
if (uri) {
const document = await vscode.workspace.openTextDocument(uri);
const strToAdd = "Hello World";
const wse = new vscode.WorkspaceEdit();
wse.insert(uri, new vscode.Position(0,0), strToAdd);
await vscode.workspace.applyEdit(wse);
await document.save();
}
}
I want to insert some text at the cursor's position but I didn't find the required code at the API docs.
Is there any function that I could put the parameters within, which solves my problem? This is just for testing.
import * as vscode from 'vscode';
var fs = require('fs');
var flow = require('xml-flow');
var inFile = fs.createReadStream('./your-xml-file.xml');
var xmlStream = flow(inFile);
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "intrexx-js-lib" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
let disposable = vscode.commands.registerCommand('intrexx-js-lib.start', () => {
const editor = vscode.window.activeTextEditor;
if(!editor){
vscode.window.showErrorMessage("Editor does not exist!");
return;
}
if (editor.selection.isEmpty) {
const position:vscode.Position = editor.selection.active;
//vscode.window.showInformationMessage(`line: ${position.line} character: ${position.character}`);
}
});
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
export function deactivate() {}
Although rioV8's code works, if any text is selected it will overwrite that text. If you want to ensure that no text is deleted by the insert operation, use edit.insert instead. For rioV8's second example, that means doing this:
vscode.commands.registerTextEditorCommand('intrexx-js-lib.start', (editor, edit) => {
editor.selections.forEach((selection, i) => {
let text = "FooBar " + i;
edit.insert(selection.active, text); // insert at current cursor
})
});
Use a different command register function, it gives you a TextEditorEdit:
vscode.commands.registerTextEditorCommand('intrexx-js-lib.start', (editor, edit) => {
let text = "FooBar";
edit.replace(editor.selection, text);
});
For use with multiple cursors, you'll have to iterate over editor.selections:
vscode.commands.registerTextEditorCommand('intrexx-js-lib.start', (editor, edit) => {
editor.selections.forEach((selection, i) => {
let text = "FooBar " + i
edit.replace(selection, text)
})
});
According to the example of a Visual Studio Code extension (https://github.com/microsoft/vscode-extension-samples/tree/master/codelens-sample) it is possible to resolve code lens:
public resolveCodeLens(codeLens: vscode.CodeLens, token: vscode.CancellationToken) {
if (vscode.workspace.getConfiguration("codelens-sample").get("enableCodeLens", true)) {
codeLens.command = {
title: "Codelens provided by sample extension",
tooltip: "Tooltip provided by sample extension",
command: "codelens-sample.codelensAction",
arguments: ["Argument 1", false]
};
return codeLens;
}
return null;
}
The code lens displays next to a line of text in the editor window.
But it does not show any information dependant on the line.
I would like to pass the line of text to display in the codeLens command title. To create multiple custom messages.
How to provide a text "next" to codeLens displays to resolveCodeLens?
I had the same need to display line contextual information. Inspecting the constructor for CodeLens it accepts the command object in the second parameter.
Codelens constructor
here is a snippet based on my implementation to solve this:
provideCodeLenses(document, token) {
this.codeLenses = [];
const regex = new RegExp("^[156789].*$");
let lines = document.getText().split("\n");
lines.forEach((lineText, lineNumber) => {
if (regex.test(lineText)) {
const position = new vscode.Position(lineNumber, 0);
const range = new vscode.Range(position, position);
let command = {
command = "",
title = "<your custom title based on lineText>"
};
this.codeLenses.push(new vscode.CodeLens(range, command));
}
});
return this.codeLenses;
}
I'm developing a VSCode extension. Is it possible to automatically have the extension reloaded when I change its source. Currently, I need to press Ctrl + SHift + F5.
I guess your extension is written in TS/javascript, so you can use fs.watch to watch your sources, and find a way to run the vscode command workbench.action.reloadWindow, which is
from sources of vscode, the function ReloadWindowAction.Run() or directly windowService.reloadWindow().
export class ReloadWindowAction extends Action {
static readonly ID = 'workbench.action.reloadWindow';
static LABEL = nls.localize('reloadWindow', "Reload Window");
constructor(
id: string,
label: string,
#IWindowService private windowService: IWindowService
) {
super(id, label);
}
run(): TPromise<boolean> {
return this.windowService.reloadWindow().then(() => true);
}
}
It might be a tiny extension that connect those functions.