mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-26 03:24:04 -08:00
137 lines
3.4 KiB
Go
137 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/text/unicode/norm"
|
|
)
|
|
|
|
func lenWithoutANSI(text, shell string) int {
|
|
rANSI := "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
|
|
stripped := replaceAllString(rANSI, text, "")
|
|
switch shell {
|
|
case zsh:
|
|
stripped = strings.ReplaceAll(stripped, "%{", "")
|
|
stripped = strings.ReplaceAll(stripped, "%}", "")
|
|
case bash:
|
|
stripped = strings.ReplaceAll(stripped, "\\[", "")
|
|
stripped = strings.ReplaceAll(stripped, "\\]", "")
|
|
}
|
|
var i norm.Iter
|
|
i.InitString(norm.NFD, stripped)
|
|
var count int
|
|
for !i.Done() {
|
|
i.Next()
|
|
count++
|
|
}
|
|
return count
|
|
}
|
|
|
|
type formats struct {
|
|
linechange string
|
|
left string
|
|
right string
|
|
title string
|
|
creset string
|
|
clearOEL string
|
|
saveCursorPosition string
|
|
restoreCursorPosition string
|
|
}
|
|
|
|
// AnsiRenderer exposes functionality using ANSI
|
|
type AnsiRenderer struct {
|
|
buffer *bytes.Buffer
|
|
formats *formats
|
|
shell string
|
|
}
|
|
|
|
const (
|
|
zsh = "zsh"
|
|
bash = "bash"
|
|
pwsh = "pwsh"
|
|
powershell5 = "powershell"
|
|
)
|
|
|
|
func (r *AnsiRenderer) init(shell string) {
|
|
r.shell = shell
|
|
r.formats = &formats{}
|
|
switch shell {
|
|
case zsh:
|
|
r.formats.linechange = "%%{\x1b[%d%s%%}"
|
|
r.formats.left = "%%{\x1b[%dC%%}"
|
|
r.formats.right = "%%{\x1b[%dD%%}"
|
|
r.formats.title = "%%{\033]0;%s\007%%}"
|
|
r.formats.creset = "%{\x1b[0m%}"
|
|
r.formats.clearOEL = "%{\x1b[K%}"
|
|
r.formats.saveCursorPosition = "%{\x1b7%}"
|
|
r.formats.restoreCursorPosition = "%{\x1b8%}"
|
|
case bash:
|
|
r.formats.linechange = "\\[\x1b[%d%s\\]"
|
|
r.formats.left = "\\[\x1b[%dC\\]"
|
|
r.formats.right = "\\[\x1b[%dD\\]"
|
|
r.formats.title = "\\[\033]0;%s\007\\]"
|
|
r.formats.creset = "\\[\x1b[0m\\]"
|
|
r.formats.clearOEL = "\\[\x1b[K\\]"
|
|
r.formats.saveCursorPosition = "\\[\x1b7\\]"
|
|
r.formats.restoreCursorPosition = "\\[\x1b8\\]"
|
|
default:
|
|
r.formats.linechange = "\x1b[%d%s"
|
|
r.formats.left = "\x1b[%dC"
|
|
r.formats.right = "\x1b[%dD"
|
|
r.formats.title = "\033]0;%s\007"
|
|
r.formats.creset = "\x1b[0m"
|
|
r.formats.clearOEL = "\x1b[K"
|
|
r.formats.saveCursorPosition = "\x1b7"
|
|
r.formats.restoreCursorPosition = "\x1b8"
|
|
}
|
|
}
|
|
|
|
func (r *AnsiRenderer) carriageForward() {
|
|
r.buffer.WriteString(fmt.Sprintf(r.formats.left, 1000))
|
|
}
|
|
|
|
func (r *AnsiRenderer) setCursorForRightWrite(text string, offset int) {
|
|
strippedLen := lenWithoutANSI(text, r.shell) + -offset
|
|
r.buffer.WriteString(fmt.Sprintf(r.formats.right, strippedLen))
|
|
}
|
|
|
|
func (r *AnsiRenderer) changeLine(numberOfLines int) {
|
|
position := "B"
|
|
if numberOfLines < 0 {
|
|
position = "F"
|
|
numberOfLines = -numberOfLines
|
|
}
|
|
r.buffer.WriteString(fmt.Sprintf(r.formats.linechange, numberOfLines, position))
|
|
}
|
|
|
|
func (r *AnsiRenderer) setConsoleTitle(title string) {
|
|
r.buffer.WriteString(fmt.Sprintf(r.formats.title, title))
|
|
}
|
|
|
|
func (r *AnsiRenderer) creset() {
|
|
r.buffer.WriteString(r.formats.creset)
|
|
}
|
|
|
|
func (r *AnsiRenderer) print(text string) {
|
|
r.buffer.WriteString(text)
|
|
r.clearEOL()
|
|
}
|
|
|
|
func (r *AnsiRenderer) clearEOL() {
|
|
r.buffer.WriteString(r.formats.clearOEL)
|
|
}
|
|
|
|
func (r *AnsiRenderer) string() string {
|
|
return r.buffer.String()
|
|
}
|
|
|
|
func (r *AnsiRenderer) saveCursorPosition() {
|
|
r.buffer.WriteString(r.formats.saveCursorPosition)
|
|
}
|
|
|
|
func (r *AnsiRenderer) restoreCursorPosition() {
|
|
r.buffer.WriteString(r.formats.restoreCursorPosition)
|
|
}
|