oh-my-posh/src/engine.go

140 lines
3.7 KiB
Go
Raw Normal View History

2019-03-13 04:14:30 -07:00
package main
import (
"fmt"
"strings"
"time"
2019-03-13 04:14:30 -07:00
)
type engine struct {
config *Config
env environmentInfo
color *AnsiColor
renderer *AnsiRenderer
consoleTitle *consoleTitle
// activeBlock *Block
// activeSegment *Segment
// previousActiveSegment *Segment
rprompt string
}
func (e *engine) render() string {
2021-03-20 11:32:15 -07:00
for _, block := range e.config.Blocks {
e.renderBlock(block)
2019-03-13 04:14:30 -07:00
}
2021-03-20 11:32:15 -07:00
if e.config.ConsoleTitle {
2021-02-14 05:09:43 -08:00
e.renderer.write(e.consoleTitle.getConsoleTitle())
2020-10-12 00:02:33 -07:00
}
e.renderer.creset()
2021-03-20 11:32:15 -07:00
if e.config.FinalSpace {
2021-02-14 05:09:43 -08:00
e.renderer.write(" ")
2019-03-13 04:14:30 -07:00
}
2021-03-20 11:32:15 -07:00
if !e.config.OSC99 {
return e.print()
2021-02-15 13:19:19 -08:00
}
cwd := e.env.getcwd()
if e.env.isWsl() {
cwd, _ = e.env.runCommand("wslpath", "-m", cwd)
}
e.renderer.osc99(cwd)
return e.print()
2020-12-17 23:59:45 -08:00
}
func (e *engine) renderBlock(block *Block) {
block.init(e.env, e.color)
block.setStringValues()
defer e.color.reset()
if !block.enabled() {
return
}
if block.Newline {
e.renderer.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")
case Prompt:
if block.VerticalOffset != 0 {
e.renderer.changeLine(block.VerticalOffset)
}
switch block.Alignment {
case Right:
e.renderer.carriageForward()
blockText := block.renderSegments()
e.renderer.setCursorForRightWrite(blockText, block.HorizontalOffset)
e.renderer.write(blockText)
case Left:
e.renderer.write(block.renderSegments())
}
case RPrompt:
e.rprompt = block.renderSegments()
}
}
// debug will loop through your config file and output the timings for each segments
func (e *engine) debug() string {
var segmentTimings []*SegmentTiming
largestSegmentNameLength := 0
2021-02-14 05:09:43 -08:00
e.renderer.write("\n\x1b[1mHere are the timings of segments in your prompt:\x1b[0m\n\n")
2021-01-14 21:10:36 -08:00
// console title timing
start := time.Now()
consoleTitle := e.consoleTitle.getTemplateText()
duration := time.Since(start)
segmentTiming := &SegmentTiming{
2021-01-14 21:10:36 -08:00
name: "ConsoleTitle",
nameLength: 12,
2021-03-20 11:32:15 -07:00
enabled: e.config.ConsoleTitle,
2021-01-14 21:10:36 -08:00
stringValue: consoleTitle,
enabledDuration: 0,
stringDuration: duration,
}
segmentTimings = append(segmentTimings, segmentTiming)
// loop each segments of each blocks
2021-03-20 11:32:15 -07:00
for _, block := range e.config.Blocks {
block.init(e.env, e.color)
longestSegmentName, timings := block.debug()
segmentTimings = append(segmentTimings, timings...)
if longestSegmentName > largestSegmentNameLength {
largestSegmentNameLength = longestSegmentName
}
}
2021-01-14 21:10:36 -08:00
// pad the output so the tabs render correctly
largestSegmentNameLength += 7
for _, segment := range segmentTimings {
duration := segment.enabledDuration.Milliseconds()
if segment.enabled {
duration += segment.stringDuration.Milliseconds()
}
segmentName := fmt.Sprintf("%s(%t)", segment.name, segment.enabled)
2021-02-14 05:09:43 -08:00
e.renderer.write(fmt.Sprintf("%-*s - %3d ms - %s\n", largestSegmentNameLength, segmentName, duration, segment.stringValue))
}
return e.renderer.string()
}
func (e *engine) print() string {
2020-12-23 04:31:21 -08:00
switch e.env.getShellName() {
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("\nRPROMPT=\"%s\"", e.rprompt)
return prompt
2020-12-23 04:31:21 -08:00
}
case pwsh, powershell5, bash, shelly:
2020-12-23 04:31:21 -08:00
if e.rprompt != "" {
e.renderer.saveCursorPosition()
e.renderer.carriageForward()
e.renderer.setCursorForRightWrite(e.rprompt, 0)
2021-02-14 05:09:43 -08:00
e.renderer.write(e.rprompt)
2020-12-23 04:31:21 -08:00
e.renderer.restoreCursorPosition()
2020-12-17 23:59:45 -08:00
}
2020-12-15 05:58:15 -08:00
}
return e.renderer.string()
2019-03-13 04:14:30 -07:00
}