diff options
Diffstat (limited to 'tools/tryselect/preset.py')
-rw-r--r-- | tools/tryselect/preset.py | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/tools/tryselect/preset.py b/tools/tryselect/preset.py new file mode 100644 index 0000000000..dc8cba5c57 --- /dev/null +++ b/tools/tryselect/preset.py @@ -0,0 +1,107 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + +import os +import shlex +import subprocess + +import yaml + + +# Ensure strings with ' like fzf query strings get double-quoted: +def represent_str(self, data): + if "'" in data: + return self.represent_scalar("tag:yaml.org,2002:str", data, style='"') + return self.represent_scalar("tag:yaml.org,2002:str", data) + + +yaml.SafeDumper.add_representer(str, represent_str) + + +class PresetHandler: + def __init__(self, path): + self.path = path + self._presets = {} + + @property + def presets(self): + if not self._presets and os.path.isfile(self.path): + with open(self.path) as fh: + self._presets = yaml.safe_load(fh) or {} + + return self._presets + + def __contains__(self, name): + return name in self.presets + + def __getitem__(self, name): + return self.presets[name] + + def __len__(self): + return len(self.presets) + + def __str__(self): + if not self.presets: + return "" + return yaml.safe_dump(self.presets, default_flow_style=False) + + def list(self): + if not self.presets: + print("no presets found") + else: + print(self) + + def edit(self): + if "EDITOR" not in os.environ: + print( + "error: must set the $EDITOR environment variable to use --edit-presets" + ) + return + + subprocess.call(shlex.split(os.environ["EDITOR"]) + [self.path]) + + def save(self, name, **data): + self.presets[name] = data + + with open(self.path, "w") as fh: + fh.write(str(self)) + + +class MergedHandler: + def __init__(self, *paths): + """Helper class for dealing with multiple preset files.""" + self.handlers = [PresetHandler(p) for p in paths] + + def __contains__(self, name): + return any(name in handler for handler in self.handlers) + + def __getitem__(self, name): + for handler in self.handlers: + if name in handler: + return handler[name] + raise KeyError(name) + + def __len__(self): + return sum(len(h) for h in self.handlers) + + def __str__(self): + all_presets = { + k: v for handler in self.handlers for k, v in handler.presets.items() + } + return yaml.safe_dump(all_presets, default_flow_style=False) + + def list(self): + if len(self) == 0: + print("no presets found") + return + + for handler in self.handlers: + val = str(handler) + if val: + val = "\n ".join( + [""] + val.splitlines() + [""] + ) # indent all lines by 2 spaces + print("Presets from {}:".format(handler.path)) + print(val) |