2019-03-13 04:14:30 -07:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2021-03-20 00:49:49 -07:00
|
|
|
"strings"
|
2020-12-27 08:53:58 -08:00
|
|
|
"time"
|
2019-03-13 04:14:30 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
type engine struct {
|
2021-04-18 10:16:06 -07:00
|
|
|
config *Config
|
|
|
|
env environmentInfo
|
|
|
|
color *AnsiColor
|
|
|
|
renderer *AnsiRenderer
|
|
|
|
consoleTitle *consoleTitle
|
|
|
|
// activeBlock *Block
|
|
|
|
// activeSegment *Segment
|
|
|
|
// previousActiveSegment *Segment
|
|
|
|
rprompt string
|
2020-10-12 23:57:46 -07:00
|
|
|
}
|
|
|
|
|
2021-04-04 11:28:41 -07:00
|
|
|
func (e *engine) render() string {
|
2021-03-20 11:32:15 -07:00
|
|
|
for _, block := range e.config.Blocks {
|
2021-04-18 10:16:06 -07:00
|
|
|
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
|
|
|
}
|
2020-10-14 07:25:18 -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-02-14 23:26:52 -08:00
|
|
|
|
2021-03-20 11:32:15 -07:00
|
|
|
if !e.config.OSC99 {
|
2021-04-04 11:28:41 -07:00
|
|
|
return e.print()
|
2021-02-15 13:19:19 -08:00
|
|
|
}
|
2021-02-14 23:26:52 -08:00
|
|
|
cwd := e.env.getcwd()
|
|
|
|
if e.env.isWsl() {
|
|
|
|
cwd, _ = e.env.runCommand("wslpath", "-m", cwd)
|
|
|
|
}
|
|
|
|
e.renderer.osc99(cwd)
|
2021-04-04 11:28:41 -07:00
|
|
|
return e.print()
|
2020-12-17 23:59:45 -08:00
|
|
|
}
|
|
|
|
|
2021-04-18 10:16:06 -07: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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-09 07:18:37 -08:00
|
|
|
// debug will loop through your config file and output the timings for each segments
|
2021-04-04 11:28:41 -07:00
|
|
|
func (e *engine) debug() string {
|
2021-04-18 10:16:06 -07:00
|
|
|
var segmentTimings []*SegmentTiming
|
2020-12-31 05:00:46 -08:00
|
|
|
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)
|
2021-04-18 10:16:06 -07:00
|
|
|
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)
|
2020-12-27 08:53:58 -08:00
|
|
|
// loop each segments of each blocks
|
2021-03-20 11:32:15 -07:00
|
|
|
for _, block := range e.config.Blocks {
|
2021-04-18 10:16:06 -07:00
|
|
|
block.init(e.env, e.color)
|
|
|
|
longestSegmentName, timings := block.debug()
|
|
|
|
segmentTimings = append(segmentTimings, timings...)
|
|
|
|
if longestSegmentName > largestSegmentNameLength {
|
|
|
|
largestSegmentNameLength = longestSegmentName
|
2020-12-27 08:53:58 -08:00
|
|
|
}
|
|
|
|
}
|
2021-01-14 21:10:36 -08:00
|
|
|
|
2020-12-31 05:00:46 -08:00
|
|
|
// pad the output so the tabs render correctly
|
|
|
|
largestSegmentNameLength += 7
|
2020-12-27 08:53:58 -08:00
|
|
|
for _, segment := range segmentTimings {
|
|
|
|
duration := segment.enabledDuration.Milliseconds()
|
|
|
|
if segment.enabled {
|
|
|
|
duration += segment.stringDuration.Milliseconds()
|
|
|
|
}
|
2020-12-31 05:00:46 -08:00
|
|
|
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))
|
2020-12-27 08:53:58 -08:00
|
|
|
}
|
2021-04-04 11:28:41 -07:00
|
|
|
return e.renderer.string()
|
2020-12-27 08:53:58 -08:00
|
|
|
}
|
|
|
|
|
2021-04-04 11:28:41 -07:00
|
|
|
func (e *engine) print() string {
|
2020-12-23 04:31:21 -08:00
|
|
|
switch e.env.getShellName() {
|
|
|
|
case zsh:
|
|
|
|
if *e.env.getArgs().Eval {
|
2021-03-20 00:49:49 -07:00
|
|
|
// escape double quotes contained in the prompt
|
2021-04-04 11:28:41 -07:00
|
|
|
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
|
|
|
}
|
2021-04-04 11:28:41 -07: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
|
|
|
}
|
2021-04-04 11:28:41 -07:00
|
|
|
return e.renderer.string()
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|