on main help sign in
chore: tidy various comments
commitfe9fdf2228f1af8a3fed99fa37036892e792e143 authorChristian Rocha <christian@rocha.is> dateMon 21 Jul 2025, 19:22 (1 year ago) parent2fd65cd
3 files changed+45−33
internal/app/app.go+18−7 internal/app/lsp.go+23−23 internal/cmd/root.go+4−3
internal/app/app.go+18−7
@@ -53,6 +53,7 @@ type App struct {
5353 cleanupFuncs []func()
5454}
5555
56+// New initializes a new applcation instance.
5657func New(ctx context.Context, conn *sql.DB, cfg *config.Config) (*App, error) {
5758 q := db.New(conn)
5859 sessions := session.NewService(q)
@@ -78,10 +79,10 @@ func New(ctx context.Context, conn *sql.DB, cfg *config.Config) (*App, error) {
7879
7980 app.setupEvents()
8081
81− // Initialize LSP clients in the background
82+ // Initialize LSP clients in the background.
8283 go app.initLSPClients(ctx)
8384
84− // TODO: remove the concept of agent config most likely
85+ // TODO: remove the concept of agent config, most likely.
8586 if cfg.IsConfigured() {
8687 if err := app.InitCoderAgent(); err != nil {
8788 return nil, fmt.Errorf("failed to initialize coder agent: %w", err)
@@ -97,20 +98,22 @@ func (app *App) Config() *config.Config {
9798 return app.config
9899}
99100
100−// RunNonInteractive handles the execution flow when a prompt is provided via CLI flag.
101+// RunNonInteractive handles the execution flow when a prompt is provided via
102+// CLI flag.
101103func (app *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool) error {
102104 slog.Info("Running in non-interactive mode")
103105
104106 ctx, cancel := context.WithCancel(ctx)
105107 defer cancel()
106108
107− // Start spinner if not in quiet mode
109+ // Start spinner if not in quiet mode.
108110 var spinner *format.Spinner
109111 if !quiet {
110112 spinner = format.NewSpinner(ctx, cancel, "Generating")
111113 spinner.Start()
112114 }
113− // Helper function to stop spinner once
115+
116+ // Helper function to stop spinner once.
114117 stopSpinner := func() {
115118 if !quiet && spinner != nil {
116119 spinner.Stop()
@@ -257,9 +260,10 @@ func (app *App) InitCoderAgent() error {
257260 return nil
258261}
259262
263+// Subscribe sends events to the TUI as tea.Msgs.
260264func (app *App) Subscribe(program *tea.Program) {
261265 defer log.RecoverPanic("app.Subscribe", func() {
262− slog.Info("TUI subscription panic - attempting graceful shutdown")
266+ slog.Info("TUI subscription panic: attempting graceful shutdown")
263267 program.Quit()
264268 })
265269
@@ -271,6 +275,7 @@ func (app *App) Subscribe(program *tea.Program) {
271275 app.tuiWG.Wait()
272276 })
273277 defer app.tuiWG.Done()
278+
274279 for {
275280 select {
276281 case <-tuiCtx.Done():
@@ -286,23 +291,28 @@ func (app *App) Subscribe(program *tea.Program) {
286291 }
287292}
288293
289−// Shutdown performs a clean shutdown of the application
294+// Shutdown performs a graceful shutdown of the application.
290295func (app *App) Shutdown() {
291296 if app.CoderAgent != nil {
292297 app.CoderAgent.CancelAll()
293298 }
299+
294300 app.cancelFuncsMutex.Lock()
295301 for _, cancel := range app.watcherCancelFuncs {
296302 cancel()
297303 }
298304 app.cancelFuncsMutex.Unlock()
305+
306+ // Wait for all LSP watchers to finish.
299307 app.lspWatcherWG.Wait()
300308
309+ // Get all LSP clients.
301310 app.clientsMutex.RLock()
302311 clients := make(map[string]*lsp.Client, len(app.LSPClients))
303312 maps.Copy(clients, app.LSPClients)
304313 app.clientsMutex.RUnlock()
305314
315+ // Shutdown all LSP clients.
306316 for name, client := range clients {
307317 shutdownCtx, cancel := context.WithTimeout(app.globalCtx, 5*time.Second)
308318 if err := client.Shutdown(shutdownCtx); err != nil {
@@ -311,6 +321,7 @@ func (app *App) Shutdown() {
311321 cancel()
312322 }
313323
324+ // Call call cleanup functions.
314325 for _, cleanup := range app.cleanupFuncs {
315326 if cleanup != nil {
316327 cleanup()
internal/app/lsp.go+23−23
@@ -10,10 +10,9 @@ import (
1010 "github.com/charmbracelet/crush/internal/lsp/watcher"
1111)
1212
13+// initLSPClients initializes LSP clients.
1314func (app *App) initLSPClients(ctx context.Context) {
14− // Initialize LSP clients
1515 for name, clientConfig := range app.config.LSP {
16− // Start each client initialization in its own goroutine
1716 go app.createAndStartLSPClient(ctx, name, clientConfig.Command, clientConfig.Args...)
1817 }
1918 slog.Info("LSP clients initialization started in background")
@@ -21,68 +20,68 @@ func (app *App) initLSPClients(ctx context.Context) {
2120
2221// createAndStartLSPClient creates a new LSP client, initializes it, and starts its workspace watcher
2322func (app *App) createAndStartLSPClient(ctx context.Context, name string, command string, args ...string) {
24− // Create a specific context for initialization with a timeout
2523 slog.Info("Creating LSP client", "name", name, "command", command, "args", args)
2624
27− // Create the LSP client
25+ // Create LSP client.
2826 lspClient, err := lsp.NewClient(ctx, command, args...)
2927 if err != nil {
3028 slog.Error("Failed to create LSP client for", name, err)
3129 return
3230 }
3331
34− // Create a longer timeout for initialization (some servers take time to start)
32+ // Increase initialization timeout as some servers take more time to start.
3533 initCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
3634 defer cancel()
3735
38− // Initialize with the initialization context
36+ // Initialize LSP client.
3937 _, err = lspClient.InitializeLSPClient(initCtx, app.config.WorkingDir())
4038 if err != nil {
4139 slog.Error("Initialize failed", "name", name, "error", err)
42− // Clean up the client to prevent resource leaks
4340 lspClient.Close()
4441 return
4542 }
4643
47− // Wait for the server to be ready
44+ // Wait for the server to be ready.
4845 if err := lspClient.WaitForServerReady(initCtx); err != nil {
4946 slog.Error("Server failed to become ready", "name", name, "error", err)
50− // We'll continue anyway, as some functionality might still work
47+ // Server never reached a ready state, but let's continue anyway, as
48+ // some functionality might still work.
5149 lspClient.SetServerState(lsp.StateError)
5250 } else {
51+ // Server reached a ready state scuccessfully.
5352 slog.Info("LSP server is ready", "name", name)
5453 lspClient.SetServerState(lsp.StateReady)
5554 }
5655
5756 slog.Info("LSP client initialized", "name", name)
5857
59− // Create a child context that can be canceled when the app is shutting down
58+ // Create a child context that can be canceled when the app is shutting
59+ // down.
6060 watchCtx, cancelFunc := context.WithCancel(ctx)
6161
62− // Create the workspace watcher
62+ // Create the workspace watcher.
6363 workspaceWatcher := watcher.NewWorkspaceWatcher(name, lspClient)
6464
65− // Store the cancel function to be called during cleanup
65+ // Store the cancel function to be called during cleanup.
6666 app.cancelFuncsMutex.Lock()
6767 app.watcherCancelFuncs = append(app.watcherCancelFuncs, cancelFunc)
6868 app.cancelFuncsMutex.Unlock()
6969
70− // Add the watcher to a WaitGroup to track active goroutines
71− app.lspWatcherWG.Add(1)
72−
7370 // Add to map with mutex protection before starting goroutine
7471 app.clientsMutex.Lock()
7572 app.LSPClients[name] = lspClient
7673 app.clientsMutex.Unlock()
7774
75+ // Run workspace watcher.
76+ app.lspWatcherWG.Add(1)
7877 go app.runWorkspaceWatcher(watchCtx, name, workspaceWatcher)
7978}
8079
81−// runWorkspaceWatcher executes the workspace watcher for an LSP client
80+// runWorkspaceWatcher executes the workspace watcher for an LSP client.
8281func (app *App) runWorkspaceWatcher(ctx context.Context, name string, workspaceWatcher *watcher.WorkspaceWatcher) {
8382 defer app.lspWatcherWG.Done()
8483 defer log.RecoverPanic("LSP-"+name, func() {
85− // Try to restart the client
84+ // Try to restart the client.
8685 app.restartLSPClient(ctx, name)
8786 })
8887
@@ -90,31 +89,32 @@ func (app *App) runWorkspaceWatcher(ctx context.Context, name string, workspaceW
9089 slog.Info("Workspace watcher stopped", "client", name)
9190}
9291
93−// restartLSPClient attempts to restart a crashed or failed LSP client
92+// restartLSPClient attempts to restart a crashed or failed LSP client.
9493func (app *App) restartLSPClient(ctx context.Context, name string) {
95− // Get the original configuration
94+ // Get the original configuration.
9695 clientConfig, exists := app.config.LSP[name]
9796 if !exists {
9897 slog.Error("Cannot restart client, configuration not found", "client", name)
9998 return
10099 }
101100
102− // Clean up the old client if it exists
101+ // Clean up the old client if it exists.
103102 app.clientsMutex.Lock()
104103 oldClient, exists := app.LSPClients[name]
105104 if exists {
106− delete(app.LSPClients, name) // Remove from map before potentially slow shutdown
105+ // Remove from map before potentially slow shutdown.
106+ delete(app.LSPClients, name)
107107 }
108108 app.clientsMutex.Unlock()
109109
110110 if exists && oldClient != nil {
111− // Try to shut it down gracefully, but don't block on errors
111+ // Try to shut down client gracefully, but don't block on errors.
112112 shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
113113 _ = oldClient.Shutdown(shutdownCtx)
114114 cancel()
115115 }
116116
117− // Create a new client using the shared function
117+ // Create a new client using the shared function.
118118 app.createAndStartLSPClient(ctx, name, clientConfig.Command, clientConfig.Args...)
119119 slog.Info("Successfully restarted LSP client", "client", name)
120120}
internal/cmd/root.go+4−3
@@ -48,6 +48,7 @@ to assist developers in writing, debugging, and understanding code directly from
4848 `,
4949 RunE: func(cmd *cobra.Command, args []string) error {
5050 // Load the config
51+ // XXX: Handle errors.
5152 debug, _ := cmd.Flags().GetBool("debug")
5253 cwd, _ := cmd.Flags().GetString("cwd")
5354 prompt, _ := cmd.Flags().GetString("prompt")
@@ -76,7 +77,7 @@ to assist developers in writing, debugging, and understanding code directly from
7677
7778 ctx := cmd.Context()
7879
79− // Connect DB, this will also run migrations
80+ // Connect to DB; this will also run migrations.
8081 conn, err := db.Connect(ctx, cfg.Options.DataDirectory)
8182 if err != nil {
8283 return err
@@ -95,13 +96,13 @@ to assist developers in writing, debugging, and understanding code directly from
9596 return err
9697 }
9798
98− // Non-interactive mode
99+ // Non-interactive mode.
99100 if prompt != "" {
100101 // Run non-interactive flow using the App method
101102 return app.RunNonInteractive(ctx, prompt, quiet)
102103 }
103104
104− // Set up the TUI
105+ // Set up the TUI.
105106 program := tea.NewProgram(
106107 tui.New(app),
107108 tea.WithAltScreen(),