mirror of https://github.com/Textualize/rich.git
detect windows
This commit is contained in:
parent
d3bd98712c
commit
fb158f81a2
|
@ -0,0 +1,64 @@
|
|||
import sys
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowsConsoleFeatures:
|
||||
"""Windows features available."""
|
||||
|
||||
vt: bool
|
||||
truecolor: bool
|
||||
|
||||
|
||||
try:
|
||||
import ctypes
|
||||
from ctypes import wintypes
|
||||
from ctypes import LibraryLoader
|
||||
|
||||
windll = LibraryLoader(ctypes.WinDLL)
|
||||
except (AttributeError, ImportError):
|
||||
|
||||
# Fallback if we can't load the Windows DLL
|
||||
def get_windows_console_features() -> WindowsConsoleFeatures:
|
||||
features = WindowsConsoleFeatures()
|
||||
return features
|
||||
|
||||
|
||||
else:
|
||||
|
||||
STDOUT = -11
|
||||
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
|
||||
_GetConsoleMode = windll.kernel32.GetConsoleMode
|
||||
_GetConsoleMode.argtypes = [wintypes.HANDLE, wintypes.LPDWORD]
|
||||
_GetConsoleMode.restype = wintypes.BOOL
|
||||
|
||||
_GetStdHandle = windll.kernel32.GetStdHandle
|
||||
_GetStdHandle.argtypes = [
|
||||
wintypes.DWORD,
|
||||
]
|
||||
_GetStdHandle.restype = wintypes.HANDLE
|
||||
|
||||
def get_windows_console_features() -> WindowsConsoleFeatures:
|
||||
"""Get windows console fatures.
|
||||
|
||||
Returns:
|
||||
WindowsConsoleFeatures: An instance of WindowsConsoleFeatures.
|
||||
"""
|
||||
handle = _GetStdHandle(STDOUT)
|
||||
console_mode = wintypes.DWORD()
|
||||
result = _GetConsoleMode(handle, console_mode)
|
||||
vt = bool(result and console_mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
truecolor = False
|
||||
if vt:
|
||||
win_version = sys.getwindowsversion()
|
||||
truecolor = win_version.major > 10 or (
|
||||
win_version.major == 10 and win_version.build > 15063
|
||||
)
|
||||
features = WindowsConsoleFeatures(vt=vt, truecolor=truecolor)
|
||||
return features
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(get_windows_console_features())
|
||||
|
|
@ -21,6 +21,7 @@ from typing import (
|
|||
Iterable,
|
||||
List,
|
||||
Optional,
|
||||
TYPE_CHECKING,
|
||||
NamedTuple,
|
||||
Union,
|
||||
)
|
||||
|
@ -44,6 +45,8 @@ from .segment import Segment
|
|||
from .text import Text, TextType
|
||||
from .theme import Theme
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ._windows import WindowsConsoleFeatures
|
||||
|
||||
WINDOWS = platform.system() == "Windows"
|
||||
|
||||
|
@ -244,9 +247,22 @@ class RenderHook:
|
|||
return renderables
|
||||
|
||||
|
||||
_windows_console_features: Optional["WindowsConsoleFeatures"] = None
|
||||
|
||||
|
||||
def get_windows_console_features() -> "WindowsConsoleFeatures":
|
||||
global _windows_console_features
|
||||
if _windows_console_features is not None:
|
||||
return _windows_console_features
|
||||
from ._windows import get_windows_console_features
|
||||
|
||||
_windows_console_features = get_windows_console_features()
|
||||
return _windows_console_features
|
||||
|
||||
|
||||
def detect_legacy_windows() -> bool:
|
||||
"""Detect legacy Windows."""
|
||||
return "WINDIR" in os.environ and "WT_SESSION" not in os.environ
|
||||
return WINDOWS and not get_windows_console_features().vt
|
||||
|
||||
|
||||
if detect_legacy_windows(): # pragma: no cover
|
||||
|
@ -364,19 +380,26 @@ class Console:
|
|||
|
||||
def _detect_color_system(self) -> Optional[ColorSystem]:
|
||||
"""Detect color system from env vars."""
|
||||
if not self.is_terminal:
|
||||
if not self.is_terminal or "NO_COLOR" in os.environ:
|
||||
return None
|
||||
if self.legacy_windows: # pragma: no cover
|
||||
return ColorSystem.WINDOWS
|
||||
if "WT_SESSION" in os.environ:
|
||||
# Exception for Windows terminal
|
||||
return ColorSystem.TRUECOLOR
|
||||
color_term = os.environ.get("COLORTERM", "").strip().lower()
|
||||
return (
|
||||
ColorSystem.TRUECOLOR
|
||||
if color_term in ("truecolor", "24bit")
|
||||
else ColorSystem.EIGHT_BIT
|
||||
)
|
||||
if WINDOWS: # pragma: no cover
|
||||
if self.legacy_windows: # pragma: no cover
|
||||
return ColorSystem.WINDOWS
|
||||
windows_console_features = get_windows_console_features()
|
||||
return (
|
||||
ColorSystem.TRUECOLOR
|
||||
if windows_console_features.truecolor
|
||||
else ColorSystem.EIGHT_BIT
|
||||
)
|
||||
else:
|
||||
if self.is_jupyter:
|
||||
return ColorSystem.TRUECOLOR
|
||||
color_term = os.environ.get("COLORTERM", "").strip().lower()
|
||||
return (
|
||||
ColorSystem.TRUECOLOR
|
||||
if color_term in ("truecolor", "24bit")
|
||||
else ColorSystem.EIGHT_BIT
|
||||
)
|
||||
|
||||
def _enter_buffer(self) -> None:
|
||||
"""Enter in to a buffer context, and buffer all output."""
|
||||
|
|
|
@ -247,9 +247,9 @@ class Style:
|
|||
for bit in range(9, 13):
|
||||
if attributes & (1 << bit):
|
||||
append(_style_map[bit])
|
||||
if self._color is not None:
|
||||
if self._color is not None and color_system:
|
||||
sgr.extend(self._color.downgrade(color_system).get_ansi_codes())
|
||||
if self._bgcolor is not None:
|
||||
if self._bgcolor is not None and color_system:
|
||||
sgr.extend(
|
||||
self._bgcolor.downgrade(color_system).get_ansi_codes(
|
||||
foreground=False
|
||||
|
|
Loading…
Reference in New Issue