Skip to content

Commit

Permalink
Improve lsp hover definition comment formatting (#3411)
Browse files Browse the repository at this point in the history
  • Loading branch information
hirasawayuki authored Dec 16, 2024
1 parent 0560ffe commit 133b9c4
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 13 deletions.
49 changes: 36 additions & 13 deletions private/buf/buflsp/symbol.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,24 +566,12 @@ func (s *symbol) FormatDocs(ctx context.Context) string {
var printed bool
for _, comments := range allComments {
for i := 0; i < comments.Len(); i++ {
comment := comments.Index(i).RawText()

// The compiler does not currently provide comments without their
// delimited removed, so we have to do this ourselves.
if strings.HasPrefix(comment, "//") {
// NOTE: We do not trim the space here, because indentation is
// significant for Markdown code fences, and if every line
// starts with a space, Markdown will trim it for us, even off
// of code blocks.
comment = strings.TrimPrefix(comment, "//")
} else {
comment = strings.TrimSuffix(strings.TrimPrefix(comment, "/*"), "*/")
}

comment := commentToMarkdown(comments.Index(i).RawText())
if comment != "" {
printed = true
}

// No need to process Markdown in comment; this Just Works!
fmt.Fprintln(&tooltip, comment)
}
Expand All @@ -596,6 +584,41 @@ func (s *symbol) FormatDocs(ctx context.Context) string {
return tooltip.String()
}

// commentToMarkdown processes comment strings and formats them for markdown display.
func commentToMarkdown(comment string) string {
if strings.HasPrefix(comment, "//") {
// NOTE: We do not trim the space here, because indentation is
// significant for Markdown code fences, and if every line
// starts with a space, Markdown will trim it for us, even off
// of code blocks.
return strings.TrimPrefix(comment, "//")
}

if strings.HasPrefix(comment, "/**") && !strings.HasPrefix(comment, "/**/") {
// NOTE: Doxygen-style comments (/** ... */) to Markdown format
// by removing comment delimiters and formatting the content.
//
// Example:
// /**
// * This is a Doxygen comment
// * with multiple lines
// */
comment = strings.TrimSuffix(strings.TrimPrefix(comment, "/**"), "*/")

lines := strings.Split(strings.TrimSpace(comment), "\n")
for i, line := range lines {
line = strings.TrimSpace(line)
line = strings.TrimPrefix(line, "*")
lines[i] = line
}

return strings.Join(lines, "\n")
}

// Handle standard multi-line comments (/* ... */)
return strings.TrimSuffix(strings.TrimPrefix(comment, "/*"), "*/")
}

// symbolWalker is an AST walker that generates the symbol table for a file in IndexSymbols().
type symbolWalker struct {
file *file
Expand Down
101 changes: 101 additions & 0 deletions private/buf/buflsp/symbol_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2020-2024 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This file defines all of the message handlers that involve symbols.
//
// In particular, this file handles semantic information in fileManager that have been
// *opened by the editor*, and thus do not need references to Buf modules to find.
// See imports.go for that part of the LSP.
package buflsp

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestCommentToMarkdown(t *testing.T) {
t.Parallel()

tests := []struct {
name string
input string
expected string
}{
{
name: "single-line-comment",
input: "// this is a single-line comment",
expected: " this is a single-line comment",
},
{
name: "multi-line-comment",
input: `/*
this is a
multi-line comment
*/`,
expected: `
this is a
multi-line comment
`,
},
{
name: "doxygen-style-comment",
input: `/**
* Documentation comment
* with asterisks
*/`,
expected: ` Documentation comment
with asterisks`,
},
{
name: "doxygen-mixed-indentation",
input: `/**
* First line
* - Second line
* - Third line
*/`,
expected: ` First line
- Second line
- Third line`,
},
{
name: "markdown-emphasis",
input: "/*This is *important**/",
expected: "This is *important*",
},
{
name: "single-line-doxygen",
input: "/** Single line doc comment */",
expected: "Single line doc comment",
},
{
name: "empty-comment",
input: "/**/",
expected: "",
},
{
name: "only-space",
input: "/* */",
expected: " ",
},
}

for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
assert.Equal(t, test.expected, commentToMarkdown(test.input))
})
}
}

0 comments on commit 133b9c4

Please sign in to comment.