oct
Loading...
Searching...
No Matches
terminal.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# oct/core/terminal.py
4
5"""
6Purpose
7-------
8Provide shared terminal color support for OCT CLI output.
9
10Responsibilities
11----------------
12- Detect ANSI escape code support (including Windows VT mode).
13- Export color constants used by linter, health, and formatter modules.
14
15Diagnostics
16-----------
17Domain: OCT-CORE
18Levels:
19 L2 - (none) detection runs at import, before diagnostics are active
20 L3 - (none) the colour constants are resolved at import
21 L4 - (none) the Windows VT probe likewise runs at import
22
23Contracts
24---------
25- Color constants are empty strings when ANSI is not supported.
26- Safe to import at module level; no side effects beyond detection.
27
28Dependencies
29------------
30- oct.core.diagnostics (_dbg structured logger; imported but never called, as detection runs at import before init)
31"""
32
33# OCT-LINT: disable-file=dbg_usage reason="Plan 263: both functions run at module level to resolve the colour constants, so any _dbg call here fires before init() and adds a RuntimeWarning to every oct invocation"
34
35import os
36import sys
37from typing import TextIO
38from oct.core.diagnostics import _dbg
39
40
41def supports_ansi() -> bool:
42 """Return True if the terminal supports ANSI escape codes."""
43 return supports_ansi_on(sys.stdout)
44
45
46def supports_ansi_on(stream: TextIO) -> bool:
47 """Return True if *stream* supports ANSI escape codes."""
48 if not hasattr(stream, "isatty") or not stream.isatty():
49 return False
50 if os.name != "nt":
51 return True
52 # Windows 10 1511+ supports ANSI if VT mode is enabled
53 try:
54 import ctypes
55 kernel32 = ctypes.windll.kernel32
56 # Map stream to the correct console handle
57 if stream is sys.stderr:
58 handle = kernel32.GetStdHandle(-12) # STD_ERROR_HANDLE
59 else:
60 handle = kernel32.GetStdHandle(-11) # STD_OUTPUT_HANDLE
61 mode = ctypes.c_ulong()
62 kernel32.GetConsoleMode(handle, ctypes.byref(mode))
63 # ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
64 return bool(mode.value & 0x0004)
65 except Exception:
66 return False
67
68
69if supports_ansi():
70 CYAN = "\033[96m"
71 GREEN = "\033[92m"
72 RED = "\033[91m"
73 YELLOW = "\033[93m"
74 RESET = "\033[0m"
75else:
76 CYAN = GREEN = RED = YELLOW = RESET = ""
bool supports_ansi()
Definition terminal.py:41
bool supports_ansi_on(TextIO stream)
Definition terminal.py:46