feat(history): add bash and fish

This commit is contained in:
verse91
2026-04-19 11:02:52 +07:00
parent c7106f9fc2
commit 00826a5c07
+53 -5
View File
@@ -8,6 +8,7 @@ import (
"sync"
"github.com/versenilvis/fuzzyvn"
"github.com/versenilvis/iris/integration/shell"
)
var (
@@ -15,6 +16,7 @@ var (
idMapCache map[string]int
searcherCache *fuzzyvn.Searcher
mu sync.Mutex
lastModTime int64
)
type HistResult struct {
@@ -26,19 +28,40 @@ func init() {
idMapCache = make(map[string]int)
}
// SearchHistory reads the zsh history and searches using fuzzyvn (my own pkg)
func SearchHistory(query string) ([]HistResult, error) {
mu.Lock()
defer mu.Unlock()
// lazy load history if cache is empty
if len(historyCache) == 0 {
home, err := os.UserHomeDir()
if err != nil {
return nil, err
}
histFile := filepath.Join(home, ".zsh_history")
shellName := "bash"
if shell.Current != nil {
shellName = shell.Current.GetName()
}
var histFile string
switch shellName {
case "zsh":
histFile = filepath.Join(home, ".zsh_history")
case "fish":
histFile = filepath.Join(home, ".local", "share", "fish", "fish_history")
default:
histFile = filepath.Join(home, ".bash_history")
}
if info, err := os.Stat(histFile); err == nil {
if info.ModTime().UnixNano() > lastModTime {
historyCache = nil // force reload
idMapCache = make(map[string]int)
lastModTime = info.ModTime().UnixNano()
}
}
// lazy load history if cache is empty
if len(historyCache) == 0 {
file, err := os.Open(histFile)
if err != nil {
return nil, err
@@ -50,12 +73,37 @@ func SearchHistory(query string) ([]HistResult, error) {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
cmd := line
if shellName == "zsh" {
// zsh history format: : <timestamp>;<command>
parts := strings.SplitN(line, ";", 2)
cmd := line
if len(parts) == 2 {
cmd = parts[1]
}
} else if shellName == "bash" {
// bash history format can include timestamps starting with #
if strings.HasPrefix(line, "#") && len(line) > 1 {
isTimestamp := true
for _, c := range line[1:] {
if c < '0' || c > '9' {
isTimestamp = false
break
}
}
if isTimestamp {
continue
}
}
} else if shellName == "fish" {
// simple parse for fish history (YAML-like)
if strings.HasPrefix(line, "- cmd: ") {
cmd = strings.TrimPrefix(line, "- cmd: ")
} else {
continue
}
}
cmd = strings.TrimSpace(cmd)
if cmd != "" {