feat(cache): split session and device cache

This commit is contained in:
Jan De Dobbeleer 2024-07-25 13:09:01 +02:00 committed by Jan De Dobbeleer
parent 4fa407d15e
commit ffd961fc6c
12 changed files with 103 additions and 51 deletions

5
.vscode/launch.json vendored
View file

@ -193,13 +193,14 @@
"envFile": "${workspaceFolder}/website/.env" "envFile": "${workspaceFolder}/website/.env"
}, },
{ {
"name": "Cache", "name": "Cache clear",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "debug", "mode": "debug",
"program": "${workspaceRoot}/src", "program": "${workspaceRoot}/src",
"args": [ "args": [
"cache" "cache",
"clear"
] ]
} }
] ]

20
src/cache/cache.go vendored
View file

@ -21,6 +21,12 @@ type Cache interface {
Delete(key string) Delete(key string)
} }
const (
FileName = "omp.cache"
)
var SessionFileName = fmt.Sprintf("%s.%s", FileName, pid())
func pid() string { func pid() string {
pid := os.Getenv("POSH_PID") pid := os.Getenv("POSH_PID")
if len(pid) == 0 { if len(pid) == 0 {
@ -29,15 +35,13 @@ func pid() string {
return pid return pid
} }
var (
TEMPLATECACHE = fmt.Sprintf("template_cache_%s", pid())
TOGGLECACHE = fmt.Sprintf("toggle_cache_%s", pid())
PROMPTCOUNTCACHE = fmt.Sprintf("prompt_count_cache_%s", pid())
ENGINECACHE = fmt.Sprintf("engine_cache_%s", pid())
FONTLISTCACHE = "font_list_cache"
)
const ( const (
TEMPLATECACHE = "template_cache"
TOGGLECACHE = "toggle_cache"
PROMPTCOUNTCACHE = "prompt_count_cache"
ENGINECACHE = "engine_cache"
FONTLISTCACHE = "font_list_cache"
ONEDAY = 1440 ONEDAY = 1440
ONEWEEK = 10080 ONEWEEK = 10080
ONEMONTH = 43200 ONEMONTH = 43200

25
src/cache/file.go vendored
View file

@ -3,28 +3,29 @@ package cache
import ( import (
"encoding/json" "encoding/json"
"os" "os"
"path/filepath"
"time" "time"
"github.com/jandedobbeleer/oh-my-posh/src/log"
"github.com/jandedobbeleer/oh-my-posh/src/maps" "github.com/jandedobbeleer/oh-my-posh/src/maps"
) )
const (
CacheFile = "/omp.cache"
)
type File struct { type File struct {
cache *maps.Concurrent cache *maps.Concurrent
cachePath string cacheFilePath string
dirty bool dirty bool
} }
func (fc *File) Init(cachePath string) { func (fc *File) Init(cacheFilePath string) {
defer log.Trace(time.Now(), cacheFilePath)
fc.cache = maps.NewConcurrent() fc.cache = maps.NewConcurrent()
fc.cachePath = cachePath fc.cacheFilePath = cacheFilePath
cacheFilePath := filepath.Join(fc.cachePath, CacheFile)
content, err := os.ReadFile(cacheFilePath) log.Debug("Loading cache file:", fc.cacheFilePath)
content, err := os.ReadFile(fc.cacheFilePath)
if err != nil { if err != nil {
log.Error(err)
return return
} }
@ -38,6 +39,7 @@ func (fc *File) Init(cachePath string) {
continue continue
} }
log.Debug("Loading cache key:", key)
fc.cache.Set(key, co) fc.cache.Set(key, co)
} }
} }
@ -50,8 +52,7 @@ func (fc *File) Close() {
cache := fc.cache.ToSimple() cache := fc.cache.ToSimple()
if dump, err := json.MarshalIndent(cache, "", " "); err == nil { if dump, err := json.MarshalIndent(cache, "", " "); err == nil {
cacheFilePath := filepath.Join(fc.cachePath, CacheFile) _ = os.WriteFile(fc.cacheFilePath, dump, 0644)
_ = os.WriteFile(cacheFilePath, dump, 0644)
} }
} }

View file

@ -45,17 +45,11 @@ You can do the following:
switch args[0] { switch args[0] {
case "path": case "path":
fmt.Print(env.CachePath()) fmt.Println(env.CachePath())
case "clear": case "clear":
cacheFilePath := filepath.Join(env.CachePath(), cache.CacheFile) clear(env.CachePath())
err := os.Remove(cacheFilePath)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("removed cache file at %s\n", cacheFilePath)
case "edit": case "edit":
cacheFilePath := filepath.Join(env.CachePath(), cache.CacheFile) cacheFilePath := filepath.Join(env.CachePath(), cache.FileName)
editFileWithEditor(cacheFilePath) editFileWithEditor(cacheFilePath)
} }
}, },
@ -67,16 +61,42 @@ func init() {
func editFileWithEditor(file string) { func editFileWithEditor(file string) {
editor := os.Getenv("EDITOR") editor := os.Getenv("EDITOR")
var args []string var args []string
if strings.Contains(editor, " ") { if strings.Contains(editor, " ") {
splitted := strings.Split(editor, " ") splitted := strings.Split(editor, " ")
editor = splitted[0] editor = splitted[0]
args = splitted[1:] args = splitted[1:]
} }
args = append(args, file) args = append(args, file)
cmd := exec.Command(editor, args...) cmd := exec.Command(editor, args...)
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
} }
func clear(cachePath string) {
// get all files in the cache directory that start with omp.cache and delete them
files, err := os.ReadDir(cachePath)
if err != nil {
return
}
for _, file := range files {
if file.IsDir() {
continue
}
if !strings.HasPrefix(file.Name(), cache.FileName) {
continue
}
path := filepath.Join(cachePath, file.Name())
if err := os.Remove(path); err == nil {
fmt.Println("removed cache file:", path)
}
}
}

View file

@ -65,7 +65,7 @@ This command is used to get the value of the following variables:
accent := color2.RGB(rgb.R, rgb.G, rgb.B) accent := color2.RGB(rgb.R, rgb.G, rgb.B)
fmt.Println("#" + accent.Hex()) fmt.Println("#" + accent.Hex())
case "toggles": case "toggles":
togglesCache, _ := env.Cache().Get(cache.TOGGLECACHE) togglesCache, _ := env.Session().Get(cache.TOGGLECACHE)
var toggles []string var toggles []string
if len(togglesCache) != 0 { if len(togglesCache) != 0 {
toggles = strings.Split(togglesCache, ",") toggles = strings.Split(togglesCache, ",")

View file

@ -23,7 +23,7 @@ var toggleCmd = &cobra.Command{
env.Init() env.Init()
defer env.Close() defer env.Close()
togglesCache, _ := env.Cache().Get(cache.TOGGLECACHE) togglesCache, _ := env.Session().Get(cache.TOGGLECACHE)
var toggles []string var toggles []string
if len(togglesCache) != 0 { if len(togglesCache) != 0 {
toggles = strings.Split(togglesCache, ",") toggles = strings.Split(togglesCache, ",")
@ -44,7 +44,7 @@ var toggleCmd = &cobra.Command{
newToggles = append(newToggles, segment) newToggles = append(newToggles, segment)
} }
env.Cache().Set(cache.TOGGLECACHE, strings.Join(newToggles, ","), 1440) env.Session().Set(cache.TOGGLECACHE, strings.Join(newToggles, ","), 1440)
}, },
} }

View file

@ -115,7 +115,7 @@ func (segment *Segment) SetEnabled(env runtime.Environment) {
segment.env.DebugF("Segment: %s", segment.Name()) segment.env.DebugF("Segment: %s", segment.Name())
// validate toggles // validate toggles
if toggles, OK := segment.env.Cache().Get(cache.TOGGLECACHE); OK && len(toggles) > 0 { if toggles, OK := segment.env.Session().Get(cache.TOGGLECACHE); OK && len(toggles) > 0 {
list := strings.Split(toggles, ",") list := strings.Split(toggles, ",")
for _, toggle := range list { for _, toggle := range list {
if SegmentType(toggle) == segment.Type || toggle == segment.Alias { if SegmentType(toggle) == segment.Type || toggle == segment.Alias {

View file

@ -192,6 +192,11 @@ func (env *Environment) Cache() cache.Cache {
return args.Get(0).(cache.Cache) return args.Get(0).(cache.Cache)
} }
func (env *Environment) Session() cache.Cache {
args := env.Called()
return args.Get(0).(cache.Cache)
}
func (env *Environment) Close() { func (env *Environment) Close() {
_ = env.Called() _ = env.Called()
} }

View file

@ -180,6 +180,7 @@ type Environment interface {
TerminalWidth() (int, error) TerminalWidth() (int, error)
CachePath() string CachePath() string
Cache() cache.Cache Cache() cache.Cache
Session() cache.Cache
Close() Close()
Logs() string Logs() string
InWSLSharedDrive() bool InWSLSharedDrive() bool
@ -204,7 +205,10 @@ type Terminal struct {
cwd string cwd string
host string host string
cmdCache *cache.Command cmdCache *cache.Command
fileCache *cache.File
deviceCache *cache.File
sessionCache *cache.File
tmplCache *cache.Template tmplCache *cache.Template
networks []*Connection networks []*Connection
@ -227,8 +231,15 @@ func (term *Terminal) Init() {
log.Plain() log.Plain()
} }
term.fileCache = &cache.File{} initCache := func(fileName string) *cache.File {
term.fileCache.Init(term.CachePath()) cache := &cache.File{}
cache.Init(filepath.Join(term.CachePath(), fileName))
return cache
}
term.deviceCache = initCache(cache.FileName)
term.sessionCache = initCache(cache.SessionFileName)
term.resolveConfigPath() term.resolveConfigPath()
term.cmdCache = &cache.Command{ term.cmdCache = &cache.Command{
Commands: maps.NewConcurrent(), Commands: maps.NewConcurrent(),
@ -722,7 +733,11 @@ func (term *Terminal) StackCount() int {
} }
func (term *Terminal) Cache() cache.Cache { func (term *Terminal) Cache() cache.Cache {
return term.fileCache return term.deviceCache
}
func (term *Terminal) Session() cache.Cache {
return term.sessionCache
} }
func (term *Terminal) saveTemplateCache() { func (term *Terminal) saveTemplateCache() {
@ -738,20 +753,21 @@ func (term *Terminal) saveTemplateCache() {
templateCache, err := json.Marshal(tmplCache) templateCache, err := json.Marshal(tmplCache)
if err == nil { if err == nil {
term.fileCache.Set(cache.TEMPLATECACHE, string(templateCache), 1440) term.sessionCache.Set(cache.TEMPLATECACHE, string(templateCache), 1440)
} }
} }
func (term *Terminal) Close() { func (term *Terminal) Close() {
defer term.Trace(time.Now()) defer term.Trace(time.Now())
term.saveTemplateCache() term.saveTemplateCache()
term.fileCache.Close() term.deviceCache.Close()
term.sessionCache.Close()
} }
func (term *Terminal) LoadTemplateCache() { func (term *Terminal) LoadTemplateCache() {
defer term.Trace(time.Now()) defer term.Trace(time.Now())
val, OK := term.fileCache.Get(cache.TEMPLATECACHE) val, OK := term.sessionCache.Get(cache.TEMPLATECACHE)
if !OK { if !OK {
return return
} }
@ -895,13 +911,13 @@ func (term *Terminal) SetPromptCount() {
} }
} }
var count int var count int
if val, found := term.Cache().Get(cache.PROMPTCOUNTCACHE); found { if val, found := term.Session().Get(cache.PROMPTCOUNTCACHE); found {
count, _ = strconv.Atoi(val) count, _ = strconv.Atoi(val)
} }
// only write to cache if we're the primary prompt // only write to cache if we're the primary prompt
if term.CmdFlags.Primary { if term.CmdFlags.Primary {
count++ count++
term.Cache().Set(cache.PROMPTCOUNTCACHE, strconv.Itoa(count), 1440) term.Session().Set(cache.PROMPTCOUNTCACHE, strconv.Itoa(count), 1440)
} }
term.CmdFlags.PromptCount = count term.CmdFlags.PromptCount = count
} }
@ -910,9 +926,11 @@ func (term *Terminal) CursorPosition() (row, col int) {
if number, err := strconv.Atoi(term.Getenv("POSH_CURSOR_LINE")); err == nil { if number, err := strconv.Atoi(term.Getenv("POSH_CURSOR_LINE")); err == nil {
row = number row = number
} }
if number, err := strconv.Atoi(term.Getenv("POSH_CURSOR_COLUMN")); err != nil { if number, err := strconv.Atoi(term.Getenv("POSH_CURSOR_COLUMN")); err != nil {
col = number col = number
} }
return return
} }

View file

@ -123,10 +123,12 @@ func (term *Terminal) Platform() string {
func (term *Terminal) CachePath() string { func (term *Terminal) CachePath() string {
defer term.Trace(time.Now()) defer term.Trace(time.Now())
// get LOCALAPPDATA if present // get LOCALAPPDATA if present
if cachePath := returnOrBuildCachePath(term.Getenv("LOCALAPPDATA")); len(cachePath) != 0 { if cachePath := returnOrBuildCachePath(term.Getenv("LOCALAPPDATA")); len(cachePath) != 0 {
return cachePath return cachePath
} }
return term.Home() return term.Home()
} }

View file

@ -1,6 +1,7 @@
setenv POWERLINE_COMMAND "oh-my-posh"; setenv POWERLINE_COMMAND "oh-my-posh";
setenv POSH_THEME ::CONFIG::; setenv POSH_THEME ::CONFIG::;
setenv POSH_SHELL_VERSION ""; setenv POSH_SHELL_VERSION "";
setenv POSH_PID $$;
set POSH_COMMAND = ::OMP::; set POSH_COMMAND = ::OMP::;
set USER_PRECMD = "`alias precmd`"; set USER_PRECMD = "`alias precmd`";

View file

@ -102,8 +102,8 @@ func Init(sh string) {
Shell = sh Shell = sh
Program = getTerminalName() Program = getTerminalName()
log.Debug("Terminal shell: %s", Shell) log.Debug("Terminal shell:", Shell)
log.Debug("Terminal program: %s", Program) log.Debug("Terminal program:", Program)
color.TrueColor = Program != AppleTerminal color.TrueColor = Program != AppleTerminal