diff --git a/languages/xquery/xquery.json b/languages/xquery/xquery.json
new file mode 100644
index 0000000..b20de80
--- /dev/null
+++ b/languages/xquery/xquery.json
@@ -0,0 +1,11 @@
+{
+ "comments": {
+ "lineComment": "//",
+ "blockComment": ["/*", "*/"]
+ },
+ "brackets": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"]
+ ]
+}
\ No newline at end of file
diff --git a/languages/xquery/xquery.tmLanguage b/languages/xquery/xquery.tmLanguage
new file mode 100644
index 0000000..5558b95
--- /dev/null
+++ b/languages/xquery/xquery.tmLanguage
@@ -0,0 +1,1066 @@
+
+
+
+
+ fileTypes
+
+ xq
+ xql
+ xqm
+ xqy
+ xquery
+
+ firstLineMatch
+ ^\bxquery version\b.*
+ foldingStartMarker
+ ^\s*(<[^!?%/](?!.+?(/>|</.+?>))|<[!%]--(?!.+?--%?>)|<%[!]?(?!.+?%>))|(declare|.*\{\s*(//.*)?$)
+ foldingStopMarker
+ ^\s*(</[^>]+>|[/%]>|-->)\s*$|(.*\}\s*;?\s*|.*;)
+ keyEquivalent
+ ^~X
+ name
+ XQuery
+ patterns
+
+
+ include
+ #Xml
+
+
+ include
+ #entity
+
+
+ include
+ #bare-ampersand
+
+
+ begin
+ (<\?)\s*([-_a-zA-Z0-9]+)
+ captures
+
+ 1
+
+ name
+ punctuation.definition.tag.begin.xml
+
+ 2
+
+ name
+ entity.name.tag.xml
+
+
+ end
+ (\?>)
+ name
+ meta.tag.preprocessor.xml
+ patterns
+
+
+ match
+ ([a-zA-Z-]+)
+ name
+ entity.other.attribute-name.xml
+
+
+ include
+ #doublequotedString
+
+
+ include
+ #singlequotedString
+
+
+
+
+ match
+ ^xquery version .*;$
+ name
+ keyword.control.import.xquery
+
+
+ match
+ \b(?i:(\d+\.\d*(e[\-\+]?\d+)?))(?=[^a-zA-Z_])
+ name
+ constant.numeric.float.xquery
+
+
+ match
+ (?<=[^0-9a-zA-Z_])(?i:(\.\d+(e[\-\+]?\d+)?))
+ name
+ constant.numeric.float.xquery
+
+
+ match
+ \b(?i:(\d+e[\-\+]?\d+))
+ name
+ constant.numeric.float.xquery
+
+
+ match
+ \b([1-9]+[0-9]*|0)
+ name
+ constant.numeric.integer.decimal.xquery
+
+
+ match
+ \b(import|module|schema)\b
+ name
+ keyword.control.import.xquery
+
+
+ begin
+ \(:
+ captures
+
+ 0
+
+ name
+ punctuation.definition.comment.xquery
+
+
+ end
+ :\)
+ name
+ comment.block.xquery
+ patterns
+
+
+ include
+ #block_comment
+
+
+
+
+ comment
+ http://www.w3.org/TR/xpath-datamodel/#types
+ match
+ (?<![:\-_a-zA-Z0-9])((xs:)(string|boolean|decimal|float|double|duration|dateTime|time|date|gYearMonth|gYear|gMonthDay|gDay|gMonth|hexBinary|base64Binary|anyURI|QName|NOTATION|anyAtomicType|anyType|anySimpleType|untypedAtomic|dayTimeDuration|yearMonthDuration|integer|nonPositiveInteger|negativeInteger|long|int|short|byte|nonNegativeInteger|unsignedLong|unsignedInt|unsignedShort|unsignedByte|positiveInteger|ENTITY|ID|NMTOKEN|language|NCName|Name|token|normalizedString))(?![:\-_a-zA-Z0-9])
+ name
+ support.type.xquery
+
+
+ captures
+
+ 1
+
+ name
+ punctuation.definition.variable.xquery
+
+
+ match
+ ((\$)(?:([\-_a-zA-Z0-9]+)((:)))?([\-_a-zA-Z0-9]+))
+ name
+ variable.other.xquery
+
+
+ match
+ /(child|descendant|attribute|self|descendant-or-self|following-sibling|following|parent|ancestor|preceding-sibling|preceding|ancestor-or-self)::
+ name
+ support.constant.xquery
+
+
+ name
+ meta.function.xquery
+ patterns
+
+
+ captures
+
+ 1
+
+ name
+ storage.type.function.xquery
+
+ 2
+
+ name
+ entity.name.function.xquery
+
+
+ match
+ (function)\s+((?:([\-_a-zA-Z0-9]+):)?([\-_a-zA-Z0-9]+))\s*\(
+ patterns
+
+
+ include
+ #function_parameters
+
+
+ include
+ $self
+
+
+
+
+ begin
+ \s*(function)\s+(?!namespace)
+ beginCaptures
+
+ 1
+
+ name
+ storage.type.function.xquery
+
+
+ end
+ \(
+ patterns
+
+
+ captures
+
+ 1
+
+ name
+ entity.name.function.xquery
+
+
+ match
+ ((?:([\-_a-zA-Z0-9]+):)?([\-_a-zA-Z0-9]+))
+
+
+ include
+ #function_parameters
+
+
+ include
+ $self
+
+
+
+
+
+
+ captures
+
+ 1
+
+ name
+ keyword.other.xquery
+
+ 2
+
+ name
+ storage.type.variable.xquery
+
+ 3
+
+ name
+ entity.name.function.variable.xquery
+
+
+ match
+ (declare)\s+(variable)\s+(\$(?:[\-_a-zA-Z0-9]+:)?[\-_a-zA-Z0-9]+)
+ name
+ meta.variable.xquery
+
+
+ begin
+ (declare)\s+(variable)\s*
+ captures
+
+ 1
+
+ name
+ keyword.other.xquery
+
+ 2
+
+ name
+ storage.type.variable.xquery
+
+
+ end
+ (\$(?:[\-_a-zA-Z0-9]+:)?[\-_a-zA-Z0-9]+)
+ endCaptures
+
+ 1
+
+ name
+ entity.name.function.variable.xquery
+
+
+ name
+ meta.variable.xquery
+
+
+ match
+ \b(base-uri|boundary-space|collation|construction|copy-namespaces|declare|default|element|empty(?![-])|function|greatest|import|inherit|instance|least|module|namespace|no-inherit|no-preserve|option|order|ordered|ordering|preserve|strip|unordered|variable|xdmp:mapping|xdmp:transaction-mode)\b
+ name
+ keyword.other.prolog.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(of|as|by|in|at|or|and)(?![:\-_a-zA-Z0-9])
+ name
+ keyword.operator.logical.xquery
+
+
+ captures
+
+ 1
+
+ name
+ keyword.control.flow.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(for|let|return|where|if|then|else|order by|satisfies|every)(?![:\-_a-zA-Z0-9])
+
+
+ captures
+
+ 1
+
+ name
+ support.type.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(element|attribute|document|document-node\(\)|empty-sequence\(\)|schema-element|schema-attribute|processing-instruction|comment|text|node)(?![:\-_a-zA-Z0-9])
+
+
+ match
+ :=
+ name
+ keyword.operator.assignment.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(\+|-|<=?|>=?|eq|ne|lt|le|ge|gt|\*|div|idiv|mod)(?![:\-_a-zA-Z0-9])
+ name
+ keyword.operator.arithmetic.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])((fn:)?(abs|adjust-date-to-timezone|adjust-dateTime-to-timezone|adjust-time-to-timezone|analyze-string|avg|base-uri|boolean|ceiling|codepoint-equal|codepoints-to-string|collection|compare|concat|contains|count|current-date|current-dateTime|current-time|data|dateTime|day-from-date|day-from-dateTime|days-from-duration|deep-equal|default-collation|distinct-values|doc|doc-available|document|document-uri|empty|encode-for-uri|ends-with|error|escape-html-uri|escape-uri|exactly-one|exists|false|filter|floor|fold-left|fold-right|format-date|format-dateTime|format-number|format-time|function-arity|function-available|function-lookup|function-name|generate-id|head|hours-from-dateTime|hours-from-duration|hours-from-time|id|idref|implicit-timezone|in-scope-prefixes|index-of|insert-before|iri-to-uri|lang|last|local-name|local-name-from-QName|lower-case|map|map-pairs|matches|max|min|minutes-from-dateTime|minutes-from-duration|minutes-from-time|month-from-date|month-from-dateTime|months-from-duration|name|namespace-uri|namespace-uri-for-prefix|namespace-uri-from-QName|nilled|node-name|normalize-space|normalize-unicode|not|number|one-or-more|position|prefix-from-QName|QName|remove|replace|resolve-QName|resolve-uri|reverse|root|round|round-half-to-even|seconds-from-dateTime|seconds-from-duration|seconds-from-time|starts-with|static-base-uri|string|string-join|string-length|string-to-codepoints|subsequence|substring|substring-after|substring-before|sum|tail|timezone-from-date|timezone-from-dateTime|timezone-from-time|tokenize|trace|translate|true|type-available|unordered|unparsed-text|unparsed-text-available|upper-case|year-from-date|year-from-dateTime|years-from-duration|zero-or-one))(?=\s*\()
+ name
+ support.function.builtin.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(xdmp:(access|add-response-header|add64|address-bindable|amp|amp-roles|and64|annotation|apply|architecture|atomizable|audit|aws-url-encode|base64-decode|base64-encode|binary-decode|binary-is-external|binary-is-large|binary-is-small|binary-join|binary-key|binary-offset|binary-original-length|binary-size|cache-status|can-grant-roles|castable-as|cluster|cluster-name|collation-canonical-uri|collection-delete|collection-locks|collection-properties|commit|compressed-tree-cache-clear|compressed-tree-cache-partitions|compressed-tree-cache-size|configuration-timestamp|content-type|crypt|crypt2|customized-binary|data-directory|database|database-backup|database-backup-cancel|database-backup-purge|database-backup-status|database-backup-validate|database-forests|database-fragment-counts|database-global-nonblocking-timestamp|database-is-replica|database-maintain-last-modified|database-name|database-nonblocking-timestamp|database-partition-forests|database-path-namespaces|database-restore|database-restore-cancel|database-restore-status|database-restore-validate|databases|dayname-from-date|debug-print|decode-from-NCName|default-collections|default-in-memory-limit|default-in-memory-list-size|default-in-memory-range-index-size|default-in-memory-reverse-index-size|default-in-memory-tree-size|default-in-memory-triple-index-size|default-journal-count|default-journal-size|default-license-key|default-licensee|default-permissions|default-preallocate-journals|default-s3-domain|default-zone|delete-cluster-config-file|delete-host-config-file|describe|diacritic-less|directory|directory-create|directory-delete|directory-locks|directory-properties|disable-event|document-add-collections|document-add-permissions|document-add-properties|document-assign|document-delete|document-filter|document-forest|document-get|document-get-collections|document-get-events|document-get-permissions|document-get-properties|document-get-quality|document-insert|document-load|document-locks|document-properties|document-remove-collections|document-remove-permissions|document-remove-properties|document-set-collections|document-set-permissions|document-set-properties|document-set-property|document-set-quality|document-timestamp|dsa-generate|dump-paths|dump-xsd|duplicates|eager|ec2-host|ec2-product-code|elapsed-time|element-content-type|email|email-address|enable-event|encode-for-NCName|encoding-language-detect|estimate|eval|eval-in|excel-convert|exists|expanded-tree-cache-clear|expanded-tree-cache-partitions|expanded-tree-cache-size|external-binary|external-binary-path|external-security|filesystem-directory|filesystem-directory-create|filesystem-directory-delete|filesystem-file|filesystem-file-delete|filesystem-file-exists|filesystem-file-length|filesystem-file-rename|filesystem-filepath|foreign-cluster-status|foreign-clusters|forest|forest-backup|forest-clear|forest-combine|forest-compare|forest-copy|forest-counts|forest-databases|forest-delete|forest-directory-delete|forest-directory-exists|forest-docinfos|forest-get-readonly|forest-host|forest-name|forest-online|forest-open-replica|forest-rename|forest-restart|forest-restore|forest-rollback|forest-set-readonly|forest-status|forest-updates-allowed|forests|format-number|from-json|function|function-module|function-name|function-parameter-name|function-parameter-type|function-return-type|function-signature|functions|get|get-current-roles|get-current-user|get-current-userid|get-external-variable|get-hot-updates|get-invoked-path|get-ip|get-original-url|get-orphaned-binaries|get-request-body|get-request-client-address|get-request-client-certificate|get-request-field|get-request-field-content-type|get-request-field-filename|get-request-field-names|get-request-header|get-request-header-names|get-request-method|get-request-part-body|get-request-part-headers|get-request-path|get-request-port|get-request-protocol|get-request-url|get-request-user|get-request-username|get-response-code|get-response-encoding|get-server-field|get-server-field-names|get-session-field|get-session-field-names|get-transaction-by-xid|get-transaction-mode|get-url-rewriter-path|getenv|group|group-hosts|group-name|group-servers|groups|gss-server-negotiate|gunzip|gzip|has-privilege|hash32|hash64|hex-to-integer|hmac-md5|hmac-sha1|hmac-sha256|hmac-sha512|host|host-cores|host-cpus|host-forests|host-get-ssl-fips-enabled|host-name|host-size|host-status|hostname|hosts|http-delete|http-get|http-head|http-options|http-post|http-put|initcap|install-directory|integer-to-hex|integer-to-octal|invoke|invoke-function|invoke-in|jobject|key-from-QName|language-stemmer-normalization|language-tokenizer-normalization|lazy|ldap-lookup|ldap-search|license-key|license-key-agreement|license-key-cores|license-key-cpus|license-key-decode|license-key-encode|license-key-expires|license-key-options|license-key-size|license-key-valid|license-key-version|licensee|list-cache-clear|list-cache-partitions|list-cache-size|load|lock-acquire|lock-for-update|lock-release|log|log-level|login|logout|lshift64|match-priority|md5|merge|merge-cancel|merging|missing-directories|modules-database|modules-root|month-name-from-date|mul64|multipart-decode|multipart-encode|n3|n3-get|node-database|node-delete|node-insert-after|node-insert-before|node-insert-child|node-kind|node-output-definition|node-replace|node-uri|not64|nquad|nquad-get|octal-to-integer|or64|original-binary|parse-dateTime|parse-yymmdd|path|pdf-convert|permission|plan|plannable|platform|position|powerpoint-convert|pre-release-expires|pretty-print|privilege|privilege-roles|product-edition|product-environment|product-initials|product-name|QName-from-key|quality|quarter-from-date|query-forests|query-meters|query-trace|quote|random|read-cluster-config-file|read-host-config-file|redirect-response|remove-orphaned-binary|request|request-cancel|request-key|request-status|request-timestamp|resolve-uri|restart|rethrow|role|role-roles|rollback|rsa-generate|rshift64|save|schema-database|score|security-assert|security-database|security-version|server|server-backup|server-name|server-restore|server-status|servers|set|set-current-transaction|set-hot-updates|set-request-time-limit|set-response-code|set-response-content-type|set-response-encoding|set-server-field|set-server-field-privilege|set-session-field|set-transaction-mode|set-transaction-name|set-transaction-time-limit|sha1|sha256|sha384|sha512|shutdown|sleep|smtp-relay|spawn|spawn-function|spawn-in|sql|start-journal-archiving|step64|stop-journal-archiving|strftime|subbinary|test-future|test-lazy|test-skiplist|tidy|timestamp-to-wallclock|to-json|trace|transaction|transaction-commit|transaction-create|transaction-rollback|triggers-database|triple-cache-partitions|triple-cache-size|triple-value-cache-partitions|triple-value-cache-size|turtle|turtle-get|type|unpath|unquote|update|uri-content-type|uri-format|uri-is-file|url-decode|url-encode|user|user-external-security|user-last-login|user-roles|username|validate|value|version|wallclock-to-timestamp|week-from-date|weekday-from-date|word-convert|write-cluster-config-file|write-host-config-file|x509-certificate-extract|x509-certificate-generate|x509-crl-der2pem|x509-crl-extract|x509-crl-generate|x509-request-extract|x509-request-generate|xa-complete|xa-complete-xid|xa-complete1|xa-forget|xa-forget-xid|xa-prepare|xor64|xquery-version|xslt-eval|xslt-invoke|yearday-from-date|zip-create|zip-get|zip-manifest))(?=\s*\()
+ name
+ support.function.marklogic.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(cts:(aggregate|and-not-query|and-not-query-negative-query|and-not-query-positive-query|and-query|and-query-options|and-query-queries|approx-center|arc-intersection|avg|avg-aggregate|bearing|boost-query|boost-query-boosting-query|boost-query-matching-query|bounding-boxes|box|box-east|box-intersects|box-north|box-south|box-west|circle|circle-center|circle-intersects|circle-radius|classify|cluster|codepoint-tokenizer-class|collection-match|collection-query|collection-query-uris|collection-reference|collections|complex-polygon|complex-polygon-contains|complex-polygon-inner|complex-polygon-intersects|complex-polygon-outer|confidence|contains|correlation|count|count-aggregate|covariance|covariance-p|deregister|destination|directory-query|directory-query-depth|directory-query-uris|distance|distinctive-terms|document-fragment-query|document-fragment-query-query|document-query|document-query-uris|element-attribute-pair-geospatial-boxes|element-attribute-pair-geospatial-query|element-attribute-pair-geospatial-query-element-name|element-attribute-pair-geospatial-query-latitude-name|element-attribute-pair-geospatial-query-longitude-name|element-attribute-pair-geospatial-query-options|element-attribute-pair-geospatial-query-region|element-attribute-pair-geospatial-query-weight|element-attribute-pair-geospatial-value-match|element-attribute-pair-geospatial-values|element-attribute-range-query|element-attribute-range-query-attribute-name|element-attribute-range-query-element-name|element-attribute-range-query-operator|element-attribute-range-query-options|element-attribute-range-query-value|element-attribute-range-query-weight|element-attribute-reference|element-attribute-value-co-occurrences|element-attribute-value-geospatial-co-occurrences|element-attribute-value-match|element-attribute-value-query|element-attribute-value-query-attribute-name|element-attribute-value-query-element-name|element-attribute-value-query-options|element-attribute-value-query-text|element-attribute-value-query-weight|element-attribute-value-ranges|element-attribute-values|element-attribute-word-match|element-attribute-word-query|element-attribute-word-query-attribute-name|element-attribute-word-query-element-name|element-attribute-word-query-options|element-attribute-word-query-text|element-attribute-word-query-weight|element-attribute-words|element-child-geospatial-boxes|element-child-geospatial-query|element-child-geospatial-query-child-name|element-child-geospatial-query-element-name|element-child-geospatial-query-options|element-child-geospatial-query-region|element-child-geospatial-query-weight|element-child-geospatial-value-match|element-child-geospatial-values|element-geospatial-boxes|element-geospatial-query|element-geospatial-query-element-name|element-geospatial-query-options|element-geospatial-query-region|element-geospatial-query-weight|element-geospatial-value-match|element-geospatial-values|element-pair-geospatial-boxes|element-pair-geospatial-query|element-pair-geospatial-query-element-name|element-pair-geospatial-query-latitude-name|element-pair-geospatial-query-longitude-name|element-pair-geospatial-query-options|element-pair-geospatial-query-region|element-pair-geospatial-query-weight|element-pair-geospatial-value-match|element-pair-geospatial-values|element-query|element-query-element-name|element-query-query|element-range-query|element-range-query-element-name|element-range-query-operator|element-range-query-options|element-range-query-value|element-range-query-weight|element-reference|element-value-co-occurrences|element-value-geospatial-co-occurrences|element-value-match|element-value-query|element-value-query-element-name|element-value-query-options|element-value-query-text|element-value-query-weight|element-value-ranges|element-values|element-word-match|element-word-query|element-word-query-element-name|element-word-query-options|element-word-query-text|element-word-query-weight|element-words|field-range-query|field-range-query-field-name|field-range-query-operator|field-range-query-options|field-range-query-value|field-range-query-weight|field-reference|field-value-co-occurrences|field-value-match|field-value-query|field-value-query-field-name|field-value-query-options|field-value-query-text|field-value-query-weight|field-value-ranges|field-values|field-word-match|field-word-query|field-word-query-field-name|field-word-query-options|field-word-query-text|field-word-query-weight|field-words|fitness|frequency|geospatial-attribute-pair-reference|geospatial-co-occurrences|geospatial-element-attribute-pair-reference|geospatial-element-child-reference|geospatial-element-pair-reference|geospatial-element-reference|geospatial-path-reference|hash-terms|index-path-key|index-path-keys|index-path-ns-prefixes|linear-model|linestring|linestring-vertices|locks-query|locks-query-query|long-lat-point|matches|max|median|min|near-query|near-query-distance|near-query-options|near-query-queries|near-query-weight|not-in-query|not-in-query-negative-query|not-in-query-positive-query|not-query|not-query-query|not-query-weight|or-query|or-query-queries|parse|parse-wkt|path-geospatial-query|path-geospatial-query-options|path-geospatial-query-path-expression|path-geospatial-query-region|path-geospatial-query-weight|path-range-query|path-range-query-operator|path-range-query-options|path-range-query-path-name|path-range-query-value|path-range-query-weight|path-reference|percent-rank|percentile|point|point-latitude|point-longitude|polygon|polygon-contains|polygon-intersects|polygon-vertices|properties-query|properties-query-query|punctuation|quality|query|rank|reference|reference-parse|region|region-contains|region-intersects|register|registered-query|registered-query-ids|registered-query-options|registered-query-weight|relevance-info|remainder|reverse-query|reverse-query-nodes|reverse-query-weight|score|search|shortest-distance|show-get-query|similar-query|similar-query-nodes|similar-query-weight|space|special|stddev|stddev-p|stem|sum|sum-aggregate|term-query|term-query-term|term-query-weight|thresholds|time-series|timestamp-query|to-wkt|token|tokenize|train|triple-range-query|triple-range-query-object|triple-range-query-operator|triple-range-query-options|triple-range-query-predicate|triple-range-query-subject|triple-range-query-weight|triples|uri-match|uri-reference|uris|valid-index-path|value-co-occurrences|value-match|value-ranges|value-tuples|values|variance|variance-p|word|word-match|word-query|word-query-options|word-query-text|word-query-weight|words))(?=\s*\()
+ name
+ support.function.cts.xquery
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(xdmp:([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*:)?([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*))\s*\(
+ name
+ invalid.illegal.function.xdmp
+
+
+ match
+ (?<![:\-_a-zA-Z0-9])(cts:([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*:)?([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*))\s*\(
+ name
+ invalid.illegal.function.cts
+
+
+ include
+ #string
+
+
+ begin
+ (\()
+ beginCaptures
+
+ 1
+
+ name
+ punctuation.definition.begin.xquery
+
+
+ end
+ (\))
+ endCaptures
+
+ 1
+
+ name
+ punctuation.definition.end.xquery
+
+
+ name
+ meta
+ patterns
+
+
+ include
+ $self
+
+
+
+
+ include
+ #function_call
+
+
+ repository
+
+ EntityDecl
+
+ begin
+ (<!)(ENTITY)\s+(%\s+)?([:a-zA-Z_][:a-zA-Z0-9_.-]*)(\s+(?:SYSTEM|PUBLIC)\s+)?
+ captures
+
+ 1
+
+ name
+ punctuation.definition.tag.begin.xml
+
+ 2
+
+ name
+ keyword.entity.xml
+
+ 3
+
+ name
+ punctuation.definition.entity.xml
+
+ 4
+
+ name
+ variable.entity.xml
+
+ 5
+
+ name
+ keyword.entitytype.xml
+
+
+ end
+ (>)
+ patterns
+
+
+ include
+ #doublequotedStringXml
+
+
+ include
+ #singlequotedStringXml
+
+
+
+ Xml
+
+ patterns
+
+
+ begin
+ (<\?)\s*([-_a-zA-Z0-9]+)
+ captures
+
+ 1
+
+ name
+ punctuation.definition.tag.begin.xml
+
+ 2
+
+ name
+ entity.name.tag.xml
+
+
+ end
+ (\?>)
+ name
+ meta.tag.preprocessor.xml
+ patterns
+
+
+ match
+ ([a-zA-Z-]+)
+ name
+ entity.other.attribute-name.xml
+
+
+ include
+ #doublequotedString
+
+
+ include
+ #singlequotedString
+
+
+
+
+ begin
+ (<!)(DOCTYPE)\s+([:a-zA-Z_][:a-zA-Z0-9_.-]*)
+ captures
+
+ 1
+
+ name
+ punctuation.definition.tag.begin.xml
+
+ 2
+
+ name
+ keyword.doctype.xml
+
+ 3
+
+ name
+ variable.documentroot.xml
+
+
+ end
+ \s*(>)
+ name
+ meta.tag.sgml.doctype.xml
+ patterns
+
+
+ include
+ #internalSubset
+
+
+
+
+ begin
+ <[!%]--
+ captures
+
+ 0
+
+ name
+ punctuation.definition.comment.xml
+
+
+ end
+ --%?>
+ name
+ comment.block.xml
+
+
+ begin
+ <\?
+ captures
+
+ 0
+
+ name
+ punctuation.definition.processing-instruction.xml
+
+
+ end
+ \?>
+ name
+ comment.processing-instruction.xml
+
+
+ begin
+ (<)((?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]+))(?=(\s[^>]*)?></\2>)
+ beginCaptures
+
+ 1
+
+ name
+ punctuation.definition.tag.begin.xml
+
+ 3
+
+ name
+ entity.name.tag.namespace.xml
+
+ 4
+
+ name
+ entity.name.tag.xml
+
+ 5
+
+ name
+ punctuation.separator.namespace.xml
+
+ 6
+
+ name
+ entity.name.tag.localname.xml
+
+
+ end
+ (>)(<)(/)(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]+)(>)
+ endCaptures
+
+ 1
+
+ name
+ punctuation.definition.tag.end.xml
+
+ 2
+
+ name
+ punctuation.definition.tag.begin.xml meta.scope.between-tag-pair.xml
+
+ 3
+
+ name
+ punctuation.definition.tag.begin.xml
+
+ 4
+
+ name
+ entity.name.tag.namespace.xml
+
+ 5
+
+ name
+ entity.name.tag.xml
+
+ 6
+
+ name
+ punctuation.separator.namespace.xml
+
+ 7
+
+ name
+ entity.name.tag.localname.xml
+
+ 8
+
+ name
+ punctuation.definition.tag.end.xml
+
+
+ name
+ meta.tag.no-content.xml
+ patterns
+
+
+ include
+ #tagStuff
+
+
+
+
+ begin
+ (</?)(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]+)
+ captures
+
+ 1
+
+ name
+ punctuation.definition.tag.begin.xml
+
+ 2
+
+ name
+ entity.name.tag.namespace.xml
+
+ 3
+
+ name
+ entity.name.tag.xml
+
+ 4
+
+ name
+ punctuation.separator.namespace.xml
+
+ 5
+
+ name
+ entity.name.tag.localname.xml
+
+
+ end
+ (/?>)
+ endCaptures
+
+ 1
+
+ name
+ punctuation.definition.tag.end.xml
+
+
+ name
+ meta.tag.xml
+ patterns
+
+
+ include
+ #tagStuff
+
+
+
+
+ include
+ #entity
+
+
+ include
+ #bare-ampersand
+
+
+ begin
+ <!\[CDATA\[
+ beginCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.begin.xml
+
+
+ end
+ ]]>
+ endCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.end.xml
+
+
+ name
+ string.unquoted.cdata.xml
+
+
+
+ bare-ampersand
+
+ match
+ &
+ name
+ invalid.illegal.bad-ampersand.xml
+
+ block_comment
+
+ begin
+ \(:
+ end
+ :\)
+ patterns
+
+
+ include
+ #block_comment
+
+
+
+ code_block
+
+ begin
+ \{
+ end
+ \}
+ name
+ meta.code-block.xquery
+ patterns
+
+
+ include
+ $self
+
+
+
+ doublequotedString
+
+ begin
+ (?<![-_a-zA-Z0-9:]>)\s*"(?!\s*</[-_a-zA-Z0-9:])
+ beginCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.begin.xquery
+
+
+ end
+ "
+ endCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.end.xquery
+
+
+ name
+ string.quoted.double.xquery
+ patterns
+
+
+ include
+ #entity
+
+
+ include
+ #bare-ampersand
+
+
+
+ doublequotedStringXml
+
+ begin
+ "
+ beginCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.begin.xml
+
+
+ end
+ "
+ endCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.end.xml
+
+
+ name
+ string.quoted.double.xml
+ patterns
+
+
+ include
+ #entity
+
+
+ include
+ #bare-ampersand
+
+
+ include
+ #code_block
+
+
+
+ entity
+
+ captures
+
+ 1
+
+ name
+ punctuation.definition.constant.xml
+
+
+ match
+ (&)([:a-zA-Z_][:a-zA-Z0-9_.-]*|#[0-9]+|#x[0-9a-fA-F]+)(;)
+ name
+ constant.character.entity.xml
+
+ function_call
+
+ captures
+
+ 1
+
+ name
+ punctuation.definition.parameters.begin.xquery
+
+
+ match
+ [\-_a-zA-Z0-9]+:[\-_a-zA-Z0-9]+(?=\()
+ name
+ support.function.xquery
+
+ function_parameters
+
+ match
+ \$([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*:)?([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*)
+ name
+ variable.parameter.xquery
+
+ internalSubset
+
+ begin
+ (\[)
+ captures
+
+ 1
+
+ name
+ punctuation.definition.constant.xml
+
+
+ end
+ (\])
+ name
+ meta.internalsubset.xml
+ patterns
+
+
+ include
+ #EntityDecl
+
+
+ include
+ #parameterEntity
+
+
+
+ parameterEntity
+
+ captures
+
+ 1
+
+ name
+ punctuation.definition.constant.xml
+
+ 3
+
+ name
+ punctuation.definition.constant.xml
+
+
+ match
+ (%)([:a-zA-Z_][:a-zA-Z0-9_.-]*)(;)
+ name
+ constant.character.parameter-entity.xml
+
+ singlequotedString
+
+ begin
+ (?<![-_a-zA-Z0-9:]>)\s*'(?!\s*</[-_a-zA-Z0-9:])
+ beginCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.begin.xquery
+
+
+ end
+ '
+ endCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.end.xquery
+
+
+ name
+ string.quoted.single.xquery
+ patterns
+
+
+ include
+ #entity
+
+
+ include
+ #bare-ampersand
+
+
+
+ singlequotedStringXml
+
+ begin
+ '
+ beginCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.begin.xml
+
+
+ end
+ '
+ endCaptures
+
+ 0
+
+ name
+ punctuation.definition.string.end.xml
+
+
+ name
+ string.quoted.single.xml
+ patterns
+
+
+ include
+ #entity
+
+
+ include
+ #bare-ampersand
+
+
+ include
+ #code_block
+
+
+
+ string
+
+ patterns
+
+
+ include
+ #singlequotedString
+
+
+ include
+ #doublequotedString
+
+
+
+ tagStuff
+
+ patterns
+
+
+ captures
+
+ 1
+
+ name
+ entity.other.attribute-name.namespace.xml
+
+ 2
+
+ name
+ entity.other.attribute-name.xml
+
+ 3
+
+ name
+ punctuation.separator.namespace.xml
+
+ 4
+
+ name
+ entity.other.attribute-name.localname.xml
+
+
+ match
+ (?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9]+)=
+
+
+ include
+ #doublequotedStringXml
+
+
+ include
+ #singlequotedStringXml
+
+
+
+
+ scopeName
+ source.xquery
+ uuid
+ cddd8a73-ed1e-4303-a649-a23e816fafa1
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 0197a8d..1dff24a 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
},
"categories": [
"Languages",
+ "Linters",
"Other"
],
"main": "./src/Extension",
@@ -75,10 +76,26 @@
"key": "ctrl+shift+alt+x",
"command": "xmlTools.evaluateXPath"
}
- ]
+ ],
+ "languages": [
+ {
+ "id": "xquery",
+ "aliases": ["XQuery", "xquery"],
+ "extensions": [".xq",".xql",".xqm",".xqy",".xquery"],
+ "configuration": "./languages/xquery/xquery.json"
+ }
+ ],
+ "grammars": [
+ {
+ "language": "xquery",
+ "scopeName": "source.xquery",
+ "path": "./languages/xquery/xquery.tmLanguage"
+ }
+ ]
},
"activationEvents": [
- "onLanguage:xml"
+ "onLanguage:xml",
+ "onLanguage:xquery"
],
"devDependencies": {
"vscode": "^0.10.7",
@@ -86,7 +103,8 @@
},
"dependencies": {
"xmldom": "DotJoshJohnson/xmldom#2794915",
- "xpath": "^0.0.9"
+ "xpath": "^0.0.9",
+ "xqlint": "^0.2.9"
},
"scripts": {
"vscode:prepublish": "tsc"
diff --git a/src/Extension.ts b/src/Extension.ts
index 6bcdbe9..85df16d 100644
--- a/src/Extension.ts
+++ b/src/Extension.ts
@@ -3,11 +3,14 @@
import * as vsc from 'vscode';
import { TextEditorCommands } from './Commands';
import { XmlFormattingEditProvider } from './providers/Formatting';
+import { XQueryLintingFeatureProvider } from './providers/Linting';
+import { XQueryCompletionItemProvider } from './providers/Completion';
export var GlobalState: vsc.Memento;
export var WorkspaceState: vsc.Memento;
const LANG_XML: string = 'xml';
+const LANG_XQUERY: string = 'xquery;'
const MEM_QUERY_HISTORY: string = 'xpathQueryHistory';
export function activate(ctx: vsc.ExtensionContext) {
@@ -25,7 +28,15 @@ export function activate(ctx: vsc.ExtensionContext) {
// register language feature providers
ctx.subscriptions.push(
vsc.languages.registerDocumentFormattingEditProvider(LANG_XML, new XmlFormattingEditProvider()),
- vsc.languages.registerDocumentRangeFormattingEditProvider(LANG_XML, new XmlFormattingEditProvider())
+ vsc.languages.registerDocumentRangeFormattingEditProvider(LANG_XML, new XmlFormattingEditProvider()),
+
+ vsc.languages.registerCompletionItemProvider(LANG_XQUERY, new XQueryCompletionItemProvider(), ':', '$')
+ );
+
+ // listen to editor events (for linting)
+ ctx.subscriptions.push(
+ vsc.window.onDidChangeActiveTextEditor(_handleChangeActiveTextEditor),
+ vsc.window.onDidChangeTextEditorSelection(_handleChangeTextEditorSelection)
);
}
@@ -35,4 +46,20 @@ export function deactivate() {
let history = memento.get(MEM_QUERY_HISTORY, []);
history.splice(0);
memento.update(MEM_QUERY_HISTORY, history);
+}
+
+function _handleContextChange(editor: vsc.TextEditor): void {
+ switch (editor.document.languageId) {
+ case 'xquery':
+ XQueryLintingFeatureProvider.provideXQueryDiagnostics(editor);
+ break;
+ }
+}
+
+function _handleChangeActiveTextEditor(editor: vsc.TextEditor): void {
+ _handleContextChange(editor);
+}
+
+function _handleChangeTextEditorSelection(e: vsc.TextEditorSelectionChangeEvent): void {
+ _handleContextChange(e.textEditor);
}
\ No newline at end of file
diff --git a/src/providers/Completion.ts b/src/providers/Completion.ts
new file mode 100644
index 0000000..c969e7f
--- /dev/null
+++ b/src/providers/Completion.ts
@@ -0,0 +1,46 @@
+'use strict';
+
+import * as vsc from 'vscode';
+import { XQueryCompleter, XQueryCompletionItem } from '../services/XQueryCompleter';
+
+export class XQueryCompletionItemProvider implements vsc.CompletionItemProvider {
+ provideCompletionItems(document: vsc.TextDocument, position: vsc.Position): vsc.CompletionItem[] {
+ let items: vsc.CompletionItem[] = new Array();
+
+ let completer: XQueryCompleter = new XQueryCompleter(document.getText());
+ let completions: XQueryCompletionItem[] = completer.getCompletions(position.line, position.character);
+
+ completions.forEach((completion: XQueryCompletionItem) => {
+ let item: vsc.CompletionItem = new vsc.CompletionItem(completion.name);
+ item.insertText = completion.value;
+
+ switch (completion.meta) {
+ // functions (always qualified with a colon)
+ case 'function':
+ item.kind = vsc.CompletionItemKind.Function;
+
+ let funcStart = (completion.value.indexOf(':') + 1);
+ let funcEnd = completion.value.indexOf('(');
+
+ item.insertText = completion.value.substring(funcStart, funcEnd);
+ break;
+
+ // variables and parameters (always qualified with a dollar sign)
+ case 'Let binding':
+ case 'Local variable':
+ case 'Window variable':
+ case 'Function parameter':
+ item.kind = vsc.CompletionItemKind.Variable;
+ item.insertText = completion.value.substring(1);
+ break;
+
+ // everything else
+ default: item.kind = vsc.CompletionItemKind.Text;
+ }
+
+ items.push(item);
+ });
+
+ return items;
+ }
+}
\ No newline at end of file
diff --git a/src/providers/Linting.ts b/src/providers/Linting.ts
new file mode 100644
index 0000000..e2c755a
--- /dev/null
+++ b/src/providers/Linting.ts
@@ -0,0 +1,34 @@
+'use strict';
+
+import * as vsc from 'vscode';
+import { XQueryLinter, XQueryDiagnostic } from '../services/XQueryLinter';
+
+export class XQueryLintingFeatureProvider {
+ private static _coreDiagnostics: vsc.DiagnosticCollection;
+
+ static get coreDiagnostics(): vsc.DiagnosticCollection {
+ if (!XQueryLintingFeatureProvider._coreDiagnostics) {
+ XQueryLintingFeatureProvider._coreDiagnostics = vsc.languages.createDiagnosticCollection('XQueryDiagnostics');
+ }
+
+ return XQueryLintingFeatureProvider._coreDiagnostics;
+ }
+
+ static provideXQueryDiagnostics(editor: vsc.TextEditor): void {
+ let diagnostics: vsc.Diagnostic[] = new Array();
+ let xqDiagnostics: XQueryDiagnostic[] = XQueryLinter.lint(editor.document.getText());
+
+ xqDiagnostics.forEach((xqd: XQueryDiagnostic) => {
+ let vSeverity: vsc.DiagnosticSeverity = (xqd.severity == 1) ? vsc.DiagnosticSeverity.Warning : vsc.DiagnosticSeverity.Error;
+
+ let startPos: vsc.Position = new vsc.Position(xqd.startLine, xqd.startColumn);
+ let endPos: vsc.Position = new vsc.Position(xqd.endLine, xqd.endColumn);
+ let range: vsc.Range = new vsc.Range(startPos, endPos);
+ let diagnostic: vsc.Diagnostic = new vsc.Diagnostic(range, xqd.message, vSeverity);
+
+ diagnostics.push(diagnostic);
+ });
+
+ XQueryLintingFeatureProvider.coreDiagnostics.set(editor.document.uri, diagnostics);
+ }
+}
\ No newline at end of file
diff --git a/src/services/XQueryCompleter.ts b/src/services/XQueryCompleter.ts
new file mode 100644
index 0000000..fcaf029
--- /dev/null
+++ b/src/services/XQueryCompleter.ts
@@ -0,0 +1,43 @@
+'use strict';
+
+let XQLint = require('xqlint').XQLint;
+
+export class XQueryCompleter {
+ constructor(script: string) {
+ this.script = script;
+ }
+
+ private _script: string;
+ private _linter: any;
+
+ get script(): string {
+ return this._script;
+ }
+
+ set script(value: string) {
+ this._script = value;
+ this._linter = new XQLint(this._script);
+ }
+
+ getCompletions(line: number, column: number): XQueryCompletionItem[] {
+ let items: XQueryCompletionItem[] = new Array();
+
+ this._linter.getCompletions({line: line, col: column}).forEach((completion: any) => {
+ items.push(new XQueryCompletionItem(completion.name, completion.value, completion.meta));
+ });
+
+ return items;
+ }
+}
+
+export class XQueryCompletionItem {
+ constructor(name: string, value: string, meta: string) {
+ this.name = name;
+ this.value = value;
+ this.meta = meta;
+ }
+
+ name: string;
+ value: string;
+ meta: string;
+}
\ No newline at end of file
diff --git a/src/services/XQueryLinter.ts b/src/services/XQueryLinter.ts
new file mode 100644
index 0000000..ba7db16
--- /dev/null
+++ b/src/services/XQueryLinter.ts
@@ -0,0 +1,41 @@
+'use strict';
+
+let XQLint = require('xqlint').XQLint;
+
+export class XQueryLinter {
+ static SEVERITY_WARNING: number = 1;
+ static SEVERITY_ERROR: number = 2;
+
+ static lint(text: string): XQueryDiagnostic[] {
+ let linter = new XQLint(text);
+ let diagnostics: XQueryDiagnostic[] = new Array();
+
+ linter.getErrors().forEach((error: any) => {
+ diagnostics.push(new XQueryDiagnostic(XQueryLinter.SEVERITY_ERROR, error.message, error.pos.sl, error.pos.sc, error.pos.el, error.pos.ec));
+ });
+
+ linter.getWarnings().forEach((warning: any) => {
+ diagnostics.push(new XQueryDiagnostic(XQueryLinter.SEVERITY_WARNING, warning.message, warning.pos.sl, warning.pos.sc, warning.pos.el, warning.pos.ec));
+ });
+
+ return diagnostics;
+ }
+}
+
+export class XQueryDiagnostic {
+ constructor(severity: number, message: string, startLine: number, startColumn: number, endLine: number, endColumn: number) {
+ this.severity = severity;
+ this.message = message;
+ this.startLine = startLine;
+ this.startColumn = startColumn;
+ this.endLine = endLine;
+ this.endColumn = endColumn;
+ }
+
+ severity: number;
+ message: string;
+ startLine: number;
+ startColumn: number;
+ endLine: number;
+ endColumn: number;
+}
\ No newline at end of file