diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..329efad --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +*.pyc +config.gie diff --git a/config.default.gie b/config.default.gie new file mode 100644 index 0000000..5bc65c0 --- /dev/null +++ b/config.default.gie @@ -0,0 +1,59 @@ +# vim: set ft=dosini: +# +# Comments start with a # or ; and always exist on a line of their own. +# +# Key value pairs are in the form of key = value. Keys cannot have whitespaces +# or = in them. Values can have any character as part of them. Surrounding +# spaces in values are stripped away. To keep surrounding spaces as a part of +# the value. Although, keys are case-sensitive in gINIe, wish treats them case- +# insensitively. +# +# Block names are enclosed in [] (e.g. [core]). Block names are case sensitive. +# All key value pairs after a block starts and before the next block begins are +# considered a part of that block. All key value pairs must be in a block. +# +# Available Blocks: +# +# core: Core block configures Wish itself. Available keys are: +# - auto_newline: Automatically add a newline if last line of output +# doesn't end in newline. (0 to disable, 1 to enable) +# - theme: Wish theme. +# - powerline: Enable / Disable powerline. (0 to disable, 1 to enable) +# +# plugin: Adds a plugin to the section the block is added to. All config for +# that plugin goes there. The key "name" defines the plugin to use. +# Plugin blocks outside a section are ignored. +# +# Section names are enclosed in || (e.g. |left|). All blocks after a section +# starts and before the next section begins are considered a part of that +# section. Blocks don't necessarily need to be in a section. +# +# Available sections are left, right for left prompt and right prompt +# respectively. + +[core] +auto_newline = 1 +powerline = 1 +theme = plain + +|left| +[plugin] +name = exit_code_smiley + +[plugin] +name = bg_jobs + +[plugin] +name = date +format = %d %b %H:%M + +[plugin] +name = path + +[plugin] +name = newline + +[plugin] +name = vcs + +|right| diff --git a/ginie.py b/ginie.py new file mode 100755 index 0000000..6cff476 --- /dev/null +++ b/ginie.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +"gINIe Parser for Wish" + +import re +import sys + + +class GinieParseError(ValueError): + "Exception Class for errors in" + + +def loads(string): + """ + Deserialize `string` (a `str` instance containing a gINIe document) + into a Python list. + + Return Value: List of `block` and `section` dicts + + `block` dicts are of form + { + 'type': 'block', + 'name': 'name_of_block_as_in_config', + 'config': {} + } + where `name` and `config` keys are based on the gINIe document. + + `section` dicts are of form + + { + 'type': 'block', + 'name': 'name_of_block_as_in_config', + 'blocks': [] + } + where `name` and `blocks` keys are based on the gINIe document and blocks + is a list of block dicts found in the section. + """ + config = [] + section_re = re.compile(r"^\|(?P
.+)\|$") + block_re = re.compile(r"^\[(?P[^\]]*)\]$") + line_re = re.compile(r"^\s*(?P[^\s=]+)(\s*)=\s*?(?P.*)$") + empty_re = re.compile(r"^\s*$") + comment_re = re.compile(r"^\s*(#|;)") + current_block = None + current_section = None + for idx, line in enumerate(string.splitlines()): + idx += 1 # Since line numbers begin with 1 + # Skip comments and empty lines + if empty_re.match(line) or comment_re.match(line): + continue + + # Section parsing + if line.startswith("|"): + match = section_re.match(line) + if match is None: + err = "Invalid line {}".format(idx) + raise GinieParseError(err) + current_section = { + "type": "section", + "name": match.group("section"), + "blocks": [] + } + config.append(current_section) + continue + + # Block Parsing + if line.startswith("["): + match = block_re.match(line) + if match is None: + err = "Invalid block name on line {}".format(idx) + raise GinieParseError(err) + current_block = { + "type": "block", + "name": match.group("block"), + "config": {} + } + if current_section is None: + config.append(current_block) + else: + current_section["blocks"].append(current_block) + continue + + # If it is neither a comment, nor a section, nor a block, it has to be + # a key, value pair. + if current_block is None: + raise GinieParseError("Found lines outside a block") + + match = line_re.match(line) + if match is None: + raise GinieParseError("Invalid line {}: {}".format(idx, line)) + + value = match.group('value').strip() + if value: + if value[0] == value[-1] == "'" or value[0] == value[-1] == '"': + value = value[1:-1] + current_block["config"][match.group('key').strip()] = value + + return config + + +def load(file): + """ + Deserialize `file` (a file-like object containing a gINIe document) + into a Python list. + + Return Value: List of `block` and `section` dicts + + `block` dicts are of form + { + 'type': 'block', + 'name': 'name_of_block_as_in_config', + 'config': {} + } + where `name` and `config` keys are based on the gINIe document. + + `section` dicts are of form + + { + 'type': 'block', + 'name': 'name_of_block_as_in_config', + 'blocks': [] + } + where `name` and `blocks` keys are based on the gINIe document and blocks + is a list of block dicts found in the section. + """ + return loads(file.read()) + + +if __name__ == "__main__": + if len(sys.argv) == 1: + print("Usage: {} file.gie|-".format(sys.argv[0])) + elif sys.argv[1] == '-': + print(load(sys.stdin)) + else: + with open(sys.argv[1]) as source: + print(load(source)) diff --git a/install.sh b/install.sh index c1eafd6..ae5b083 100755 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash if hash git; then - git clone https://gitlab.com/ceda_ei/wish.git $HOME/.config/wish.git + git clone https://gitlab.com/ceda_ei/Wish.git $HOME/.config/wish else curl https://gitlab.com/ceda_ei/wish/-/archive/master/wish-master.tar -o /tmp/wish.tar mkdir $HOME/.config 2> /dev/null @@ -10,12 +10,11 @@ else mv wish-master/ wish/ mv wish/ $HOME/.config/ fi +cp $HOME/.config/wish/config.default.gie $HOME/.config/wish/config.gie cat >> ~/.bashrc < /dev/null && break done