monaco-editor

How to set precondition in addAction?


How can precondition be set so that the menu only appears when language: 'javascript'?

editor.addAction({
  id: 'my-unique-id',
  label: 'My Label!!!',
  keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter],
  precondition: null,
  keybindingContext: null,
  run: function() { alert('action called') }
});

Solution

  • You can create an action (initially has a default value of false):

    var isLanguageJavascript = editor.createContextKey(
      "isLanguageJavascript", // name/key
      false // default value
    );
    

    Add your action as in your SO question, but set the precondition to be the name of the action:

    editor.addAction({
      id: 'my-unique-id',
      label: 'My Label!!!',
      keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter],
      precondition: "isLanguageJavascript",
      keybindingContext: null,
      run: function() { alert('action called') }
    });
    

    Add an event handler to listen for changes to the language, and update the condition to true if the language is now javascript (and false otherwise):

    editor.onDidChangeModelLanguage(e => {
      console.log("language has changed")
      isLanguageJavascript.set(e.newLanguage === "javascript");
    });
    

    This will mean the action will only execute if the value of the precondition isLanguageJavascript is true.

    There's a working demo here. To simulate language changing, I've added this setTimeout so it sets the language to javascript after 10 seconds (a real life example would probably have a button or something so the user could change the language):

    setTimeout(function () {
      monaco.editor.setModelLanguage(editor.getModel(), "javascript");
    }, 10000);
    

    If you press Ctrl+Enter before 10 seconds it won't execute the action but after 10 seconds it will. If you change the language in the setTimeout call to "java" then it won't execute the action even after 10 seconds as the language isn't javascript.