Page moved to: Moltenform


One of the reasons I use the SciTE code editor is that keyboard shortcuts can be easily changed in a plain-text configuration file.

If you use SciTE, here is a Python script to list current keyboard shortcuts. You will need to have downloaded SciTE's source code, or at least download the file SciTERes.rc.

# list SciTE shortcuts
# Ben Fisher, http://halfhourhacks.blogspot.com
# 1) shortcuts from user.shortcuts
# 2) shortcuts from commands
# 3) shortcuts from SciTE's rc
# does not include scintilla's simple keybindings (see KeyMap.cxx KeyMap::MapDefault)

scite_src = 'path/to/scite'
scite_props = 'path/to/sciteinstall/properties'
specificfiletypes = []
# specificfiletypes = ['*.py', '$(file.patterns.py)']

import os, sys, re

class Shortcut(object):
  def __init__(self, name='',keys='',filetypes='',type='plugin'):
    self.name=name; self.keys=keys; self.filetypes=filetypes; self.type=type
  def __str__(self):
    return self.keys.ljust(20) + self.name.ljust(30)+ self.type
  def getsortkey(self):
    # create a tuple specifying sort priority. length of key-shortcut is most important.
    sortvallastpart = self.keys.split('+')[-1]
    sortlenlastpart = len(sortvallastpart)
    sorttypepriority = dict(builtin=3, usershortcuts=2, plugin=1).get(self.type, 0)
    return (sortlenlastpart, sortvallastpart,self.keys, sorttypepriority)

def go():
  scite_src_rc = os.path.join(scite_src, 'win32', 'SciTERes.rc')
  assert os.path.exists(scite_src)
  assert os.path.exists(scite_src)
  assert os.path.exists(scite_props)
  if not os.path.exists(os.path.join(scite_props, 'SciTEGlobal.properties')):
    print 'warning: SciTEGlobal.properties not found.'
  results = []
  
  f = open(scite_src_rc, 'r')
  bAccels = False
  for line in f:
    line=line.strip()
    if bAccels:
      if line=='BEGIN' or not line or line=='*/': continue
      if line.startswith('//') or line.startswith('#') or line.startswith('/*'): continue
      if line=='END': break
      items = [item.strip() for item in line.split(',')]
      keys = items[0].replace('"','').replace('VK_','')
      keys = keys[0].upper() + keys[1:].lower()
      if 'SHIFT' in items: keys = 'Shift+'+keys
      if 'ALT' in items: keys = 'Alt+'+keys
      if 'CONTROL' in items: keys = 'Ctrl+'+keys
      results.append(Shortcut(items[1], keys, '*', 'builtin'))
    if line=='ACCELS ACCELERATORS': bAccels = True
  f.close()
  
  propcmds = {}
  specificfiletypes.append('*')
  specificfiletypes.append('*.*')
  for filename in os.listdir(scite_props):
    if not filename.lower().endswith('.properties'): continue
    f.close()
    f = open(os.path.join(scite_props, filename))
    bUsershort=False # are we currently looking at user.shortcuts
    for line in f:
      line=line.strip()
      if bUsershort:
        if '|' in line:
          shortcut, cmd, unused = line.split('|')
          results.append(Shortcut(cmd, shortcut, '*', 'usershortcuts'))
        if not line.endswith('\\'): bUsershort=False
      else:
        parse = re.match(r'command\.(name|shortcut)\.(\w+)\.([^=]+)=(.*)', line)
        if parse and parse.group(3) in specificfiletypes:
          # add to a dict of in-progress commands
          obj = propcmds.setdefault(parse.group(2)+';'+parse.group(3), Shortcut())
          obj.filetypes = parse.group(3)
          
          if len(parse.group(2))==1: obj.keys = 'Ctrl+'+parse.group(2)
          if parse.group(1)=='name': obj.name = parse.group(4);
          elif parse.group(1)=='shortcut': obj.keys = parse.group(4)

        if line.startswith('user.shortcuts='): bUsershort=True
    
  
  for propcmd in propcmds: results.append(propcmds[propcmd])
  results.sort(key = lambda item: item.getsortkey())
  for res in results:
    if not res.name.startswith('IDM_BUFFER+'):
      if not res.name.startswith('IDM_TOOLS+'):
        print(res)

if __name__=='__main__':
  go()