Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lift setContext from a command to proper API #10471

Open
farfromrefug opened this issue Aug 12, 2016 · 39 comments
Open

Lift setContext from a command to proper API #10471

farfromrefug opened this issue Aug 12, 2016 · 39 comments
Labels
api context-keys feature-request Request for new features or functionality
Milestone

Comments

@farfromrefug
Copy link

This would be very useful to activate extension build feature per project type.
would help for this issue

@jrieken
Copy link
Member

jrieken commented Aug 12, 2016

Like so ..., command: "xyz", when: "workspaceConatins:foo.txt"?

@farfromrefug What exactly do you want to achieve with that?

@farfromrefug
Copy link
Author

Yes exactly like that.

That's actually the only way to trigger a special build defined in an extension (see the linked issue).
An extension cannot define a new task builder. So i you want to trigger, let's say, a cordova build on cmd+b but the default task in non cordova projects, that would be the only way

@alexdima
Copy link
Member

@farfromrefug Your extension could activate on workspaceConatins:foo.txt and then invoke the command setContext:

vscode.commands.executeCommand('setContext', 'inCordovaProject', true);

and then you can use "when": "inCordovaProject".

@jrieken Now that there are more use-cases than vim, should we consider lifting setContext to a proper API method?

@jrieken
Copy link
Member

jrieken commented Aug 15, 2016

I like. Maybe something similar to how we have it internally, like

interface ContextKey<V> {
  key: string;
  value: V;
}

function createContextKey<V>('name'):ContextKey<V>;

I'll let it cook for a little

@jrieken jrieken closed this as completed Aug 15, 2016
@jrieken jrieken reopened this Aug 15, 2016
@alexdima alexdima added the api label Aug 15, 2016
@jrieken jrieken added the feature-request Request for new features or functionality label Aug 15, 2016
@farfromrefug
Copy link
Author

farfromrefug commented Aug 15, 2016

@alexandrudima i love that. Does it already works (i don't see this in the cordova plugin)?
Do i have to "unset it"?

@alexdima
Copy link
Member

@farfromrefug You can create an issue in the cordova extension repo and introduce them to the problem and provide them with the recommendation.

@farfromrefug
Copy link
Author

@alexandrudima it s not an issue. I was just wondering if that API was already existing. And i was talking of cordova as an example.
Thahnks will try it

@alexdima
Copy link
Member

vscode.commands.executeCommand('setContext', 'inCordovaProject', true); works today. It is a "sort-of-hidden" API that we introduced for vim extensions in particular. We did not want to make it a top level API concept until we found more use-cases, so having found more use-cases, we are now considering making it a top level API concept, as @jrieken suggests, perhaps via a createContextKey method. We will keep this issue around to track this work.

@farfromrefug
Copy link
Author

@alexandrudima i can confirm that it works!
BTW I have a lot of questions concerning extension dev. My extension is doing some wrong things in VSCode, where can i ask questions?
Thanks

@alexdima
Copy link
Member

Usually we direct questions to Stack Overflow. You can also open issues if you feel you're running into something that looks like a bug, but each issue should be self-contained. We also have some issues that come in which are in fact questions.

TL;DR Stack Overflow preferably, otherwise issues

@farfromrefug
Copy link
Author

@alexandrudima i wont create issues though it might be bug related. I am not sure what's the cause yet.
Thanks

@alexdima alexdima changed the title [FR] keybindings allow workspaceContains in when Lift setContext from a command to proper API Aug 29, 2016
@alexdima alexdima removed their assignment Aug 29, 2016
@rebornix
Copy link
Member

rebornix commented Nov 1, 2016

@alexandrudima from my experience in handling keybindings in Vim, the need for lifting it to API is because we only support limited context key type https://github.com/Microsoft/vscode/blob/c67ef57cda90b5f28499646f7cc94e8dcc5b0586/src/vs/platform/contextkey/common/contextkey.ts which makes keybindings contribution doesn't always meet our need.

For example, we have quite a few Vim commands implemented in our ext and ppl always come and say, hey we want to use these Vim commands and for others, we prefer Code's. In this case, a single context key to enable/disable all Vim keybinds is not enough.

Is there any possibility that we support objects instead of just booleans for context keys then we can write below code to implement whatever we want

vscode.commands.executeCommand('setContext', 'vim.keys', {esc: true, ctrld:false})


{
  "key": "Escape",
  "command": "extension.vim_escape",
  "when": "editorTextFocus && !inDebugRepl && vim.keys.esc"
}

@alexdima
Copy link
Member

alexdima commented Nov 7, 2016

@rebornix You raise a good point, but IMHO this should not be tackled with options that then pollute the keybindings. All these users can today, without any code change in vscode or in the vim extension, customize their keybindings 100%. They just need to go to their keybindings.json and write rules and IMHO that should be our de-facto answer. Introducing an option that disables a keybinding is IMHO a clutch offered to end-users that don't want to open their keybindings.json file. Also, the same users will come back in one month time and ask for a new option and so on, when we could try to educate them and let them run wild :).

For your case, the end user would need to write the following in their keybindings.json file:

{ "command": "-extension.vim_escape" }

Maybe not as easy as an option, but then that is a separate bug, that our keybindings UI is non existant.

But I agree, there is a real problem here. I install an extension and all of a sudden I need to add all these rules with { "command": "-extension.vim_escape" } to remove those keybindings. Not nice. IMHO we should tackle that by adding the possibility to disable a certain contribution point from a certain extension (think of a more fine-grained "disable extension", where instead of disabling the entire extension, you'd just disable a contribution point of an extension).

@rebornix
Copy link
Member

rebornix commented Nov 7, 2016

@alexandrudima I love your proposal here. A contribution point level enable/disable makes it possible to choose a specific command for a particular key combination. A concrete example is when you install Resharper on Visual Studio, you get a chance to decide which command you want to use for any keycap you press. We can make it happen in Code by enabling a contribution for one extension and disabling all others for a single key combination :)

@hoovercj
Copy link
Member

hoovercj commented Apr 5, 2017

Is this documented anywhere yet?

@jrieken
Copy link
Member

jrieken commented Apr 5, 2017

only in this issue

@jrieken
Copy link
Member

jrieken commented Apr 24, 2017

Moving this issue to the next milestone. It's not clear to me now we bring this to the API given that there are actually different contexts active and that extensions might want to utilise that

@jrieken jrieken added this to the May 2017 milestone Apr 24, 2017
pokey added a commit to pokey/vscode that referenced this issue Mar 11, 2021
In parallel to `setContext`.  This PR partially solves microsoft#10471
@pokey
Copy link
Contributor

pokey commented Mar 15, 2021

Fwiw #118722 would provide getContext

@miketalley
Copy link

miketalley commented Nov 17, 2022

One more thing to think about with this API is how to allow string interpolation of context variable string values within package.json contributes definitions. For example, something like this would be great...

// Somewhere in activate
const itemsFilePath = '/some/file/path.yml';
vscode.commands.executeCommand(
  'setContext',
  'ext.itemsFilePath',
  itemsFilePath
);

// In package.json
{
  "id": "ext.treedata.items",
  "name": "Items - File Location: ${context:ext.itemsFilePath}",
  "when": "ext.itemsFilePath"
}

@wszgrcy
Copy link

wszgrcy commented Oct 3, 2023

CompletionItem can set snippet and run command ,but it can't run comand after all input finished.
eg: snippet console.log('${1/(.*)/${1:/upcase}/, I want to run command after $1 input and tab to format.
so I want to get context inSnippetMode. Judge that the completion has been completed

@ArturoDent
Copy link

I would like to see getContext() as well for an extension I wrote. It would read the key editorReadonly which is set/unset by a user with the session read-only commands.

I could keep track of the state myself "perhaps", but that seems a shame if the key already exists for each editor.

@mltony
Copy link
Contributor

mltony commented Mar 25, 2024

+1 for getContext API call. I am writing screenreader accessibility extension for VSCode and I need to figure out whether cursor is in the main text editor - as opposed to panes like debug or explorer pane. It appears current extension API doesn't have a way to figure that out.

@kosirm
Copy link

kosirm commented Mar 27, 2024

+1 , it would be great if I could use Memento directly from webview withouth passing messages.

@geekley
Copy link

geekley commented Apr 25, 2024

+1 for getContext API.
It would allow some interoperability with other extensions that use setContext, without depending on them explicitly making an API to be consumed by other extensions.
For example, if they set some state as myExtension.state.isConnected = true, another would be able to check for that value and provide better interoperability (e.g. redirecting to a feature on the other extension only when its state will allow it to work).

@Citrullin
Copy link

Please. How is this not a thing yet?

@Zitrooone
Copy link

Zitrooone commented Jun 19, 2024

+1 for getContext API.
I am desperate for this to be implemented. I'm working on an extension using a webview where I want to extend the context menu. Following the official docs and guidelines, I am supposed to work with contribution points to achieve that (add a command and a context menu entry pointing to that command).
My problem is that I cannot pass the actual context of the context menu, in my case the Id of an item that is right-clicked on, into the command, thus making it useless. While I'm fairly certain I was able to set the Id into context, I have no way of retrieving it.
As of right now I see blocking the regular context menu and building my own as the only working option, which is a route I would rather not go.
If I'm missing anything, any help would be greatly appreciated!

EDIT: Out of desperation I tried receiving any arguments in my command. Turns out that you get the JSON set as data-vscode-context within your webview's HTML as an object in the command (example of JSON from docs). I find this behaviour to be very unintuitive and badly documented, if at all. I am happy to have found a solution, but after hours of reading into this I still +1 the getContext API for everyone who's been waiting for years.

filip131311 added a commit to software-mansion/radon-ide that referenced this issue Jul 9, 2024
…r. (#425)

### Description 
Because, secondary sidebar in vscode has a "close" button in top right
corner, the user is faced with two "X" buttons that do different things;
one closes the secondary sidebar and in effect hides our extension and
the second closes our extension completely.

### Solution 
To mitigate the negative effects this PR overrides the command used to
hide secondary sidebar and closes React native IDE completely before
hiding it, that makes two buttons perform similar actions instead of
doing two different things, which is an improvement.

### Hiding the second button
The natural question to ask is why can't we disable, our "close RNIDE"
button when IDE is in secondary sidebar. Unfortunately there is now
reliable way to check in which sideBar the viewContainer contributed by
an extension is located at any given time. There is a closed issue on
that topic here. One workaround for that would be to check if context
key "activeAuxiliary" has value matching our extension contributed
viewContainer, because since it is an activeAuxiliary it has to be in
Auxiliary SideBar, unfortunately the id of Extension contributed view
Containers is randomly generated, you can read the code
[here](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/services/views/browser/viewDescriptorService.ts)
the first relevant line is 502.

There is hope of discovering the generated viewContainer id by checking
the activeAxiliary and activeViewlet context fields while we know about
its location, but it would require a getContext() API that is not
currently implemented, an active issue on that can be found
[here](microsoft/vscode#10471).

---------

Co-authored-by: filip131311 <filip.kaminski@swmansiom.com>
@soyrubio
Copy link

+1 for getContext API

1 similar comment
@Artyom-Safronov
Copy link

+1 for getContext API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api context-keys feature-request Request for new features or functionality
Projects
None yet
Development

Successfully merging a pull request may close this issue.