From c42fa87c6160dae5d23b0384feb28c33b3f8afd0 Mon Sep 17 00:00:00 2001 From: Menno van Leeuwen Date: Wed, 21 May 2025 00:22:39 +0200 Subject: [PATCH] feat: integrate configuration file for clipboard history management --- src/commands/cmd_clear.go | 4 +++- src/commands/cmd_config.go | 27 +++++++++++++++++++++++++++ src/commands/cmd_copy.go | 4 +++- src/commands/cmd_list.go | 4 +++- src/commands/cmd_watch.go | 4 +++- src/config/config.go | 13 ++++++++++++- src/main.go | 5 +++-- src/models/history.go | 33 +++++++++++++++++++++++---------- 8 files changed, 77 insertions(+), 17 deletions(-) create mode 100644 src/commands/cmd_config.go diff --git a/src/commands/cmd_clear.go b/src/commands/cmd_clear.go index caef16e..d236fdb 100644 --- a/src/commands/cmd_clear.go +++ b/src/commands/cmd_clear.go @@ -3,6 +3,7 @@ package commands import ( "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "github.com/vleeuwenmenno/kcm/src/config" "github.com/vleeuwenmenno/kcm/src/models" ) @@ -12,7 +13,8 @@ func NewClearCmd(history *models.History) *cobra.Command { Short: "Clear clipboard history", Aliases: []string{"--clear"}, Run: func(cmd *cobra.Command, args []string) { - history.Clear() + cfg, _ := config.LoadConfig() + history.Clear(cfg.Clipboard.HistoryFile) log.Info().Msg("Clipboard history cleared") }, } diff --git a/src/commands/cmd_config.go b/src/commands/cmd_config.go new file mode 100644 index 0000000..c123465 --- /dev/null +++ b/src/commands/cmd_config.go @@ -0,0 +1,27 @@ +package commands + +import ( + "encoding/json" + + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" + "github.com/vleeuwenmenno/kcm/src/config" +) + +// NewConfigCmd returns the cobra command for `kcm config` +func NewConfigCmd() *cobra.Command { + return &cobra.Command{ + Use: "config", + Short: "Show the current configuration", + Run: func(cmd *cobra.Command, args []string) { + cfg, path := config.LoadConfig() + log.Info().Str("config_path", path).Msg("Config loaded from file") + cfgJson, err := json.MarshalIndent(cfg, "", " ") + if err != nil { + log.Error().Err(err).Msg("Failed to marshal config to JSON") + return + } + log.Info().Msgf("Loaded config:\n%s", string(cfgJson)) + }, + } +} diff --git a/src/commands/cmd_copy.go b/src/commands/cmd_copy.go index aa1d0bf..4795e99 100644 --- a/src/commands/cmd_copy.go +++ b/src/commands/cmd_copy.go @@ -5,6 +5,7 @@ import ( "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "github.com/vleeuwenmenno/kcm/src/config" "github.com/vleeuwenmenno/kcm/src/models" "golang.design/x/clipboard" ) @@ -20,7 +21,8 @@ func NewCopyCmd(history *models.History) *cobra.Command { if err != nil || index < 1 { log.Fatal().Err(err).Msg("Invalid index") } - history.ReloadIfChanged() + cfg, _ := config.LoadConfig() + history.ReloadIfChanged(cfg.Clipboard.HistoryFile) historyLen := len(history.Items) if index > historyLen { log.Fatal().Int("index", index).Int("historyLen", historyLen).Msg("Index out of range") diff --git a/src/commands/cmd_list.go b/src/commands/cmd_list.go index b33609a..9fbb34d 100644 --- a/src/commands/cmd_list.go +++ b/src/commands/cmd_list.go @@ -4,6 +4,7 @@ import ( "os" "github.com/spf13/cobra" + "github.com/vleeuwenmenno/kcm/src/config" "github.com/vleeuwenmenno/kcm/src/models" ) @@ -14,7 +15,8 @@ func NewListCmd(history *models.History) *cobra.Command { Short: "List clipboard history", Aliases: []string{"--list"}, Run: func(cmd *cobra.Command, args []string) { - history.ReloadIfChanged() + cfg, _ := config.LoadConfig() + history.ReloadIfChanged(cfg.Clipboard.HistoryFile) history.List(os.Stdout, noTrunc) }, } diff --git a/src/commands/cmd_watch.go b/src/commands/cmd_watch.go index d65c781..7b68e9d 100644 --- a/src/commands/cmd_watch.go +++ b/src/commands/cmd_watch.go @@ -93,7 +93,9 @@ func NewWatchCmd(history *models.History) *cobra.Command { Timestamp: time.Now(), Pinned: false, } - history.Add(item) + // Load config for history file path + cfg, _ := config.LoadConfig() + history.Add(item, cfg.Clipboard.HistoryFile) lastText = text log.Info().Str("content", text).Msg("Text item added ") } diff --git a/src/config/config.go b/src/config/config.go index 08370e6..30d255b 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -15,7 +15,8 @@ type Config struct { Path string `yaml:"path"` } `yaml:"logging"` Clipboard struct { - MaxItems int `yaml:"max_items"` + MaxItems int `yaml:"max_items"` + HistoryFile string `yaml:"history_file"` } `yaml:"clipboard"` } @@ -43,6 +44,16 @@ func LoadConfig() (Config, string) { if cfg.Logging.Path == "" { cfg.Logging.Path = logFilePath() } + if cfg.Clipboard.HistoryFile == "" { + usr, err := user.Current() + if err != nil { + cfg.Clipboard.HistoryFile = "./history.gob" + } else { + dir := filepath.Join(usr.HomeDir, ".local", "share", "kcm") + os.MkdirAll(dir, 0700) + cfg.Clipboard.HistoryFile = filepath.Join(dir, "history.gob") + } + } return cfg, path } file.Close() diff --git a/src/main.go b/src/main.go index a04e050..e44e14e 100644 --- a/src/main.go +++ b/src/main.go @@ -36,7 +36,7 @@ func main() { log.Debug().Str("config", cfgPath).Msg("Loaded configuration") history := &models.History{MaxItems: cfg.Clipboard.MaxItems} - history.Load() + history.Load(cfg.Clipboard.HistoryFile) shouldReturn := handleDebugging() if shouldReturn { @@ -56,7 +56,8 @@ func main() { commands.NewSearchCmd(history), commands.NewStatusCmd(), commands.NewVersionCmd(), - commands.NewStopCmd(), // Add the stop command + commands.NewStopCmd(), + commands.NewConfigCmd(), ) if err := rootCmd.Execute(); err != nil { diff --git a/src/models/history.go b/src/models/history.go index b9eee51..ee722c7 100644 --- a/src/models/history.go +++ b/src/models/history.go @@ -30,10 +30,23 @@ func historyFilePath() string { return filepath.Join(dir, "history.gob") } -func (h *History) Save() error { +func historyFilePathFromConfig(historyFile string) string { + if historyFile != "" { + return historyFile + } + usr, err := user.Current() + if err != nil { + return "./history.gob" + } + dir := filepath.Join(usr.HomeDir, ".local", "share", "kcm") + os.MkdirAll(dir, 0700) + return filepath.Join(dir, "history.gob") +} + +func (h *History) Save(historyFile string) error { h.mu.Lock() defer h.mu.Unlock() - file, err := os.Create(historyFilePath()) + file, err := os.Create(historyFilePathFromConfig(historyFile)) if err != nil { return err } @@ -42,10 +55,10 @@ func (h *History) Save() error { return enc.Encode(h.Items) } -func (h *History) Load() error { +func (h *History) Load(historyFile string) error { h.mu.Lock() defer h.mu.Unlock() - file, err := os.Open(historyFilePath()) + file, err := os.Open(historyFilePathFromConfig(historyFile)) if err != nil { return err } @@ -54,7 +67,7 @@ func (h *History) Load() error { return dec.Decode(&h.Items) } -func (h *History) Add(item HistoryItem) { +func (h *History) Add(item HistoryItem, historyFile string) { h.mu.Lock() // Prevent duplicates: remove any existing item with the same hash itemHash := utils.HashBytes(item.Data) @@ -77,14 +90,14 @@ func (h *History) Add(item HistoryItem) { h.Items = h.Items[over:] } h.mu.Unlock() - h.Save() + h.Save(historyFile) } -func (h *History) Clear() error { +func (h *History) Clear(historyFile string) error { h.mu.Lock() defer h.mu.Unlock() h.Items = nil - return h.Save() + return h.Save(historyFile) } func (h *History) List(w io.Writer, noTrunc bool) { @@ -110,6 +123,6 @@ func (h *History) List(w io.Writer, noTrunc bool) { } } -func (h *History) ReloadIfChanged() error { - return h.Load() +func (h *History) ReloadIfChanged(historyFile string) error { + return h.Load(historyFile) }