How to order inline view toolbar icons? - visual-studio-code

In my authoring of a VS Code extension, I'd like to have "+" icon shown to the right of refresh icon. However, the ordering in the package.json does not seem to represent the order rendered. I always get the add icon to the left of refresh icon.
Here is a snippet of the view definition:
{
"commands": [
{
"command": "refresh-jobs",
"title": "Refresh",
"icon": {
"light": "resources/light/refresh.svg",
"dark": "resources/dark/refresh.svg"
}
},
{
"command": "add-job",
"title": "Add",
"icon": {
"light": "resources/light/add.svg",
"dark": "resources/dark/add.svg"
}
},
],
...
"view/item/context": [
{
"command": "refresh-jobs",
"group": "inline",
"when": "viewItem == jobgroup"
},
{
"command": "add-job",
"group": "inline",
"when": "viewItem == jobgroup"
},
]
}
Any help? Thanks!

I found this old issue: Add custom ordering to title menu items. which suggest doing something like:
There is way to define the order and I am surprised we haven't
properly documented that... What you can do is adding an order to the
group-attribute like so group: name#number. In your case
{
"command": "md-shortcut.toggleBold",
"when": "editorLangId == 'markdown'",
"group": "2_markdown_1#1"
}
I see it here: menu example The #n syntax is used there to order menu entries but the issue I cited above seems to imply that it will also order icons in a title bar. Try this:
"view/item/context": [
{
"command": "refresh-jobs",
"group": "inline#1",
"when": "viewItem == jobgroup"
},
{
"command": "add-job",
"group": "inline#2",
"when": "viewItem == jobgroup"
},
]
"group": "inline#1", note the #1
Let me know if it works for you.

Related

Prevent asynchronous order of command sequence execution in VS Codium

How can I control the execution order of multiCommand extension? It behaves like it executes them in parallel, while I want them to be executed one after another.
I have a project with the following structure:
/home/user/myproject/dir1/problem1.py
/home/user/myproject/dir1/problem1.txt
/home/user/myproject/dir1/problem2.py
/home/user/myproject/dir1/problem2.txt
...
/home/user/myproject/pointer.txt
The pointer.txt contains the text: dir1/problem2.
I want to press a shortcut, and do a sequence of actions:
Create next problem files pair
Modify a pointer.txt to point to new files
Open them in the editor
I setuped the following things.
In settings.json I defined the command sequence named "openPointedProblemLayout" (for being able to easily reuse it):
"multiCommand.commands": [
{
"command": "multiCommand.openPointedProblemLayout",
"sequence": [
{ "command": "htmlRelatedLinks.openFile",
"args": {
"file": "${command:mypointer}.py",
"method": "vscode.open",
"viewColumn": 1,
"command": {
"mypointer": {
"command": "extension.commandvariable.file.content",
"args": {
"fileName": "${workspaceFolder}/pointer.txt"
}
}
}
}
},
{ "command": "htmlRelatedLinks.openFile",
"args": {
"file": "${command:mypointer}.txt",
"method": "vscode.open",
"viewColumn": 2,
"command": {
"mypointer": {
"command": "extension.commandvariable.file.content",
"args": {
"fileName": "${workspaceFolder}/pointer.txt"
}
}
}
}
},
]
},
]
In tasks.json I created a shell command definition, that creates a new .py and .txt pair and also changes the pointer:
{
"version": "2.0.0",
"tasks": [
{
"label": "create_new_problem_files_pair",
"type": "shell",
"command": "python /home/user/scripts/create_new_problem_files_pair.py \"${file}\""
},
],
}
In keybindings.json I defined shortcut numpad2 that executes both actions (creates files and opens them) and a numpad5 (just opens them):
{
"key": "numpad2",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
{
"command": "workbench.action.tasks.runTask",
"args": "create_new_problem_files_pair"
},
{
"command": "multiCommand.openPointedProblemLayout"
},
]
}
},
{
"key": "numpad5",
"command": "extension.multiCommand.execute",
"args": { "command": "multiCommand.openPointedProblemLayout" },
},
Now, when I press numpad2, the two new files are created:
/home/user/myproject/dir1/problem3.py
/home/user/myproject/dir1/problem3.txt
And then two files are opened in layout (means the command actually runs), but wrong files. They are problem2.py and problem2.txt, i.e. the previous pointer is used.
I checked the content of the pointer.txt now, and it actually contains dir1/problem3. And when I press numpad5, they are opened correctly.
Why does the VS Codium uses previous content of pointer, while at the moment of command run, it should already take the new content? It looks like VS Code executes the command sequence in parallel, instead of sequence them.
Am I doing something wrong? Is that an issue with configuration or vs code itself or maybe in multiCommand extension?
I have solved the problem by avoiding usage of any extensions. A command sequence can be defined via Tasks. See https://stackoverflow.com/a/72201981/7869636
In keybindings.json I define:
{
"key": "numpad2",
"command": "workbench.action.tasks.runTask",
"args": "create_new_problem_files_pair_and_open_file_pair_in_layout"
},
And in tasks.json I defined the whole things:
{
"version": "2.0.0",
"tasks": [
{
"label": "create_new_problem_files_pair",
"type": "shell",
"command": "python /home/user/scripts/create_new_problem_files_pair.py \"${file}\""
},
{
"label": "open_file_pair_in_layout",
"dependsOrder": "sequence",
"dependsOn": [
"open_in_layout_left",
"open_in_layout_right",
],
},
{
"label": "create_new_problem_files_pair_and_open_file_pair_in_layout",
"dependsOrder": "sequence",
"dependsOn": [
"create_new_problem_files_pair",
"open_file_pair_in_layout",
],
},
{
"label": "open_in_layout_left",
"command": "${input:open_in_layout_left}",
},
{
"label": "open_in_layout_right",
"command": "${input:open_in_layout_right}",
},
],
"inputs": [
{
"id": "open_in_layout_left",
"type": "command",
"command": "htmlRelatedLinks.openFile",
"args": {
"file": "${command:mypointer}.py",
"method": "vscode.open",
"viewColumn": 1,
"command": {
"mypointer": {
"command": "extension.commandvariable.file.content",
"args": {
"fileName": "${workspaceFolder}/pointer.txt"
}
}
}
}
},
{
"id": "open_in_layout_right",
"type": "command",
"command": "htmlRelatedLinks.openFile",
"args": {
"file": "${command:mypointer}.txt",
"method": "vscode.open",
"viewColumn": 2,
"command": {
"mypointer": {
"command": "extension.commandvariable.file.content",
"args": {
"fileName": "${workspaceFolder}/pointer.txt"
}
}
}
}
}
]
}
This approach has a benefit that it defines these tasks in a scope of that project's workspace, and not globally in setting.json.

Unable to create menu with contributes.menu

I am unable to create a menu using the documentation at the link below for contributes.menu. Actually, I was able to create one menu item, but could not create a second one. The code excerpt is from my package.json on Windows 10 using VS Code 1.37.0.
So my question is, can someone show me an example of adding two menu items?
-TIA
"contributes": {
"menus": {
"editor/title": [{
"title": "Underline Text",
"when": "editorHasSelection",
"command": "macros.underline",
"alt": "markdown.showPreviewToSide",
"group": "MyGroup#1"
}]
},
"languages": [
https://code.visualstudio.com/api/references/contribution-points#contributes.menus
Already tried the above code.
Here is an example package.json, based on the one in the tutorial, that creates two menu items:
{
...
"activationEvents": [
"onCommand:extension.helloWorld",
"onCommand:extension.helloAnotherWorld"
],
"contributes": {
"commands": [
{
"command": "extension.helloWorld",
"title": "Hello World"
},
{
"command": "extension.helloAnotherWorld",
"title": "Hello Another World"
}
],
"menus": {
"editor/title/context": [
{
"command": "extension.helloWorld"
},
{
"command": "extension.helloAnotherWorld"
}
]
}
},
...
}

How do I hide a command in the palette menu from my extension in VS Code

I am building a VS Code extension starting from this page. Now I want to hide in the palette menu the command extension.timerStart after I run it. I have read this page, didn't helped. I have the code bellow for package.json. How do I make the varFromMyExtension===false part work?
"contributes": {
"commands": [
{
"command": "extension.timerStart",
"title": "Timer Start"
}
],
"menus": {
"commandPalette": [
{
"command": "extension.timerStart",
"when": "varFromMyExtension===false"
}
]
}
I think it is not possible to access variables from your extension directly in a when clause. However you can access any configuration of the settings.json.
From the docs (at the bottom of the chapter):
Note: You can use any user or workspace setting that evaluates to a boolean here with the prefix "config.".
So when your extension contributes a boolean configuration called varFromMyExtension you should be able to use it in the when clause. This configuration then can be manipulated programmatically, too.
So your package.json would probably contain something like this (not tested):
"contributes": {
"commands": [
{
"command": "extension.timerStart",
"title": "Timer Start"
}
],
"menus": {
"commandPalette": [
{
"command": "extension.timerStart",
"when": "!config.myextension.varFromMyExtension"
}
]
},
"configuration": {
"type": "object",
"title": "Indicates whether ...",
"properties": {
"myextension.varFromMyExtension": {
"title": "My title.",
"description": "My description",
"type": "boolean",
"default": false,
"pattern": "(true|false)"
}
}
}
}
But bare in mind that the user can see and edit this setting, too.

How to bind one key to multiple commands in VSCode

I'm trying to make the key Ctrl+UpArrow execute both commands
cursorUp and
scrollLineUp.
I was hoping that this would work, but it doesn't:
{
"key": "ctrl+up",
"command": ["cursorUp", "scrollLineUp"], // This doesn't work
"when": "editorTextFocus"
}
How do I do that in VSCode?
This is currently not possible, but the corresponding feature request is tracked here. However you should take a look to the macros extension. It enables you to chain different commands to a single custom command. This custom command then can be bound to a hotkey.
In your case you could add this to your settings.json:
"macros": {
"myCustomCommand": [
"cursorUp",
"scrollLineUp"
]
}
And then add your custom hotkey to the keybindings.json:
{
"key": "ctrl+up",
"command": "macros.myCustomCommand"
}
There's a new way to achieve this without an extension:
Run "Tasks: Open User Tasks" command to create or open a user level tasks file.
Define commands as separate tasks, like so:
{
"version": "2.0.0",
"tasks": [
{
"label": "ctrlUp1",
"command": "${command:cursorUp}"
},
{
"label": "ctrlUp2",
"command": "${command:scrollLineUp}"
},
{
"label": "ctrlUpAll",
"dependsOrder": "sequence",
"dependsOn": [
"ctrlUp1",
"ctrlUp2"
],
"problemMatcher": []
}
]
}
In your keybindings.json:
{
"key": "ctrl+up",
"command": "workbench.action.tasks.runTask",
"args": "ctrlUpAll",
"when": "editorTextFocus"
}
("ctrlUpNNN" label format chosen for readability, task labels can be anything).

Can i pass arguments to command in contributes block?

I would like to reusing command with some arguments.
I found key binding can do this with "args" property:
{
"key": "cmd+k 8",
"command": "editor.action.insertSnippet",
"when": "resourceLangId == 'markdown'",
"args": {
"name": "Insert bold text"
}
}
so i try to write my package.json/contributes/menus in a similar way and it didnt work:
"commands": [
{
"command": "extension.sayHello",
"title": "Say Hello"
}
],
"menus": {
"editor/context": [
{
//menu one
"command": "extension.sayHello",
"group": "navigation#1",
"args": {
"text": "Say Hello 1!"
}
},
{
//menu two
"command": "extension.sayHello",
"group": "navigation#2",
"args": {
"text": "Say Hello 2!"
}
}
]
}
I would like to pass "text" to command handler function.
Are there any feature to archive similar result?
This is an old question, founded it on Github firstly, but i wanted to share some info that i actually founded within many resources and code-analysis:
So, even now, in a date when i writing it down here, there is still no normal way for making it in package.json... Like, at all...
But, by looking at some other extensions, i see that some of them are actually founded another way for making it working:
To do this, we need to look at the vscode.commands.registerCommand command.
function commands.registerCommand(command: string, callback: (...args: any[]) => any, thisArg?: any): vscode.Disposable
That means, we can use third parameter to actually send some data.
As an example:
package.json:
"contributes": {
...
"menus": {
"view/title": [
{
"command": "extension.addEntryOne",
"when": "view == extension",
"group": "navigation"
},
{
"command": "extension.addEntryTwo",
"when": "view == extension2",
"group": "navigation"
}
]
},
"commands": [
{
"command": "extension.addEntryOne",
"title": "Add entry One",
"icon":"$(diff-insert)"
},
{
"command": "remospace.addEntryTwo",
"title": "Add entry Two",
"icon":"$(diff-insert)"
}
]
...
}
extension.ts:
//
//Activation part before
//
let Execution = function(this: any){
console.log(this)
}
let entryOne = vscode.commands.registerCommand('extension.addEntryOne', Execution,{from:'one'});
let entryTwo = vscode.commands.registerCommand('remospace.addEntryTwo', Execution,{from:'one'});
context.subscriptions.push(entryOne,entryTwo);
In this case, we can bypass issue when we need to do same thing with different args. Yes, this may not be the best solution to do it, but at least this is one of it.