summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/appconfig/app_feature_sections.go40
-rw-r--r--internal/appconfig/app_feature_sections_test.go68
-rw-r--r--internal/appconfig/app_sections.go30
-rw-r--r--internal/appconfig/app_sections_test.go50
-rw-r--r--internal/appconfig/config_features_test.go4
-rw-r--r--internal/appconfig/config_load.go4
-rw-r--r--internal/appconfig/config_types.go8
-rw-r--r--internal/appconfig/feature_sections.go50
-rw-r--r--internal/hexaimcp/run.go2
-rw-r--r--internal/hexaimcp/run_test.go18
-rw-r--r--internal/lsp/ignore_test.go2
-rw-r--r--internal/slashcommands/syncer.go3
-rw-r--r--internal/slashcommands/syncer_test.go22
-rw-r--r--internal/tmuxedit/run_test.go4
14 files changed, 232 insertions, 73 deletions
diff --git a/internal/appconfig/app_feature_sections.go b/internal/appconfig/app_feature_sections.go
new file mode 100644
index 0000000..2513946
--- /dev/null
+++ b/internal/appconfig/app_feature_sections.go
@@ -0,0 +1,40 @@
+package appconfig
+
+import "slices"
+
+// This file provides fine-grained, read-only accessors for the individual
+// feature subsystems embedded in FeatureConfig. They let a consumer depend on
+// just the subsystem config it needs (e.g. the MCP server only needs MCPConfig)
+// instead of receiving the whole App God-struct. Each accessor returns a deep
+// copy so callers cannot mutate App's internal slices.
+
+// IgnoreSection returns a copy of the gitignore-aware filtering settings.
+func (a *App) IgnoreSection() IgnoreConfig {
+ c := a.IgnoreConfig
+ c.IgnoreExtraPatterns = slices.Clone(a.IgnoreExtraPatterns)
+ return c
+}
+
+// StatsSection returns the usage statistics settings.
+func (a *App) StatsSection() StatsConfig {
+ return a.StatsConfig
+}
+
+// TmuxEditSection returns a copy of the tmux popup editor settings.
+func (a *App) TmuxEditSection() TmuxEditConfig {
+ c := a.TmuxEditConfig
+ c.TmuxEditAgents = append([]TmuxEditAgentCfg{}, a.TmuxEditAgents...)
+ return c
+}
+
+// TmuxActionSection returns a copy of the tmux action menu settings.
+func (a *App) TmuxActionSection() TmuxActionConfig {
+ c := a.TmuxActionConfig
+ c.TmuxActionMenu = append([]TmuxActionMenuEntry{}, a.TmuxActionMenu...)
+ return c
+}
+
+// MCPSection returns the Model Context Protocol server settings.
+func (a *App) MCPSection() MCPConfig {
+ return a.MCPConfig
+}
diff --git a/internal/appconfig/app_feature_sections_test.go b/internal/appconfig/app_feature_sections_test.go
new file mode 100644
index 0000000..1f9ac2d
--- /dev/null
+++ b/internal/appconfig/app_feature_sections_test.go
@@ -0,0 +1,68 @@
+package appconfig
+
+import (
+ "reflect"
+ "testing"
+)
+
+// buildFeatureApp returns an App whose FeatureConfig subsystems are all
+// populated, used to verify the fine-grained section accessors.
+func buildFeatureApp() App {
+ cfg := App{}
+ cfg.ApplyFeatureSection(testFeatureConfig())
+ return cfg
+}
+
+func TestIgnoreSectionCopiesAndReads(t *testing.T) {
+ cfg := buildFeatureApp()
+ got := cfg.IgnoreSection()
+ if !reflect.DeepEqual(got.IgnoreExtraPatterns, []string{"vendor/**", "tmp/**"}) {
+ t.Fatalf("IgnoreExtraPatterns = %v", got.IgnoreExtraPatterns)
+ }
+ // Mutating the returned copy must not affect the source App.
+ got.IgnoreExtraPatterns[0] = "mutated"
+ if cfg.IgnoreExtraPatterns[0] == "mutated" {
+ t.Fatal("IgnoreSection did not return a defensive copy")
+ }
+}
+
+func TestStatsSectionReads(t *testing.T) {
+ cfg := buildFeatureApp()
+ if got := cfg.StatsSection(); got.StatsWindowMinutes != 15 {
+ t.Fatalf("StatsWindowMinutes = %d, want 15", got.StatsWindowMinutes)
+ }
+}
+
+func TestTmuxEditSectionCopies(t *testing.T) {
+ cfg := buildFeatureApp()
+ got := cfg.TmuxEditSection()
+ if got.TmuxEditDefaultAgent != "codex" || len(got.TmuxEditAgents) != 1 {
+ t.Fatalf("unexpected tmux edit section: %+v", got)
+ }
+ got.TmuxEditAgents[0].Name = "mutated"
+ if cfg.TmuxEditAgents[0].Name == "mutated" {
+ t.Fatal("TmuxEditSection did not return a defensive copy")
+ }
+}
+
+func TestTmuxActionSectionCopies(t *testing.T) {
+ cfg := App{}
+ cfg.TmuxActionMenu = []TmuxActionMenuEntry{{Kind: "rewrite"}}
+ got := cfg.TmuxActionSection()
+ if len(got.TmuxActionMenu) != 1 || got.TmuxActionMenu[0].Kind != "rewrite" {
+ t.Fatalf("unexpected tmux action section: %+v", got)
+ }
+ got.TmuxActionMenu[0].Kind = "mutated"
+ if cfg.TmuxActionMenu[0].Kind == "mutated" {
+ t.Fatal("TmuxActionSection did not return a defensive copy")
+ }
+}
+
+func TestMCPSectionReads(t *testing.T) {
+ cfg := buildFeatureApp()
+ got := cfg.MCPSection()
+ if got.MCPPromptsDir != ".hexai/prompts" || !got.MCPSlashCommandSync ||
+ got.MCPSlashCommandDir != ".hexai/slash" {
+ t.Fatalf("unexpected MCP section: %+v", got)
+ }
+}
diff --git a/internal/appconfig/app_sections.go b/internal/appconfig/app_sections.go
index 05b3171..5919db1 100644
--- a/internal/appconfig/app_sections.go
+++ b/internal/appconfig/app_sections.go
@@ -102,26 +102,18 @@ type PromptConfig struct {
TmuxCustomMenuHotkey string `json:"-"`
}
-// FeatureConfig contains non-LLM feature toggles/integration settings.
-// It is embedded in App; fields use json:"-" since features are not exposed via JSON.
+// FeatureConfig groups the non-LLM feature subsystems. Rather than a flat
+// grab-bag, it now embeds one cohesive struct per subsystem (see
+// feature_sections.go). Embedding keeps field promotion intact so existing flat
+// access (e.g. cfg.MCPPromptsDir) and the JSON shape are unchanged; the split
+// just makes the subsystem boundaries explicit and lets callers depend on a
+// single subsystem via the App.*Section accessors.
type FeatureConfig struct {
- // Stats
- StatsWindowMinutes int `json:"-"`
- // Ignore: gitignore-aware file filtering for LSP
- IgnoreGitignore *bool `json:"-"`
- IgnoreExtraPatterns []string `json:"-"`
- IgnoreLSPNotify *bool `json:"-"`
- // TmuxEdit: popup editor settings for hexai-tmux-edit
- TmuxEditPopupWidth string `json:"-"`
- TmuxEditPopupHeight string `json:"-"`
- TmuxEditDefaultAgent string `json:"-"`
- TmuxEditAgents []TmuxEditAgentCfg `json:"-"`
- // TmuxAction: configurable main menu for hexai-tmux-action
- TmuxActionMenu []TmuxActionMenuEntry `json:"-"`
- // MCP: Model Context Protocol server settings
- MCPPromptsDir string `json:"-"` // Directory for prompt storage
- MCPSlashCommandSync bool `json:"-"` // Enable slash command sync
- MCPSlashCommandDir string `json:"-"` // Directory for slash command files
+ StatsConfig // usage statistics window
+ IgnoreConfig // gitignore-aware file filtering for LSP
+ TmuxEditConfig // popup editor settings for hexai-tmux-edit
+ TmuxActionConfig // configurable main menu for hexai-tmux-action
+ MCPConfig // Model Context Protocol server settings
}
// AppSections is the focused split of App into subsystem-specific config groups.
diff --git a/internal/appconfig/app_sections_test.go b/internal/appconfig/app_sections_test.go
index e26d3f3..bcd1cbe 100644
--- a/internal/appconfig/app_sections_test.go
+++ b/internal/appconfig/app_sections_test.go
@@ -169,28 +169,34 @@ func testPromptConfig() PromptConfig {
func testFeatureConfig() FeatureConfig {
return FeatureConfig{
- StatsWindowMinutes: 15,
- IgnoreGitignore: sectionBoolPtr(true),
- IgnoreExtraPatterns: []string{"vendor/**", "tmp/**"},
- IgnoreLSPNotify: sectionBoolPtr(false),
- TmuxEditPopupWidth: "80%",
- TmuxEditPopupHeight: "75%",
- TmuxEditDefaultAgent: "codex",
- TmuxEditAgents: []TmuxEditAgentCfg{{
- Name: "codex",
- DisplayName: "Codex",
- DetectPattern: "(?i)codex",
- SectionPattern: "section",
- PromptPattern: "prompt",
- StripPatterns: []string{"x", "y"},
- ClearFirst: sectionBoolPtr(true),
- ClearKeys: "C-u",
- NewlineKeys: "S-Enter",
- SubmitKeys: "Enter",
- }},
- MCPPromptsDir: ".hexai/prompts",
- MCPSlashCommandSync: true,
- MCPSlashCommandDir: ".hexai/slash",
+ StatsConfig: StatsConfig{StatsWindowMinutes: 15},
+ IgnoreConfig: IgnoreConfig{
+ IgnoreGitignore: sectionBoolPtr(true),
+ IgnoreExtraPatterns: []string{"vendor/**", "tmp/**"},
+ IgnoreLSPNotify: sectionBoolPtr(false),
+ },
+ TmuxEditConfig: TmuxEditConfig{
+ TmuxEditPopupWidth: "80%",
+ TmuxEditPopupHeight: "75%",
+ TmuxEditDefaultAgent: "codex",
+ TmuxEditAgents: []TmuxEditAgentCfg{{
+ Name: "codex",
+ DisplayName: "Codex",
+ DetectPattern: "(?i)codex",
+ SectionPattern: "section",
+ PromptPattern: "prompt",
+ StripPatterns: []string{"x", "y"},
+ ClearFirst: sectionBoolPtr(true),
+ ClearKeys: "C-u",
+ NewlineKeys: "S-Enter",
+ SubmitKeys: "Enter",
+ }},
+ },
+ MCPConfig: MCPConfig{
+ MCPPromptsDir: ".hexai/prompts",
+ MCPSlashCommandSync: true,
+ MCPSlashCommandDir: ".hexai/slash",
+ },
}
}
diff --git a/internal/appconfig/config_features_test.go b/internal/appconfig/config_features_test.go
index 77beb07..2b8c769 100644
--- a/internal/appconfig/config_features_test.go
+++ b/internal/appconfig/config_features_test.go
@@ -183,13 +183,13 @@ func TestTmuxEditConfig_Merge(t *testing.T) {
clearHexaiEnv(t)
a := newDefaultConfig()
b := App{
- FeatureConfig: FeatureConfig{
+ FeatureConfig: FeatureConfig{TmuxEditConfig: TmuxEditConfig{
TmuxEditPopupWidth: "70%",
TmuxEditDefaultAgent: "amp",
TmuxEditAgents: []TmuxEditAgentCfg{
{Name: "amp", DisplayName: "Amp"},
},
- },
+ }},
}
a.mergeWith(&b)
if a.TmuxEditPopupWidth != "70%" {
diff --git a/internal/appconfig/config_load.go b/internal/appconfig/config_load.go
index 1e4c6b7..ccbf49f 100644
--- a/internal/appconfig/config_load.go
+++ b/internal/appconfig/config_load.go
@@ -388,11 +388,11 @@ func applyIgnoreSection(fc *fileConfig, out *App) {
if fc.Ignore.Gitignore == nil && len(fc.Ignore.ExtraPatterns) == 0 && fc.Ignore.LSPNotifyIgnored == nil {
return
}
- tmp := App{FeatureConfig: FeatureConfig{
+ tmp := App{FeatureConfig: FeatureConfig{IgnoreConfig: IgnoreConfig{
IgnoreGitignore: fc.Ignore.Gitignore,
IgnoreExtraPatterns: fc.Ignore.ExtraPatterns,
IgnoreLSPNotify: fc.Ignore.LSPNotifyIgnored,
- }}
+ }}}
out.mergeBasics(&tmp)
}
diff --git a/internal/appconfig/config_types.go b/internal/appconfig/config_types.go
index 8d50f35..7069b21 100644
--- a/internal/appconfig/config_types.go
+++ b/internal/appconfig/config_types.go
@@ -106,10 +106,12 @@ func newDefaultConfig() App {
},
PromptConfig: defaultPromptConfig(),
FeatureConfig: FeatureConfig{
- StatsWindowMinutes: 60,
+ StatsConfig: StatsConfig{StatsWindowMinutes: 60},
// Ignore: respect .gitignore by default, notify in LSP by default
- IgnoreGitignore: boolPtr(true),
- IgnoreLSPNotify: boolPtr(true),
+ IgnoreConfig: IgnoreConfig{
+ IgnoreGitignore: boolPtr(true),
+ IgnoreLSPNotify: boolPtr(true),
+ },
},
}
}
diff --git a/internal/appconfig/feature_sections.go b/internal/appconfig/feature_sections.go
new file mode 100644
index 0000000..9216400
--- /dev/null
+++ b/internal/appconfig/feature_sections.go
@@ -0,0 +1,50 @@
+package appconfig
+
+// This file defines the cohesive per-subsystem config structs that make up
+// FeatureConfig. The old FeatureConfig was a grab-bag that mixed five unrelated
+// non-LLM subsystems (ignore filtering, stats, tmux popup editor, tmux action
+// menu, MCP server). Splitting them into named structs documents the seams
+// between subsystems and lets consumers depend on a single subsystem's config
+// (via the *Section accessors on App) instead of the whole App God-struct.
+//
+// Each struct is embedded into FeatureConfig, so Go field promotion keeps the
+// historical flat access (e.g. cfg.MCPPromptsDir) working for read sites across
+// the codebase. Only composite literals that set these leaf fields directly on
+// FeatureConfig had to move to the nested form.
+
+// IgnoreConfig controls gitignore-aware file filtering for the LSP server.
+// Files matching these patterns are skipped for completions and code actions.
+type IgnoreConfig struct {
+ // IgnoreGitignore enables respecting .gitignore entries (default true).
+ IgnoreGitignore *bool `json:"-"`
+ // IgnoreExtraPatterns are additional glob patterns to always ignore.
+ IgnoreExtraPatterns []string `json:"-"`
+ // IgnoreLSPNotify controls whether the LSP notifies when ignoring a file.
+ IgnoreLSPNotify *bool `json:"-"`
+}
+
+// StatsConfig holds settings for the usage statistics subsystem.
+type StatsConfig struct {
+ // StatsWindowMinutes is the rolling window (in minutes) used for stats.
+ StatsWindowMinutes int `json:"-"`
+}
+
+// TmuxEditConfig configures the tmux popup editor feature (hexai-tmux-edit).
+type TmuxEditConfig struct {
+ TmuxEditPopupWidth string `json:"-"`
+ TmuxEditPopupHeight string `json:"-"`
+ TmuxEditDefaultAgent string `json:"-"`
+ TmuxEditAgents []TmuxEditAgentCfg `json:"-"`
+}
+
+// TmuxActionConfig configures the main menu for hexai-tmux-action.
+type TmuxActionConfig struct {
+ TmuxActionMenu []TmuxActionMenuEntry `json:"-"`
+}
+
+// MCPConfig holds Model Context Protocol server settings.
+type MCPConfig struct {
+ MCPPromptsDir string `json:"-"` // Directory for prompt storage
+ MCPSlashCommandSync bool `json:"-"` // Enable slash command sync
+ MCPSlashCommandDir string `json:"-"` // Directory for slash command files
+}
diff --git a/internal/hexaimcp/run.go b/internal/hexaimcp/run.go
index 7c487c3..7043ed2 100644
--- a/internal/hexaimcp/run.go
+++ b/internal/hexaimcp/run.go
@@ -205,7 +205,7 @@ func expandPath(path string) (string, error) {
// createSyncer creates a slash command syncer from config.
// Returns nil syncer if sync is disabled.
func createSyncer(cfg appconfig.App, logger *log.Logger) (*slashcommands.Syncer, error) {
- syncer, err := slashcommands.NewSyncer(cfg)
+ syncer, err := slashcommands.NewSyncer(cfg.MCPSection())
if err != nil {
return nil, err
}
diff --git a/internal/hexaimcp/run_test.go b/internal/hexaimcp/run_test.go
index 09f4f87..d567f2e 100644
--- a/internal/hexaimcp/run_test.go
+++ b/internal/hexaimcp/run_test.go
@@ -113,7 +113,7 @@ func TestGetPromptsDir(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{MCPPromptsDir: tt.cfgValue},
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{MCPPromptsDir: tt.cfgValue}},
}
result, err := getPromptsDir(cfg)
@@ -425,7 +425,7 @@ func TestGetPromptsDir_XDGDataHome(t *testing.T) {
// TestGetPromptsDir_TildeInConfig verifies tilde expansion for config path.
func TestGetPromptsDir_TildeInConfig(t *testing.T) {
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{MCPPromptsDir: "~/my-prompts"},
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{MCPPromptsDir: "~/my-prompts"}},
}
result, err := getPromptsDir(cfg)
@@ -450,7 +450,7 @@ func TestGetPromptsDir_TildeInConfig(t *testing.T) {
func TestCreateSyncer_Disabled(t *testing.T) {
logger := log.New(io.Discard, "", 0)
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{MCPSlashCommandSync: false},
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{MCPSlashCommandSync: false}},
}
syncer, err := createSyncer(cfg, logger)
@@ -468,10 +468,10 @@ func TestCreateSyncer_Enabled(t *testing.T) {
tmpDir := t.TempDir()
logger := log.New(io.Discard, "", 0)
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: tmpDir,
- },
+ }},
}
syncer, err := createSyncer(cfg, logger)
@@ -488,10 +488,10 @@ func TestCreateSyncer_Enabled(t *testing.T) {
func TestCreateSyncer_Error(t *testing.T) {
logger := log.New(io.Discard, "", 0)
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: "",
- },
+ }},
}
_, err := createSyncer(cfg, logger)
@@ -651,11 +651,11 @@ func TestApplyOverrides(t *testing.T) {
t.Run("does not overwrite with zero values", func(t *testing.T) {
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPPromptsDir: "/existing/prompts",
MCPSlashCommandSync: true,
MCPSlashCommandDir: "/existing/cmds",
- },
+ }},
}
overrides := MCPOverrides{} // all zero values
applyOverrides(&cfg, overrides)
diff --git a/internal/lsp/ignore_test.go b/internal/lsp/ignore_test.go
index 31ed828..b1899f2 100644
--- a/internal/lsp/ignore_test.go
+++ b/internal/lsp/ignore_test.go
@@ -21,7 +21,7 @@ func newIgnoreTestServer(gitRoot string, useGI bool, extra []string, notifyIgnor
ChatSuffix: ">",
ChatPrefixes: []string{"?", "!", ":", ";"},
},
- FeatureConfig: appconfig.FeatureConfig{IgnoreLSPNotify: notifyIgnored},
+ FeatureConfig: appconfig.FeatureConfig{IgnoreConfig: appconfig.IgnoreConfig{IgnoreLSPNotify: notifyIgnored}},
}
s := &Server{
logger: log.New(io.Discard, "", 0),
diff --git a/internal/slashcommands/syncer.go b/internal/slashcommands/syncer.go
index 1268e7b..674b974 100644
--- a/internal/slashcommands/syncer.go
+++ b/internal/slashcommands/syncer.go
@@ -30,7 +30,8 @@ type Syncer struct {
// NewSyncer creates a new syncer and validates the commands directory.
// Returns error if directory cannot be created or is not writable.
-func NewSyncer(cfg appconfig.App) (*Syncer, error) {
+// It depends only on the MCP subsystem config rather than the whole App.
+func NewSyncer(cfg appconfig.MCPConfig) (*Syncer, error) {
if !cfg.MCPSlashCommandSync {
return &Syncer{enabled: false}, nil
}
diff --git a/internal/slashcommands/syncer_test.go b/internal/slashcommands/syncer_test.go
index 01c6d28..b7ffe47 100644
--- a/internal/slashcommands/syncer_test.go
+++ b/internal/slashcommands/syncer_test.go
@@ -13,10 +13,10 @@ import (
func TestNewSyncer_Disabled(t *testing.T) {
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{MCPSlashCommandSync: false},
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{MCPSlashCommandSync: false}},
}
- syncer, err := NewSyncer(cfg)
+ syncer, err := NewSyncer(cfg.MCPSection())
if err != nil {
t.Fatalf("NewSyncer() with disabled sync failed: %v", err)
}
@@ -28,13 +28,13 @@ func TestNewSyncer_Disabled(t *testing.T) {
func TestNewSyncer_NoDirectory(t *testing.T) {
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: "",
- },
+ }},
}
- _, err := NewSyncer(cfg)
+ _, err := NewSyncer(cfg.MCPSection())
if err == nil {
t.Error("NewSyncer() should fail when directory is not configured")
}
@@ -45,13 +45,13 @@ func TestNewSyncer_CreatesDirectory(t *testing.T) {
testDir := filepath.Join(tmpDir, "test-commands")
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: testDir,
- },
+ }},
}
- syncer, err := NewSyncer(cfg)
+ syncer, err := NewSyncer(cfg.MCPSection())
if err != nil {
t.Fatalf("NewSyncer() failed: %v", err)
}
@@ -75,13 +75,13 @@ func TestNewSyncer_ExpandsHomeDirectory(t *testing.T) {
defer os.Setenv("HOME", home)
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: "~/test-commands",
- },
+ }},
}
- syncer, err := NewSyncer(cfg)
+ syncer, err := NewSyncer(cfg.MCPSection())
if err != nil {
t.Fatalf("NewSyncer() failed: %v", err)
}
diff --git a/internal/tmuxedit/run_test.go b/internal/tmuxedit/run_test.go
index e8ca6c1..f528b95 100644
--- a/internal/tmuxedit/run_test.go
+++ b/internal/tmuxedit/run_test.go
@@ -167,10 +167,10 @@ func TestRunWithConfig_CustomDimensions(t *testing.T) {
sendKeys = func(string, ...string) error { return nil }
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{TmuxEditConfig: appconfig.TmuxEditConfig{
TmuxEditPopupWidth: "90%",
TmuxEditPopupHeight: "85%",
- },
+ }},
}
err := runWithConfig(Options{}, cfg)
if err != nil {