x/tools/gopls:支持注解渲染

z18hc3ub  于 4个月前  发布在  Go
关注(0)|答案(9)|浏览(63)

我建议添加一个gopls命令,使用doc/comment来渲染包级声明的文档注解。意图是这个命令将被开发环境用于为工作区包渲染pkgsite风格的文档。这可以实现以下目的:

  1. 查看尚未发布的代码更改的文档。
  2. 查看私有仓库的文档。
  3. 在编写文档时审查文档,以确保格式是我想要的。
  4. 在开发环境中查看文档,无需切换到浏览器。
    我承认前三项可以通过在本地运行pkgsite来实现,但这并不能解决(4),不够方便,而且根据我的经验,对于(3)也不太好用。
    我建议:
  5. gopls/internal/lsp/cache/docs,它将定位文档注解,使用doc/comment.Parser解析它们,并将doc/comment.Doc转换为可编组类型,以便结果可以被缓存。
  6. gopls/internal/lsp/command.Interface.RenderDocs,它将从快照中检索doc/comment.Doc并呈现它们:
oymdgrw7

oymdgrw71#

@gopherbot, please add label FeatureRequest

hc8w905p

hc8w905p2#

(4) 在开发环境中查看文档,无需切换到浏览器。
我承认前三项可以通过在本地运行pkgsite来实现,但这并不能解决(4)问题,不够方便,而且根据我的经验,它对(3)的效果也不好。

这个新的协议级命令将如何使用?每个LSP客户端是否需要添加自定义逻辑来调用它?

如果你想在编辑器中查看符号的完整文档,请跳转到其声明。如果你想查看摘要,请使用编辑器的LSP悬停功能。如果你想查看完整的渲染标记,就像出现在pkg.go.dev上一样,运行本地服务器是正确的方法(尽管不幸的是,目前还不可能,但很快就会实现)。我真的不明白这个命令还能提供什么额外的价值。

rseugnpd

rseugnpd3#

我不太明白这个命令能提供什么额外的价值。
我的动机是我想在VSCode中(如点击某个东西)执行一个操作,弹出一个基本相当于pkg.go.dev的本地包编辑器视图。我不想真正地将pkg.go.dev(或本地版本)嵌入到webview中 - 我更喜欢更无缝的方式。我一直在想一个markdown预览。这是我很长时间以来一直想要的东西,而且我一直在回来。我尝试用gddo生成HTML并将其放入webview中,但代码一团糟,用户体验很差。一个类似于gopls的单独辅助进程会更好,但我基本上是在重新创建gopls的一个子集,而且是一个更糟糕的版本。为了使其性能良好,我需要重新实现gopls的缓存和工作区逻辑。
这个新的协议级命令将如何使用?每个LSP客户端都需要添加自定义逻辑来调用它吗?
通过协议级命令,你是指一个语言服务器方法吗?我建议通过workspace/executeCommand LSP方法执行一个命令,就像你建议的#59445一样,而不是一个新的LSP方法。由于这不是LSP的标准部分,是的,每个客户端都需要添加自定义逻辑来调用它。以VSCode为例,我想象用户点击某个UI元素;然后vscode-go执行命令并创建一个只读的编辑器、markdown预览或带有结果的webview。
如果你想在编辑器中查看符号的完整文档,请跳转到其声明。[...] 如果你想查看pkg.go.dev上完整的呈现标记,运行本地服务器是正确的方法(尽管不幸的是,目前还不可能,但很快就会)。
就我个人而言,当我试图弄清楚如何使用某个包时,我发现pkg.go.dev比源代码更容易阅读。我已经有效地训练自己在看到源代码时进入“这段代码是如何工作的”模式,而不是“我该如何调用这段代码”模式,而且我觉得渲染后的HTML比注解更容易阅读。因此,我认为通过pkg.go.dev回答“我该如何调用这段代码”比通过源代码更容易。
我尝试过在本地运行pkgsite。对于(1)和(2)的使用场景,它运行得足够好,但是当我不带任何标志运行它时,它不能为(3)工作,因为一旦渲染了一个包,如果我更新了注解,它就不会重新渲染它们。有一个标志可以改变这一点,但上次我使用它时事情变得奇怪/出错,我几乎每次都不得不重新启动进程才能让它重新渲染我的更新。假设/无论如何这些都是bug并且已经修复了,这并没有解决(4)。我的很大一部分动机是我想在VSCode/不打开浏览器的情况下查看文档,并且我希望它感觉无缝/融入VSCode的UX和主题。这就是为什么我在考虑使用VSCode的markdown预览功能进行展示的原因。
我很乐意自己做这项工作,我也愿意在独立的扩展中完成VSCode/展示部分的工作。我打开了这个问题,因为在讨论之前做这项工作和提交CL似乎不是正确的举动。

kkbh8khc

kkbh8khc4#

我不想在webview中直接嵌入pkg.go.dev(或本地版本),我更喜欢更无缝的方式。
我明白了。而我(一个石器时代的emacs用户)认为webview是集成的巅峰...
你是指通过协议级别的命令是指语言服务器方法吗?我建议通过workspace/executeCommand LSP方法执行一个命令,就像你为#59445建议的那样,而不是一个新的LSP方法。由于这不是LSP的标准部分,是的,每个客户端都需要添加自定义逻辑来调用它。
我明白了。从系统设计的Angular 来看,这两种类型之间几乎没有什么区别:客户端和服务器都需要为每个服务器RPC和每个临时命令提供特殊的逻辑。
(我真的希望LSP能够更加可组合。例如,我想实现一个新的查询操作,返回一组源代码位置及其一行描述,类似于grep、编译器或引用查询的结果,或者任何其他类型的工作区范围查询。如果有一种方法可以在协议中指示结果应使用客户端通常用于此类事物的UI元素显示,那就太好了。但除非你为n个不同的客户端编写逻辑,否则你什么都得不到...)
就我个人而言,当我试图弄清楚如何使用某个包时,我认为pkg.go.dev比源代码更容易阅读。我已经有效地训练自己在看到源代码时进入“这段代码是如何工作的”模式,而不是“我该如何调用这段代码”模式,而且我觉得渲染后的HTML比注解更容易阅读。因此,我认为通过pkg.go.dev回答“我该如何调用这段代码”要比通过源代码容易得多。
是的,我同意。API文档提供了更清晰的概述,并让你诚实地了解接口与实现之间的关系。它们对于预览新代码将如何呈现给其用户也非常有用。
我尝试过在本地运行pkgsite。它对于用例(1)和(2)来说效果很好,但是当我不带任何标志运行它时,它对于用例(3)不起作用,因为一旦它渲染了一个包,如果我更新了注解,它就不会重新渲染它们。有一个标志可以改变这一点,但上次我使用它的时候,事情变得奇怪/出错,我几乎每次都不得不重新启动进程才能让它重新渲染我的更新。假设/无论如何这些都是bug并且它们会被修复,
没错,我们今年会解决所有这些问题。
......这并没有解决(4)。我的主要动机之一是我想在VSCode/无需打开浏览器的情况下查看文档,并且我想让它感觉无缝/融入VSCode的UX和主题。这就是为什么我在考虑使用VS Code的markdown预览功能进行演示的原因。
我明白了。在我看来,相对于VS Code webview的边际价值仍然相当小,不足以证明为N个编辑器添加对新协议级请求的支持是有意义的。它似乎也是重复的:漂亮地呈现Go文档是pkgsite的工作,而这个特性需要gopls知道如何做到这一点(并且当两个工具不同时会导致一系列问题)。
我想知道这是否可能被挤进现有的协议中,也许作为“package foo”声明的悬停响应,目前似乎没有生成任何悬停文本---尽管我可以想象完整的包文档对于悬停弹出窗口来说太多了。
我很乐意自己做这项工作,我也愿意在独立的扩展中完成VSCode/演示部分。我打开了这个问题是因为在讨论之前做这项工作和提交CL似乎不是正确的举动。
感谢你的提议,以及首先讨论这件事。

whhtz7ly

whhtz7ly5#

我确实希望LSP能够更加可组合。
关于这个问题,已经有一些讨论了。LSP规范中包含了一个Base protocol specification,这在一定程度上满足了你的需求。虽然可扩展性不等于可组合性,但这是值得注意的一点。
在我看来,VS Code webview的边际价值仍然相当小。我认为这一点,加上在VS Code内部与浏览器之间的差异以及格式化,都是主观的,所以我能做的就是阐述我自己的观点。既然每次我alt-tab到另一个窗口时,都会对我的工作流程产生一定程度的干扰(尤其是当我在切换两个以上的窗口时),那么在VS Code内部拥有一些内容是值得我投入时间的。我对使用webview的不满也是类似的——直接嵌入网站感觉笨重,因为UI和样式非常不同,在这个上下文中有UI组件只是额外的噪音(主要是导航),链接可能会很棘手等等。我试图通过注入样式和/或脚本以及修改HTML来解决这些问题,但结果一团糟。最终这意味着让它感觉无缝要困难得多,因此需要付出更多的心理代价来弥补这种不和谐。
至于格式化,这更是主观的价值判断。就我个人而言,我相信我会对VS Code内置的渲染器的一些markdown感到满意。我不期望我的开发环境能达到pkgsite级别的美观程度。例如,对我来说,能够做这样的事情远比其他事情更重要:

  1. 选择一个方法并执行“打开文档”(通过右键单击、命令面板等)。
  2. 打开该方法所属的包的文档并滚动到该方法。
  3. 我找到我想跳转到的其他声明;例如点击返回类型,或者在方法的文档中点击“另请参阅”链接,或者滚动浏览包文档直到找到我想要的内容。
  4. 我点击新声明以在VS Code内部跳转到其源代码,或者右键单击它并执行“查找所有引用”。
    我的意思是,格式良好的文档并不在我优先考虑的清单上;对我来说更重要的是最小化上下文切换、分心和其他不和谐(例如在深色模式代码和浅色模式pkgsite之间切换),以及能够轻松地从代码跳转到文档,从文档跳转到文档,以及从文档跳转到代码(也可以从代码跳转到代码,但这已经涵盖了)。
    ......不足以证明为N个编辑器添加新的协议级请求是必要的
    我立即回应说,作为用户,这是一个语言服务器提供的便利功能,因此不需要为每个编辑器都实现它。但是当我再多想一些并戴上维护者的帽子时,我可以想象为一个编辑器实现它可能会导致用户问:“为什么<我的编辑器>没有这个功能”,从而给所有编辑器施加实施它的压力。
    它似乎也是重复的:美化Go文档是pkgsite的工作,而这个功能需要gopls知道如何做到这一点(并且当这两个工具有所不同时会导致一系列问题)。
    我没有提议添加任何渲染代码;我希望重用 doc/comment 的渲染:
type RenderDocsParams struct {
	Format string // comment, html, markdown, or text
	// ...
}

type RenderDocsResult struct {
	Result []string
}

func RenderDocs(ctx context.Context, params RenderDocsParams) (RenderDocsResult, error) {
	var result RenderDocsResult
	docs, err := retrieveDocs(ctx, params)
	if err != nil {
		return result, err
	}

	printer := configureCommentPrinter(params)
	var render func(*comment.Doc) []byte
	switch params.Format {
	case "comment":
		render = printer.Comment(doc)
	case "html":
		render = printer.HTML(doc)
	case "markdown":
		render = printer.Markdown(doc)
	case "text":
		render = printer.Text(doc)
	default:
		return result, fmt.Errorf("unsupported format %q", params.Format)
	}

	for _, doc := range docs {
		result.Result = append(result.Result, string(render(doc)))
	}
	return result, nil
}

在vscode-go方面,我建议向gopls请求markdown并让VS Code处理渲染。我在上面写了一个关于格式化的简短文章,所以我就不再赘述了。

hujrc8aj

hujrc8aj6#

我建议向gopls请求markdown格式,并让VSCode处理渲染。
这与我所期望的一致。我同意pkgsite UI不适合在编辑器中查看。它对javascript和pkgsite面向服务设计的使用并不好融合。重型webview也不是VS Code推荐的最佳实践。
一个自定义命令(例如gopls.render_package),它接受文档URI和可选参数(例如包括未导出的符号、包括索引等),并返回字节将是有帮助的。这也不需要启动带有端口的Web服务器,这是一个额外的好处。不确定除了markdown或HeadingLevel之外的所有Format,HeadingIdTmpl等,但我们可以在找到更多用例时扩展请求消息类型。
我尝试使用princjef/gomarkdoc进行了一些修改+vscode markdown渲染器,得到了一个相当有前途的输出。从gopls提供这些信息是有意义的(除非go doc将其功能扩展到生成完整的包文档的html/markdown格式)。

w51jfk4q

w51jfk4q7#

更新:似乎vscode的默认markdown预览功能相当有限。例如,我们可能希望有一些链接指向工作区之外的文件(例如模块缓存或stdlib中的文件),但是vscode的默认markdown预览不支持file:/// URI(microsoft/vscode#182870,...),也不支持真正的相对/绝对路径(microsoft/vscode#120754,microsoft/vscode#139289,...)。MS VSCode团队似乎建议使用markdown扩展或自定义解决方案。:-(我认为在这种情况下,一个简单、基本的html(没有任何花哨的样式或javascript)更好。

ni65a41a

ni65a41a8#

关于除markdown或HeadingLevel、HeadingIdTmpl之外的所有格式,我们暂时不确定,但随着发现更多用例,我们可以扩展请求消息类型。
我的想法是让doc/comment.Printer暴露出大部分/所有功能,以应对未知的未来需求/客户端,除了VSCode。不过,我也可以先从小处着手。尽管我认为允许自定义文档链接是个好主意,因为我们可能希望这些链接执行VSCode命令。
我尝试过使用princjef/gomarkdoc。它是否比go/doc/comment.Printer.Markdown有优势?看起来它有自己的自定义模板。我的倾向是使用标准库的markdown生成器,除非有充分的理由使用第三方库。
似乎vscode的默认markdown预览功能相当有限。这真是遗憾😞。我的倾向是先忍受将markdown扔给vscode的局限性,然后稍后为vscode-go添加一个自定义markdown渲染器,增加更多的功能。

8qgya5xd

8qgya5xd9#

这是否比go/doc/comment.Printer.Markdown有优势?
go/doc/comment.Printer.Markdown 本身不足以生成包文档的markdown版本。( princjef/gomarkdocgo docpkgsitegopls 悬停格式化都使用 go/doc/comment 在下方转换选定的注解块,但将markdown打印机输出片段 Package 在针对其需求制定的模板中)。我只是使用了 princjef/gomarkdoc 来快速测试markdown输出与vscode的markdown预览器,并展示为什么我们需要比仅仅将pkgsite Package 在webview中更好的集成。

相关问题