diff options
| author | Paul Buetow <paul@buetow.org> | 2025-09-28 17:30:44 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-09-28 17:30:44 +0300 |
| commit | 0761409497041c752086b9aded08cf9e32e30fd2 (patch) | |
| tree | e62721bc119d4ae435d2609292faea06a68244a4 /internal/hexailsp | |
| parent | 0ac2d186e84f77d73d924e2c0ce975a17c3a8078 (diff) | |
Add --config flag support across CLI, LSP, and tmux tools
Diffstat (limited to 'internal/hexailsp')
| -rw-r--r-- | internal/hexailsp/run.go | 15 | ||||
| -rw-r--r-- | internal/hexailsp/run_more_test.go | 4 | ||||
| -rw-r--r-- | internal/hexailsp/run_test.go | 10 |
3 files changed, 19 insertions, 10 deletions
diff --git a/internal/hexailsp/run.go b/internal/hexailsp/run.go index ffb9f86..750e544 100644 --- a/internal/hexailsp/run.go +++ b/internal/hexailsp/run.go @@ -25,7 +25,12 @@ type ServerFactory func(r io.Reader, w io.Writer, logger *log.Logger, opts lsp.S // Run configures logging, loads config, builds the LLM client and runs the LSP server. // It is thin and delegates to RunWithFactory for testability. + func Run(logPath string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { + return RunWithConfig(logPath, "", stdin, stdout, stderr) +} + +func RunWithConfig(logPath string, configPath string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error { logger := log.New(stderr, "hexai-lsp ", log.LstdFlags|log.Lmsgprefix) if strings.TrimSpace(logPath) != "" { f, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644) @@ -36,19 +41,20 @@ func Run(logPath string, stdin io.Reader, stdout io.Writer, stderr io.Writer) er logger.SetOutput(f) } logging.Bind(logger) - cfg := appconfig.Load(logger) + loadOpts := appconfig.LoadOptions{ConfigPath: configPath} + cfg := appconfig.LoadWithOptions(logger, loadOpts) if err := cfg.Validate(); err != nil { logger.Fatalf("invalid config: %v", err) } if cfg.StatsWindowMinutes > 0 { stats.SetWindow(time.Duration(cfg.StatsWindowMinutes) * time.Minute) } - return RunWithFactory(logPath, stdin, stdout, logger, cfg, nil, nil) + return RunWithFactory(logPath, configPath, stdin, stdout, logger, cfg, nil, nil) } // RunWithFactory is the testable entrypoint. When client is nil, it is built from cfg+env. // When factory is nil, lsp.NewServer is used. -func RunWithFactory(logPath string, stdin io.Reader, stdout io.Writer, logger *log.Logger, cfg appconfig.App, client llm.Client, factory ServerFactory) error { +func RunWithFactory(logPath string, configPath string, stdin io.Reader, stdout io.Writer, logger *log.Logger, cfg appconfig.App, client llm.Client, factory ServerFactory) error { normalizeLoggingConfig(&cfg) if err := cfg.Validate(); err != nil { logger.Fatalf("invalid config: %v", err) @@ -58,7 +64,9 @@ func RunWithFactory(logPath string, stdin io.Reader, stdout io.Writer, logger *l store := runtimeconfig.New(cfg) logContext := strings.TrimSpace(logPath) != "" + loadOpts := appconfig.LoadOptions{ConfigPath: strings.TrimSpace(configPath)} opts := makeServerOptions(cfg, logContext, client) + opts.ConfigLoadOptions = loadOpts opts.ConfigStore = store server := factory(stdin, stdout, logger, opts) if configurable, ok := server.(interface{ ApplyOptions(lsp.ServerOptions) }); ok { @@ -72,6 +80,7 @@ func RunWithFactory(logPath string, stdin io.Reader, stdout io.Writer, logger *l client = newClient } opts := makeServerOptions(updated, logContext, client) + opts.ConfigLoadOptions = loadOpts opts.ConfigStore = store configurable.ApplyOptions(opts) }) diff --git a/internal/hexailsp/run_more_test.go b/internal/hexailsp/run_more_test.go index faaae41..338dd48 100644 --- a/internal/hexailsp/run_more_test.go +++ b/internal/hexailsp/run_more_test.go @@ -44,7 +44,7 @@ func TestRunWithFactory_BuildsOptionsAndClient(t *testing.T) { cfg.MaxTokens = 123 cfg.PromptCodeActionRewriteSystem = "RSYS" cfg.PromptCodeActionRewriteUser = "RUSER" - if err := RunWithFactory("", &in, &out, logger, cfg, nil, factory); err != nil { + if err := RunWithFactory("", "", &in, &out, logger, cfg, nil, factory); err != nil { t.Fatalf("RunWithFactory error: %v", err) } if captured.MaxTokens != 123 { @@ -71,7 +71,7 @@ func TestRunWithFactory_SubscriptionAppliesUpdates(t *testing.T) { cfg := appconfig.Load(nil) cfg.StatsWindowMinutes = 0 cfg.ContextMode = " WINDOW " - if err := RunWithFactory("", &in, &out, logger, cfg, stubClient{}, factory); err != nil { + if err := RunWithFactory("", "", &in, &out, logger, cfg, stubClient{}, factory); err != nil { t.Fatalf("RunWithFactory error: %v", err) } if capturedStore == nil { diff --git a/internal/hexailsp/run_test.go b/internal/hexailsp/run_test.go index 340a08a..6a3c789 100644 --- a/internal/hexailsp/run_test.go +++ b/internal/hexailsp/run_test.go @@ -36,7 +36,7 @@ func TestRunWithFactory_UsesDefaultsAndCallsServer(t *testing.T) { gotOpts = opts return &fakeServer{opts: opts} } - if err := RunWithFactory("", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { + if err := RunWithFactory("", "", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { t.Fatalf("RunWithFactory error: %v", err) } if gotOpts.MaxTokens != cfg.MaxTokens { @@ -71,7 +71,7 @@ func TestRunWithFactory_BuildsClientWhenKeysPresent(t *testing.T) { got = opts.Client return &fakeServer{opts: opts} } - if err := RunWithFactory("", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { + if err := RunWithFactory("", "", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { t.Fatalf("RunWithFactory error: %v", err) } if got == nil { @@ -104,7 +104,7 @@ func TestRunWithFactory_NormalizesContextMode_AndSetsPreviewLimit(t *testing.T) gotOpts = opts return &fakeServer{opts: opts} } - if err := RunWithFactory("", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { + if err := RunWithFactory("", "", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { t.Fatalf("RunWithFactory error: %v", err) } if gotOpts.ContextMode != "file-on-new-func" { @@ -130,13 +130,13 @@ func TestRunWithFactory_LogContextFlag(t *testing.T) { } return &fakeServer{opts: opts} } - if err := RunWithFactory("/tmp/some.log", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { + if err := RunWithFactory("/tmp/some.log", "", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { t.Fatalf("RunWithFactory error: %v", err) } if !got1.LogContext { t.Fatalf("expected LogContext true when logPath is non-empty") } - if err := RunWithFactory("", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { + if err := RunWithFactory("", "", bytes.NewBuffer(nil), bytes.NewBuffer(nil), logger, cfg, nil, factory); err != nil { t.Fatalf("RunWithFactory error: %v", err) } if got2.LogContext { |
