oh-my-posh/engine.go

193 lines
5.1 KiB
Go
Raw Normal View History

2019-03-13 04:14:30 -07:00
package main
import (
"fmt"
"sync"
2019-03-13 04:14:30 -07:00
)
type engine struct {
settings *Settings
env environmentInfo
2020-12-17 23:59:45 -08:00
color *AnsiColor
renderer *AnsiRenderer
2019-03-13 04:14:30 -07:00
activeBlock *Block
activeSegment *Segment
previousActiveSegment *Segment
2020-12-17 23:59:45 -08:00
rprompt string
2019-03-13 04:14:30 -07:00
}
func (e *engine) getPowerlineColor(foreground bool) string {
if e.previousActiveSegment == nil {
2020-09-21 06:44:09 -07:00
return Transparent
2019-03-13 04:14:30 -07:00
}
if !foreground && e.activeSegment.Style != Powerline {
2020-09-21 06:44:09 -07:00
return Transparent
2019-03-13 04:14:30 -07:00
}
if foreground && e.previousActiveSegment.Style != Powerline {
2020-09-21 06:44:09 -07:00
return Transparent
2019-03-13 04:14:30 -07:00
}
return e.previousActiveSegment.Background
}
func (e *engine) writePowerLineSeparator(background, foreground string, end bool) {
symbol := e.activeSegment.PowerlineSymbol
if end {
symbol = e.previousActiveSegment.PowerlineSymbol
}
2020-09-27 00:37:50 -07:00
if e.activeSegment.InvertPowerline {
2020-12-17 23:59:45 -08:00
e.color.write(foreground, background, symbol)
2019-03-13 04:14:30 -07:00
return
}
2020-12-17 23:59:45 -08:00
e.color.write(background, foreground, symbol)
2019-03-13 04:14:30 -07:00
}
func (e *engine) endPowerline() {
if e.activeSegment != nil &&
e.activeSegment.Style != Powerline &&
e.previousActiveSegment != nil &&
e.previousActiveSegment.Style == Powerline {
e.writePowerLineSeparator(e.getPowerlineColor(false), e.previousActiveSegment.Background, true)
2019-03-13 04:14:30 -07:00
}
}
func (e *engine) renderPowerLineSegment(text string) {
e.writePowerLineSeparator(e.activeSegment.Background, e.getPowerlineColor(true), false)
2019-03-13 04:14:30 -07:00
e.renderText(text)
}
func (e *engine) renderPlainSegment(text string) {
e.renderText(text)
}
func (e *engine) renderDiamondSegment(text string) {
2020-12-17 23:59:45 -08:00
e.color.write(Transparent, e.activeSegment.Background, e.activeSegment.LeadingDiamond)
2019-03-13 04:14:30 -07:00
e.renderText(text)
2020-12-17 23:59:45 -08:00
e.color.write(Transparent, e.activeSegment.Background, e.activeSegment.TrailingDiamond)
2019-03-13 04:14:30 -07:00
}
func (e *engine) renderText(text string) {
defaultValue := " "
if e.activeSegment.Background != "" {
defaultValue = fmt.Sprintf("<%s>\u2588</>", e.activeSegment.Background)
}
2020-12-02 00:20:58 -08:00
prefix := e.activeSegment.getValue(Prefix, defaultValue)
postfix := e.activeSegment.getValue(Postfix, defaultValue)
2020-12-17 23:59:45 -08:00
e.color.write(e.activeSegment.Background, e.activeSegment.Foreground, fmt.Sprintf("%s%s%s", prefix, text, postfix))
if *e.env.getArgs().Debug {
2020-12-17 23:59:45 -08:00
e.color.write(e.activeSegment.Background, e.activeSegment.Foreground, fmt.Sprintf("(%s:%s)", e.activeSegment.Type, e.activeSegment.timing))
}
2019-03-13 04:14:30 -07:00
}
func (e *engine) renderSegmentText(text string) {
switch e.activeSegment.Style {
case Plain:
e.renderPlainSegment(text)
case Diamond:
e.renderDiamondSegment(text)
case Powerline:
2019-03-13 04:14:30 -07:00
e.renderPowerLineSegment(text)
}
e.previousActiveSegment = e.activeSegment
}
func (e *engine) renderBlockSegments(block *Block) string {
2020-12-17 23:59:45 -08:00
defer e.resetBlock()
2019-03-13 04:14:30 -07:00
e.activeBlock = block
e.setStringValues(block.Segments)
2019-03-13 04:14:30 -07:00
for _, segment := range block.Segments {
if !segment.active {
2019-03-13 04:14:30 -07:00
continue
}
e.activeSegment = segment
e.endPowerline()
2020-11-10 09:38:24 -08:00
text := segment.stringValue
e.activeSegment.Background = segment.props.background
e.activeSegment.Foreground = segment.props.foreground
2019-03-13 04:14:30 -07:00
e.renderSegmentText(text)
}
if e.previousActiveSegment != nil && e.previousActiveSegment.Style == Powerline {
e.writePowerLineSeparator(Transparent, e.previousActiveSegment.Background, true)
2019-03-13 04:14:30 -07:00
}
2020-12-17 23:59:45 -08:00
return e.color.string()
2019-03-13 04:14:30 -07:00
}
func (e *engine) setStringValues(segments []*Segment) {
wg := sync.WaitGroup{}
wg.Add(len(segments))
defer wg.Wait()
cwd := e.env.getcwd()
debug := *e.env.getArgs().Debug
for _, segment := range segments {
go func(s *Segment) {
defer wg.Done()
s.setStringValue(e.env, cwd, debug)
}(segment)
}
}
func (e *engine) render() {
2019-03-13 04:14:30 -07:00
for _, block := range e.settings.Blocks {
// if line break, append a line break
2020-12-17 23:59:45 -08:00
switch block.Type {
case LineBreak:
2020-10-27 08:18:58 -07:00
e.renderer.print("\n")
2020-12-17 23:59:45 -08:00
case Prompt:
if block.VerticalOffset != 0 {
e.renderer.changeLine(block.VerticalOffset)
}
switch block.Alignment {
case Right:
e.renderer.carriageForward()
blockText := e.renderBlockSegments(block)
e.renderer.setCursorForRightWrite(blockText, block.HorizontalOffset)
e.renderer.print(blockText)
case Left:
e.renderer.print(e.renderBlockSegments(block))
}
case RPrompt:
e.rprompt = e.renderBlockSegments(block)
2019-03-13 04:14:30 -07:00
}
}
2020-10-12 00:02:33 -07:00
if e.settings.ConsoleTitle {
switch e.settings.ConsoleTitleStyle {
case FullPath:
e.renderer.setConsoleTitle(e.env.getcwd())
case FolderName:
fallthrough
default:
e.renderer.setConsoleTitle(base(e.env.getcwd(), e.env))
}
2020-10-12 00:02:33 -07:00
}
e.renderer.creset()
if e.settings.FinalSpace {
2020-10-27 08:18:58 -07:00
e.renderer.print(" ")
2019-03-13 04:14:30 -07:00
}
2020-12-17 23:59:45 -08:00
e.write()
}
func (e *engine) write() {
2020-12-23 04:31:21 -08:00
switch e.env.getShellName() {
case zsh:
if *e.env.getArgs().Eval {
fmt.Printf("PS1=\"%s\"", e.renderer.string())
2020-12-17 23:59:45 -08:00
fmt.Printf("\nRPROMPT=\"%s\"", e.rprompt)
2020-12-23 04:31:21 -08:00
return
}
case pwsh, powershell5, bash:
if e.rprompt != "" {
e.renderer.saveCursorPosition()
e.renderer.carriageForward()
e.renderer.setCursorForRightWrite(e.rprompt, 0)
e.renderer.print(e.rprompt)
e.renderer.restoreCursorPosition()
2020-12-17 23:59:45 -08:00
}
2020-12-15 05:58:15 -08:00
}
2020-12-17 23:59:45 -08:00
fmt.Print(e.renderer.string())
2019-03-13 04:14:30 -07:00
}
2020-12-17 23:59:45 -08:00
func (e *engine) resetBlock() {
e.color.reset()
2019-03-13 04:14:30 -07:00
e.previousActiveSegment = nil
e.activeBlock = nil
}