Skip to content

Instantly share code, notes, and snippets.

@staticaland
Created September 3, 2024 13:16
Show Gist options
  • Save staticaland/cff47a50dc4867da44f549ff3b427859 to your computer and use it in GitHub Desktop.
Save staticaland/cff47a50dc4867da44f549ff3b427859 to your computer and use it in GitHub Desktop.
type Cache struct {
Completions []string
Timestamp time.Time
}
const cacheFile = "completions_cache.gob"
const cacheExpiration = 1 * time.Hour
func addTabCompletionApp(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCompDirective) {
cache, err := loadCache()
if err == nil && time.Since(cache.Timestamp) < cacheExpiration {
return filterCompletions(cache.Completions, toComplete), cobra.ShellCompDirectiveNoFileComp
}
latest, err := githubreleases.GetLatestReleases(true)
if err != nil {
cmd.PrintErrf("failed to load package manifest: %s\n", err)
return nil, cobra.ShellCompDirectiveError
}
var completions []string
for template := range latest {
completions = append(completions, template)
}
saveCache(Cache{Completions: completions, Timestamp: time.Now()})
return filterCompletions(completions, toComplete), cobra.ShellCompDirectiveNoFileComp
}
func filterCompletions(completions []string, toComplete string) []string {
var filtered []string
for _, c := range completions {
if strings.HasPrefix(c, toComplete) {
filtered = append(filtered, c)
}
}
return filtered
}
func loadCache() (Cache, error) {
file, err := os.Open(getCachePath())
if err != nil {
return Cache{}, err
}
defer file.Close()
var cache Cache
if err := gob.NewDecoder(file).Decode(&cache); err != nil {
return Cache{}, err
}
return cache, nil
}
func saveCache(cache Cache) {
file, err := os.Create(getCachePath())
if err != nil {
return
}
defer file.Close()
gob.NewEncoder(file).Encode(cache)
}
func getCachePath() string {
dir, err := os.UserCacheDir()
if err != nil {
return cacheFile
}
return filepath.Join(dir, cacheFile)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment