func (e *CodeEditor) ShowSuggestionList() { if e.suggestionProvider == nil || e.IsSuggestionListShowing() { return } caret := e.controller.LastCaret() s, _ := e.controller.WordAt(caret) suggestions := e.suggestionProvider.SuggestionsAt(s) if len(suggestions) == 0 { e.HideSuggestionList() return } e.suggestionAdapter.SetSuggestions(suggestions) e.SortSuggestionList() child := e.AddChild(e.suggestionList) // Position the suggestion list below the last caret lineIdx := e.controller.LineIndex(caret) // TODO: What if the last caret is not visible? bounds := e.Size().Rect().Contract(e.Padding()) line := e.Line(lineIdx) lineOffset := gxui.ChildToParent(math.ZeroPoint, line, e.outer) target := line.PositionAt(caret).Add(lineOffset) cs := e.suggestionList.DesiredSize(math.ZeroSize, bounds.Size()) e.suggestionList.Select(e.suggestionList.Adapter().ItemAt(0)) e.suggestionList.SetSize(cs) child.Layout(cs.Rect().Offset(target).Intersect(bounds)) }
func (e *CodeEditor) updateSuggestionList() { caret := e.Controller().LastCaret() lineIdx := e.LineIndex(caret) text := e.Controller().Line(lineIdx) // TODO: This only skips suggestions on line comments, not block comments // (/* ... */). Since block comments seem to be pretty uncommon in Go, // I'm not going to worry about it just yet. Ideally, this would be solved // by having the syntax highlighting logic provide some context details to // the editor, so it knows some information about the context surrounding // the caret. if comment := strings.Index(text, "//"); comment != -1 && comment <= caret { e.HideSuggestionList() return } start, _ := e.Controller().WordAt(caret) suggestions := e.SuggestionProvider().SuggestionsAt(start) // TODO: if len(suggestions) == 1, show the completion in-line // instead of in a completion box. longest := 0 for _, suggestion := range suggestions { suggestionText := suggestion.(fmt.Stringer).String() if len(suggestionText) > longest { longest = len(suggestionText) } } size := e.Font().GlyphMaxSize() size.W *= longest e.adapter.SetSize(size) partial := e.Controller().TextRange(start, caret) e.adapter.SetSuggestions(suggestions) e.adapter.Sort(partial) if e.adapter.Len() == 0 { e.HideSuggestionList() return } e.suggestions.Select(e.suggestions.Adapter().ItemAt(0)) // Position the suggestion list below the last caret bounds := e.Size().Rect().Contract(e.Padding()) line := e.Line(lineIdx) lineOffset := gxui.ChildToParent(math.ZeroPoint, line, e) target := line.PositionAt(caret).Add(lineOffset) cs := e.suggestions.DesiredSize(math.ZeroSize, bounds.Size()) e.suggestions.SetSize(cs) e.suggestionsChild.Layout(cs.Rect().Offset(target).Intersect(bounds)) e.suggestions.Redraw() e.Redraw() }
func (e *editor) updateSuggestionList() { caret := e.Controller().LastCaret() suggestions := e.SuggestionProvider().SuggestionsAt(caret) if len(suggestions) == 0 { // TODO: if len(suggestions) == 1, show the completion in-line // instead of in a completion box. e.HideSuggestionList() return } longest := 0 for _, suggestion := range suggestions { suggestionText := suggestion.(fmt.Stringer).String() if len(suggestionText) > longest { longest = len(suggestionText) } } size := e.Font().GlyphMaxSize() size.W *= longest e.adapter.SetSize(size) e.adapter.SetSuggestions(suggestions) e.SortSuggestionList() child := e.AddChild(e.suggestions) // Position the suggestion list below the last caret lineIdx := e.LineIndex(caret) // TODO: What if the last caret is not visible? bounds := e.Size().Rect().Contract(e.Padding()) line := e.Line(lineIdx) lineOffset := gxui.ChildToParent(math.ZeroPoint, line, e) target := line.PositionAt(caret).Add(lineOffset) cs := e.suggestions.DesiredSize(math.ZeroSize, bounds.Size()) e.suggestions.Select(e.suggestions.Adapter().ItemAt(0)) e.suggestions.SetSize(cs) child.Layout(cs.Rect().Offset(target).Intersect(bounds)) }