VS Code Extension: TreeItem command property how to issue vscode.open - visual-studio-code

I'd like to open a file when my treeView items are clicked (similar to how the default explorer opens a file). However, I'm stuck on implementing this feature. From my understanding, one way to implement this is to define the command property of the TreeItem type, as seen here. This link also says:
Please use vscode.open or vscode.diff as command IDs when the tree item is opening something in the editor. Using these commands ensures that the resulting editor will appear consistent with how other built-in trees open editors.
As seen here, vscode.open takes in some arguments, in particular it needs a uri of a text document. I'm very confused at how to pass that argument to this command in this manner. I tried:
class MyTreeItem extends TreeItem {
children: FunctionsTreeItem[]|undefined;
constructor(label: string, filePath: string, children?: FunctionsTreeItem[]) {
super(
label,
children === undefined ? TreeItemCollapsibleState.None :
TreeItemCollapsibleState.Expanded);
this.children = children;
this.command = {
title: "",
command: "vscode.open",
arguments: [{"uri": filePath}]
}
or with the arguments line modified to just [filePath]. Neither works. I'm not sure how to approach this.

I finally found an example from one of their issues. The code here gives a very good example.
So, the syntax is just this:
arguments: [Uri.file(filePath)]

Related

VsCode Extension custom CompletionItem disables built-in Intellisense

I am working on a VsCode extension in that I want to provide custom snippets for code completion.
I know about the option of using snippet json files directly, however those have the limitation of not being able to utilize the CompletionItemKind property that determines the icon next to the completion suggestion in the pop-up.
My issue:
If I implement a simple CompletionItemProvider like this:
context.subscriptions.push(
vscode.languages.registerCompletionItemProvider(
{scheme:"file",language:"MyLang"},
{
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
let item = new vscode.CompletionItem('test');
item.documentation = 'my test function';
item.kind = vscode.CompletionItemKind.Function;
return [item];
}
}
)
)
then the original VsCode IntelliSense text suggestions are not shown anymore, only my own. Should I just return a kind of an empty response, like
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
return [null|[]|undefined];
}
the suggestions appear again as they should. It seems to me that instead of merging the results of the built-in IntelliSense and my own provider, the built-in ones get simply overridden.
Question:
How can I keep the built-in IntelliSense suggestions while applying my own CompletionItems?
VsCode Version: v1.68.1 Ubuntu
I seem to have found the answer for my problem, so I will answer my question.
Multiple providers can be registered for a language. In that case providers are sorted
by their {#link languages.match score} and groups of equal score are sequentially asked for
completion items. The process stops when one or many providers of a group return a
result.
My provider seems to provide results that are just higher scored than those of IntelliSense.
Since I didn't provide any trigger characters, my CompletionItems were comteping directly with the words found by the built-in system by every single pressed key and won.My solution is to simply parse and register the words in my TextDocument myself and extend my provider results by them. I could probably just as well create and register a new CompletionItemProvider for them if I wanted to, however I decided to have a different structure for my project.

How to list all commands related to a specific extension in VS Code's command palette?

I'm writing an extension and I would like to know if there is a way to list all the commands that belong to my extension in the command palette.
I have added an item in the status bar that once clicked should ideally list all the commands available from my extension in the command palette, similar to when you click on the language, a list of languages shows up.
The closest thing I could get is this:
const statusBar = vscode.window.createStatusBarItem();
statusBar.text = 'Cloudflare';
statusBar.command = 'cloudflareDevTools.commands';
statusBar.show();
let commands = vscode.commands.registerCommand('cloudflareDevTools.commands', () => {
vscode.commands.executeCommand("workbench.action.quickOpen", ">Cloudflare");
});
Which results in this:
This way I'm basically filtering the commands in the command palette by providing a string that's part of the extension's name, and it kinda works as it shows all the commands from my extension, but you can see how it's not ideal in case multiple extensions have a similar name.
There's something similar when you go in the settings: you can provide #ext:kenhowardpdx.vscode-gist and this will list all the settings related to that specific extension. I would like something similar but for the commands I've registered in package.json and extension.js.
Thank you!
Not sure why I didn't think of this before. You can show a QuickPick, basically a mini-Command Palette, with only commands you have filtered.
const qpOptions = {title: "commands from the find-and-transform extension", canPickMany: false};
const allCommands = await vscode.commands.getCommands(true);
// filter by your extensionID
const findExtensionCommands = allCommands.filter(command => command.startsWith('find-and-transform'));
const selectedCommand = await vscode.window.showQuickPick(findExtensionCommands, qpOptions);
if (selectedCommand) {
// do whatever you are going to do if the user makes a selection, like
// vscode.commands.executeCommand(selectedCommand);
console.log(selectedCommand);
}
You can also make QuickPickItems out of the commands, so that you can add descriptions to them for example.

Recommended Way to get Proper Linting for Flow in VSCode?

I've read lots of discussions on here about how to setup VSCode to allow linting of Javascript files when // #flow is enabled at the top of the file.
I believe I've implemented things properly but am still getting mysterious errors that seem to indicate otherwise.
For example, I'm getting a Missing type annotation for destructuring.Flow(InferError) for classes here:
const AddCustomer = ({ classes }) => {
So I changed it to this:
const AddCustomer = ({ classes:any }) => {
but the error persisted.
Here is another observation of the way things are working in my VSCode at the moment:
export const useFetch = (initialUrl, initialData) => {
With this code I get warnings that the two parameters are not typed. So I changed the code to this:
export const useFetch = (initialUrl:string, initialData:any) => {
Nothing happened immediately but when I saved the file then the warnings went away. Not a biggie but that's not the way I expect linters to work.
Might anyone have any thoughts on why #flow linting is not quite working correctly in my VSCode?
So, for the first issue regarding Missing type annotation for destructuring.Flow(InferError), I believe the type is placed in the wrong place. The syntax ({ classes: any }) is renaming the classes property on the first parameter to any. A more thorough explanation can be read in MDN's page Destructuring assignment. To correctly specify the type of the object parameter, you will want to place the type definition after the object
const addCustomer = ({ classes }: { classes: any }) => { ... };
This may feel verbose and repetitive, but the idea is to separate the code from the types. For example, the type definition of a customer may be imported from another file, so the code would look more like
// types.js
export type Customer = { classes: any };
// index.js
import type { Customer } from './types';
const addCustomer = ({ classes }: Customer) => { ... };
This allows the parameter to be specified in any way (e.g., without destructuring) and the type to be specified in any way.
For your second issue, check to make sure that the setting flow.runOnEdit is set to true. This will allow Flow to check your files without saving. If that does not seem to fix the problem, then I would raise an issue with the maintainers of the VSCode extension.

Making vscode snippets only trigger after specific characters

Let's say I have a bunch of functions below:
library.object1.function1()
library.object1.function2()
library.object2.function1()
library.object2.function2()
library.object3.function1()
library.object3.function2()
With what they provide in current custom snippet, when I type lib, it will show all those above functions, which will be a mess if there are too many functions.
I want to make my snippets work like what they did in default code completion:
When I type lib, it only shows:
library
When I type library., it shows:
object1
object2
object3
When I type library.object1., it shows
function1()
function2()
Also, if I type lib, and leave it there, then comeback and add rary, the snippet doesn't work at all, I want it to continue the completion.
Is there a way to achieve it?
I think the closest you can get is something like this (using javascript.json snippet file as an example):
"my library": {
"prefix": "lib",
"body": [
"library.${1|object1,object2,object3|}.${2|function1,function2,function3,function4|}()",
],
"description": "my library functions"
}
With that, when you type lib you get only the library suggested completion. Tab and you will get all the object choices you included in the snippet in the suggestion panel. Tab again and will get the function options that you listed in the snippet.
See snippet choices.

How to support powershell tab expansion in psprovider?

I'm implementing Powershell PSProvider for some internal hierarchical data. Everything works fine, I can navigate through the tree with usual cd/dir commands, the only thing doesn't work is tab completion.
What I can see is that Powershell calls function GetChildName() with an asterisk in the path when Tab is pressed (if I type "dir c" and press Tab, GetChildName() function will be called with string "c*", several times). I tried to return all child names from the folder that begins with "c", but Powershell always displays just the first child name in the front. I can't find any documentation about this behavior, what I'm missing?
Are you sure you aren't just seeing normal behavior? With the default Tab Expansion, you will only see the first result. Pressing tab additional times will cycle through the list of returned results from the provider.
There are some quirks with providers. I have been working on one using the Script Provider project. I put debug code in all my methods to see which ones PowerShell was calling, when, and with what arguments.
I found where's the problem - function GetChildName() in the provider shouldn't try to expand given file name if asterisk is part of the name; The function should return child name if it can find an exact match, or call base.GetChildName() in any other case. Something like this:
protected override string GetChildName(string path) {
string name = SomeFunctionThatTriesToFindExactMatchForGivenPath(path);
if(string.IsNullOrEmpty( ret ) )
ret = base.GetChildName( path );
return ret;
}
BTW, I found that default tab expansion is very forgiving about stuff that can be returned from GetChildName() function - even if return value have slash/backslash in the front/back, tab expansion will work. But PowerTab, popular tab expansion module, is much more picky about return values.