Sublime Forum

Plugin which shows a popup with all keybindings

#1

I’m posting this here in case some people may find it useful.

I implemented my own Git implementation on top of ST. In some Git views I use a lot of key-bndings (e.g. for Git Diff I can press c to commit, z to revert a hunk, etc.). Since I have a lot of these key bindings, I often forget them. As such I wanted to be able to press h and see all the key bindings associated to a given Git view.

The helper is dynamically generated by Default.sublime-keymap.

"""
On 'h' keypress, show a popup re. the key bindings available for a
given view. Used mostly for Git views.

The help is dinamically generated by Default.sublime-keymap file like this.
Enable helper for a given context:

    { "keys": ["h"],
      "command": "show_helper",
      "args": {"marker": [{ "key": "setting.git_diff_view" }] },
      "context": [{ "key": "setting.git_diff_view" }] },

Add an entry:

    { "keys": ["c"],
      "command": "git_diff_view_commit",
      "context": [{ "key": "setting.git_diff_view" }],
      "help": "commit" },
"""

import os

import sublime
import sublime_plugin
from sublime_plugin import WindowCommand

SUBLIME_ROOT_DIR = os.path.realpath(os.path.dirname(sublime.packages_path()))
SUBLIME_USER_DIR = os.path.join(SUBLIME_ROOT_DIR, "Packages", "User")


HTML = """
<html>
<style>
html {
    border: 1px solid white;
}
h2 {
    margin-top: 0;
    color: #fce566;
    font-size: 1.2em;
}
ul {
    border: 0px solid white;
    padding-left: 13px;
}
.header-wrapper {
    border: 0px solid white;
}
.shortcut-key {
    font-weight: bold;
    color: #fce566;
}
</style>
<body>
    <h2>Keyboard Shortcuts</h2>
    <ul>
    %s
    </ul>
</body>
</html>
"""


def show_helper(keys):
    popup_max_width = 800
    popup_max_height = 800
    view = sublime.active_window().active_view()
    items = []
    for key, help in keys:
        key = ", ".join(key).replace("+", " + ")
        key += "&nbsp;" * (22 - len(key))
        items.append(
            f'<li><code><span class="shortcut-key">{key}</span><span class="helper"></span>{help}</code></li>'  # noqa
        )
    html = HTML % "\n".join(items)
    view.show_popup(html, 0, -1, popup_max_width, popup_max_height)


# key: ?
class ShowHelperCommand(WindowCommand):
    def run(self, marker):
        file = os.path.join(SUBLIME_USER_DIR, "Default (Linux).sublime-keymap")
        with open(file) as f:
            js = sublime.decode_value(f.read())  # json without comments
        keys = []
        for item in js:
            if item.get("context") == marker and "help" in item:
                keys.append((item["keys"], item["help"]))
        show_helper(keys)
0 Likes