aboutsummaryrefslogtreecommitdiff
path: root/src/config.py
blob: ee0d1f822040f38ef234229319ddcc455ddf41f8 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import re,tempfile,shutil,theme

config_keys=["client.focused",
             "client.focused_inactive",
             "client.unfocused",
             "client.urgent",
             "separator",
             "background",
             "statusline",
             "focused_workspace",
             "active_workspace",
             "inactive_workspace",
             "urgent_workspace"]

##### Parsing Utils #####
def contains(r,line):
    """
    Return true if line contains regex r.
    """
    return(re.match(r,line)!=None)
def before_token(token, line):
    """
    Return what is before token in line.
    """
    found=re.search(".*"+token,line)
    if found:
        return(found.group(0)[:-len(token)])
    return("")
def sorted_items(d):
    """
    Mainly used for integration testing (to keep having deterministic results).
    """
    return(sorted(d.items()))
def no_comment(line):
    """
    Remove comment from a line.
    """
    newline=""
    for ch in line:
        if ch=='#':
            break
        else:
            newline+=ch
    return(newline)
#########################

def extract(config_file):
    """
     Return a temporary file path containing the current user configuration
     without any related theme/colors lines.
    """
    f=open(config_file,"r")
    tmp=tempfile.NamedTemporaryFile(mode="w",delete=False)

    in_colors=False
    for line_orig in f:
        line=no_comment(line_orig)
        is_theme_line=False
        for key in config_keys:
            if contains(".*"+key+"\s",line):
                is_theme_line=True
        if contains(".*colors",line):
            in_colors=True
            beforeColor=before_token("colors",line).strip()
            if len(beforeColor)>0:
                tmp.write(beforeColor+"\n")
        if not(is_theme_line) and not(in_colors):
            tmp.write(line_orig)
        if contains(".*}",line) and in_colors:
            in_colors=False    
    f.close()
    tmp.close()
    return(tmp.name)


def extract_theme(config_file):
    """
    Return a ThemeBuilder object of the config_file file.
    """
    f=open(config_file,"r")
    build=theme.ThemeBuilder()
    in_colors=False
    for line_orig in f:
        line=no_comment(line_orig)
        is_theme_line=False
        for key in config_keys:
            if contains(".*"+key+"\s",line):
                is_theme_line=True
        if contains(".*colors",line):
            in_colors=True
        if contains("(\s)*set",line): # If var definition
            build.parse(line_orig)
        elif is_theme_line or in_colors:
            build.parse(line_orig) # Seems to by strange to have comment here
        if contains(".*}",line) and in_colors:
            in_colors=False    
    f.close()
    return(build)


def write_theme(tmp_config,theme):
    """
    Write the theme in a temporary file
    based on tmp_config file.
    """
    f=open(tmp_config,mode="r")
    tmp=tempfile.NamedTemporaryFile(mode="w",delete=False)

    ##### Apply bar theme #####
    bar_theme=theme["bar_colors"]
    in_bar=False
    for line_orig in f:
        line=no_comment(line_orig)
        if contains("(\s)*bar",line):
            in_bar=True
        if contains(".*}",line) and in_bar:
            beforeBrace=before_token("}",line).strip()
            if len(beforeBrace)>0:
                tmp.write(beforeBrace+"\n")
            tmp.write("  colors {\n")
            for key,value in sorted_items(bar_theme):
                if not(isinstance(value,dict)):
                    tmp.write("    "+key+" "+value+"\n")
                else:
                    tmp.write("    "+key+" "+value["border"]+" "+value["background"]+" "+value["text"]+"\n")
            tmp.write("  }\n}\n")
            in_bar=False
        else:
            tmp.write(line_orig)
    tmp.close()
    f.close()
    shutil.move(tmp.name,tmp_config)
    
    ##### Apply client theme #####
    client_theme=theme["window_colors"]
    f=open(tmp_config,mode="a")
    for key,value in sorted_items(client_theme):
        f.write("client."+key+" "+value["border"]+" "+value["background"]+" "+value["text"]+" "+value["indicator"]+" "+value["child_border"]+"\n")
    f.close()


def apply(config_file,theme,dry=False):
    tmp=extract(config_file)
    write_theme(tmp,theme)
    f=open(tmp,mode="r")
    new_config=f.read()
    f.close()
    if not(dry):
        shutil.move(tmp,config_file)
    return(new_config)