File: zsh_utils.py

package info (click to toggle)
crazy-complete 0.3.6-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,404 kB
  • sloc: python: 7,949; sh: 4,636; makefile: 74
file content (91 lines) | stat: -rw-r--r-- 2,510 bytes parent folder | download | duplicates (2)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
'''Utility functions for Zsh.'''

from . import algo
from . import shell

# pylint: disable=too-many-branches
# pylint: disable=too-many-arguments
# pylint: disable=too-many-positional-arguments


def escape_colon(s):
    '''Escape colons in a string with backslash.'''

    return s.replace(':', '\\:')


def escape_square_brackets(s):
    '''Escape square brackets with backslash.'''

    return s.replace('[', '\\[').replace(']', '\\]')


def make_option_spec(
        option_strings,
        conflicting_options = None,
        description         = None,
        complete            = None,
        optional_arg        = False,
        repeatable          = False,
        final               = False,
        metavar             = None,
        action              = None
    ):

    '''
    Make a Zsh option spec.

    Returns something like this:
        (--option -o){--option=,-o+}[Option description]:Metavar:Action
    '''

    result = []

    if conflicting_options is None:
        conflicting_options = []

    # Not options =============================================================
    not_options = []

    for o in sorted(conflicting_options):
        not_options.append(escape_colon(o))

    if not repeatable:
        for o in sorted(option_strings):
            not_options.append(escape_colon(o))

    if final:
        not_options = ['- *']

    if not_options:
        result.append(shell.escape('(%s)' % ' '.join(algo.uniq(not_options))))

    # Repeatable option =======================================================
    if repeatable:
        result.append("'*'")

    # Option strings ==========================================================
    if complete and optional_arg is True:
        opts = [o+'-' if len(o) == 2 else o+'=-' for o in option_strings]
    elif complete:
        opts = [o+'+' if len(o) == 2 else o+'=' for o in option_strings]
    else:
        opts = option_strings

    if len(opts) == 1:
        result.append(opts[0])
    else:
        result.append('{%s}' % ','.join(opts))

    # Description =============================================================
    if description is not None:
        result.append(shell.escape('[%s]' % escape_colon(escape_square_brackets(description))))

    # Complete ================================================================
    if complete:
        if metavar is None:
            metavar = ' '

        result.append(':%s:%s' % (shell.escape(escape_colon(metavar)), action))

    return ''.join(result)