-
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for completion requests (en, de)
Fixes valentjn/vscode-ltex#409.
- Loading branch information
Showing
11 changed files
with
382 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,14 @@ jobs: | |
with: | ||
java-version: "11.0.9" | ||
|
||
- name: "Set up Python" | ||
uses: "actions/setup-python@v2" | ||
with: | ||
python-version: "3.9.0" | ||
|
||
- name: "Create Completion Lists" | ||
run: "python -u tools/createCompletionLists.py" | ||
|
||
- name: "Build LTeX LS" | ||
run: "mvn -B -e verify" | ||
|
||
|
@@ -59,6 +67,9 @@ jobs: | |
with: | ||
python-version: "3.9.0" | ||
|
||
- name: "Create Completion Lists" | ||
run: "python -u tools/createCompletionLists.py" | ||
|
||
- name: "Build LTeX LS" | ||
run: "mvn -B -e verify" | ||
|
||
|
@@ -116,6 +127,14 @@ jobs: | |
with: | ||
java-version: "11.0.9" | ||
|
||
- name: "Set up Python" | ||
uses: "actions/setup-python@v2" | ||
with: | ||
python-version: "3.9.0" | ||
|
||
- name: "Create Completion Lists" | ||
run: "python -u tools/createCompletionLists.py" | ||
|
||
- name: "Build LTeX LS" | ||
run: "mvn -B -e verify" | ||
|
||
|
@@ -166,11 +185,14 @@ jobs: | |
- name: "Set LTEX_LS_CHANGELOG" | ||
run: "if [ \"$LTEX_LS_IS_PRERELEASE\" = \"false\" ]; then echo \"LTEX_LS_CHANGELOG<<EOF\" >> $GITHUB_ENV; python -u tools/convertChangelog.py --xml-file changelog.xml --version latest >> $GITHUB_ENV; echo \"EOF\" >> $GITHUB_ENV; else echo \"LTEX_LS_CHANGELOG=This is a pre-release. Use at your own risk.\" >> $GITHUB_ENV; fi" | ||
|
||
- name: "Create Completion Lists" | ||
run: "python -u tools/createCompletionLists.py" | ||
|
||
- name: "Build LTeX LS" | ||
run: "mvn -B -e package" | ||
|
||
- name: "Create Binary Archives" | ||
run: "python tools/createBinaryArchives.py" | ||
run: "python -u tools/createBinaryArchives.py" | ||
|
||
- name: "Create GitHub Release" | ||
uses: "softprops/[email protected]" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,7 @@ jobs: | |
run: "mvn -B -e package" | ||
|
||
- name: "Create Binary Archives" | ||
run: "python tools/createBinaryArchives.py" | ||
run: "python -u tools/createBinaryArchives.py" | ||
|
||
- name: "Delete Old Nightly Releases" | ||
uses: "dev-drprasad/[email protected]" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,5 @@ | |
|
||
/.vscode/ltex.*.txt | ||
/.vscode/settings.json | ||
|
||
/src/main/resources/completionList.*.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
src/main/kotlin/org/bsplines/ltexls/server/CompletionListProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* Copyright (C) 2019-2021 Julian Valentin, LTeX Development Community | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
package org.bsplines.ltexls.server | ||
|
||
import org.bsplines.ltexls.parsing.AnnotatedTextFragment | ||
import org.bsplines.ltexls.parsing.CodeAnnotatedTextBuilder | ||
import org.bsplines.ltexls.parsing.CodeFragment | ||
import org.bsplines.ltexls.parsing.CodeFragmentizer | ||
import org.bsplines.ltexls.settings.SettingsManager | ||
import org.eclipse.lsp4j.CompletionItem | ||
import org.eclipse.lsp4j.CompletionList | ||
import org.eclipse.lsp4j.Position | ||
import org.languagetool.Language | ||
import org.languagetool.language.LanguageIdentifier | ||
import org.languagetool.markup.AnnotatedText | ||
|
||
class CompletionListProvider( | ||
val settingsManager: SettingsManager, | ||
) { | ||
private val fullCompletionListMap: MutableMap<String, List<String>> = HashMap() | ||
private val languageIdentifier = LanguageIdentifier() | ||
|
||
fun createCompletionList(document: LtexTextDocumentItem, position: Position): CompletionList { | ||
val codeFragmentPositionPair: Pair<CodeFragment, Int> = | ||
getCodeFragmentFromPosition(document, position) ?: return CompletionList(emptyList()) | ||
|
||
val annotatedTextFragment: AnnotatedTextFragment = | ||
buildAnnotatedTextFragment(document, codeFragmentPositionPair.first) | ||
|
||
val languageShortCode: String = getLanguageShortCode(annotatedTextFragment) ?: | ||
return CompletionList(emptyList()) | ||
|
||
val prefix: String = getPrefixFromPosition( | ||
annotatedTextFragment.codeFragment.code, codeFragmentPositionPair.second | ||
) | ||
if (prefix.isEmpty()) return CompletionList(emptyList()) | ||
|
||
val fullCompletionList: List<String> = getFullCompletionList(languageShortCode) | ||
if (fullCompletionList.isEmpty()) return CompletionList(emptyList()) | ||
|
||
val completionList = ArrayList<CompletionItem>() | ||
|
||
for (entry: String in annotatedTextFragment.codeFragment.settings.dictionary) { | ||
if (entry.startsWith(prefix)) completionList.add(CompletionItem(entry)) | ||
} | ||
|
||
for (entry: String in fullCompletionList) { | ||
if (entry.startsWith(prefix)) completionList.add(CompletionItem(entry)) | ||
} | ||
|
||
return CompletionList(completionList) | ||
} | ||
|
||
private fun getCodeFragmentFromPosition( | ||
document: LtexTextDocumentItem, | ||
position: Position, | ||
): Pair<CodeFragment, Int>? { | ||
val codeFragmentizer: CodeFragmentizer = CodeFragmentizer.create(document.languageId) | ||
val code: String = document.text | ||
val codeFragments: List<CodeFragment> = | ||
codeFragmentizer.fragmentize(code, this.settingsManager.settings) | ||
val pos: Int = document.convertPosition(position) | ||
|
||
var matchingCodeFragment: CodeFragment? = null | ||
|
||
for (codeFragment: CodeFragment in codeFragments) { | ||
if ( | ||
(codeFragment.fromPos <= pos) && (pos < codeFragment.fromPos + codeFragment.code.length) | ||
) { | ||
if ( | ||
(matchingCodeFragment == null) | ||
|| (codeFragment.fromPos > matchingCodeFragment.fromPos) | ||
) { | ||
matchingCodeFragment = codeFragment | ||
} | ||
} | ||
} | ||
|
||
return if (matchingCodeFragment != null) { | ||
Pair(matchingCodeFragment, pos - matchingCodeFragment.fromPos) | ||
} else { | ||
null | ||
} | ||
} | ||
|
||
private fun buildAnnotatedTextFragment( | ||
document: LtexTextDocumentItem, | ||
codeFragment: CodeFragment, | ||
): AnnotatedTextFragment { | ||
val builder: CodeAnnotatedTextBuilder = CodeAnnotatedTextBuilder.create( | ||
codeFragment.codeLanguageId) | ||
builder.setSettings(codeFragment.settings) | ||
builder.addCode(codeFragment.code) | ||
val annotatedText: AnnotatedText = builder.build() | ||
return AnnotatedTextFragment(annotatedText, codeFragment, document) | ||
} | ||
|
||
private fun getLanguageShortCode( | ||
annotatedTextFragment: AnnotatedTextFragment, | ||
): String? { | ||
return if (annotatedTextFragment.codeFragment.settings.languageShortCode == "auto") { | ||
val cleanText: String = this.languageIdentifier.cleanAndShortenText( | ||
annotatedTextFragment.annotatedText.plainText | ||
) | ||
val language: Language? = this.languageIdentifier.detectLanguage(cleanText) | ||
language?.shortCodeWithCountryAndVariant | ||
} else { | ||
annotatedTextFragment.codeFragment.settings.languageShortCode | ||
} | ||
} | ||
|
||
private fun getPrefixFromPosition(code: String, pos: Int): String { | ||
if (pos >= code.length) return "" | ||
|
||
for (curPos: Int in pos - 1 downTo 0) { | ||
val character: Char = code[curPos] | ||
if (!character.isLetter() && (character != '-')) return code.substring(curPos + 1, pos) | ||
} | ||
|
||
return code.substring(0, pos) | ||
} | ||
|
||
private fun getFullCompletionList(languageShortCode: String): List<String> { | ||
var fullCompletionList: List<String>? = fullCompletionListMap[languageShortCode] | ||
if (fullCompletionList != null) return fullCompletionList | ||
|
||
if (!LANGUAGE_SHORT_CODE_REGEX.matches(languageShortCode)) return emptyList() | ||
|
||
val completionListText: String = | ||
javaClass.getResource("/completionList.$languageShortCode.txt")?.readText()?.trim() ?: "" | ||
|
||
fullCompletionList = if (completionListText.isNotEmpty()) { | ||
completionListText.split('\n') | ||
} else { | ||
emptyList() | ||
} | ||
|
||
fullCompletionListMap[languageShortCode] = fullCompletionList | ||
|
||
return fullCompletionList | ||
} | ||
|
||
companion object { | ||
private val LANGUAGE_SHORT_CODE_REGEX = Regex("^[-A-Za-z]+$") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/test/kotlin/org/bsplines/ltexls/server/CompletionListProviderTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* Copyright (C) 2019-2021 Julian Valentin, LTeX Development Community | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
package org.bsplines.ltexls.server | ||
|
||
import org.eclipse.lsp4j.CompletionItem | ||
import org.eclipse.lsp4j.CompletionList | ||
import org.eclipse.lsp4j.Position | ||
import kotlin.test.Test | ||
import kotlin.test.assertTrue | ||
|
||
class CompletionListProviderTest { | ||
@Test | ||
fun testCreateCompletionList() { | ||
val languageServer = LtexLanguageServer() | ||
languageServer.settingsManager.settings = languageServer.settingsManager.settings.copy( | ||
_allDictionaries = mapOf(Pair("en-US", setOf("testfoobar"))) | ||
) | ||
|
||
val document = | ||
LtexTextDocumentItem(languageServer, "untitled:test.md", "markdown", 1, "This is a test.\n") | ||
val completionList: CompletionList = | ||
languageServer.completionListProvider.createCompletionList(document, Position(0, 14)) | ||
|
||
assertTrue(completionList.items.size >= 10) | ||
var containsDictionaryWord = false | ||
|
||
for (completionItem: CompletionItem in completionList.items) { | ||
val entry: String = completionItem.label | ||
assertTrue(entry.startsWith("test")) | ||
if (entry == "testfoobar") containsDictionaryWord = true | ||
} | ||
|
||
assertTrue(containsDictionaryWord) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.