mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-12-23 09:19:21 +00:00
Refactor hovering
This commit is contained in:
parent
4179272056
commit
0354e6dfb2
8 changed files with 104 additions and 61 deletions
|
|
@ -28,17 +28,17 @@ import texlab.highlight.AggregateHighlightProvider
|
|||
import texlab.highlight.HighlightProvider
|
||||
import texlab.highlight.HighlightRequest
|
||||
import texlab.highlight.LatexLabelHighlightProvider
|
||||
import texlab.hover.*
|
||||
import texlab.link.AggregateLinkProvider
|
||||
import texlab.link.LatexIncludeLinkProvider
|
||||
import texlab.link.LinkProvider
|
||||
import texlab.link.LinkRequest
|
||||
import texlab.metadata.BibtexEntryTypeMetadataProvider
|
||||
import texlab.metadata.LatexPackageMetadataProvider
|
||||
import texlab.metadata.LatexComponentMetadataProvider
|
||||
import texlab.references.*
|
||||
import texlab.rename.*
|
||||
import texlab.symbol.*
|
||||
import texlab.syntax.bibtex.BibtexDeclarationSyntax
|
||||
import texlab.syntax.bibtex.BibtexEntrySyntax
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.file.Path
|
||||
|
|
@ -127,8 +127,10 @@ class TextDocumentServiceImpl(private val workspace: Workspace) : CustomTextDocu
|
|||
private val highlightProvider: HighlightProvider =
|
||||
AggregateHighlightProvider(LatexLabelHighlightProvider)
|
||||
|
||||
private val packageMetadataProvider = LatexPackageMetadataProvider()
|
||||
private val bibtexEntryTypeMetadataProvider = BibtexEntryTypeMetadataProvider()
|
||||
private val hoverProvider: HoverProvider =
|
||||
AggregateHoverProvider(
|
||||
LatexComponentHoverProvider,
|
||||
BibtexEntryTypeHoverProvider)
|
||||
|
||||
private val referenceProvider: ReferenceProvider =
|
||||
AggregateReferenceProvider(
|
||||
|
|
@ -238,8 +240,8 @@ class TextDocumentServiceImpl(private val workspace: Workspace) : CustomTextDocu
|
|||
override fun resolveCompletionItem(unresolved: CompletionItem): CompletableFuture<CompletionItem> {
|
||||
return CompletableFuture.supplyAsync<CompletionItem> {
|
||||
val provider = when (unresolved.kind) {
|
||||
CompletionItemKind.Class -> packageMetadataProvider
|
||||
CompletionItemKind.Interface -> bibtexEntryTypeMetadataProvider
|
||||
CompletionItemKind.Class -> LatexComponentMetadataProvider
|
||||
CompletionItemKind.Interface -> BibtexEntryTypeMetadataProvider
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
|
@ -278,44 +280,9 @@ class TextDocumentServiceImpl(private val workspace: Workspace) : CustomTextDocu
|
|||
|
||||
override fun hover(params: TextDocumentPositionParams): CompletableFuture<Hover> {
|
||||
val uri = URIHelper.parse(params.textDocument.uri)
|
||||
val (name, provider) = synchronized(workspace) {
|
||||
val document = workspace.documents
|
||||
.firstOrNull { it.uri == uri }
|
||||
?: return CompletableFuture.completedFuture(null)
|
||||
|
||||
val name = when (document) {
|
||||
is LatexDocument -> {
|
||||
document.tree.includes
|
||||
.filter { it.isUnitImport }
|
||||
.firstOrNull { it.command.range.contains(params.position) }?.path
|
||||
?: return CompletableFuture.completedFuture(null)
|
||||
|
||||
}
|
||||
is BibtexDocument -> {
|
||||
document.tree.root.children
|
||||
.filterIsInstance<BibtexEntrySyntax>()
|
||||
.firstOrNull { it.type.range.contains(params.position) }?.type?.text?.substring(1)
|
||||
?: return CompletableFuture.completedFuture(null)
|
||||
}
|
||||
}
|
||||
|
||||
val provider = when (document) {
|
||||
is LatexDocument -> packageMetadataProvider
|
||||
is BibtexDocument -> bibtexEntryTypeMetadataProvider
|
||||
}
|
||||
|
||||
name to provider
|
||||
}
|
||||
|
||||
return CompletableFuture.supplyAsync {
|
||||
val metadata = provider.getMetadata(name)
|
||||
val description = metadata?.documentation
|
||||
if (description != null) {
|
||||
Hover(description)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
val relatedDocuments = synchronized(workspace) { workspace.relatedDocuments(uri) }
|
||||
val request = HoverRequest(uri, relatedDocuments, params.position)
|
||||
return CompletableFuture.completedFuture(hoverProvider.getHover(request))
|
||||
}
|
||||
|
||||
override fun formatting(params: DocumentFormattingParams): CompletableFuture<MutableList<out TextEdit>> {
|
||||
|
|
|
|||
15
src/main/kotlin/texlab/hover/AggregateHoverProvider.kt
Normal file
15
src/main/kotlin/texlab/hover/AggregateHoverProvider.kt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package texlab.hover
|
||||
|
||||
import org.eclipse.lsp4j.Hover
|
||||
|
||||
class AggregateHoverProvider(private vararg val providers: HoverProvider) : HoverProvider {
|
||||
override fun getHover(request: HoverRequest): Hover? {
|
||||
for (provider in providers) {
|
||||
val hover = provider.getHover(request)
|
||||
if (hover != null) {
|
||||
return hover
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
24
src/main/kotlin/texlab/hover/BibtexEntryTypeHoverProvider.kt
Normal file
24
src/main/kotlin/texlab/hover/BibtexEntryTypeHoverProvider.kt
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package texlab.hover
|
||||
|
||||
import org.eclipse.lsp4j.Hover
|
||||
import texlab.BibtexDocument
|
||||
import texlab.contains
|
||||
import texlab.metadata.BibtexEntryTypeMetadataProvider
|
||||
import texlab.syntax.bibtex.BibtexEntrySyntax
|
||||
|
||||
object BibtexEntryTypeHoverProvider : HoverProvider {
|
||||
override fun getHover(request: HoverRequest): Hover? {
|
||||
if (request.document !is BibtexDocument) {
|
||||
return null
|
||||
}
|
||||
|
||||
val name = request.document.tree.root.children
|
||||
.filterIsInstance<BibtexEntrySyntax>()
|
||||
.firstOrNull { it.type.range.contains(request.position) }?.type?.text?.substring(1)
|
||||
?: return null
|
||||
|
||||
val metadata = BibtexEntryTypeMetadataProvider.getMetadata(name)
|
||||
val documentation = metadata?.documentation ?: return null
|
||||
return Hover(documentation)
|
||||
}
|
||||
}
|
||||
7
src/main/kotlin/texlab/hover/HoverProvider.kt
Normal file
7
src/main/kotlin/texlab/hover/HoverProvider.kt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package texlab.hover
|
||||
|
||||
import org.eclipse.lsp4j.Hover
|
||||
|
||||
interface HoverProvider {
|
||||
fun getHover(request: HoverRequest): Hover?
|
||||
}
|
||||
11
src/main/kotlin/texlab/hover/HoverRequest.kt
Normal file
11
src/main/kotlin/texlab/hover/HoverRequest.kt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package texlab.hover
|
||||
|
||||
import org.eclipse.lsp4j.Position
|
||||
import texlab.Document
|
||||
import java.net.URI
|
||||
|
||||
data class HoverRequest(val uri: URI,
|
||||
val relatedDocuments: List<Document>,
|
||||
val position: Position) {
|
||||
val document: Document = relatedDocuments.first { it.uri == uri }
|
||||
}
|
||||
22
src/main/kotlin/texlab/hover/LatexComponentHoverProvider.kt
Normal file
22
src/main/kotlin/texlab/hover/LatexComponentHoverProvider.kt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package texlab.hover
|
||||
|
||||
import org.eclipse.lsp4j.Hover
|
||||
import texlab.LatexDocument
|
||||
import texlab.contains
|
||||
import texlab.metadata.LatexComponentMetadataProvider
|
||||
|
||||
object LatexComponentHoverProvider : HoverProvider {
|
||||
override fun getHover(request: HoverRequest): Hover? {
|
||||
if (request.document !is LatexDocument) {
|
||||
return null
|
||||
}
|
||||
|
||||
val name = request.document.tree.includes
|
||||
.filter { it.isUnitImport }
|
||||
.firstOrNull { it.command.range.contains(request.position) }?.path ?: return null
|
||||
|
||||
val metadata = LatexComponentMetadataProvider.getMetadata(name)
|
||||
val documentation = metadata?.documentation ?: return null
|
||||
return Hover(documentation)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,22 +3,19 @@ package texlab.metadata
|
|||
import org.eclipse.lsp4j.MarkupContent
|
||||
import org.eclipse.lsp4j.MarkupKind
|
||||
|
||||
class BibtexEntryTypeMetadataProvider : MetadataProvider {
|
||||
private val trimRegex = Regex("""^[ \t]+""", RegexOption.MULTILINE)
|
||||
|
||||
object BibtexEntryTypeMetadataProvider : MetadataProvider {
|
||||
override fun getMetadata(name: String): Metadata? {
|
||||
return if (documentationByName.containsKey(name)) {
|
||||
val documentation = MarkupContent().apply {
|
||||
kind = MarkupKind.MARKDOWN
|
||||
value = documentationByName.getValue(name).replace(trimRegex, "")
|
||||
}
|
||||
Metadata(name, name, documentation)
|
||||
} else {
|
||||
null
|
||||
val markdown = DOCUMENTATION_BY_NAME[name] ?: return null
|
||||
val documentation = MarkupContent().apply {
|
||||
kind = MarkupKind.MARKDOWN
|
||||
value = markdown.replace(TRIM_REGEX, "")
|
||||
}
|
||||
return Metadata(name, name, documentation)
|
||||
}
|
||||
|
||||
private val documentationByName = mapOf(
|
||||
private val TRIM_REGEX = Regex("""^[ \t]+""", RegexOption.MULTILINE)
|
||||
|
||||
private val DOCUMENTATION_BY_NAME = mapOf(
|
||||
"article" to
|
||||
"""An article in a journal, magazine, newspaper, or other periodical which forms a
|
||||
self-contained unit with its own title. The title of the periodical is given in the
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import org.eclipse.lsp4j.MarkupKind
|
|||
import java.io.IOException
|
||||
import java.net.URL
|
||||
|
||||
class LatexPackageMetadataProvider : MetadataProvider {
|
||||
object LatexComponentMetadataProvider : MetadataProvider {
|
||||
override fun getMetadata(name: String): Metadata? {
|
||||
return try {
|
||||
val json = URL("https://ctan.org/json/2.0/pkg/$name").readText()
|
||||
val mapper = jacksonObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
val result = mapper.readValue<Package>(json)
|
||||
val result = mapper.readValue<Component>(json)
|
||||
val description = result.descriptions.firstOrNull { it.language == null }?.text ?: return null
|
||||
val documentation = MarkupContent().apply {
|
||||
kind = MarkupKind.MARKDOWN
|
||||
|
|
@ -27,9 +27,9 @@ class LatexPackageMetadataProvider : MetadataProvider {
|
|||
}
|
||||
}
|
||||
|
||||
private data class Package(val name: String,
|
||||
val caption: String,
|
||||
val descriptions: List<Description>)
|
||||
private data class Component(val name: String,
|
||||
val caption: String,
|
||||
val descriptions: List<Description>)
|
||||
|
||||
private data class Description(val language: String?,
|
||||
val text: String)
|
||||
Loading…
Add table
Add a link
Reference in a new issue