Skip to content

Commit

Permalink
Reimplement buggy default completion behaviour (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
InSyncWithFoo committed May 24, 2024
1 parent 2834e69 commit 8aab34f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.insyncwithfoo.pyrightls.configuration.project.WorkspaceFolders
import com.insyncwithfoo.pyrightls.message
import com.insyncwithfoo.pyrightls.path
import com.insyncwithfoo.pyrightls.pyrightLSConfigurations
import com.insyncwithfoo.pyrightls.server.completion.CompletionSupport
import com.insyncwithfoo.pyrightls.server.diagnostics.DiagnosticsSupport
import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.openapi.diagnostic.Logger
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.insyncwithfoo.pyrightls.server.completion

import com.intellij.codeInsight.completion.InsertHandler
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.codeInsight.lookup.LookupElementDecorator
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.LogicalPosition
import org.eclipse.lsp4j.InsertReplaceEdit
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.TextEdit
import org.eclipse.lsp4j.jsonrpc.messages.Either


private typealias LookupElementWrapper = LookupElementDecorator<LookupElementBuilder>


private fun Document.getLogicalPosition(offset: Int): LogicalPosition {
val line = getLineNumber(offset)
val column = offset - getLineStartOffset(line)

return LogicalPosition(line, column)
}


private fun Document.getOffset(position: Position): Int {
val lineStart = getLineStartOffset(position.line)
return lineStart + position.character
}


private fun Document.replaceString(range: Range, replacement: String) {
val start = getOffset(range.start)
val end = getOffset(range.end)

replaceString(start, end, replacement)
}


internal class CompletionDecorator(
private val builder: LookupElementBuilder,
private val itemTextEdit: Either<TextEdit, InsertReplaceEdit>?
) : LookupElementWrapper(builder) {

override fun getDelegateInsertHandler() = InsertHandler<LookupElementBuilder> { context, _ ->
val (range, replacement) = when (val edit = itemTextEdit?.get()) {
is TextEdit -> edit.range to edit.newText
is InsertReplaceEdit -> (edit.replace ?: edit.insert) to edit.newText
else -> {
builder.handleInsert(context)
return@InsertHandler
}
}

val document = context.document
document.replaceString(range, replacement)

val newCaretOffset = document.getOffset(range.start) + replacement.length
val newCaretPosition = document.getLogicalPosition(newCaretOffset)

context.editor.caretModel.moveToLogicalPosition(newCaretPosition)
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.insyncwithfoo.pyrightls.server
package com.insyncwithfoo.pyrightls.server.completion

import com.google.gson.JsonObject
import com.insyncwithfoo.pyrightls.pyrightLSConfigurations
import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.openapi.project.Project
import com.intellij.platform.lsp.api.customization.LspCompletionSupport
import org.eclipse.lsp4j.CompletionItem
Expand Down Expand Up @@ -41,12 +42,18 @@ private fun CompletionItem.useSourceAsDetailIfPossible() {
}


private fun CompletionItem.nullifyIncomprehensibleDefaultInsertingBehaviour() {
textEdit = null
insertText = ""
}


@Suppress("UnstableApiUsage")
internal class CompletionSupport(project: Project) : LspCompletionSupport() {

private val configurations = project.pyrightLSConfigurations

override fun createLookupElement(parameters: CompletionParameters, item: CompletionItem): LookupElement? {
override fun createLookupElement(parameters: CompletionParameters, item: CompletionItem): LookupElement {
if (item.isCallable && configurations.autocompleteParentheses) {
item.completeWithParentheses()
}
Expand All @@ -55,7 +62,12 @@ internal class CompletionSupport(project: Project) : LspCompletionSupport() {
item.useSourceAsDetailIfPossible()
}

return super.createLookupElement(parameters, item)
val edit = item.textEdit
item.nullifyIncomprehensibleDefaultInsertingBehaviour()

val builder = super.createLookupElement(parameters, item) as LookupElementBuilder

return CompletionDecorator(builder, edit)
}

}

0 comments on commit 8aab34f

Please sign in to comment.