atom-community / tool-bar

Package providing customisable toolbar for Atom
MIT License
160 stars 50 forks source link

Changing callback based on the grammar of the active text editor? #290

Open aminya opened 4 years ago

aminya commented 4 years ago

Is it possible to change the callback for a button based on the grammar of the active text editor?

aminya commented 4 years ago

This issue seems related: https://github.com/suda/tool-bar/issues/192

suda commented 4 years ago

Interesting idea. How would you propose to declare different callback s for different grammars?

aminya commented 4 years ago
function mycallback() {
    // change callback based on the grammar
    let grammar = atom.workspace.getActiveEditor().getGrammar()
    if (grammar == "julia") {
      // do this
    } else {
      // do that
    }
}

The first way allows for more flexibility, which is currently possible anyways.


The second way is nicer in my opinion. However, I don't know how we are going to handle its possible conflict with Key modifiers without breaking backward compatibility. Probably there is a way.

Maybe we can add an option to enable grammar dispatch:
```ts
  toolBar.addButton({
    icon: 'octoface',
    grammars: true, // enables grammars and breaks key modifiers
    callback: {
        julia: "app:do-julia",
        python: "app:do-python",
        c: {
          // now key modifiers should be under the individual grammar
          "": "app:do-c1",
          "shift": "app:do-c2"
        }
      }
  });
ericcornelissen commented 4 years ago

I like the idea, I don't think it would cause problems with key modifiers, personally, as I wouldn't use any other keys than shift, ctrl, etc. But of course, some people may use e.g. c (and there may be grammers that conflict with those keys as well...).

Perhaps we could make the grammar thing explicit from within the callbacks object, e.g.:

toolBar.addButton({
  icon: 'octoface',
  callback: {
    grammar: {
      julia: "app:do-julia",
      python: "app:do-python",

      // The "c" language
      c: "app:do-c-lang",
    },

    // the "c" key
    c: "app:do-c-key",
  }
});

Or distinguish grammers/languages from keys in the key name, e.g.:

toolBar.addButton({
  icon: 'octoface',
  callback: {
    // Using a "lang" or "language" prefix
    "lang-julia": "app:do-julia",
    "language-julia": "app:do-julia",

    // Using a "grammer" prefix
    "grammer-julia": "app:do-julia",

    // The you can use the "c" language
    "lang-c": "app:do-c-lang",
    // And the "c" key
    c: "app:do-c-key",
  }
});

Where only one or multiple prefixes can be supported.

aminya commented 4 years ago

My concern is about the case when someone wants to use both modifiers and grammars. We should allow this too. My example allowed this. See c language for example that has modifiers for itself (shift, when in C grammar).

  toolBar.addButton({
    icon: 'octoface',
    grammars: true, // enables grammars and breaks key modifiers.
                    // now key modifiers should be under the individual grammar
    callback: {
        julia: "app:do-julia",
        python: "app:do-python",
        c: {
          "": "app:do-c1",
          "shift": "app:do-c2"
        }
      }
  });
aminya commented 4 years ago

Another way is to just avoid doing this, and add an option to addButton itself, and have separate buttons for different grammars. This doesn't change modifiers syntax too. It allows for different class or shape for different grammars, and it can also solve https://github.com/suda/tool-bar/issues/192, since we can hide the buttons when they are not in their grammar.

  toolBar.addButton({
    icon: 'octoface',
    grammar: "julia",
    callback: "app:do-julia"
  });

  toolBar.addButton({
    icon: 'octoface',
    grammar: "python",
    callback: "app:do-python"
  });
ericcornelissen commented 4 years ago

My concern is about the case when someone wants to use both modifiers and grammars. We should allow this too. My example allowed this. See c language for example that has modifiers for itself (shift, when in C grammar).

  toolBar.addButton({
    icon: 'octoface',
  grammars: true, // enables grammars and breaks key modifiers.
                  // now key modifiers should be under the individual grammar
    callback: {
        julia: "app:do-julia",
        python: "app:do-python",
        c: {
          "": "app:do-c1",
          "shift": "app:do-c2"
        }
      }
  });

Of course! That would be possible with all proposals so far! If you want modifiers for the grammar callback you should specify it as an object.

Another way is to just avoid doing this, and add an option to addButton itself, and have separate buttons for different grammars. This doesn't change modifiers syntax too. It allows for different class or shape for different grammars, and it can also solve #192, since we can hide the buttons when they are not in their grammar.

  toolBar.addButton({
    icon: 'octoface',
  grammar: "julia",
    callback: "app:do-julia"
  });

  toolBar.addButton({
    icon: 'octoface',
  grammar: "python",
    callback: "app:do-python"
  });

This is quite a nice solution I think, definitely the most compatible with the current API. Unfortunately it would result in some duplication that is perhaps not desirable. :thinking:

aminya commented 4 years ago
  toolBar.addButton({
    icon: 'octoface',
    grammar: "julia",
    callback: "app:do-julia"
  });

  toolBar.addButton({
    icon: 'octoface',
    grammar: "python",
    callback: "app:do-python"
  });

This is quite a nice solution I think, definitely the most compatible with the current API. Unfortunately it would result in some duplication that is perhaps not desirable. 🤔

Yes, I like this one more! Duplication could be solved by using variables.

let icon1 = 'octoface'

toolBar.addButton({
    icon: icon1
    grammar: "julia",
    callback: "app:do-julia"
});

toolBar.addButton({
    icon: icon1
    grammar: "python",
    callback: "app:do-python"
});

or more crazy:

let myoption = {
    icon: "octoface",
    grammar: "julia",
    callback: "app:do-julia"
}

toolBar.addButton(myoption);

myoption.grammar = "python"
myoption.callback= "app:do-python"
toolBar.addButton(myoption);

If it was me I will just use separate variables to avoid duplication. 😄