summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorewy <ewy0@protonmail.com>2026-05-17 02:13:25 +0200
committerewy <ewy0@protonmail.com>2026-05-17 02:13:25 +0200
commit5cfc8bd701037a215c62789916cda283a018d3fd (patch)
treed29c1b65e69314917e15390ce43e8bba0ae2bc2d
parenteb340173fe0508240da4bb03d37a5a2fa259c2fd (diff)
add priority to version and completion to reduce start times for those modes
-rw-r--r--cache/cache.go12
-rw-r--r--cache/cache_test.go10
-rw-r--r--completion/completion.go4
-rw-r--r--main.go13
-rw-r--r--modes.go16
5 files changed, 29 insertions, 26 deletions
diff --git a/cache/cache.go b/cache/cache.go
index 2784e23..9f25af0 100644
--- a/cache/cache.go
+++ b/cache/cache.go
@@ -12,18 +12,13 @@ import (
"strings"
)
+// Cache is a wrapper for its entries. I guess it could be a plain type.
type Cache struct {
Entries []Entry
}
type cacheInit struct{}
-var Init model.Initializer = &cacheInit{}
-
-func (i *cacheInit) Init() error {
- return nil
-}
-
// Merge combines two caches and filters duplicate keys
func (c *Cache) Merge(other *Cache) *Cache {
switch {
@@ -46,11 +41,13 @@ func (c *Cache) Merge(other *Cache) *Cache {
return result
}
+// Entry is a cache entry containing a path and name
type Entry struct {
Path string
Label string
}
+// String returns the string representation of this cache entry
func (e Entry) String() string {
return e.Path + " # " + e.Label
}
@@ -104,6 +101,7 @@ func (c *Cache) Marshal() []byte {
return []byte(b.String())
}
+// String returns the string representation of the Cache
func (c *Cache) String() string {
return string(c.Marshal())
}
@@ -118,6 +116,8 @@ func New(st *model.State) *Cache {
return c
}
+// MergeAndSave creates a cache from a state, combines it with
+// a potential saved context file, and writes it to disk
func MergeAndSave(in *model.State) error {
root := "/"
f := os.DirFS(root)
diff --git a/cache/cache_test.go b/cache/cache_test.go
index 204f670..7746be4 100644
--- a/cache/cache_test.go
+++ b/cache/cache_test.go
@@ -207,16 +207,6 @@ func TestMergeNilNormal(t *testing.T) {
_ = e.Merge(c)
}
-func TestCacheInit_Init(t *testing.T) {
- d := t.TempDir()
- paths.SetAll(d)
- defer paths.Reset()
- c := &cacheInit{}
- err := c.Init()
- assert.NoError(t, err)
- assert.Contains(t, paths.ContextsFile.String(), d)
-}
-
func TestInsert(t *testing.T) {
d := t.TempDir()
st := TState(TSource("source", "target"))
diff --git a/completion/completion.go b/completion/completion.go
index 641eb8a..9d3ae72 100644
--- a/completion/completion.go
+++ b/completion/completion.go
@@ -31,8 +31,10 @@ var completionFileByShell = map[string]string{
"zsh": ".zshrc",
}
+// AlreadyInstalledError is returned when we already found completion code in your shell rc file
var AlreadyInstalledError = errors.New("completion already installed")
+// Add finds the right file to append the completion code to and does that
func Add(shell string) error {
f := filepath.Join(paths.HomeDir.String(), completionFileByShell[shell])
content, err := os.ReadFile(f)
@@ -59,6 +61,8 @@ func successMessage(shell string, file string) {
_, _ = spool.Print("Installed completion for %s in %s\n", shell, file)
}
+// Echo prints the actual completion script
+// because it is baked in with the program it should always be version-appropriate
func Echo() error {
_, err := spool.Print("%s", completionCode)
return err
diff --git a/main.go b/main.go
index 8b905d8..800232a 100644
--- a/main.go
+++ b/main.go
@@ -30,7 +30,6 @@ import (
// useful for initializing stuff like paths, preparing directories, and reading the environment
var syncInitializers = ComponentList[model.Initializer]{
paths.Component,
- cache.Init,
}
// initializers are ran before indexing with the indexers,
@@ -108,17 +107,23 @@ func mode[T any](list ModeMap[T], fire func(mode T) error) *int {
func pik() int {
pflag.Parse()
- syncInitializers.RunSync(func(initializer model.Initializer) error {
- return initializer.Init()
+ code := mode(uninitializedModes, func(mode func() error) error {
+ return mode()
})
+ if code != nil {
+ return *code
+ }
- code := mode(statelessModes, func(mode func() error) error {
+ code = mode(statelessModes, func(mode func() error) error {
return mode()
})
if code != nil {
return *code
}
+ syncInitializers.RunSync(func(initializer model.Initializer) error {
+ return initializer.Init()
+ })
initializers.RunAsync(func(initializer model.Initializer) error {
return initializer.Init()
})
diff --git a/modes.go b/modes.go
index bc9e90f..1d651b6 100644
--- a/modes.go
+++ b/modes.go
@@ -46,13 +46,20 @@ var profileFd *os.File
var UnknownShellError = errors.New("$SHELL not set or empty")
-// statelessModes are program modes which do not require state to operate.
-// like --version and --completion
-var statelessModes = ModeMap[func() error]{
+// uninitializedModes are modes which can run before the program runs initializers
+var uninitializedModes = ModeMap[func() error]{
flags.Version: func() error {
_, err := spool.Print("%s\n", version)
return err
},
+ flags.Completion: func() error {
+ return completion.Echo()
+ },
+}
+
+// statelessModes are program modes which do not require state to operate.
+// like --version and --completion
+var statelessModes = ModeMap[func() error]{
flags.InstallCompletion: func() error {
sh := os.Getenv("SHELL")
if sh == "" {
@@ -61,9 +68,6 @@ var statelessModes = ModeMap[func() error]{
_, sh = filepath.Split(sh)
return completion.Add(sh)
},
- flags.Completion: func() error {
- return completion.Echo()
- },
flags.Profile: func() error {
fd, err := os.Create("pik-profile.out")
if err != nil {