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