package app import ( "context" "rickub.com/turbo-editors/turbo-core/lsp" ) // RequestCompletion asks the language server what could be typed here and // opens the popup with the answer. // // It is deliberately synchronous: the request has its own short timeout, and a // completion that arrives after the user has typed three more characters is // worse than none at all. func (a *App) RequestCompletion() { view := a.activeView() if view == nil { return } if !a.language.Ready() { a.Message(a.language.Status()) return } buf := view.Buffer() cursor := buf.Cursor() items, err := a.language.Complete(context.Background(), buf.Path(), cursor.Line, cursor.Col, buf.Line(cursor.Line)) if err != nil { a.Message("Completion: " + err.Error()) return } if len(items) == 0 { a.Message(a.noCompletionsReason(buf.Path())) return } x, y := view.CursorScreenPosition() a.completion.Show(items, view.WordBeforeCursor(), x, y, a.screenRect()) } // refreshCompletionPrefix narrows the open popup as the user keeps typing. func (a *App) refreshCompletionPrefix() { if !a.completion.Visible() { return } if view := a.activeView(); view != nil { a.completion.SetPrefix(view.WordBeforeCursor()) } } // acceptCompletion puts the chosen suggestion into the buffer, replacing the // part of the word that had already been typed. func (a *App) acceptCompletion(item lsp.CompletionItem) { if view := a.activeView(); view != nil { view.ReplaceWordBeforeCursor(item.Insertion()) } } // noCompletionsReason explains an empty completion list. // // A language server answers nothing at all — no error, just an empty list — // for a package it cannot load, which is what a duplicate declaration or an // unresolved import produces. Saying "no completions" and stopping there // leaves the user with nowhere to go, when the server has already said what is // wrong through its diagnostics. func (a *App) noCompletionsReason(path string) string { if diagnostic, ok := a.language.FirstError(path); ok { return "No completions — this file does not compile: " + diagnostic.Message } return "No completions here" }