Keyword code completion for a space separated XML attribute

Hi,

I'm adding code completion support for an XML attribute that supports a space separated list of HTTP method names (`GET`, `POST`, etc.). I have this working for single item values, but when typing a second method name after a space (e.g. from "GET P"), the completion list is not working.

How do I get the method name LookupElement objects to be displayed in that case?

Kind regards,

Reece

2 comments
Comment actions Permalink

Please post your code with some usage samples

0
Comment actions Permalink

The code I'm using is located at https://github.com/rhdunn/xquery-intellij-plugin/blob/master/src/plugin-marklogic/main/uk/co/reecedunn/intellij/plugin/marklogic/rewriter/completion/RewriterCompletionContributor.kt. That is:

fun PsiElement.toXmlAttributeValue(): XmlAttributeValue? {
// Case #1: The file is an XML file.
if (this is XmlAttributeValue) return this
// Case #2: The file is an injected language file.
return PsiTreeUtil.getContextOfType(this, XmlAttributeValue::class.java)
}
object Rewriter {
const val NAMESPACE = "http://marklogic.com/xdmp/rewriter"
}
class RewriterCompletionContributor : CompletionContributor() {
override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) {
val attribute = parameters.position.toXmlAttributeValue()?.attribute ?: return

val element = attribute.parent
if (element.namespace != Rewriter.NAMESPACE) return

when (attribute.localName) {
"all-of" -> when (element.localName) {
"match-execute-privilege" -> result.addAllElements(EXECUTE_PRIVILEGE)
}
"any-of" -> when (element.localName) {
"match-accept" -> result.addAllElements(MIMETYPE)
"match-content-type" -> result.addAllElements(MIMETYPE)
"match-execute-privilege" -> result.addAllElements(EXECUTE_PRIVILEGE)
"match-method" -> result.addAllElements(HTTP_METHOD)
}
"name" -> when (element.localName) {
"match-header" -> result.addAllElements(HTTP_HEADER)
}
}
}

companion object {
private fun completionList(filename: String): List<LookupElement> {
return ResourceVirtualFile.create(this::class.java.classLoader, filename).decode()!!.lineSequence()
.map { LookupElementBuilder.create(it) }
.toList()
}

private val EXECUTE_PRIVILEGE: List<LookupElement> by lazy {
completionList("code-completion/execute-privilege.lst")
}

private val HTTP_HEADER: List<LookupElement> by lazy {
completionList("code-completion/http-header.lst")
}

private val HTTP_METHOD: List<LookupElement> by lazy {
completionList("code-completion/http-method.lst")
}

private val MIMETYPE: List<LookupElement> by lazy {
val mimetypes = HashSet<String>()

Language.getRegisteredLanguages().forEach { language ->
mimetypes.addAll(language.mimeTypes)

mimetypes.add("application/rdf+json")
mimetypes.add("application/rdf+xml")
mimetypes.add("application/sparql-query")
mimetypes.add("application/sparql-update")
mimetypes.add("application/sql")
mimetypes.add("application/trig")
mimetypes.add("application/xslt+xml")

mimetypes.add("text/csv")
mimetypes.add("text/n-quads")
mimetypes.add("text/n-triples")
mimetypes.add("text/n3")
mimetypes.add("text/turtle")
}

mimetypes.map { LookupElementBuilder.create(it) }
}
}
}

The code-completion/http-method.lst file is a simple list file that looks like:

ACL
CONNECT
COPY
DELETE
GET
HEAD
LOCK
MKCALENDAR
MKCOL
MOVE
OPTIONS
PATCH
POST
PROPFIND
PROPPATCH
PUT
REPORT
TRACE
UNLOCK

This is used to provide completion for MarkLogic rewriter XML files. The situation I describe above is for the `match-method` elements. For example:

<rewriter xmlns="http://marklogic.com/xdmp/rewriter">
<match-method any-of="GET HEAD">
</match-method>
<match-method any-of="POST">
</match-method>
</rewriter>
0

Please sign in to leave a comment.