import os.path import json import copy keymap = { "expand_abbreviation": "ctrl+e", "match_pair_outward": {"mac": "ctrl+d", "pc": "ctrl+,"}, "match_pair_inward": {"mac": "ctrl+j", "pc": "ctrl+shift+0"}, "matching_pair": {"mac": "ctrl+shift+t", "pc": "ctrl+alt+j"}, "next_edit_point": "ctrl+alt+right", "prev_edit_point": "ctrl+alt+left", "toggle_comment": { "mac": "alt+shift+forward_slash", "pc": "ctrl+shift+forward_slash", "context": [{ "key": "selector", "operand": "source.css - source.css.less, text.xml, text.html - source", "operator": "equal" }] }, "split_join_tag": {"mac": "shift+super+'", "pc": "shift+ctrl+`"}, "remove_tag": {"mac": "super+'", "pc": "shift+ctrl+;"}, "evaluate_math_expression": {"mac": "shift+super+y", "pc": "shift+ctrl+y"}, "increment_number_by_1": "ctrl+up", "decrement_number_by_1": "ctrl+down", "increment_number_by_01": "alt+up", "decrement_number_by_01": "alt+down", "increment_number_by_10": {"mac": "alt+super+up", "pc": "shift+alt+up"}, "decrement_number_by_10": {"mac": "alt+super+down", "pc": "shift+alt+down"}, "select_next_item": {"mac": "shift+super+.", "pc": "shift+ctrl+."}, "select_previous_item": {"mac": "shift+super+,", "pc": "shift+ctrl+,"}, "reflect_css_value": {"mac": "shift+super+r", "pc": "shift+ctrl+r"}, "rename_tag": {"mac": "super+shift+k", "pc": "shift+ctrl+'"}, "encode_decode_data_url": {"mac": "shift+ctrl+d", "pc": "ctrl+'"}, "update_image_size": {"mac": "shift+ctrl+i", "pc": "ctrl+u"}, "expand_as_you_type": { "keys": ["ctrl+alt+enter"], "context": [{ "key": "setting.is_widget", "operand": False, "operator": "equal" }] }, "wrap_as_you_type": { "mac": "ctrl+w", "pc": "shift+ctrl+g", "context": [{ "key": "setting.is_widget", "operand": False, "operator": "equal" }] } } # additional "raw" ST2 actions definition addon = [ { "keys": ["tab"], "command": "expand_abbreviation_by_tab", "context": [ { "key": "selector", "match_all": True, "operand": "source.css, source.sass, source.less, source.scss, source.stylus, text.xml, text.html, text.haml, text.scala.html, source string", "operator": "equal" }, { "key": "selector", "operand": "text.html source.php, text.html source.js, storage.type.templatetag.django", "operator": "not_equal", "match_all": True }, { "key": "selection_empty", "match_all": True }, { "key": "has_next_field", "operator": "equal", "operand": False, "match_all": True }, { "key": "setting.disable_tab_abbreviations", "operator": "equal", "operand": False, "match_all": True }, { "key": "auto_complete_visible", "operand": False, "operator": "equal", "match_all": True }, { "key": "is_abbreviation", "match_all": True } ] }, # behaviour of tab key when autocomplete popup is visible { "keys": ["tab"], "command": "expand_abbreviation_by_tab", "context": [ { "key": "selector", "match_all": True, "operand": "source.css, source.sass, source.less, source.scss, source.stylus, text.xml, text.html, text.haml, text.scala.html, source string", "operator": "equal" }, { "key": "selector", "operand": "text.html source.php, text.html source.js, storage.type.templatetag.django", "operator": "not_equal", "match_all": True }, { "key": "selection_empty", "match_all": True }, { "key": "has_next_field", "operator": "equal", "operand": False, "match_all": True }, { "key": "auto_complete_visible", "operator": "equal", "operand": True, "match_all": True }, { "key": "setting.disable_tab_abbreviations_on_auto_complete", "operator": "equal", "operand": False, "match_all": True }, { "key": "is_abbreviation", "match_all": True } ] }, # insert linebreak with formatting { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n\t${0}\n"}, "context": [ { "key": "selector", "operand": "meta.scope.between-tag-pair.html, meta.scope.between-tag-pair.xml", "match_all": True }, { "key": "auto_complete_visible", "operand": False, "match_all": True }, { "key": "clear_fields_on_enter_key", "match_all": True }, { "key": "setting.disable_formatted_linebreak", "operand": False, "match_all": True } ] }, { "keys": ["#"], "command": "emmet_insert_attribute", "args": {"attribute": "id"}, "context": [ { "key": "selector", "match_all": True, "operand": "text.html meta.tag -string -punctuation.definition.tag.begin.html -meta.scope.between-tag-pair.html -source -meta.tag.template.value.twig", "operator": "equal" }, { "key": "setting.auto_id_class", "operator": "equal", "operand": True } ] }, { "keys": ["."], "command": "emmet_insert_attribute", "args": {"attribute": "class"}, "context": [ { "key": "selector", "match_all": True, "operand": "text.html meta.tag -string -punctuation.definition.tag.begin.html -meta.scope.between-tag-pair.html -source -meta.tag.template.value.twig", "operator": "equal" }, { "key": "setting.auto_id_class", "operator": "equal", "operand": True } ] } ] # header of generated file header = "// This file is automatically generated with misc/generate-keymap.py script\n\n" _dir = os.path.dirname(os.path.abspath(__file__)) standalone_actions = ["wrap_as_you_type", "expand_as_you_type", "rename_tag"] def create_record(k, v, os_type): if isinstance(v, basestring): v = {"keys": [v]} else: v = copy.deepcopy(v) if os_type in v: v['keys'] = [v[os_type]] if 'pc' in v: del v['pc'] if 'mac' in v: del v['mac'] if k in standalone_actions: v['command'] = k else: v['command'] = 'run_emmet_action' v['args'] = {"action": k} if 'context' not in v: v['context'] = [] v['context'].append({'key': 'emmet_action_enabled.%s' % k}) if len(v['context']) > 1: for ctx in v['context']: ctx['match_all'] = True return v def generate_keymap_file(path): os_type = 'mac' if '(OSX)' in path else 'pc' path = os.path.abspath(os.path.join(_dir, path)) print('Generate %s (%s)' % (path, os_type)) editor_keymap = [create_record(k, v, os_type) for k, v in keymap.items()] + addon content = json.dumps(editor_keymap, indent=4) f = open(path, 'w') f.write(header + content) f.close() for path in ['../Default (OSX).sublime-keymap', '../Default (Windows).sublime-keymap', '../Default (Linux).sublime-keymap']: generate_keymap_file(path)