feat(spec): support tool aliases (#107)
closes #57 IRIS now automatically read and suggest internal configuration aliases for Git (`.gitconfig`, `.git/config`) and Cargo (`.cargo/config.toml`) - Added the `Provider` interface and extended registry for CLI tools that define aliases - Git: parse aliases via `git config --show-scope`, supporting raw tab/space separation and scope differentiation - Cargo: traverse the directory tree upwards to root to read the `.cargo/config.toml` configuration - 0ms hot-path caching: key caching is calculated entirely via `os.Stat` mtime (no subprocess spawn) combined with a 2-second TTL window to ensure 0ms latency when typing - Lookup integration: display alias suggestions at the subcommand level and automatically expand aliases as the user enters further arguments (ignore shell pipeline commands starting with `!`)
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
package root
|
||||
|
||||
import "github.com/versenilvis/iris/spec/alias"
|
||||
|
||||
type mockGitProvider struct{}
|
||||
|
||||
func (m *mockGitProvider) ToolName() string { return "git" }
|
||||
func (m *mockGitProvider) GetAliases(cwd string) []alias.AliasEntry {
|
||||
return []alias.AliasEntry{{Name: "co", Expansion: "checkout", Scope: "local"}}
|
||||
}
|
||||
+4
-1
@@ -25,7 +25,10 @@ func MergeResults(query string, mode string) []spec.Suggestion {
|
||||
// add suggestion helper to deduplicate
|
||||
addSuggestion := func(s spec.Suggestion) {
|
||||
normalizedCmd := strings.TrimSpace(s.Cmd)
|
||||
if normalizedCmd == "" || normalizedCmd == normalizedQuery {
|
||||
if normalizedCmd == "" {
|
||||
return
|
||||
}
|
||||
if s.Source != "alias" && normalizedCmd == normalizedQuery {
|
||||
return
|
||||
}
|
||||
if s.Source == "" {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/versenilvis/iris/spec"
|
||||
"github.com/versenilvis/iris/spec/alias"
|
||||
)
|
||||
|
||||
func TestMergeResults(t *testing.T) {
|
||||
@@ -48,6 +49,22 @@ func TestMergeResults(t *testing.T) {
|
||||
t.Errorf("Expected promoted source 'ai', got %q", res[0].Source)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Tool Alias Preserved When Matching Query", func(t *testing.T) {
|
||||
alias.Register(&mockGitProvider{})
|
||||
defer alias.Reset()
|
||||
res := MergeResults("git co", "default")
|
||||
foundCo := false
|
||||
for _, r := range res {
|
||||
if r.Cmd == "git co" {
|
||||
foundCo = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundCo {
|
||||
t.Errorf("expected 'git co' alias suggestion in results for query 'git co', got %v", res)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestPrevRecordedCommandState(t *testing.T) {
|
||||
|
||||
@@ -821,6 +821,7 @@ func runWrapper() {
|
||||
overlay.ClearGhostTextState()
|
||||
userNavigated.Store(false)
|
||||
writeStdout([]byte(overlay.Render()))
|
||||
renderOverlay()
|
||||
}
|
||||
i += consumed - 1
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user