| 117 | |
| 118 | |
| 119 | def open_extern(): |
| 120 | for path in _default_configs: |
| 121 | path = util.expand_path(path) |
| 122 | if os.access(path, os.R_OK | os.W_OK): |
| 123 | break |
| 124 | else: |
| 125 | log.warning("Unable to find any writable configuration file") |
| 126 | return 1 |
| 127 | |
| 128 | if util.WINDOWS: |
| 129 | openers = ("explorer", "notepad") |
| 130 | else: |
| 131 | openers = ("xdg-open", "open") |
| 132 | if editor := os.environ.get("EDITOR"): |
| 133 | openers = (editor,) + openers |
| 134 | |
| 135 | import shutil |
| 136 | for opener in openers: |
| 137 | if opener := shutil.which(opener): |
| 138 | break |
| 139 | else: |
| 140 | log.warning("Unable to find a program to open '%s' with", path) |
| 141 | return 1 |
| 142 | |
| 143 | log.info("Running '%s %s'", opener, path) |
| 144 | retcode = util.Popen((opener, path)).wait() |
| 145 | |
| 146 | if not retcode: |
| 147 | try: |
| 148 | with open(path, encoding="utf-8") as fp: |
| 149 | _load(fp.read()) |
| 150 | except Exception as exc: |
| 151 | log.warning("%s when parsing '%s': %s", |
| 152 | exc.__class__.__name__, path, exc) |
| 153 | return 2 |
| 154 | |
| 155 | return retcode |
| 156 | |
| 157 | |
| 158 | def status(): |