This commit is contained in:
Jeffrey C. Ollie 2023-10-13 09:51:16 -05:00
parent f1efca7ea8
commit bfe7dedd6f
No known key found for this signature in database
GPG key ID: F936E4DCB7E25F15
3 changed files with 148 additions and 12 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/result*
/.venv
__pycache__

View file

@ -1,6 +1,9 @@
"""Configure logging."""
import base64
from enum import Enum
from enum import IntEnum
from enum import auto
import logging
import pathlib
import re
@ -23,7 +26,65 @@ class ANSIColor(IntEnum):
WHITE = 8
class Mode(Enum):
C0 = auto()
C1 = auto()
class ANSI:
mode: Mode
SOH = "\u0001"
STX = "\u0002"
BEL = "\u0007"
BS = "\u0008"
HT = "\u0009"
LF = "\u000a"
VT = "\u000b"
FF = "\u000c"
CR = "\u000d"
ESC = "\u001b"
DEL = "\u007f"
def __init__(self, mode: Mode = Mode.C0):
self.mode = mode
@property
def DCS(self: Self) -> str:
"""Device Control String"""
match self.mode:
case Mode.C1:
return "\u008d"
case Mode.C0 | _:
return f"{self.ESC}P"
@property
def CSI(self: Self) -> str:
"""Control Sequence Introducer"""
match self.mode:
case Mode.C1:
return "\u009b"
case Mode.C0 | _:
return f"{self.ESC}["
@property
def ST(self: Self) -> str:
"""String Terminator"""
match self.mode:
case Mode.C1:
return "\u009c"
case Mode.C0 | _:
return f"{self.ESC}\\"
@property
def OSC(self: Self) -> str:
"""Operating System Command"""
match self.mode:
case Mode.C1:
return "\u009d"
case Mode.C0 | _:
return f"{self.ESC}]"
def __getattr__(self: Self, item: str) -> str:
return self.color(item)
@ -42,7 +103,7 @@ class ANSI:
try:
color = ANSIColor[item]
return f"\u001b[1;{color+offset:d}{extra}m"
return f"{self.CSI}1;{color+offset:d}{extra}m"
except KeyError:
return self.fg24bitrgb(*(getrgb(item)[:3]))
@ -54,6 +115,10 @@ class ANSI:
def white(self: Self) -> str:
return self.color("white")
@property
def green(self: Self) -> str:
return self.color("green")
@property
def blue(self: Self) -> str:
return self.color("blue")
@ -64,37 +129,76 @@ class ANSI:
@property
def reset(self: Self) -> str:
return "\u001b[0m"
return f"{self.CSI}0m"
@property
def bold(self: Self) -> str:
return "\u001b[1m"
return f"{self.CSI}1m"
@property
def faint(self: Self) -> str:
return "\u001b[2m"
return f"{self.CSI}2m"
@property
def italic(self: Self) -> str:
return "\u001b[3m"
return f"{self.CSI}3m"
@property
def underline(self: Self) -> str:
return "\u001b[4m"
return f"{self.CSI}4m"
@property
def reversed(self: Self) -> str:
return "\u001b[7m"
return f"{self.CSI}7m"
def icon_name_and_window_title(self: Self, text: str) -> str:
return f"{self.OSC}0;{text}{self.ST}"
def icon_name(self: Self, text: str) -> str:
return f"{self.OSC}1;{text}{self.ST}"
def window_title(self: Self, text: str) -> str:
return f"{self.OSC}2;{text}{self.ST}"
def hyperlink(self: Self, link: str, text: str) -> str:
return f"{self.OSC}8;;{link}{self.ST}{text}{self.OSC}8;;{self.ST}"
def post_notification(self: Self, message: str) -> str:
return f"{self.OSC}9;{message}{self.ST}"
def write_to_pastboard(self: Self, pasteboard: str, data: str) -> str:
return f"{self.OSC}52;{pasteboard};{base64.b64encode(data).decode()}{self.ST}"
def query_pasteboard(self: Self, pasteboard: str) -> str:
return f"{self.OSC}52;{pasteboard};?{self.ST}"
def copy_to_clipboard(self: Self, clipboard_name: str) -> str:
return f"{self.OSC}1337;CopyToClipboard={clipboard_name}{self.ST}"
def end_copy(self: Self) -> str:
return f"{self.OSC}1337;EndCopy{self.ST}"
def clear_scrollback_history(self: Self) -> str:
return f"{self.OSC}1337;ClearScrollback{self.ST}"
def set_current_directory(self: Self, dir: str) -> str:
return f"{self.OSC}1337;CurrentDir={dir}{self.ST}"
def change_profile(self: Self, new_profile_name: str) -> str:
return f"{self.OSC}1337;SetProfile={new_profile_name}{self.ST}"
def steal_focus(self: Self) -> str:
return f"{self.OSC}1337;StealFocus{self.ST}"
def fg8bit(self: Self, code: int) -> str:
assert code >= 0
assert code < 256
code = f"\u001b[38;5;{code}m"
code = f"{self.CSI}38;5;{code}m"
def bg8bit(self: Self, code: int) -> str:
assert code >= 0
assert code < 256
return f"\u001b[48;5;{code}m"
return f"{self.CSI}48;5;{code}m"
def fg24bitrgb(self: Self, red: int, green: int, blue: int) -> str:
assert red >= 0
@ -103,7 +207,7 @@ class ANSI:
assert green < 256
assert blue >= 0
assert blue < 256
return f"\u001b[38;2;{red};{green};{blue}m"
return f"{self.CSI}38;2;{red};{green};{blue}m"
def bg24bitrgb(self: Self, red: int, green: int, blue: int) -> str:
assert red >= 0
@ -112,7 +216,7 @@ class ANSI:
assert green < 256
assert blue >= 0
assert blue < 256
return f"\u001b[48;2;{red};{green};{blue}m"
return f"{self.CSI}48;2;{red};{green};{blue}m"
# def fg24bitcmy(self, cyan: int, magenta: int, yellow: int) -> str:
# assert cyan >= 0
@ -121,12 +225,41 @@ class ANSI:
# assert magenta < 256
# assert yellow >= 0
# assert yellow < 256
# return f"\u001b[38:2::{cyan};{magenta};{yellow}:::m"
# return f"{self.OSC}38:2::{cyan};{magenta};{yellow}:::m"
ansi = ANSI()
class BashPromptBuilder:
ansi: ANSI
ESC = "\\e"
BEL = "\\a"
prompt = "\\$"
current_working_directory = "\\w"
username = "\\u"
hostname_short = "\\h"
hostname_long = "\\H"
@property
def RL_PROMPT_START_IGNORE(self: Self) -> str:
return self.ansi.SOH
@property
def RL_PROMPT_END_IGNORE(self: Self) -> str:
return self.ansi.STX
def __init__(self: Self, ansi: ANSI = ansi) -> None:
self.ansi = ansi
def wrap_nonprinting(self: Self, text: str) -> str:
return f"{self.RL_PROMPT_START_IGNORE}{text}{self.RL_PROMPT_END_IGNORE}"
def title_bar(self: Self, text: str) -> str:
return self.wrap_nonprinting(self.ansi.icon_name_and_window_title(text))
class JLogFormatter(logging.Formatter):
"""Format time the way it SHOULD be done."""