refactor: ansi module cleanup

This commit is contained in:
Jan De Dobbeleer 2021-04-20 21:30:46 +02:00 committed by Jan De Dobbeleer
parent c24ca82f17
commit b11b69f0e8
12 changed files with 162 additions and 182 deletions

View file

@ -9,7 +9,7 @@ const (
ANSIRegex = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
)
type ansiFormats struct {
type ansiUtils struct {
shell string
linechange string
left string
@ -32,7 +32,7 @@ type ansiFormats struct {
strikethrough string
}
func (a *ansiFormats) init(shell string) {
func (a *ansiUtils) init(shell string) {
a.shell = shell
switch shell {
case zsh:
@ -98,7 +98,7 @@ func (a *ansiFormats) init(shell string) {
}
}
func (a *ansiFormats) lenWithoutANSI(text string) int {
func (a *ansiUtils) lenWithoutANSI(text string) int {
if len(text) == 0 {
return 0
}
@ -119,7 +119,7 @@ func (a *ansiFormats) lenWithoutANSI(text string) int {
return len(runeText)
}
func (a *ansiFormats) generateHyperlink(text string) string {
func (a *ansiUtils) generateHyperlink(text string) string {
// hyperlink matching
results := findNamedRegexMatch("(?P<all>(?:\\[(?P<name>.+)\\])(?:\\((?P<url>.*)\\)))", text)
if len(results) != 3 {
@ -131,7 +131,7 @@ func (a *ansiFormats) generateHyperlink(text string) string {
return strings.Replace(text, results["all"], hyperlink, 1)
}
func (a *ansiFormats) formatText(text string) string {
func (a *ansiUtils) formatText(text string) string {
results := findAllNamedRegexMatch("(?P<context><(?P<format>[buis])>(?P<text>[^<]+)</[buis]>)", text)
for _, result := range results {
var formatted string
@ -149,3 +149,25 @@ func (a *ansiFormats) formatText(text string) string {
}
return text
}
func (a *ansiUtils) carriageForward() string {
return fmt.Sprintf(a.left, 1000)
}
func (a *ansiUtils) getCursorForRightWrite(text string, offset int) string {
strippedLen := a.lenWithoutANSI(text) + -offset
return fmt.Sprintf(a.right, strippedLen)
}
func (a *ansiUtils) changeLine(numberOfLines int) string {
position := "B"
if numberOfLines < 0 {
position = "F"
numberOfLines = -numberOfLines
}
return fmt.Sprintf(a.linechange, numberOfLines, position)
}
func (a *ansiUtils) consolePwd(pwd string) string {
return fmt.Sprintf(a.osc99, pwd)
}

View file

@ -43,10 +43,16 @@ func getColorFromName(colorName string, isBackground bool) (string, error) {
return "", errors.New("color name does not exist")
}
type colorWriter interface {
write(background, foreground, text string)
string() string
reset()
}
// AnsiColor writes colorized strings
type AnsiColor struct {
builder strings.Builder
formats *ansiFormats
ansi *ansiUtils
terminalBackground string
}
@ -75,24 +81,24 @@ func (a *AnsiColor) writeColoredText(background, foreground, text string) {
if foreground == Transparent && background != "" && a.terminalBackground != "" {
bgAnsiColor := a.getAnsiFromColorString(background, true)
fgAnsiColor := a.getAnsiFromColorString(a.terminalBackground, false)
coloredText := fmt.Sprintf(a.formats.colorFull, bgAnsiColor, fgAnsiColor, text)
coloredText := fmt.Sprintf(a.ansi.colorFull, bgAnsiColor, fgAnsiColor, text)
a.builder.WriteString(coloredText)
return
}
if foreground == Transparent && background != "" {
ansiColor := a.getAnsiFromColorString(background, false)
coloredText := fmt.Sprintf(a.formats.colorTransparent, ansiColor, text)
coloredText := fmt.Sprintf(a.ansi.colorTransparent, ansiColor, text)
a.builder.WriteString(coloredText)
return
} else if background == "" || background == Transparent {
ansiColor := a.getAnsiFromColorString(foreground, false)
coloredText := fmt.Sprintf(a.formats.colorSingle, ansiColor, text)
coloredText := fmt.Sprintf(a.ansi.colorSingle, ansiColor, text)
a.builder.WriteString(coloredText)
return
}
bgAnsiColor := a.getAnsiFromColorString(background, true)
fgAnsiColor := a.getAnsiFromColorString(foreground, false)
coloredText := fmt.Sprintf(a.formats.colorFull, bgAnsiColor, fgAnsiColor, text)
coloredText := fmt.Sprintf(a.ansi.colorFull, bgAnsiColor, fgAnsiColor, text)
a.builder.WriteString(coloredText)
}
@ -102,7 +108,7 @@ func (a *AnsiColor) writeAndRemoveText(background, foreground, text, textToRemov
}
func (a *AnsiColor) write(background, foreground, text string) {
text = a.formats.formatText(text)
text = a.ansi.formatText(text)
// first we match for any potentially valid colors enclosed in <>
match := findAllNamedRegexMatch(`<(?P<foreground>[^,>]+)?,?(?P<background>[^>]+)?>(?P<content>[^<]*)<\/>`, text)
for i := range match {

View file

@ -12,10 +12,10 @@ const (
)
func TestWriteAndRemoveText(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := renderer.writeAndRemoveText("#193549", "#fff", "This is white, ", "This is white, ", inputText)
assert.Equal(t, "<#ff5733>this is orange</>, white again", text)
@ -23,10 +23,10 @@ func TestWriteAndRemoveText(t *testing.T) {
}
func TestWriteAndRemoveTextColored(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := renderer.writeAndRemoveText("#193549", "#ff5733", "this is orange", "<#ff5733>this is orange</>", inputText)
assert.Equal(t, "This is white, , white again", text)
@ -34,20 +34,20 @@ func TestWriteAndRemoveTextColored(t *testing.T) {
}
func TestWriteColorOverride(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
renderer.write("#193549", "#ff5733", inputText)
assert.NotContains(t, renderer.string(), "<#ff5733>")
}
func TestWriteColorOverrideBackground(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "This is white, <,#000000>this is black</>, white again"
renderer.write("#193549", "#ff5733", text)
@ -55,10 +55,10 @@ func TestWriteColorOverrideBackground(t *testing.T) {
}
func TestWriteColorOverrideBackground16(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "This is default <,white> this background is changed</> default again"
renderer.write("#193549", "#ff5733", text)
@ -68,10 +68,10 @@ func TestWriteColorOverrideBackground16(t *testing.T) {
}
func TestWriteColorOverrideBoth(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "This is white, <#000000,#ffffff>this is black</>, white again"
renderer.write("#193549", "#ff5733", text)
@ -80,10 +80,10 @@ func TestWriteColorOverrideBoth(t *testing.T) {
}
func TestWriteColorOverrideBoth16(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "This is white, <black,white>this is black</>, white again"
renderer.write("#193549", "#ff5733", text)
@ -92,10 +92,10 @@ func TestWriteColorOverrideBoth16(t *testing.T) {
}
func TestWriteColorOverrideDouble(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "<#ffffff>jan</>@<#ffffff>Jans-MBP</>"
renderer.write("#193549", "#ff5733", text)
@ -104,10 +104,10 @@ func TestWriteColorOverrideDouble(t *testing.T) {
}
func TestWriteColorTransparent(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "This is white"
renderer.writeColoredText("#193549", Transparent, text)
@ -115,10 +115,10 @@ func TestWriteColorTransparent(t *testing.T) {
}
func TestWriteColorName(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "This is white, <red>this is red</>, white again"
renderer.write("#193549", "red", text)
@ -126,10 +126,10 @@ func TestWriteColorName(t *testing.T) {
}
func TestWriteColorInvalid(t *testing.T) {
formats := &ansiFormats{}
formats.init("pwsh")
ansi := &ansiUtils{}
ansi.init("pwsh")
renderer := &AnsiColor{
formats: formats,
ansi: ansi,
}
text := "This is white, <invalid>this is orange</>, white again"
renderer.write("#193549", "invalid", text)

View file

@ -1,61 +0,0 @@
package main
import (
"fmt"
"strings"
)
// AnsiRenderer exposes functionality using ANSI
type AnsiRenderer struct {
builder strings.Builder
formats *ansiFormats
}
func (r *AnsiRenderer) carriageForward() {
r.builder.WriteString(fmt.Sprintf(r.formats.left, 1000))
}
func (r *AnsiRenderer) setCursorForRightWrite(text string, offset int) {
strippedLen := r.formats.lenWithoutANSI(text) + -offset
r.builder.WriteString(fmt.Sprintf(r.formats.right, strippedLen))
}
func (r *AnsiRenderer) changeLine(numberOfLines int) {
position := "B"
if numberOfLines < 0 {
position = "F"
numberOfLines = -numberOfLines
}
r.builder.WriteString(fmt.Sprintf(r.formats.linechange, numberOfLines, position))
}
func (r *AnsiRenderer) creset() {
r.builder.WriteString(r.formats.creset)
}
func (r *AnsiRenderer) write(text string) {
r.builder.WriteString(text)
// Due to a bug in Powershell, the end of the line needs to be cleared.
// If this doesn't happen, the portion after the prompt gets colored in the background
// color of the line above the new input line. Clearing the line fixes this,
// but can hopefully one day be removed when this is resolved natively.
if r.formats.shell == pwsh || r.formats.shell == powershell5 {
r.builder.WriteString(r.formats.clearEOL)
}
}
func (r *AnsiRenderer) string() string {
return r.builder.String()
}
func (r *AnsiRenderer) saveCursorPosition() {
r.builder.WriteString(r.formats.saveCursorPosition)
}
func (r *AnsiRenderer) restoreCursorPosition() {
r.builder.WriteString(r.formats.restoreCursorPosition)
}
func (r *AnsiRenderer) osc99(pwd string) {
r.builder.WriteString(fmt.Sprintf(r.formats.osc99, pwd))
}

View file

@ -17,7 +17,7 @@ func TestLenWithoutAnsi(t *testing.T) {
{Text: "\\[\x1b[44m\\]hello\\[\x1b[0m\\]", ShellName: bash, Expected: 5},
}
for _, tc := range cases {
a := ansiFormats{}
a := ansiUtils{}
a.init(tc.ShellName)
strippedLength := a.lenWithoutANSI(tc.Text)
assert.Equal(t, 5, strippedLength)
@ -35,7 +35,7 @@ func TestGenerateHyperlinkNoUrl(t *testing.T) {
{Text: "sample text with no url", ShellName: bash, Expected: "sample text with no url"},
}
for _, tc := range cases {
a := ansiFormats{}
a := ansiUtils{}
a.init(tc.ShellName)
hyperlinkText := a.generateHyperlink(tc.Text)
assert.Equal(t, tc.Expected, hyperlinkText)
@ -53,7 +53,7 @@ func TestGenerateHyperlinkWithUrl(t *testing.T) {
{Text: "[google](http://www.google.be)", ShellName: bash, Expected: "\\[\x1b]8;;http://www.google.be\x1b\\\\\\]google\\[\x1b]8;;\x1b\\\\\\]"},
}
for _, tc := range cases {
a := ansiFormats{}
a := ansiUtils{}
a.init(tc.ShellName)
hyperlinkText := a.generateHyperlink(tc.Text)
assert.Equal(t, tc.Expected, hyperlinkText)
@ -71,7 +71,7 @@ func TestGenerateHyperlinkWithUrlNoName(t *testing.T) {
{Text: "[](http://www.google.be)", ShellName: bash, Expected: "[](http://www.google.be)"},
}
for _, tc := range cases {
a := ansiFormats{}
a := ansiUtils{}
a.init(tc.ShellName)
hyperlinkText := a.generateHyperlink(tc.Text)
assert.Equal(t, tc.Expected, hyperlinkText)
@ -91,7 +91,7 @@ func TestFormatText(t *testing.T) {
{Case: "strikethrough", Text: "This <s>is</s> white", Expected: "This \x1b[9mis\x1b[29m white"},
}
for _, tc := range cases {
a := ansiFormats{}
a := ansiUtils{}
a.init("")
formattedText := a.formatText(tc.Text)
assert.Equal(t, tc.Expected, formattedText, tc.Case)

View file

@ -35,14 +35,16 @@ type Block struct {
Newline bool `config:"newline"`
env environmentInfo
color *AnsiColor
writer colorWriter
ansi *ansiUtils
activeSegment *Segment
previousActiveSegment *Segment
}
func (b *Block) init(env environmentInfo, color *AnsiColor) {
func (b *Block) init(env environmentInfo, writer colorWriter, ansi *ansiUtils) {
b.env = env
b.color = color
b.writer = writer
b.ansi = ansi
}
func (b *Block) enabled() bool {
@ -71,6 +73,7 @@ func (b *Block) setStringValues() {
}
func (b *Block) renderSegments() string {
defer b.writer.reset()
for _, segment := range b.Segments {
if !segment.active {
continue
@ -82,7 +85,7 @@ func (b *Block) renderSegments() string {
if b.previousActiveSegment != nil && b.previousActiveSegment.Style == Powerline {
b.writePowerLineSeparator(Transparent, b.previousActiveSegment.background(), true)
}
return b.color.string()
return b.writer.string()
}
func (b *Block) endPowerline() {
@ -100,10 +103,10 @@ func (b *Block) writePowerLineSeparator(background, foreground string, end bool)
symbol = b.previousActiveSegment.PowerlineSymbol
}
if b.activeSegment.InvertPowerline {
b.color.write(foreground, background, symbol)
b.writer.write(foreground, background, symbol)
return
}
b.color.write(background, foreground, symbol)
b.writer.write(background, foreground, symbol)
}
func (b *Block) getPowerlineColor(foreground bool) string {
@ -141,17 +144,17 @@ func (b *Block) renderPlainSegment(text string) {
}
func (b *Block) renderDiamondSegment(text string) {
b.color.write(Transparent, b.activeSegment.background(), b.activeSegment.LeadingDiamond)
b.writer.write(Transparent, b.activeSegment.background(), b.activeSegment.LeadingDiamond)
b.renderText(text)
b.color.write(Transparent, b.activeSegment.background(), b.activeSegment.TrailingDiamond)
b.writer.write(Transparent, b.activeSegment.background(), b.activeSegment.TrailingDiamond)
}
func (b *Block) renderText(text string) {
text = b.color.formats.generateHyperlink(text)
text = b.ansi.generateHyperlink(text)
defaultValue := " "
prefix := b.activeSegment.getValue(Prefix, defaultValue)
postfix := b.activeSegment.getValue(Postfix, defaultValue)
b.color.write(b.activeSegment.background(), b.activeSegment.foreground(), fmt.Sprintf("%s%s%s", prefix, text, postfix))
b.writer.write(b.activeSegment.background(), b.activeSegment.foreground(), fmt.Sprintf("%s%s%s", prefix, text, postfix))
}
func (b *Block) debug() (int, []*SegmentTiming) {
@ -183,8 +186,8 @@ func (b *Block) debug() (int, []*SegmentTiming) {
if b.activeSegment.Style == Powerline {
b.writePowerLineSeparator(Transparent, b.activeSegment.background(), true)
}
segmentTiming.stringValue = b.color.string()
b.color.builder.Reset()
segmentTiming.stringValue = b.writer.string()
b.writer.reset()
}
segmentTimings = append(segmentTimings, &segmentTiming)
}

View file

@ -8,7 +8,7 @@ import (
type consoleTitle struct {
env environmentInfo
config *Config
formats *ansiFormats
ansi *ansiUtils
}
// ConsoleTitleStyle defines how to show the title in the console window
@ -37,7 +37,7 @@ func (t *consoleTitle) getConsoleTitle() string {
default:
title = base(t.getPwd(), t.env)
}
return fmt.Sprintf(t.formats.title, title)
return fmt.Sprintf(t.ansi.title, title)
}
func (t *consoleTitle) getTemplateText() string {

View file

@ -62,12 +62,12 @@ func TestGetConsoleTitle(t *testing.T) {
env.On("getenv", "USERDOMAIN").Return("MyCompany")
env.On("getCurrentUser", nil).Return("MyUser")
env.On("getHostName", nil).Return("MyHost", nil)
formats := &ansiFormats{}
formats.init(tc.ShellName)
ansi := &ansiUtils{}
ansi.init(tc.ShellName)
ct := &consoleTitle{
env: env,
config: config,
formats: formats,
ansi: ansi,
}
got := ct.getConsoleTitle()
assert.Equal(t, tc.Expected, got)
@ -117,12 +117,12 @@ func TestGetConsoleTitleIfGethostnameReturnsError(t *testing.T) {
env.On("getenv", "USERDOMAIN").Return("MyCompany")
env.On("getCurrentUser", nil).Return("MyUser")
env.On("getHostName", nil).Return("", fmt.Errorf("I have a bad feeling about this"))
formats := &ansiFormats{}
formats.init(tc.ShellName)
ansi := &ansiUtils{}
ansi.init(tc.ShellName)
ct := &consoleTitle{
env: env,
config: config,
formats: formats,
ansi: ansi,
}
got := ct.getConsoleTitle()
assert.Equal(t, tc.Expected, got)

View file

@ -9,25 +9,39 @@ import (
type engine struct {
config *Config
env environmentInfo
color *AnsiColor
renderer *AnsiRenderer
colorWriter colorWriter
ansi *ansiUtils
consoleTitle *consoleTitle
// activeBlock *Block
// activeSegment *Segment
// previousActiveSegment *Segment
console strings.Builder
rprompt string
}
func (e *engine) write(text string) {
e.console.WriteString(text)
// Due to a bug in Powershell, the end of the line needs to be cleared.
// If this doesn't happen, the portion after the prompt gets colored in the background
// color of the line above the new input line. Clearing the line fixes this,
// but can hopefully one day be removed when this is resolved natively.
if e.ansi.shell == pwsh || e.ansi.shell == powershell5 {
e.console.WriteString(e.ansi.clearEOL)
}
}
func (e *engine) string() string {
return e.console.String()
}
func (e *engine) render() string {
for _, block := range e.config.Blocks {
e.renderBlock(block)
}
if e.config.ConsoleTitle {
e.renderer.write(e.consoleTitle.getConsoleTitle())
e.write(e.consoleTitle.getConsoleTitle())
}
e.renderer.creset()
e.write(e.ansi.creset)
if e.config.FinalSpace {
e.renderer.write(" ")
e.write(" ")
}
if !e.config.OSC99 {
@ -37,38 +51,37 @@ func (e *engine) render() string {
if e.env.isWsl() {
cwd, _ = e.env.runCommand("wslpath", "-m", cwd)
}
e.renderer.osc99(cwd)
e.write(e.ansi.consolePwd(cwd))
return e.print()
}
func (e *engine) renderBlock(block *Block) {
block.init(e.env, e.color)
block.init(e.env, e.colorWriter, e.ansi)
block.setStringValues()
defer e.color.reset()
if !block.enabled() {
return
}
if block.Newline {
e.renderer.write("\n")
e.write("\n")
}
switch block.Type {
// This is deprecated but leave if to not break current configs
// It is encouraged to used "newline": true on block level
// rather than the standalone the linebreak block
case LineBreak:
e.renderer.write("\n")
e.write("\n")
case Prompt:
if block.VerticalOffset != 0 {
e.renderer.changeLine(block.VerticalOffset)
e.write(e.ansi.changeLine(block.VerticalOffset))
}
switch block.Alignment {
case Right:
e.renderer.carriageForward()
e.write(e.ansi.carriageForward())
blockText := block.renderSegments()
e.renderer.setCursorForRightWrite(blockText, block.HorizontalOffset)
e.renderer.write(blockText)
e.write(e.ansi.getCursorForRightWrite(blockText, block.HorizontalOffset))
e.write(blockText)
case Left:
e.renderer.write(block.renderSegments())
e.write(block.renderSegments())
}
case RPrompt:
e.rprompt = block.renderSegments()
@ -79,7 +92,7 @@ func (e *engine) renderBlock(block *Block) {
func (e *engine) debug() string {
var segmentTimings []*SegmentTiming
largestSegmentNameLength := 0
e.renderer.write("\n\x1b[1mHere are the timings of segments in your prompt:\x1b[0m\n\n")
e.write("\n\x1b[1mHere are the timings of segments in your prompt:\x1b[0m\n\n")
// console title timing
start := time.Now()
@ -96,7 +109,7 @@ func (e *engine) debug() string {
segmentTimings = append(segmentTimings, segmentTiming)
// loop each segments of each blocks
for _, block := range e.config.Blocks {
block.init(e.env, e.color)
block.init(e.env, e.colorWriter, e.ansi)
longestSegmentName, timings := block.debug()
segmentTimings = append(segmentTimings, timings...)
if longestSegmentName > largestSegmentNameLength {
@ -112,9 +125,9 @@ func (e *engine) debug() string {
duration += segment.stringDuration.Milliseconds()
}
segmentName := fmt.Sprintf("%s(%t)", segment.name, segment.enabled)
e.renderer.write(fmt.Sprintf("%-*s - %3d ms - %s\n", largestSegmentNameLength, segmentName, duration, segment.stringValue))
e.write(fmt.Sprintf("%-*s - %3d ms - %s\n", largestSegmentNameLength, segmentName, duration, segment.stringValue))
}
return e.renderer.string()
return e.string()
}
func (e *engine) print() string {
@ -122,18 +135,18 @@ func (e *engine) print() string {
case zsh:
if *e.env.getArgs().Eval {
// escape double quotes contained in the prompt
prompt := fmt.Sprintf("PS1=\"%s\"", strings.ReplaceAll(e.renderer.string(), "\"", "\"\""))
prompt := fmt.Sprintf("PS1=\"%s\"", strings.ReplaceAll(e.string(), "\"", "\"\""))
prompt += fmt.Sprintf("\nRPROMPT=\"%s\"", e.rprompt)
return prompt
}
case pwsh, powershell5, bash, shelly:
if e.rprompt != "" {
e.renderer.saveCursorPosition()
e.renderer.carriageForward()
e.renderer.setCursorForRightWrite(e.rprompt, 0)
e.renderer.write(e.rprompt)
e.renderer.restoreCursorPosition()
e.write(e.ansi.saveCursorPosition)
e.write(e.ansi.carriageForward())
e.write(e.ansi.getCursorForRightWrite(e.rprompt, 0))
e.write(e.rprompt)
e.write(e.ansi.restoreCursorPosition)
}
}
return e.renderer.string()
return e.string()
}

View file

@ -96,7 +96,7 @@ func NewRGBColor(ansiColor string) *RGB {
type ImageRenderer struct {
ansiString string
author string
formats *ansiFormats
ansi *ansiUtils
factor float64
@ -189,7 +189,7 @@ func (ir *ImageRenderer) fontHeight() float64 {
func (ir *ImageRenderer) calculateWidth() int {
longest := 0
for _, line := range strings.Split(ir.ansiString, "\n") {
length := ir.formats.lenWithoutANSI(line)
length := ir.ansi.lenWithoutANSI(line)
if length > longest {
longest = length
}

View file

@ -15,11 +15,11 @@ func runImageTest(content string) error {
return err
}
defer os.Remove(file.Name())
formats := &ansiFormats{}
formats.init(shelly)
ansi := &ansiUtils{}
ansi.init(shelly)
image := &ImageRenderer{
ansiString: content,
formats: formats,
ansi: ansi,
}
image.init()
err = image.SavePNG(poshImagePath)

View file

@ -173,26 +173,23 @@ func main() {
return
}
formats := &ansiFormats{}
formats.init(env.getShellName())
renderer := &AnsiRenderer{
formats: formats,
}
ansi := &ansiUtils{}
ansi.init(env.getShellName())
colorer := &AnsiColor{
formats: formats,
ansi: ansi,
terminalBackground: getConsoleBackgroundColor(env, cfg.TerminalBackground),
}
title := &consoleTitle{
env: env,
config: cfg,
formats: formats,
ansi: ansi,
}
engine := &engine{
config: cfg,
env: env,
color: colorer,
renderer: renderer,
colorWriter: colorer,
consoleTitle: title,
ansi: ansi,
}
if *args.Debug {
@ -209,7 +206,7 @@ func main() {
author: *args.Author,
cursorPadding: *args.CursorPadding,
rPromptOffset: *args.RPromptOffset,
formats: formats,
ansi: ansi,
}
imageCreator.init()
match := findNamedRegexMatch(`.*(\/|\\)(?P<STR>.+).omp.(json|yaml|toml)`, *args.Config)