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"
},
{
"name": "Cache",
"name": "Cache clear",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceRoot}/src",
"args": [
"cache"
"cache",
"clear"
]
}
]

20
src/cache/cache.go vendored
View file

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

29
src/cache/file.go vendored
View file

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

View file

@ -45,17 +45,11 @@ You can do the following:
switch args[0] {
case "path":
fmt.Print(env.CachePath())
fmt.Println(env.CachePath())
case "clear":
cacheFilePath := filepath.Join(env.CachePath(), cache.CacheFile)
err := os.Remove(cacheFilePath)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("removed cache file at %s\n", cacheFilePath)
clear(env.CachePath())
case "edit":
cacheFilePath := filepath.Join(env.CachePath(), cache.CacheFile)
cacheFilePath := filepath.Join(env.CachePath(), cache.FileName)
editFileWithEditor(cacheFilePath)
}
},
@ -67,16 +61,42 @@ func init() {
func editFileWithEditor(file string) {
editor := os.Getenv("EDITOR")
var args []string
if strings.Contains(editor, " ") {
splitted := strings.Split(editor, " ")
editor = splitted[0]
args = splitted[1:]
}
args = append(args, file)
cmd := exec.Command(editor, args...)
err := cmd.Run()
if err != nil {
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)
fmt.Println("#" + accent.Hex())
case "toggles":
togglesCache, _ := env.Cache().Get(cache.TOGGLECACHE)
togglesCache, _ := env.Session().Get(cache.TOGGLECACHE)
var toggles []string
if len(togglesCache) != 0 {
toggles = strings.Split(togglesCache, ",")

View file

@ -23,7 +23,7 @@ var toggleCmd = &cobra.Command{
env.Init()
defer env.Close()
togglesCache, _ := env.Cache().Get(cache.TOGGLECACHE)
togglesCache, _ := env.Session().Get(cache.TOGGLECACHE)
var toggles []string
if len(togglesCache) != 0 {
toggles = strings.Split(togglesCache, ",")
@ -44,7 +44,7 @@ var toggleCmd = &cobra.Command{
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())
// 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, ",")
for _, toggle := range list {
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)
}
func (env *Environment) Session() cache.Cache {
args := env.Called()
return args.Get(0).(cache.Cache)
}
func (env *Environment) Close() {
_ = env.Called()
}

View file

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

View file

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

View file

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

View file

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