summaryrefslogtreecommitdiffstats
path: root/http_prompt/utils.py
blob: 4d8568157520ee71aa5de74da50c973ba9c7038e (plain)
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
from __future__ import unicode_literals

import math
import re
import shlex

from prompt_toolkit.output.defaults import create_output


RE_ANSI_ESCAPE = re.compile(r'\x1b[^m]*m')


def smart_quote(s):
    return shlex.quote(s)


def unquote(s):
    quotes = ["'", '"']
    quote_str = None
    if s[0] in quotes:
        quote_str = s[0]

    if quote_str and s[-1] == quote_str:
        return s[1: -1]
    return s


def unescape(s, exclude=None):
    if exclude:
        char = '[^%s]' % exclude
    else:
        char = '.'
    return re.sub(r'\\(%s)' % char, r'\1', s)


def get_terminal_size():
    return create_output().get_size()


def strip_ansi_escapes(text):
    return RE_ANSI_ESCAPE.sub('', text)


def colformat(strings, num_sep_spaces=1, terminal_width=None):
    """Format a list of strings like ls does multi-column output."""
    if terminal_width is None:
        terminal_width = get_terminal_size().columns

    if not strings:
        return

    num_items = len(strings)
    max_len = max([len(strip_ansi_escapes(s)) for s in strings])

    num_columns = min(
        int((terminal_width + num_sep_spaces) / (max_len + num_sep_spaces)),
        num_items)
    num_columns = max(1, num_columns)

    num_lines = int(math.ceil(float(num_items) / num_columns))
    num_columns = int(math.ceil(float(num_items) / num_lines))

    num_elements_last_column = num_items % num_lines
    if num_elements_last_column == 0:
        num_elements_last_column = num_lines

    lines = []
    for i in range(num_lines):
        line_size = num_columns
        if i >= num_elements_last_column:
            line_size -= 1
        lines.append([None] * line_size)

    for i, line in enumerate(lines):
        line_size = len(line)
        for j in range(line_size):
            k = i + num_lines * j
            item = strings[k]
            if j % line_size != line_size - 1:
                item_len = len(strip_ansi_escapes(item))
                item = item + ' ' * (max_len - item_len)
            line[j] = item

    sep = ' ' * num_sep_spaces
    for line in lines:
        yield sep.join(line)