monaco-editor version: 0.X.Y
Browser: Chrome
OS: windows
Steps or JS usage snippet reproducing the issue:
From the below URL, a new context menu option "My label" is added.
https://microsoft.github.io/monaco-editor/playground.html#interacting-with-the-editor-adding-an-action-to-an-editor-instance
Can i Hide the "My label" option if the selected line is a comment or some other condition.
I have tried with
precondition: "!editorReadOnly",
in the add action, but the precondition works only while creating editor instance, can i update the action dynamically to hide the context menu option or can you suggest me a better way to hide the context menu options?
You can create your own context key and you can define its value dynamically.
An example that uses context keys can be found here
thanks @alexandrudima for you quick and valuable suggestion, i have tried with command with context key(KeyCode.ContextMenu), but it didn't work, so,i tried with an event > editor.onContextmenu()
which works only once. run the following snippet in the Monaco Editor Playground:
var editor = monaco.editor.create(document.getElementById("container"), {
value: [
'',
'class Example {',
'\tprivate m:number;',
'',
'\tpublic met(): string {',
'\t\treturn "Hello world!";',
'\t}',
'}'
].join('\n'),
language: "typescript"
});
var myCondition1 = editor.createContextKey(/*key name*/'myCondition1', /*default value*/false);
editor.addAction({
id: 'my-unique-id',
label: 'My Label!!!',
keybindings: [
monaco.KeyMod.CtrlCmd | monaco.KeyCode.F10,
monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_K, monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_M)
],
precondition: myCondition1.set(true),
keybindingContext: null,
contextMenuGroupId: 'navigation',
contextMenuOrder: 1.5,
run: function(ed) {
//alert("i'm running => " + ed.getPosition());
return null;
}
});
var myBinding = editor.addCommand(monaco.KeyCode.F9, function() {
myCondition1.set(false);
});
// Uncomment this for hiding "My Label" option only once.
// editor.onContextMenu(function (e) {
// var a =editor.getModel().getLineContent(e.target.position.lineNumber);
// var c=editor.getAction('my-unique-id');
// if(a.includes('class')){
// alert(a);
// c._precondition.expr[0].value=1;
// }else{
// c._precondition.expr[0].value=0;
// }
// c.isSupported(true);
// c.run();
// });
the Result i need is when we select some text we will get format selection option in context menu else that option is hidden in the context menu options
From above:
],
precondition: myCondition1.set(true),
keybindingContext: null,
That should be:
],
precondition: 'myCondition1',
keybindingContext: null,
Then, somewhere else in your code you can use myCondition1.set(false); or myCondition1.set(true);
thanks @alexandrudima the condition is working for me. But the problem is, i need to update the precondition value when a user right click's or on context menu opens. I have tried with the below events.
monaco.KeyCode.ContextMenu and
editor.onContextMenu
In the first case, i am unable to get the alert also.
In the second case, when the user right clicks twice, then i am getting the correct output.
var editor = monaco.editor.create(document.getElementById("container"), {
value: [
'class Example {',
'\tpublic met(): string {',
'\t\treturn "Hello world!";',
'\t}',
'}'
].join('\n'),
language: "typescript"
});
var myCondition1 = editor.createContextKey(/*key name*/'myCondition1', /*default value*/false);
editor.addAction({
id: 'my-unique-id',
label: 'My Label!!!',
precondition: 'myCondition1',
contextMenuGroupId: 'navigation',
contextMenuOrder: 1.5,
run: function(ed) {
alert("i'm running => " + ed.getPosition());
return null;
}
});
var myBinding = editor.addCommand(monaco.KeyCode.ContextMenu, function() {
var a =editor.getModel().getLineContent(e.target.position.lineNumber);
alert("context menu");
if(a.includes('world')){
myCondition1.set(false);
}else{
myCondition1.set(true);
}
});
editor.onContextMenu(function (e) {
var a =editor.getModel().getLineContent(e.target.position.lineNumber);
if(a.includes('world')){
myCondition1.set(false);
}else{
myCondition1.set(true);
}
});
so please tell me, if there is any better way to hide "my label" item in context menu??
hi
Alexandru.Have you tried this.Please helpin this.
var editor = monaco.editor.create(document.getElementById("container"),
{ value: [
'class Example {',
'\tpublic met(): string {',
'\t\treturn "Hello world!";',
'\t}', '}' ].join('\n'), language: "typescript" });
var myCondition1 = editor.createContextKey(/key name/'myCondition1', /default value/false);
editor.addAction({
id: 'my-unique-id',
label: 'My Label!!!',
precondition: 'myCondition1',
contextMenuGroupId: 'navigation',
contextMenuOrder: 1.5,
run: function(ed) {
alert("i'm running => " + ed.getPosition()); return null; } });
var myBinding = editor.addCommand(monaco.KeyCode.ContextMenu, function()
{
var a =editor.getModel().getLineContent(e.target.position.lineNumber);
alert("context menu");
if(a.includes('world'))
{
myCondition1.set(false);
}else{
myCondition1.set(true);
}
});
editor.onContextMenu(function (e) {
var a =editor.getModel().getLineContent(e.target.position.lineNumber);
if(a.includes('world'))
{
myCondition1.set(false); }else{ myCondition1.set(true); } });
the condition is working for me. But the problem is, i need to update the precondition value when a user right click's or on context menu opens. I have tried with the below events.
monaco.KeyCode.ContextMenu and
editor.onContextMenu
In the first case, i am unable to get the alert also.
In the second case, when the user right clicks twice, then i am getting the correct output.
@alexandrudima Hi.
I've come to need a dynamic context menu as well. The issue with using a context key is that its value is updated after the context menu appear:
const myCondition = editor.createContextKey('myCondition', false);
editor.onContextMenu(function(e) {
myCondition.set(true);
});
editor.addAction({
...
precondition: 'myCondition',
....
});
Using this example on the playground, we can see that when the context menu appears the first time, the custom action is hidden. myCondition.set(true) was executed _after_.
Is there any way to alter the context menu depending on the current line?
I can't seem to find any event that's triggered _before_ the context menu is opened.
+1, expreriencing the same issue as @CyriacBr.
@alexandrudima Hey. I understand you're probably busy with a lot of things, but we'd appreciate if you can guide us how or where to edit the source to alter context keys before the context menu is populated.
@Geloosa Maybe we should open a new issue for visibility?
Since this is JavaScript, you can implement whatever you want when we don't have API for each and every thing.
e.g.
const editor = monaco.editor.create(...);
// ...
const contextmenu = editor.getContribution('editor.contrib.contextmenu')
const realMethod = contextmenu._onContextMenu;
contextmenu._onContextMenu = function() {
console.log('here I am, taking over');
realMethod.apply(contextmenu, arguments);
};
Good luck!
@alexandrudima Pretty sweet! I didn't know about getContribution.
That makes monkey-patching a lot easier now! Thanks a lot.
Most helpful comment
Since this is JavaScript, you can implement whatever you want when we don't have API for each and every thing.
e.g.
Good luck!