on main help sign in
Merge branch 'main' into ui
commit84830614667409cba8f896c6db93f7862268b841 authorAyman Bagabas <ayman.bagabas@gmail.com> dateThu 18 Dec 2025, 12:38 (1 year ago) parentf14253f996539f
4 files changed+28−12
README.md+5 cspell.json−1 internal/config/load.go+13−9 internal/tui/components/mcp/mcp.go+10−2
README.md+5
@@ -232,6 +232,11 @@ $HOME/.local/share/crush/crush.json
232232%LOCALAPPDATA%\crush\crush.json
233233```
234234
235+> [!TIP]
236+> You can override the user and data config locations by setting:
237+> * `CRUSH_GLOBAL_CONFIG`
238+> * `CRUSH_GLOBAL_DATA`
239+
235240### LSPs
236241
237242Crush can use LSPs for additional context to help inform its decisions, just
cspell.jsondeleted−1
@@ -1 +0,0 @@
1−{"words":["afero","agentic","alecthomas","anthropics","aymanbagabas","azidentity","bmatcuk","bubbletea","charlievieth","charmbracelet","charmtone","Charple","chkconfig","crush","curlie","cursorrules","diffview","doas","Dockerfiles","doublestar","dpkg","Emph","fastwalk","fdisk","filepicker","Focusable","fseventsd","fsext","genai","goquery","GROQ","Guac","imageorient","Inex","jetta","jsons","jsonschema","jspm","Kaufmann","killall","Lanczos","lipgloss","LOCALAPPDATA","lsps","lucasb","makepkg","mcps","MSYS","mvdan","natefinch","nfnt","noctx","nohup","nolint","nslookup","oksvg","Oneshot","openrouter","opkg","pacman","paru","pfctl","postamble","postambles","preconfigured","Preproc","Proactiveness","Puerkito","pycache","pytest","qjebbs","rasterx","rivo","sabhiram","sess","shortlog","sjson","Sourcegraph","srwiley","SSEMCP","Streamable","stretchr","Strikethrough","substrs","Suscriber","systeminfo","tasklist","termenv","textinput","tidwall","timedout","trashhalo","udiff","uniseg","Unticked","urllib","USERPROFILE","VERTEXAI","webp","whatis","whereis","sahilm","csync","Highlightable","Highlightable","prerendered","prerender","kujtim","animatable"],"version":"0.2","flagWords":[],"language":"en"}
internal/config/load.go+13−9
@@ -1,6 +1,7 @@
11package config
22
33import (
4+ "cmp"
45 "context"
56 "encoding/json"
67 "fmt"
@@ -695,19 +696,22 @@ func hasAWSCredentials(env env.Env) bool {
695696
696697// GlobalConfig returns the global configuration file path for the application.
697698func GlobalConfig() string {
698− xdgConfigHome := os.Getenv("XDG_CONFIG_HOME")
699− if xdgConfigHome != "" {
699+ if crushGlobal := os.Getenv("CRUSH_GLOBAL_CONFIG"); crushGlobal != "" {
700+ return filepath.Join(crushGlobal, fmt.Sprintf("%s.json", appName))
701+ }
702+ if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
700703 return filepath.Join(xdgConfigHome, appName, fmt.Sprintf("%s.json", appName))
701704 }
702−
703705 return filepath.Join(home.Dir(), ".config", appName, fmt.Sprintf("%s.json", appName))
704706}
705707
706708// GlobalConfigData returns the path to the main data directory for the application.
707709// this config is used when the app overrides configurations instead of updating the global config.
708710func GlobalConfigData() string {
709− xdgDataHome := os.Getenv("XDG_DATA_HOME")
710− if xdgDataHome != "" {
711+ if crushData := os.Getenv("CRUSH_GLOBAL_DATA"); crushData != "" {
712+ return filepath.Join(crushData, fmt.Sprintf("%s.json", appName))
713+ }
714+ if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" {
711715 return filepath.Join(xdgDataHome, appName, fmt.Sprintf("%s.json", appName))
712716 }
713717
@@ -715,10 +719,10 @@ func GlobalConfigData() string {
715719 // for windows, it should be in `%LOCALAPPDATA%/crush/`
716720 // for linux and macOS, it should be in `$HOME/.local/share/crush/`
717721 if runtime.GOOS == "windows" {
718− localAppData := os.Getenv("LOCALAPPDATA")
719− if localAppData == "" {
720− localAppData = filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Local")
721− }
722+ localAppData := cmp.Or(
723+ os.Getenv("LOCALAPPDATA"),
724+ filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Local"),
725+ )
722726 return filepath.Join(localAppData, appName, fmt.Sprintf("%s.json", appName))
723727 }
724728
internal/tui/components/mcp/mcp.go+10−2
@@ -69,10 +69,18 @@ func RenderMCPList(opts RenderOptions) []string {
6969 case mcp.StateConnected:
7070 icon = t.ItemOnlineIcon
7171 if count := state.Counts.Tools; count > 0 {
72− extraContent = append(extraContent, t.S().Subtle.Render(fmt.Sprintf("%d tools", count)))
72+ label := "tools"
73+ if count == 1 {
74+ label = "tool"
75+ }
76+ extraContent = append(extraContent, t.S().Subtle.Render(fmt.Sprintf("%d %s", count, label)))
7377 }
7478 if count := state.Counts.Prompts; count > 0 {
75− extraContent = append(extraContent, t.S().Subtle.Render(fmt.Sprintf("%d prompts", count)))
79+ label := "prompts"
80+ if count == 1 {
81+ label = "prompt"
82+ }
83+ extraContent = append(extraContent, t.S().Subtle.Render(fmt.Sprintf("%d %s", count, label)))
7684 }
7785 case mcp.StateError:
7886 icon = t.ItemErrorIcon