From 4f72bb9894a9007b98b61f60d66ee2ec6291f2d3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 9 Aug 2023 12:08:42 +0530 Subject: [PATCH] Replace utils.Once with stdlib sync.OnceValue --- kittens/diff/highlight.go | 3 ++- kittens/diff/mouse.go | 3 ++- kittens/diff/patch.go | 5 ++-- kittens/hints/marks.go | 5 ++-- kittens/hyperlinked_grep/main.go | 3 ++- kittens/ssh/utils.go | 9 ++++--- kittens/transfer/ftc.go | 5 ++-- tools/config/utils.go | 5 ++-- tools/themes/collection.go | 3 ++- tools/tty/tty.go | 3 ++- tools/tui/run.go | 3 ++- tools/tui/shell_integration/data.go | 3 ++- tools/tui/tmux.go | 7 +++--- tools/tui/ui_kitten.go | 3 ++- tools/utils/hostname.go | 3 ++- tools/utils/images/loading.go | 3 ++- tools/utils/mimetypes.go | 3 ++- tools/utils/once.go | 39 ----------------------------- tools/utils/once_test.go | 24 ------------------ tools/utils/passwd.go | 5 ++-- tools/utils/paths.go | 9 ++++--- tools/utils/which.go | 3 ++- 22 files changed, 53 insertions(+), 96 deletions(-) delete mode 100644 tools/utils/once.go delete mode 100644 tools/utils/once_test.go diff --git a/kittens/diff/highlight.go b/kittens/diff/highlight.go index cd79d4fa0..f27479965 100644 --- a/kittens/diff/highlight.go +++ b/kittens/diff/highlight.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "strings" + "sync" "kitty/tools/utils" "kitty/tools/utils/images" @@ -22,7 +23,7 @@ var _ = fmt.Print var _ = os.WriteFile var ErrNoLexer = errors.New("No lexer available for this format") -var DefaultStyle = utils.Once(func() *chroma.Style { +var DefaultStyle = sync.OnceValue(func() *chroma.Style { // Default style generated by python style.py default pygments.styles.default.DefaultStyle // with https://raw.githubusercontent.com/alecthomas/chroma/master/_tools/style.py return styles.Register(chroma.MustNewStyle("default", chroma.StyleEntries{ diff --git a/kittens/diff/mouse.go b/kittens/diff/mouse.go index 674e5d485..a64459938 100644 --- a/kittens/diff/mouse.go +++ b/kittens/diff/mouse.go @@ -7,6 +7,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" "kitty" "kitty/tools/config" @@ -43,7 +44,7 @@ func read_relevant_kitty_opts(path string) KittyOpts { return ans } -var RelevantKittyOpts = utils.Once(func() KittyOpts { +var RelevantKittyOpts = sync.OnceValue(func() KittyOpts { return read_relevant_kitty_opts(filepath.Join(utils.ConfigDir(), "kitty.conf")) }) diff --git a/kittens/diff/patch.go b/kittens/diff/patch.go index cb9e699f2..396692896 100644 --- a/kittens/diff/patch.go +++ b/kittens/diff/patch.go @@ -13,6 +13,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" ) var _ = fmt.Print @@ -22,11 +23,11 @@ const DIFF_DIFF = `diff -p -U _CONTEXT_ --` var diff_cmd []string -var GitExe = utils.Once(func() string { +var GitExe = sync.OnceValue(func() string { return utils.FindExe("git") }) -var DiffExe = utils.Once(func() string { +var DiffExe = sync.OnceValue(func() string { return utils.FindExe("diff") }) diff --git a/kittens/hints/marks.go b/kittens/hints/marks.go index b410b4b96..6c4fb5921 100644 --- a/kittens/hints/marks.go +++ b/kittens/hints/marks.go @@ -12,6 +12,7 @@ import ( "regexp" "strconv" "strings" + "sync" "unicode" "unicode/utf8" @@ -163,7 +164,7 @@ func linenum_group_processor(gd map[string]string) { gd[`path`] = utils.Expanduser(gd[`path`]) } -var PostProcessorMap = utils.Once(func() map[string]PostProcessorFunc { +var PostProcessorMap = sync.OnceValue(func() map[string]PostProcessorFunc { return map[string]PostProcessorFunc{ "url": func(text string, s, e int) (int, int) { if s > 4 && text[s-5:s] == "link:" { // asciidoc URLs @@ -227,7 +228,7 @@ func read_relevant_kitty_opts(path string) KittyOpts { return ans } -var RelevantKittyOpts = utils.Once(func() KittyOpts { +var RelevantKittyOpts = sync.OnceValue(func() KittyOpts { return read_relevant_kitty_opts(filepath.Join(utils.ConfigDir(), "kitty.conf")) }) diff --git a/kittens/hyperlinked_grep/main.go b/kittens/hyperlinked_grep/main.go index 359207560..21613b97b 100644 --- a/kittens/hyperlinked_grep/main.go +++ b/kittens/hyperlinked_grep/main.go @@ -12,6 +12,7 @@ import ( "path/filepath" "regexp" "strings" + "sync" "unicode" "kitty/tools/cli" @@ -22,7 +23,7 @@ import ( var _ = fmt.Print -var RgExe = utils.Once(func() string { +var RgExe = sync.OnceValue(func() string { return utils.FindExe("rg") }) diff --git a/kittens/ssh/utils.go b/kittens/ssh/utils.go index 358c9805a..a1ff921b9 100644 --- a/kittens/ssh/utils.go +++ b/kittens/ssh/utils.go @@ -13,15 +13,16 @@ import ( "regexp" "strconv" "strings" + "sync" ) var _ = fmt.Print -var SSHExe = utils.Once(func() string { +var SSHExe = sync.OnceValue(func() string { return utils.FindExe("ssh") }) -var SSHOptions = utils.Once(func() (ssh_options map[string]string) { +var SSHOptions = sync.OnceValue(func() (ssh_options map[string]string) { defer func() { if ssh_options == nil { ssh_options = map[string]string{ @@ -201,7 +202,7 @@ func (self SSHVersion) SupportsAskpassRequire() bool { return self.Major > 8 || (self.Major == 8 && self.Minor >= 4) } -var GetSSHVersion = utils.Once(func() SSHVersion { +var GetSSHVersion = sync.OnceValue(func() SSHVersion { b, err := exec.Command(SSHExe(), "-V").CombinedOutput() if err != nil { return SSHVersion{} @@ -235,6 +236,6 @@ func read_relevant_kitty_opts(path string) KittyOpts { return ans } -var RelevantKittyOpts = utils.Once(func() KittyOpts { +var RelevantKittyOpts = sync.OnceValue(func() KittyOpts { return read_relevant_kitty_opts(filepath.Join(utils.ConfigDir(), "kitty.conf")) }) diff --git a/kittens/transfer/ftc.go b/kittens/transfer/ftc.go index 92f4dd7ae..92b727d09 100644 --- a/kittens/transfer/ftc.go +++ b/kittens/transfer/ftc.go @@ -11,6 +11,7 @@ import ( "regexp" "strconv" "strings" + "sync" "time" "kitty" @@ -140,7 +141,7 @@ func escape_semicolons(x string) string { return strings.ReplaceAll(x, ";", ";;") } -var ftc_field_map = utils.Once(func() map[string]reflect.StructField { +var ftc_field_map = sync.OnceValue(func() map[string]reflect.StructField { ans := make(map[string]reflect.StructField) self := FileTransmissionCommand{} v := reflect.ValueOf(self) @@ -155,7 +156,7 @@ var ftc_field_map = utils.Once(func() map[string]reflect.StructField { return ans }) -var safe_string_pat = utils.Once(func() *regexp.Regexp { +var safe_string_pat = sync.OnceValue(func() *regexp.Regexp { return regexp.MustCompile(`[^0-9a-zA-Z_:./@-]`) }) diff --git a/tools/config/utils.go b/tools/config/utils.go index bd43a5817..426aa583d 100644 --- a/tools/config/utils.go +++ b/tools/config/utils.go @@ -9,6 +9,7 @@ import ( "regexp" "strconv" "strings" + "sync" "golang.org/x/exp/maps" "golang.org/x/exp/slices" @@ -189,7 +190,7 @@ func StringLiteral(val string) (string, error) { return ans.String(), nil } -var ModMap = utils.Once(func() map[string]string { +var ModMap = sync.OnceValue(func() map[string]string { return map[string]string{ "shift": "shift", "⇧": "shift", @@ -211,7 +212,7 @@ var ModMap = utils.Once(func() map[string]string { } }) -var ShortcutSpecPat = utils.Once(func() *regexp.Regexp { +var ShortcutSpecPat = sync.OnceValue(func() *regexp.Regexp { return regexp.MustCompile(`([^+])>`) }) diff --git a/tools/themes/collection.go b/tools/themes/collection.go index 7b0b54341..6c6f92cf2 100644 --- a/tools/themes/collection.go +++ b/tools/themes/collection.go @@ -17,6 +17,7 @@ import ( "regexp" "strconv" "strings" + "sync" "time" "kitty/tools/cli" @@ -780,7 +781,7 @@ func (self *Themes) Copy() *Themes { return ans } -var camel_case_pat = utils.Once(func() *regexp.Regexp { +var camel_case_pat = sync.OnceValue(func() *regexp.Regexp { return regexp.MustCompile(`([a-z])([A-Z])`) }) diff --git a/tools/tty/tty.go b/tools/tty/tty.go index ca0cdd374..7dc2d5048 100644 --- a/tools/tty/tty.go +++ b/tools/tty/tty.go @@ -9,6 +9,7 @@ import ( "io" "os" "strconv" + "sync" "time" "golang.org/x/sys/unix" @@ -340,7 +341,7 @@ func (self *Term) GetSize() (*unix.Winsize, error) { // go doesn't have a wrapper for ctermid() func Ctermid() string { return "/dev/tty" } -var KittyStdout = utils.Once(func() *os.File { +var KittyStdout = sync.OnceValue(func() *os.File { if fds := os.Getenv(`KITTY_STDIO_FORWARDED`); fds != "" { if fd, err := strconv.Atoi(fds); err == nil && fd > -1 { if f := os.NewFile(uintptr(fd), ""); f != nil { diff --git a/tools/tui/run.go b/tools/tui/run.go index 3640c7c0d..a8ab57761 100644 --- a/tools/tui/run.go +++ b/tools/tui/run.go @@ -10,6 +10,7 @@ import ( "path/filepath" "runtime" "strings" + "sync" "github.com/shirou/gopsutil/v3/process" "golang.org/x/sys/unix" @@ -60,7 +61,7 @@ func get_effective_ksi_env_var(x string) string { return x } -var relevant_kitty_opts = utils.Once(func() KittyOpts { +var relevant_kitty_opts = sync.OnceValue(func() KittyOpts { return read_relevant_kitty_opts(filepath.Join(utils.ConfigDir(), "kitty.conf")) }) diff --git a/tools/tui/shell_integration/data.go b/tools/tui/shell_integration/data.go index 0210f4e4c..ff5a8538f 100644 --- a/tools/tui/shell_integration/data.go +++ b/tools/tui/shell_integration/data.go @@ -11,6 +11,7 @@ import ( "kitty/tools/utils" "regexp" "strings" + "sync" ) var _ = fmt.Print @@ -25,7 +26,7 @@ type Entry struct { type Container map[string]Entry -var Data = utils.Once(func() Container { +var Data = sync.OnceValue(func() Container { tr := tar.NewReader(utils.ReaderForCompressedEmbeddedData(embedded_data)) ans := make(Container, 64) for { diff --git a/tools/tui/tmux.go b/tools/tui/tmux.go index f3d9a21c9..d56903574 100644 --- a/tools/tui/tmux.go +++ b/tools/tui/tmux.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" "time" "github.com/shirou/gopsutil/v3/process" @@ -20,7 +21,7 @@ import ( var _ = fmt.Print -var TmuxExe = utils.Once(func() string { +var TmuxExe = sync.OnceValue(func() string { return utils.FindExe("tmux") }) @@ -55,7 +56,7 @@ func tmux_socket_address() (socket string) { return socket } -var TmuxSocketAddress = utils.Once(tmux_socket_address) +var TmuxSocketAddress = sync.OnceValue(tmux_socket_address) func tmux_command(args ...string) (c *exec.Cmd, stderr *strings.Builder) { c = exec.Command(TmuxExe(), args...) @@ -100,4 +101,4 @@ func tmux_allow_passthrough() error { } } -var TmuxAllowPassthrough = utils.Once(tmux_allow_passthrough) +var TmuxAllowPassthrough = sync.OnceValue(tmux_allow_passthrough) diff --git a/tools/tui/ui_kitten.go b/tools/tui/ui_kitten.go index bf3dce086..f4def13e9 100644 --- a/tools/tui/ui_kitten.go +++ b/tools/tui/ui_kitten.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "os" + "sync" "kitty/tools/cli" "kitty/tools/utils" @@ -15,7 +16,7 @@ import ( var _ = fmt.Print -var RunningAsUI = utils.Once(func() bool { +var RunningAsUI = sync.OnceValue(func() bool { defer func() { os.Unsetenv("KITTEN_RUNNING_AS_UI") }() return os.Getenv("KITTEN_RUNNING_AS_UI") != "" }) diff --git a/tools/utils/hostname.go b/tools/utils/hostname.go index 5e1effe39..fe7bcb0ee 100644 --- a/tools/utils/hostname.go +++ b/tools/utils/hostname.go @@ -5,13 +5,14 @@ package utils import ( "fmt" "os" + "sync" ) var _ = fmt.Print var hostname string = "*" -var Hostname = Once(func() string { +var Hostname = sync.OnceValue(func() string { h, err := os.Hostname() if err == nil { return h diff --git a/tools/utils/images/loading.go b/tools/utils/images/loading.go index f145644ff..97506950b 100644 --- a/tools/utils/images/loading.go +++ b/tools/utils/images/loading.go @@ -16,6 +16,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" "kitty/tools/utils" "kitty/tools/utils/shm" @@ -264,7 +265,7 @@ func OpenNativeImageFromReader(f io.ReadSeeker) (ans *ImageData, err error) { return } -var MagickExe = utils.Once(func() string { +var MagickExe = sync.OnceValue(func() string { return utils.FindExe("magick") }) diff --git a/tools/utils/mimetypes.go b/tools/utils/mimetypes.go index 026aaaf2a..6fd8415b4 100644 --- a/tools/utils/mimetypes.go +++ b/tools/utils/mimetypes.go @@ -11,6 +11,7 @@ import ( "os" "path/filepath" "strings" + "sync" "golang.org/x/sys/unix" ) @@ -44,7 +45,7 @@ func load_mime_file(filename string, mime_map map[string]string) error { return nil } -var UserMimeMap = Once(func() map[string]string { +var UserMimeMap = sync.OnceValue(func() map[string]string { conf_path := filepath.Join(ConfigDir(), "mime.types") ans := make(map[string]string, 32) err := load_mime_file(conf_path, ans) diff --git a/tools/utils/once.go b/tools/utils/once.go deleted file mode 100644 index 822a8ab24..000000000 --- a/tools/utils/once.go +++ /dev/null @@ -1,39 +0,0 @@ -// License: GPLv3 Copyright: 2023, Kovid Goyal, - -package utils - -import ( - "fmt" - "sync" - "sync/atomic" -) - -var _ = fmt.Print - -type once[T any] struct { - done uint32 - mutex sync.Mutex - cached_val T - - Run func() T -} - -func (self *once[T]) Get() T { - if atomic.LoadUint32(&self.done) == 0 { - self.do_slow() - } - return self.cached_val -} - -func (self *once[T]) do_slow() { - self.mutex.Lock() - defer self.mutex.Unlock() - if atomic.LoadUint32(&self.done) == 0 { - defer atomic.StoreUint32(&self.done, 1) - self.cached_val = self.Run() - } -} - -func Once[T any](f func() T) func() T { - return (&once[T]{Run: f}).Get -} diff --git a/tools/utils/once_test.go b/tools/utils/once_test.go deleted file mode 100644 index 63518090d..000000000 --- a/tools/utils/once_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// License: GPLv3 Copyright: 2023, Kovid Goyal, - -package utils - -import ( - "fmt" - "testing" -) - -var _ = fmt.Print - -func TestOnce(t *testing.T) { - num := 0 - var G = Once(func() string { - num++ - return fmt.Sprintf("%d", num) - }) - G() - G() - G() - if num != 1 { - t.Fatalf("num unexpectedly: %d", num) - } -} diff --git a/tools/utils/passwd.go b/tools/utils/passwd.go index 0b996d5d3..1557508bc 100644 --- a/tools/utils/passwd.go +++ b/tools/utils/passwd.go @@ -10,6 +10,7 @@ import ( "runtime" "strconv" "strings" + "sync" "howett.net/plist" ) @@ -49,7 +50,7 @@ func ParsePasswdFile(path string) (ans map[string]PasswdEntry, err error) { } var passwd_err error -var passwd_database = Once(func() (ans map[string]PasswdEntry) { +var passwd_database = sync.OnceValue(func() (ans map[string]PasswdEntry) { ans, passwd_err = ParsePasswdFile("/etc/passwd") return }) @@ -107,7 +108,7 @@ func parse_dscl_data(raw []byte) (ans map[string]PasswdEntry, err error) { var dscl_error error -var dscl_user_database = Once(func() map[string]PasswdEntry { +var dscl_user_database = sync.OnceValue(func() map[string]PasswdEntry { c := exec.Command("/usr/bin/dscl", "-plist", ".", "-readall", "/Users", "uid", "gid", "name", "realname", "home", "shell") raw, err := c.Output() if err != nil { diff --git a/tools/utils/paths.go b/tools/utils/paths.go index 3446e2f8b..759177fcc 100644 --- a/tools/utils/paths.go +++ b/tools/utils/paths.go @@ -16,6 +16,7 @@ import ( "sort" "strconv" "strings" + "sync" "unicode/utf8" "golang.org/x/sys/unix" @@ -64,7 +65,7 @@ func Abspath(path string) string { return path } -var KittyExe = Once(func() string { +var KittyExe = sync.OnceValue(func() string { exe, err := os.Executable() if err == nil { ans := filepath.Join(filepath.Dir(exe), "kitty") @@ -119,11 +120,11 @@ func ConfigDirForName(name string) (config_dir string) { return } -var ConfigDir = Once(func() (config_dir string) { +var ConfigDir = sync.OnceValue(func() (config_dir string) { return ConfigDirForName("kitty.conf") }) -var CacheDir = Once(func() (cache_dir string) { +var CacheDir = sync.OnceValue(func() (cache_dir string) { candidate := "" if edir := os.Getenv("KITTY_CACHE_DIRECTORY"); edir != "" { candidate = Abspath(Expanduser(edir)) @@ -178,7 +179,7 @@ func macos_user_cache_dir() string { return "" } -var RuntimeDir = Once(func() (runtime_dir string) { +var RuntimeDir = sync.OnceValue(func() (runtime_dir string) { var candidate string if q := os.Getenv("KITTY_RUNTIME_DIRECTORY"); q != "" { candidate = q diff --git a/tools/utils/which.go b/tools/utils/which.go index c5f015ffa..4cbd270d4 100644 --- a/tools/utils/which.go +++ b/tools/utils/which.go @@ -7,13 +7,14 @@ import ( "os" "path/filepath" "strings" + "sync" "golang.org/x/sys/unix" ) var _ = fmt.Print -var DefaultExeSearchPaths = Once(func() []string { +var DefaultExeSearchPaths = sync.OnceValue(func() []string { candidates := [...]string{"/usr/local/bin", "/opt/bin", "/opt/homebrew/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"} ans := make([]string, 0, len(candidates)) for _, x := range candidates {