|
7 | 7 | """
|
8 | 8 | import logging
|
9 | 9 | import re
|
| 10 | +import shlex |
10 | 11 | import shutil
|
11 | 12 | import subprocess
|
12 | 13 | import sys
|
@@ -150,6 +151,152 @@ def set_option(
|
150 | 151 |
|
151 | 152 | return self
|
152 | 153 |
|
| 154 | + @t.overload |
| 155 | + def show_options( |
| 156 | + self, |
| 157 | + g: t.Optional[bool], |
| 158 | + scope: t.Optional[OptionScope], |
| 159 | + include_hooks: t.Optional[bool], |
| 160 | + include_parents: t.Optional[bool], |
| 161 | + values_only: t.Literal[True], |
| 162 | + ) -> t.List[str]: |
| 163 | + ... |
| 164 | + |
| 165 | + @t.overload |
| 166 | + def show_options( |
| 167 | + self, |
| 168 | + g: t.Optional[bool], |
| 169 | + scope: t.Optional[OptionScope], |
| 170 | + include_hooks: t.Optional[bool], |
| 171 | + include_parents: t.Optional[bool], |
| 172 | + values_only: t.Literal[None] = None, |
| 173 | + ) -> "WindowOptionDict": |
| 174 | + ... |
| 175 | + |
| 176 | + @t.overload |
| 177 | + def show_options( |
| 178 | + self, |
| 179 | + g: t.Optional[bool] = None, |
| 180 | + scope: t.Optional[OptionScope] = None, |
| 181 | + include_hooks: t.Optional[bool] = None, |
| 182 | + include_parents: t.Optional[bool] = None, |
| 183 | + values_only: t.Literal[False] = False, |
| 184 | + ) -> "WindowOptionDict": |
| 185 | + ... |
| 186 | + |
| 187 | + def show_options( |
| 188 | + self, |
| 189 | + g: t.Optional[bool] = False, |
| 190 | + scope: t.Optional[OptionScope] = OptionScope.Window, |
| 191 | + include_hooks: t.Optional[bool] = None, |
| 192 | + include_parents: t.Optional[bool] = None, |
| 193 | + values_only: t.Optional[bool] = False, |
| 194 | + ) -> t.Union["WindowOptionDict", t.List[str]]: |
| 195 | + """Return a dict of options for the window. |
| 196 | +
|
| 197 | + Parameters |
| 198 | + ---------- |
| 199 | + g : str, optional |
| 200 | + Pass ``-g`` flag for global variable, default False. |
| 201 | + """ |
| 202 | + tmux_args: t.Tuple[str, ...] = () |
| 203 | + |
| 204 | + if g: |
| 205 | + tmux_args += ("-g",) |
| 206 | + |
| 207 | + if scope is not None: |
| 208 | + assert scope in OPTION_SCOPE_FLAG_MAP |
| 209 | + tmux_args += (OPTION_SCOPE_FLAG_MAP[scope],) |
| 210 | + |
| 211 | + if include_parents is not None and include_parents: |
| 212 | + tmux_args += ("-A",) |
| 213 | + |
| 214 | + if include_hooks is not None and include_hooks: |
| 215 | + tmux_args += ("-H",) |
| 216 | + |
| 217 | + if values_only is not None and values_only: |
| 218 | + tmux_args += ("-v",) |
| 219 | + |
| 220 | + cmd = self.cmd("show-options", *tmux_args) |
| 221 | + |
| 222 | + output = cmd.stdout |
| 223 | + |
| 224 | + # The shlex.split function splits the args at spaces, while also |
| 225 | + # retaining quoted sub-strings. |
| 226 | + # shlex.split('this is "a test"') => ['this', 'is', 'a test'] |
| 227 | + |
| 228 | + window_options: "WindowOptionDict" = {} |
| 229 | + for item in output: |
| 230 | + try: |
| 231 | + key, val = shlex.split(item) |
| 232 | + except ValueError: |
| 233 | + logger.exception(f"Error extracting option: {item}") |
| 234 | + assert isinstance(key, str) |
| 235 | + assert isinstance(val, str) |
| 236 | + |
| 237 | + if isinstance(val, str) and val.isdigit(): |
| 238 | + window_options[key] = int(val) |
| 239 | + |
| 240 | + return window_options |
| 241 | + |
| 242 | + def show_option( |
| 243 | + self, |
| 244 | + option: str, |
| 245 | + g: bool = False, |
| 246 | + scope: t.Optional[OptionScope] = OptionScope.Window, |
| 247 | + include_hooks: t.Optional[bool] = None, |
| 248 | + include_parents: t.Optional[bool] = None, |
| 249 | + ) -> t.Optional[t.Union[str, int]]: |
| 250 | + """Return option value for the target window. |
| 251 | +
|
| 252 | + todo: test and return True/False for on/off string |
| 253 | +
|
| 254 | + Parameters |
| 255 | + ---------- |
| 256 | + option : str |
| 257 | + g : bool, optional |
| 258 | + Pass ``-g`` flag, global. Default False. |
| 259 | +
|
| 260 | + Raises |
| 261 | + ------ |
| 262 | + :exc:`exc.OptionError`, :exc:`exc.UnknownOption`, |
| 263 | + :exc:`exc.InvalidOption`, :exc:`exc.AmbiguousOption` |
| 264 | + """ |
| 265 | + tmux_args: t.Tuple[t.Union[str, int], ...] = () |
| 266 | + |
| 267 | + if g: |
| 268 | + tmux_args += ("-g",) |
| 269 | + |
| 270 | + if scope is not None: |
| 271 | + assert scope in OPTION_SCOPE_FLAG_MAP |
| 272 | + tmux_args += (OPTION_SCOPE_FLAG_MAP[scope],) |
| 273 | + |
| 274 | + if include_parents is not None and include_parents: |
| 275 | + tmux_args += ("-A",) |
| 276 | + |
| 277 | + if include_hooks is not None and include_hooks: |
| 278 | + tmux_args += ("-H",) |
| 279 | + |
| 280 | + tmux_args += (option,) |
| 281 | + |
| 282 | + cmd = self.cmd("show-options", *tmux_args) |
| 283 | + |
| 284 | + if len(cmd.stderr): |
| 285 | + handle_option_error(cmd.stderr[0]) |
| 286 | + |
| 287 | + window_options_output = cmd.stdout |
| 288 | + |
| 289 | + if not len(window_options_output): |
| 290 | + return None |
| 291 | + |
| 292 | + value_raw = next(shlex.split(item) for item in window_options_output) |
| 293 | + |
| 294 | + value: t.Union[str, int] = ( |
| 295 | + int(value_raw[1]) if value_raw[1].isdigit() else value_raw[1] |
| 296 | + ) |
| 297 | + |
| 298 | + return value |
| 299 | + |
153 | 300 |
|
154 | 301 | class EnvironmentMixin:
|
155 | 302 | """Mixin for manager session and server level environment variables in tmux."""
|
|
0 commit comments