internal/lsp: support single-line hover for LSP clients like Vim

Fixes golang/go#32561

Change-Id: I4399be3cfe745b85a23a82a183277e290ef2a3d8
Reviewed-on: https://go-review.googlesource.com/c/tools/+/188981
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/lsp/general.go b/internal/lsp/general.go
index cd9ac7a..f1f9351 100644
--- a/internal/lsp/general.go
+++ b/internal/lsp/general.go
@@ -226,6 +226,8 @@
 		switch hoverKind {
 		case "NoDocumentation":
 			s.hoverKind = source.NoDocumentation
+		case "SingleLine":
+			s.hoverKind = source.SingleLine
 		case "SynopsisDocumentation":
 			s.hoverKind = source.SynopsisDocumentation
 		case "FullDocumentation":
diff --git a/internal/lsp/source/hover.go b/internal/lsp/source/hover.go
index e46fe35..1f370fd 100644
--- a/internal/lsp/source/hover.go
+++ b/internal/lsp/source/hover.go
@@ -25,16 +25,21 @@
 
 const (
 	NoDocumentation = HoverKind(iota)
+	SingleLine
 	SynopsisDocumentation
 	FullDocumentation
-
-	// TODO: Support a single-line hover mode for clients like Vim.
-	singleLine
 )
 
 func (i *IdentifierInfo) Hover(ctx context.Context, markdownSupported bool, hoverKind HoverKind) (string, error) {
 	ctx, done := trace.StartSpan(ctx, "source.Hover")
 	defer done()
+
+	// If the user has explicitly requested a single line of hover information,
+	// fall back to using types.ObjectString.
+	if hoverKind == SingleLine {
+		return types.ObjectString(i.decl.obj, i.qf), nil
+	}
+
 	h, err := i.decl.hover(ctx)
 	if err != nil {
 		return "", err