Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from types import NoneType
import sys
import os
import re

import plistlib
to_plist = plistlib.writePlistToString
from_plist = plistlib.readPlistFromString

def escape(s):
    return re.sub(r"(?=[^a-zA-Z0-9_.\/\-\x7F-\xFF\n])", r'\\', s).replace("\n", "'\n'")

support = os.environ["TM_SUPPORT_PATH"]
dialog = os.path.join(support, 'bin/tm_dialog')

if not sys.version.startswith("2.5"):
    def all(it):
        return not bool(len([truth for truth in it if truth is False]))

def item(val):
    if isinstance(val, str):
        return {"title": val}
    if isinstance(val, tuple):
        return {"title": val[0]}
    elif val is None:
        return {"separator": 1}

def sh(cmd): 
    result = ""
    pipe = None
    try:
        pipe = os.popen(cmd)
        result = pipe.read()
    finally:
        if pipe: pipe.close()
    return result

def all_are_instance(it, typ):
    return all([(isinstance(i, typ)) for i in it])

def menu(options):
    """ Accepts a list and causes TextMate to show an inline menu.
    
    If options is a list of strings, will return the selected index.
    
    If options is a list of (key, value) tuples, will return value of the
    selected key. Note that we don't use dicts, so that key-value options
    can be ordered. If you want to use a dict, try dict.items().
    """
    hashed_options = False
    if not options:
        return None
    if all_are_instance(options, (str, NoneType)):
        menu = dict(menuItems=[item(val) for val in options])    
    elif all_are_instance(options, (tuple, NoneType)):
        hashed_options = True
        menu = dict(menuItems=[item(pair) for pair in options])
    plist = to_plist(menu)
    cmd = 'bash -c "%s -up %s"' % (escape(dialog), escape(plist))
    result = from_plist(sh(cmd))
    if not 'selectedIndex' in result:
        return None
    index = int(result['selectedIndex'])
    if hashed_options:
        return options[index][1]
    return options[index]None