mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-03-05 20:49:04 -08:00
feat(cache): make template cache available to all prompts
This commit is contained in:
parent
8295e48ed3
commit
388fa2e128
1
src/cache/template.go
vendored
1
src/cache/template.go
vendored
|
@ -23,7 +23,6 @@ type Template struct {
|
||||||
Jobs int
|
Jobs int
|
||||||
WSL bool
|
WSL bool
|
||||||
Root bool
|
Root bool
|
||||||
Initialized bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Template) AddSegmentData(key string, value any) {
|
func (t *Template) AddSegmentData(key string, value any) {
|
||||||
|
|
|
@ -76,6 +76,7 @@ func createPrintCmd() *cobra.Command {
|
||||||
NoExitCode: noStatus,
|
NoExitCode: noStatus,
|
||||||
Column: column,
|
Column: column,
|
||||||
JobCount: jobCount,
|
JobCount: jobCount,
|
||||||
|
IsPrimary: args[0] == prompt.PRIMARY,
|
||||||
SaveCache: saveCache,
|
SaveCache: saveCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,8 @@ func (segment *Segment) Render() {
|
||||||
|
|
||||||
segment.SetText(text)
|
segment.SetText(text)
|
||||||
segment.setCache()
|
segment.setCache()
|
||||||
|
|
||||||
|
// We do this to make `.Text` available for a cross-segment reference in an extra prompt.
|
||||||
segment.env.TemplateCache().AddSegmentData(segment.Name(), segment.writer)
|
segment.env.TemplateCache().AddSegmentData(segment.Name(), segment.writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,58 +1,36 @@
|
||||||
package maps
|
package maps
|
||||||
|
|
||||||
import (
|
import "sync"
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewConcurrent() *Concurrent {
|
func NewConcurrent() *Concurrent {
|
||||||
return &Concurrent{
|
var cm Concurrent
|
||||||
data: make(map[string]any),
|
return &cm
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Concurrent struct {
|
type Concurrent sync.Map
|
||||||
data map[string]any
|
|
||||||
sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cm *Concurrent) Set(key string, value any) {
|
func (cm *Concurrent) Set(key string, value any) {
|
||||||
cm.Lock()
|
(*sync.Map)(cm).Store(key, value)
|
||||||
defer cm.Unlock()
|
|
||||||
|
|
||||||
if cm.data == nil {
|
|
||||||
cm.data = make(map[string]any)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm.data[key] = value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *Concurrent) Get(key string) (any, bool) {
|
func (cm *Concurrent) Get(key string) (any, bool) {
|
||||||
cm.RLock()
|
return (*sync.Map)(cm).Load(key)
|
||||||
defer cm.RUnlock()
|
|
||||||
|
|
||||||
if cm.data == nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
value, ok := cm.data[key]
|
|
||||||
return value, ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *Concurrent) Delete(key string) {
|
func (cm *Concurrent) Delete(key string) {
|
||||||
cm.Lock()
|
(*sync.Map)(cm).Delete(key)
|
||||||
defer cm.Unlock()
|
|
||||||
|
|
||||||
delete(cm.data, key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *Concurrent) Contains(key string) bool {
|
func (cm *Concurrent) Contains(key string) bool {
|
||||||
_, ok := cm.Get(key)
|
_, ok := (*sync.Map)(cm).Load(key)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *Concurrent) ToSimple() Simple {
|
func (cm *Concurrent) ToSimple() Simple {
|
||||||
cm.RLock()
|
list := make(map[string]any)
|
||||||
defer cm.RUnlock()
|
(*sync.Map)(cm).Range(func(key, value any) bool {
|
||||||
|
list[key.(string)] = value
|
||||||
return cm.data
|
return true
|
||||||
|
})
|
||||||
|
return list
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ package maps
|
||||||
type Simple map[string]any
|
type Simple map[string]any
|
||||||
|
|
||||||
func (m Simple) ToConcurrent() *Concurrent {
|
func (m Simple) ToConcurrent() *Concurrent {
|
||||||
return &Concurrent{
|
var cm Concurrent
|
||||||
data: m,
|
for k, v := range m {
|
||||||
|
cm.Set(k, v)
|
||||||
}
|
}
|
||||||
|
return &cm
|
||||||
}
|
}
|
||||||
|
|
|
@ -468,21 +468,19 @@ func New(flags *runtime.Flags) *Engine {
|
||||||
|
|
||||||
env.Init()
|
env.Init()
|
||||||
cfg := config.Load(env)
|
cfg := config.Load(env)
|
||||||
|
env.Var = cfg.Var
|
||||||
|
|
||||||
// load the template cache for extra prompts prior to
|
// To prevent cross-segment template referencing issues, this should not be moved elsewhere.
|
||||||
// rendering any template
|
// Related: https://github.com/JanDeDobbeleer/oh-my-posh/discussions/2885#discussioncomment-4497439
|
||||||
if flags.Type == DEBUG ||
|
env.PopulateTemplateCache()
|
||||||
flags.Type == SECONDARY ||
|
|
||||||
flags.Type == TRANSIENT ||
|
|
||||||
flags.Type == VALID ||
|
|
||||||
flags.Type == ERROR {
|
|
||||||
env.LoadTemplateCache()
|
|
||||||
}
|
|
||||||
|
|
||||||
template.Init(env)
|
template.Init(env)
|
||||||
|
|
||||||
env.Var = cfg.Var
|
flags.HasExtra = cfg.DebugPrompt != nil ||
|
||||||
flags.HasTransient = cfg.TransientPrompt != nil
|
cfg.SecondaryPrompt != nil ||
|
||||||
|
cfg.TransientPrompt != nil ||
|
||||||
|
cfg.ValidLine != nil ||
|
||||||
|
cfg.ErrorLine != nil
|
||||||
|
|
||||||
terminal.Init(env.Shell())
|
terminal.Init(env.Shell())
|
||||||
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate()
|
terminal.BackgroundColor = cfg.TerminalBackground.ResolveTemplate()
|
||||||
|
|
|
@ -10,7 +10,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRenderBlock(t *testing.T) {
|
func TestRenderBlock(t *testing.T) {
|
||||||
engine := New(&runtime.Flags{})
|
engine := New(&runtime.Flags{
|
||||||
|
IsPrimary: true,
|
||||||
|
})
|
||||||
block := &config.Block{
|
block := &config.Block{
|
||||||
Segments: []*config.Segment{
|
Segments: []*config.Segment{
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,7 +69,6 @@ type Environment interface {
|
||||||
ConvertToWindowsPath(path string) string
|
ConvertToWindowsPath(path string) string
|
||||||
Connection(connectionType ConnectionType) (*Connection, error)
|
Connection(connectionType ConnectionType) (*Connection, error)
|
||||||
TemplateCache() *cache.Template
|
TemplateCache() *cache.Template
|
||||||
LoadTemplateCache()
|
|
||||||
CursorPosition() (row, col int)
|
CursorPosition() (row, col int)
|
||||||
SystemInfo() (*SystemInfo, error)
|
SystemInfo() (*SystemInfo, error)
|
||||||
Debug(message string)
|
Debug(message string)
|
||||||
|
@ -93,7 +92,8 @@ type Flags struct {
|
||||||
TerminalWidth int
|
TerminalWidth int
|
||||||
ExecutionTime float64
|
ExecutionTime float64
|
||||||
JobCount int
|
JobCount int
|
||||||
HasTransient bool
|
IsPrimary bool
|
||||||
|
HasExtra bool
|
||||||
Debug bool
|
Debug bool
|
||||||
Plain bool
|
Plain bool
|
||||||
Strict bool
|
Strict bool
|
||||||
|
|
|
@ -231,10 +231,6 @@ func (env *Environment) TemplateCache() *cache.Template {
|
||||||
return args.Get(0).(*cache.Template)
|
return args.Get(0).(*cache.Template)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Environment) LoadTemplateCache() {
|
|
||||||
_ = env.Called()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (env *Environment) MockGitCommand(dir, returnValue string, args ...string) {
|
func (env *Environment) MockGitCommand(dir, returnValue string, args ...string) {
|
||||||
args = append([]string{"-C", dir, "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
|
args = append([]string{"-C", dir, "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
|
||||||
env.On("RunCommand", "git", args).Return(returnValue, nil)
|
env.On("RunCommand", "git", args).Return(returnValue, nil)
|
||||||
|
|
|
@ -37,10 +37,10 @@ type Terminal struct {
|
||||||
deviceCache *cache.File
|
deviceCache *cache.File
|
||||||
sessionCache *cache.File
|
sessionCache *cache.File
|
||||||
tmplCache *cache.Template
|
tmplCache *cache.Template
|
||||||
|
lsDirMap maps.Concurrent
|
||||||
cwd string
|
cwd string
|
||||||
host string
|
host string
|
||||||
networks []*Connection
|
networks []*Connection
|
||||||
lsDirMap maps.Concurrent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) Init() {
|
func (term *Terminal) Init() {
|
||||||
|
@ -78,7 +78,7 @@ func (term *Terminal) Init() {
|
||||||
Commands: maps.NewConcurrent(),
|
Commands: maps.NewConcurrent(),
|
||||||
}
|
}
|
||||||
|
|
||||||
term.tmplCache = &cache.Template{}
|
term.tmplCache = new(cache.Template)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) ResolveConfigPath() {
|
func (term *Terminal) ResolveConfigPath() {
|
||||||
|
@ -580,8 +580,8 @@ func (term *Terminal) Session() cache.Cache {
|
||||||
|
|
||||||
func (term *Terminal) saveTemplateCache() {
|
func (term *Terminal) saveTemplateCache() {
|
||||||
// only store this when in a primary prompt
|
// only store this when in a primary prompt
|
||||||
// and when we have a transient prompt in the config
|
// and when we have any extra prompt in the config
|
||||||
canSave := term.CmdFlags.Type == PRIMARY && term.CmdFlags.HasTransient
|
canSave := term.CmdFlags.Type == PRIMARY && term.CmdFlags.HasExtra
|
||||||
if !canSave {
|
if !canSave {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -619,40 +619,15 @@ func (term *Terminal) clearCacheFiles() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) LoadTemplateCache() {
|
func (term *Terminal) PopulateTemplateCache() {
|
||||||
defer term.Trace(time.Now())
|
if !term.CmdFlags.IsPrimary {
|
||||||
|
// Load the template cache for a non-primary prompt before rendering any templates.
|
||||||
val, OK := term.sessionCache.Get(cache.TEMPLATECACHE)
|
term.loadTemplateCache()
|
||||||
if !OK {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmplCache cache.Template
|
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(val), &tmplCache)
|
|
||||||
if err != nil {
|
|
||||||
term.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tmplCache.Segments = tmplCache.SegmentsCache.ToConcurrent()
|
|
||||||
tmplCache.Initialized = true
|
|
||||||
|
|
||||||
term.tmplCache = &tmplCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (term *Terminal) Logs() string {
|
|
||||||
return log.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (term *Terminal) TemplateCache() *cache.Template {
|
|
||||||
defer term.Trace(time.Now())
|
|
||||||
tmplCache := term.tmplCache
|
tmplCache := term.tmplCache
|
||||||
|
|
||||||
if tmplCache.Initialized {
|
|
||||||
return tmplCache
|
|
||||||
}
|
|
||||||
|
|
||||||
tmplCache.Root = term.Root()
|
tmplCache.Root = term.Root()
|
||||||
tmplCache.Shell = term.Shell()
|
tmplCache.Shell = term.Shell()
|
||||||
tmplCache.ShellVersion = term.CmdFlags.ShellVersion
|
tmplCache.ShellVersion = term.CmdFlags.ShellVersion
|
||||||
|
@ -697,9 +672,33 @@ func (term *Terminal) TemplateCache() *cache.Template {
|
||||||
if shlvl, err := strconv.Atoi(val); err == nil {
|
if shlvl, err := strconv.Atoi(val); err == nil {
|
||||||
tmplCache.SHLVL = shlvl
|
tmplCache.SHLVL = shlvl
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tmplCache.Initialized = true
|
func (term *Terminal) loadTemplateCache() {
|
||||||
return tmplCache
|
defer term.Trace(time.Now())
|
||||||
|
|
||||||
|
val, OK := term.sessionCache.Get(cache.TEMPLATECACHE)
|
||||||
|
if !OK {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tmplCache := term.tmplCache
|
||||||
|
|
||||||
|
err := json.Unmarshal([]byte(val), &tmplCache)
|
||||||
|
if err != nil {
|
||||||
|
term.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tmplCache.Segments = tmplCache.SegmentsCache.ToConcurrent()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (term *Terminal) Logs() string {
|
||||||
|
return log.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (term *Terminal) TemplateCache() *cache.Template {
|
||||||
|
return term.tmplCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) DirMatchesOneOf(dir string, regexes []string) (match bool) {
|
func (term *Terminal) DirMatchesOneOf(dir string, regexes []string) (match bool) {
|
||||||
|
|
|
@ -20,11 +20,6 @@ type context struct {
|
||||||
|
|
||||||
func (c *context) init(t *Text) {
|
func (c *context) init(t *Text) {
|
||||||
c.Data = t.Context
|
c.Data = t.Context
|
||||||
|
|
||||||
if c.Initialized {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Getenv = env.Getenv
|
c.Getenv = env.Getenv
|
||||||
c.Template = *env.TemplateCache()
|
c.Template = *env.TemplateCache()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue