feat: integrate configuration file for clipboard history management

This commit is contained in:
Menno van Leeuwen 2025-05-21 00:22:39 +02:00
parent 380742a869
commit c42fa87c61
Signed by: vleeuwenmenno
SSH Key Fingerprint: SHA256:OJFmjANpakwD3F2Rsws4GLtbdz1TJ5tkQF0RZmF0TRE
8 changed files with 77 additions and 17 deletions

View File

@ -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")
},
}

View File

@ -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))
},
}
}

View File

@ -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")

View File

@ -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)
},
}

View File

@ -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 ")
}

View File

@ -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()

View File

@ -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 {

View File

@ -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)
}