sublimehq / sublime_text

Issue tracker for Sublime Text
https://www.sublimetext.com
807 stars 39 forks source link

Allow hiding and disabling of menu items with submenus #1859

Open evandrocoan opened 7 years ago

evandrocoan commented 7 years ago

If a package group several of its menu's entries in a sub-menu, we currently cannot hide folder on non-related projects files:

image

I would suggest to hide each folder the same way the menu's entries are hidden.

Context.sublime-menu

[
    {
        "id": "sublimelinter",
        "caption": "SublimeLinter",
        "children":
        [
            {
                "caption": "Toggle Linter...",
                "command": "sublimelinter_toggle_linter", "args":
                {
                    "which": "all"
                }
            },
            {
                "caption": "-"
            },
            {
                "caption": "Lint This View",
                "command": "sublimelinter_lint"
            },
            ...

-->

[
    {
        "id": "sublimelinter",
        "caption": "SublimeLinter",
        "command": "sublimelinter_main_linter_context_menu"
        "children":
        [
            {
                "caption": "Toggle Linter...",
                "command": "sublimelinter_toggle_linter", "args":
                {
                    "which": "all"
                }
            },
            {
                "caption": "-"
            },
            {
                "caption": "Lint This View",
                "command": "sublimelinter_lint"
            },
            ...

Here the sublimelinter_main_linter_context_menu would never be called to run a action, but just to check whether it is visible or not, as in:

class SublimelinterMainLinterContextMenuCommand(sublime_plugin.WindowCommand):

    def is_enabled(self, **args):
        return do_logic()

    def is_checked(self, **args):
        pass

    def run(self, **args):
        pass

Note, if different Context.sublime-menu file define the same folder, they are independent from each other, so hiding the folder from one, should not remove the folder entries from the other folder. For example, the package Anaconda, and its related packages as Anaconda-Rust, both define the folder menu Anaconda, so when the main Anaconda package say to hide the folder, it should not hide the other package's defined folders.


Related issues:

  1. https://github.com/SublimeTextIssues/Core/issues/1095 Menus without child menuitems should be hidden
  2. https://github.com/DamnWidget/anaconda/issues/571 Hide Anaconda context menu entry on non-python projects
keith-hall commented 7 years ago

@evandrocoan can you clarify why you don't believe this is a duplicate of https://github.com/SublimeTextIssues/Core/issues/1095 please? is the main difference that you want to control the visibility of the parent menu item "folder" explicitly, as opposed to just automatically having the parent hidden when all of it's children are hidden/disabled?

FichteFoll commented 7 years ago

@keith-hall I think so, yes. I generally prefer this approach over #1095, because this shows clear intent that a parent item should be disabled or hidden rather than implicitly doing it when a sub-menu has no visible or enabled items. Sometimes a user might want to see this specifically.

I vote to close #1095 as a duplicate in favor of this more general suggestion.

@evandrocoan In your code example, I believe your is_checked should be is_enabled instead.

evandrocoan commented 7 years ago

You are right @FichteFoll, I updated the issue. @keith-hall, the package SublimeLinter, has menu entries which are not disabled when it is on a non-linted project. Therefore it would also not be enough to just check whether all entries are disabled. Perhaps I could also want to some menu folder only show up on certain projects, other than only its entries are accessible.

cameronbroe commented 7 years ago

+1 for this feature request

tjtyrrell commented 5 years ago

+1 from me as well

Perhaps just add the ability to call specific menu checkers from the JSON object itself. So something like:

{
    "caption": "My Menu",
    "id": "my_menu",
    "children": [],
    "is_visible": "my_is_visible_function", // leverage the "id" to look for the class
    "is_enabled": "my_is_enabled_function", // see "is_visible"
    "args": {"paths": []}
}
class MyMenu(sublime_plugin.WindowCommand):
    def MyIsVisibleFunction( self, paths = [] ):
        return True

    def MyIsEnabledFunction( self, paths = [] ):
        return False

I dunno, just hoping this makes it in somehow someway.