mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-12-23 09:19:21 +00:00
Add basic BibTeX formatter
This commit is contained in:
parent
f77a59a593
commit
27dc8a5fde
5 changed files with 130 additions and 0 deletions
94
src/main/kotlin/texlab/BibtexFormatter.kt
Normal file
94
src/main/kotlin/texlab/BibtexFormatter.kt
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
package texlab
|
||||
|
||||
import texlab.syntax.bibtex.*
|
||||
|
||||
object BibtexFormatter {
|
||||
fun format(builder: StringBuilder, entry: BibtexEntrySyntax, settings: BibtexFormatterSettings) {
|
||||
builder.append(entry.type.text)
|
||||
builder.append("{")
|
||||
builder.append(entry.name?.text ?: return)
|
||||
builder.append(",")
|
||||
builder.appendln()
|
||||
for (field in entry.fields) {
|
||||
format(builder, field, settings)
|
||||
}
|
||||
builder.append("}")
|
||||
}
|
||||
|
||||
private fun format(builder: StringBuilder, field: BibtexFieldSyntax, settings: BibtexFormatterSettings) {
|
||||
builder.append(settings.indent)
|
||||
builder.append(field.name.text)
|
||||
builder.append(" = ")
|
||||
val startLength = settings.tabSize + field.name.text.length + 3
|
||||
|
||||
val tokens = getTokens(field.content ?: return)
|
||||
builder.append(tokens[0].text)
|
||||
|
||||
var length = startLength + tokens[0].length
|
||||
for (i in 1 until tokens.size) {
|
||||
val previous = tokens[i - 1]
|
||||
val current = tokens[i]
|
||||
|
||||
val insertSpace = shouldInsertSpace(previous, current)
|
||||
val spaceLength = if (insertSpace) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
if (length + current.length + spaceLength > settings.lineLength) {
|
||||
builder.appendln()
|
||||
builder.append(settings.indent)
|
||||
for (j in 0 until startLength - settings.tabSize + 1) {
|
||||
builder.append(" ")
|
||||
}
|
||||
length = startLength
|
||||
} else if (insertSpace) {
|
||||
builder.append(" ")
|
||||
length++
|
||||
}
|
||||
builder.append(current.text)
|
||||
length += current.length
|
||||
}
|
||||
builder.appendln(",")
|
||||
}
|
||||
|
||||
private fun shouldInsertSpace(previous: BibtexToken, current: BibtexToken): Boolean {
|
||||
if (previous.line != current.line) {
|
||||
return true
|
||||
}
|
||||
|
||||
return previous.end.character < current.start.character
|
||||
}
|
||||
|
||||
private fun getTokens(content: BibtexContentSyntax): List<BibtexToken> {
|
||||
val tokens = mutableListOf<BibtexToken>()
|
||||
fun visit(node: BibtexContentSyntax) {
|
||||
when (node) {
|
||||
is BibtexWordSyntax -> {
|
||||
tokens.add(node.token)
|
||||
}
|
||||
is BibtexCommandSyntax -> {
|
||||
tokens.add(node.token)
|
||||
}
|
||||
is BibtexQuotedContentSyntax -> {
|
||||
tokens.add(node.left)
|
||||
node.children.forEach { visit(it) }
|
||||
node.right?.also { tokens.add(it) }
|
||||
}
|
||||
is BibtexBracedContentSyntax -> {
|
||||
tokens.add(node.left)
|
||||
node.children.forEach { visit(it) }
|
||||
node.right?.also { tokens.add(it) }
|
||||
}
|
||||
is BibtexConcatSyntax -> {
|
||||
visit(node.left)
|
||||
tokens.add(node.operator)
|
||||
node.right?.also { visit(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
visit(content)
|
||||
return tokens
|
||||
}
|
||||
}
|
||||
11
src/main/kotlin/texlab/BibtexFormatterSettings.kt
Normal file
11
src/main/kotlin/texlab/BibtexFormatterSettings.kt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package texlab
|
||||
|
||||
import java.util.*
|
||||
|
||||
data class BibtexFormatterSettings(val insertSpaces: Boolean, val tabSize: Int, val lineLength: Int) {
|
||||
val indent: String = if (insertSpaces) {
|
||||
Collections.nCopies(tabSize, " ").joinToString("")
|
||||
} else {
|
||||
"\t"
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@ class LanguageServerImpl : LanguageServer {
|
|||
foldingRangeProvider = Either.forLeft(true)
|
||||
definitionProvider = true
|
||||
hoverProvider = true
|
||||
documentFormattingProvider = true
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(InitializeResult(capabilities))
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import texlab.metadata.CtanPackageMetadataProvider
|
|||
import texlab.metadata.PackageMetadataProvider
|
||||
import texlab.rename.*
|
||||
import texlab.symbol.*
|
||||
import texlab.syntax.bibtex.BibtexEntrySyntax
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.file.Paths
|
||||
|
|
@ -244,4 +245,24 @@ class TextDocumentServiceImpl(private val workspace: Workspace) : TextDocumentSe
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun formatting(params: DocumentFormattingParams): CompletableFuture<MutableList<out TextEdit>> {
|
||||
synchronized(workspace) {
|
||||
val uri = URI.create(params.textDocument.uri)
|
||||
val document = workspace.documents
|
||||
.filterIsInstance<BibtexDocument>()
|
||||
.firstOrNull { it.uri == uri }
|
||||
?: return CompletableFuture.completedFuture(null)
|
||||
|
||||
val settings = BibtexFormatterSettings(params.options.isInsertSpaces, params.options.tabSize, 120)
|
||||
|
||||
val edits = mutableListOf<TextEdit>()
|
||||
for (entry in document.tree.root.children.filterIsInstance<BibtexEntrySyntax>()) {
|
||||
val text = StringBuilder()
|
||||
BibtexFormatter.format(text, entry, settings)
|
||||
edits.add(TextEdit(entry.range, text.toString()))
|
||||
}
|
||||
return CompletableFuture.completedFuture(edits)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,4 +19,7 @@ abstract class Token {
|
|||
get () = Range(start, end)
|
||||
|
||||
abstract val text: String
|
||||
|
||||
val length: Int
|
||||
get() = text.length
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue