Repository: DotJoshJohnson/vscode-xml
Branch: master
Commit: 95702e6355fb
Files: 100
Total size: 144.1 KB
Directory structure:
gitextract_05bouxhz/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.md
│ │ ├── feature-request.md
│ │ └── xml-formatter.md
│ └── workflows/
│ ├── release.yml
│ └── test.yml
├── .gitignore
├── .vscode/
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── .vscodeignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── azure-pipelines.yml
├── languages/
│ └── xquery/
│ ├── xquery.json
│ └── xquery.tmLanguage
├── package.json
├── src/
│ ├── common/
│ │ ├── configuration.ts
│ │ ├── create-document-selector.ts
│ │ ├── extension-state.ts
│ │ ├── index.ts
│ │ ├── native-commands.ts
│ │ └── xml-traverser.ts
│ ├── completion/
│ │ ├── index.ts
│ │ └── xquery-completion-item-provider.ts
│ ├── constants.ts
│ ├── extension.ts
│ ├── formatting/
│ │ ├── commands/
│ │ │ ├── formatAsXml.ts
│ │ │ ├── index.ts
│ │ │ ├── minifyXml.ts
│ │ │ ├── textToXml.ts
│ │ │ └── xmlToText.ts
│ │ ├── formatters/
│ │ │ ├── classic-xml-formatter.ts
│ │ │ ├── index.ts
│ │ │ └── v2-xml-formatter.ts
│ │ ├── index.ts
│ │ ├── xml-formatter.ts
│ │ ├── xml-formatting-edit-provider.ts
│ │ └── xml-formatting-options.ts
│ ├── linting/
│ │ ├── index.ts
│ │ └── xquery-linter.ts
│ ├── test/
│ │ ├── extension.test.ts
│ │ ├── test-data/
│ │ │ ├── basic.formatted.xml
│ │ │ ├── basic.unformatted.xml
│ │ │ ├── issue-149.formatted.xml
│ │ │ ├── issue-149.unformatted.xml
│ │ │ ├── issue-178.formatted.xml
│ │ │ ├── issue-178.unformatted.xml
│ │ │ ├── issue-185.formatted.xml
│ │ │ ├── issue-185.unformatted.xml
│ │ │ ├── issue-187.formatted.xml
│ │ │ ├── issue-187.unformatted.xml
│ │ │ ├── issue-189.formatted.xml
│ │ │ ├── issue-189.unformatted.xml
│ │ │ ├── issue-193.formatted.xml
│ │ │ ├── issue-193.unformatted.xml
│ │ │ ├── issue-194.formatted.xml
│ │ │ ├── issue-194.unformatted.xml
│ │ │ ├── issue-200.formatted.xml
│ │ │ ├── issue-200.unformatted.xml
│ │ │ ├── issue-227.formatted.xml
│ │ │ ├── issue-227.unformatted.xml
│ │ │ ├── issue-257.formatted.xml
│ │ │ ├── issue-257.unformatted.xml
│ │ │ ├── issue-262.minified.xml
│ │ │ ├── issue-262.unminified.xml
│ │ │ ├── issue-288.formatted.xml
│ │ │ ├── issue-288.unformatted.xml
│ │ │ ├── issue-293.formatted.xml
│ │ │ ├── issue-293.unformatted.xml
│ │ │ ├── maintain-comment-formatting.formatted.xml
│ │ │ ├── maintain-comment-formatting.unformatted.xml
│ │ │ ├── preformatted.formatted.xml
│ │ │ ├── preformatted.unformatted.xml
│ │ │ ├── preserve-breaks.formatted.xml
│ │ │ ├── preserve-breaks.unformatted.xml
│ │ │ ├── self-closing.formatted.xml
│ │ │ ├── self-closing.unformatted.xml
│ │ │ ├── single-quotes.formatted.xml
│ │ │ ├── single-quotes.unformatted.xml
│ │ │ ├── text-only-line.formatted.xml
│ │ │ ├── text-only-line.unformatted.xml
│ │ │ ├── unicode.formatted.xml
│ │ │ └── unicode.unformatted.xml
│ │ └── test-utils/
│ │ └── test-data-loader.ts
│ ├── tree-view/
│ │ ├── index.ts
│ │ └── xml-tree-data-provider.ts
│ ├── xpath/
│ │ ├── commands/
│ │ │ ├── evaluateXPath.ts
│ │ │ ├── getCurrentXPath.ts
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ ├── xpath-builder.ts
│ │ └── xpath-evaluator.ts
│ └── xquery-execution/
│ ├── child-process.ts
│ ├── commands/
│ │ ├── executeXQuery.ts
│ │ └── index.ts
│ └── index.ts
├── tsconfig.json
└── tslint.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.md
================================================
---
name: Bug Report
about: Something (aside from the formatter) isn't working right!
---
**Description**
What seems to be the problem?
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Extension Version**
What version of the XML Tools extension are you using?
**VS Code Version**
What version of VS Code are you using?
**Operating System**
What OS (and version) are you using?
================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.md
================================================
---
name: Feature Request
about: Suggest a New Feature
---
**Description**
What would you like to see added to XML Tools?
**Current Workarounds**
Are you using a workaround in the meantime?
================================================
FILE: .github/ISSUE_TEMPLATE/xml-formatter.md
================================================
---
name: XML Formatter Bug
about: Report an issue with the XML formatter.
---
#### Description
What seems to be the problem?
#### Formatter Implementation
Which XML Formatter implementation are you using (the value of your `xmlTools.xmlFormatterImplementation` setting).
#### XML Tools Version
What version of XML Tools are you using?
#### VS Code Version
What version of VS Code are you using?
#### Operating System
What OS (and version) are you using?
================================================
FILE: .github/workflows/release.yml
================================================
name: "Release to Marketplace"
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: "ubuntu-latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Setup NodeJS"
uses: "actions/setup-node@v2.1.0"
- name: "Install Dependencies"
run: "npm install"
- name: "Run Tests"
run: "npm run test"
- name: "Publish to Marketplace"
uses: "sigma/vsce-publish-action@v0.0.2"
with:
vsce_token: ${{ secrets.VSCE_TOKEN }}
================================================
FILE: .github/workflows/test.yml
================================================
name: "Run Tests"
on:
pull_request:
branches:
- "master"
jobs:
test:
runs-on: "ubuntu-latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Setup NodeJS"
uses: "actions/setup-node@v2.1.0"
- name: "Install Dependencies"
run: "npm install"
- name: "Run Tests"
run: "npm run test"
================================================
FILE: .gitignore
================================================
out
node_modules
.vscode-test/
/*.vsix
================================================
FILE: .vscode/launch.json
================================================
// A launch configuration that compiles the extension and then opens it inside a new window
{
"version": "0.1.0",
"configurations": [
{
"name": "Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [ "${workspaceRoot}/out/**/*.js" ],
"preLaunchTask": "npm: watch"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [ "${workspaceRoot}/out/test/**/*.js" ],
"preLaunchTask": "npm: watch"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
}
}
================================================
FILE: .vscode/tasks.json
================================================
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
================================================
FILE: .vscodeignore
================================================
.vscode/**
.vscode-test/**
out/test/**
out/**/*.map
src/**
.gitignore
tsconfig.json
vsc-extension-quickstart.md
================================================
FILE: CHANGELOG.md
================================================
Detailed release notes are available [here](https://github.com/DotJoshJohnson/vscode-xml/releases).
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to XML Tools
Welcome and thank you for contributing to **XML Tools for Visual Studio Code**! This document aims to provide an overview of standards and expectations for those interested in contributing to the project.
## Asking Questions
If you have any questions, please ask on Gitter or Twitter instead of submitting an issue.
## Reporting Issues
Before submitting a new issue, please be sure to check for an existing issue that matches yours first. Issues that are waiting for information for more than 30 days will be closed, so please be sure to follow your issues!
## Writing Code
If you would like to contribute code to the project, please follow these conventions:
* Use spaces over tabs (4 spaces per tab is preferred).
* Use double quotes whenever possible instead of single quotes.
* Use **snake-case** for file names.
* Use **PascalCase** for class and interface names.
* Use **camelCase** for all other identifiers unless otherwise specified.
* Prefix private members with an underscore.
* Implement and maintain barrels (`index.ts` files) when creating new folders or files.
* Use constants when referencing a static value more than once in your code.
* Place `else` and `else if` on their own lines.
* Never put opening braces (`{`) on their own line.
* Always use semicolons.
* Always prefer `const` whenever possible and fall back to `let` only if absolutely necessary.
### Branches and Pull Requests
Always develop on a new feature branch in your fork and submit pull requests from that branch to our master branch. Don't worry about changing any version numbers - that happens in its own PR before a release.
### Formatter Changes
For small bug fixes or feature additions, always add a new test case to accompany your change. If you are making large sweeping changes to how the formatter works or leveraging an external dependency for formatting XML, please create a new XmlFormatter implementation.
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 Josh Johnson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# XML Tools for Visual Studio Code
[](https://marketplace.visualstudio.com/items?itemName=DotJoshJohnson.xml)
[](https://marketplace.visualstudio.com/items?itemName=DotJoshJohnson.xml)
[](https://twitter.com/DotJoshJohnson)
[](https://gitter.im/vscode-xml/vscode-xml)
[](https://beerpay.io/DotJoshJohnson/vscode-xml)
## Features
* [XML Formatting](https://github.com/DotJoshJohnson/vscode-xml/wiki/xml-formatting)
* [XML Tree View](https://github.com/DotJoshJohnson/vscode-xml/wiki/xml-tree-view)
* [XPath Evaluation](https://github.com/DotJoshJohnson/vscode-xml/wiki/xpath-evaluation)
* [XQuery Linting](https://github.com/DotJoshJohnson/vscode-xml/wiki/xquery-linting)
* [XQuery Execution](https://github.com/DotJoshJohnson/vscode-xml/wiki/xquery-script-execution)
* [XQuery Code Completion](https://github.com/DotJoshJohnson/vscode-xml/wiki/xquery-code-completion)
## Requirements
* VS Code `1.22.2` or higher
## Extension Settings
* **`xmlTools.enableXmlTreeView`:** Enables the XML Tree View for XML documents.
* **`xmlTools.enableXmlTreeViewMetadata`:** Enables attribute and child element counts in the XML Document view.
* **`xmlTools.enableXmlTreeViewCursorSync`:** Enables auto-reveal of elements in the XML Document view when a start tag is clicked in the editor.
* **`xmlTools.enforcePrettySelfClosingTagOnFormat`:** Ensures a space is added before the forward slash at the end of a self-closing tag.
* **`xmlTools.ignoreDefaultNamespace`:** Ignore default xmlns attributes when evaluating XPath.
* **`xmlTools.persistXPathQuery`:** Remember the last XPath query used.
* **`xmlTools.removeCommentsOnMinify`:** Remove XML comments during minification.
* **`xmlTools.splitAttributesOnFormat`:** Put each attribute on a new line when formatting XML. Overrides `xmlTools.splitXmlnsOnFormat` if set to `true`. (V2 Formatter Only)
* **`xmlTools.splitXmlnsOnFormat`:** Put each xmlns attribute on a new line when formatting XML.
* **`xmlTools.xmlFormatterImplementation`:** Supported XML Formatters: `classic`, `v2`.
* **`xmlTools.xqueryExecutionArguments`:** Arguments to be passed to the XQuery execution engine.
* **`xmlTools.xqueryExecutionEngine`:** The full path to the executable to run when executing XQuery scripts.
## Release Notes
Detailed release notes are available [here](https://github.com/DotJoshJohnson/vscode-xml/releases).
## Issues
Run into a bug? Report it [here](https://github.com/DotJoshJohnson/vscode-xml/issues).
## Icon Credits
Icons used in the XML Tree View are used under the Creative Commons 3.0 BY license.
* "Code" icon by Dave Gandy from www.flaticon.com
* "At" icon by FreePik from www.flaticon.com
================================================
FILE: azure-pipelines.yml
================================================
name: "$(Build.SourceBranchName)-$(Build.SourceVersion)$(Rev:.r)"
pr:
- master
trigger:
- "refs/tags/*"
pool:
vmImage: "windows-2019"
steps:
- task: NodeTool@0
inputs:
versionSpec: "10.x"
displayName: "Install NodeJS"
- script: |
npm install -g vsce
displayName: "Install VSCE"
- script: |
npm install
displayName: "NPM Install"
- script: |
vsce package --out "$(Build.ArtifactStagingDirectory)/xml-$(Build.SourceBranchName)-$(Build.SourceVersion).vsix"
displayName: "VSCE Package"
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: $(Build.ArtifactStagingDirectory)
artifactName: drop
================================================
FILE: languages/xquery/xquery.json
================================================
{
"comments": {
"lineComment": ["(:", ":)"],
"blockComment": [ "(:~", "~:)"]
},
"brackets": [
[
"{",
"}"
],
[
"[",
"]"
],
[
"(",
")"
]
]
}
================================================
FILE: languages/xquery/xquery.tmLanguage
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>xq</string>
<string>xql</string>
<string>xqm</string>
<string>xqy</string>
<string>xquery</string>
</array>
<key>firstLineMatch</key>
<string>^\bxquery version\b.*</string>
<key>foldingStartMarker</key>
<string>^\s*(<[^!?%/](?!.+?(/>|</.+?>))|<[!%]--(?!.+?--%?>)|<%[!]?(?!.+?%>))|(declare|.*\{\s*(//.*)?$)</string>
<key>foldingStopMarker</key>
<string>^\s*(</[^>]+>|[/%]>|-->)\s*$|(.*\}\s*;?\s*|.*;)</string>
<key>keyEquivalent</key>
<string>^~X</string>
<key>name</key>
<string>XQuery</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#Xml</string>
</dict>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
<dict>
<key>begin</key>
<string>(<\?)\s*([-_a-zA-Z0-9]+)</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
</dict>
<key>end</key>
<string>(\?>)</string>
<key>name</key>
<string>meta.tag.preprocessor.xml</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string> ([a-zA-Z-]+)</string>
<key>name</key>
<string>entity.other.attribute-name.xml</string>
</dict>
<dict>
<key>include</key>
<string>#doublequotedString</string>
</dict>
<dict>
<key>include</key>
<string>#singlequotedString</string>
</dict>
</array>
</dict>
<dict>
<key>match</key>
<string>^xquery version .*;$</string>
<key>name</key>
<string>keyword.control.import.xquery</string>
</dict>
<dict>
<key>match</key>
<string>\b(?i:(\d+\.\d*(e[\-\+]?\d+)?))(?=[^a-zA-Z_])</string>
<key>name</key>
<string>constant.numeric.float.xquery</string>
</dict>
<dict>
<key>match</key>
<string>(?<=[^0-9a-zA-Z_])(?i:(\.\d+(e[\-\+]?\d+)?))</string>
<key>name</key>
<string>constant.numeric.float.xquery</string>
</dict>
<dict>
<key>match</key>
<string>\b(?i:(\d+e[\-\+]?\d+))</string>
<key>name</key>
<string>constant.numeric.float.xquery</string>
</dict>
<dict>
<key>match</key>
<string>\b([1-9]+[0-9]*|0)</string>
<key>name</key>
<string>constant.numeric.integer.decimal.xquery</string>
</dict>
<dict>
<key>match</key>
<string>\b(import|module|schema)\b</string>
<key>name</key>
<string>keyword.control.import.xquery</string>
</dict>
<dict>
<key>begin</key>
<string>\(:</string>
<key>captures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.xquery</string>
</dict>
</dict>
<key>end</key>
<string>:\)</string>
<key>name</key>
<string>comment.block.xquery</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#block_comment</string>
</dict>
</array>
</dict>
<dict>
<key>comment</key>
<string>http://www.w3.org/TR/xpath-datamodel/#types</string>
<key>match</key>
<string>(?<![:\-_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])</string>
<key>name</key>
<string>support.type.xquery</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.variable.xquery</string>
</dict>
</dict>
<key>match</key>
<string>((\$)(?:([\-_a-zA-Z0-9]+)((:)))?([\-_a-zA-Z0-9]+))</string>
<key>name</key>
<string>variable.other.xquery</string>
</dict>
<dict>
<key>match</key>
<string>/(child|descendant|attribute|self|descendant-or-self|following-sibling|following|parent|ancestor|preceding-sibling|preceding|ancestor-or-self)::</string>
<key>name</key>
<string>support.constant.xquery</string>
</dict>
<dict>
<key>name</key>
<string>meta.function.xquery</string>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.type.function.xquery</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.function.xquery</string>
</dict>
</dict>
<key>match</key>
<string>(function)\s+((?:([\-_a-zA-Z0-9]+):)?([\-_a-zA-Z0-9]+))\s*\(</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#function_parameters</string>
</dict>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>\s*(function)\s+(?!namespace)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>storage.type.function.xquery</string>
</dict>
</dict>
<key>end</key>
<string>\(</string>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.name.function.xquery</string>
</dict>
</dict>
<key>match</key>
<string>((?:([\-_a-zA-Z0-9]+):)?([\-_a-zA-Z0-9]+))</string>
</dict>
<dict>
<key>include</key>
<string>#function_parameters</string>
</dict>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.other.xquery</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>storage.type.variable.xquery</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>entity.name.function.variable.xquery</string>
</dict>
</dict>
<key>match</key>
<string>(declare)\s+(variable)\s+(\$(?:[\-_a-zA-Z0-9]+:)?[\-_a-zA-Z0-9]+)</string>
<key>name</key>
<string>meta.variable.xquery</string>
</dict>
<dict>
<key>begin</key>
<string>(declare)\s+(variable)\s*</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.other.xquery</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>storage.type.variable.xquery</string>
</dict>
</dict>
<key>end</key>
<string>(\$(?:[\-_a-zA-Z0-9]+:)?[\-_a-zA-Z0-9]+)</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.name.function.variable.xquery</string>
</dict>
</dict>
<key>name</key>
<string>meta.variable.xquery</string>
</dict>
<dict>
<key>match</key>
<string>\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</string>
<key>name</key>
<string>keyword.other.prolog.xquery</string>
</dict>
<dict>
<key>match</key>
<string>(?<![:\-_a-zA-Z0-9])(of|as|by|in|at|or|and)(?![:\-_a-zA-Z0-9])</string>
<key>name</key>
<string>keyword.operator.logical.xquery</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>keyword.control.flow.xquery</string>
</dict>
</dict>
<key>match</key>
<string>(?<![:\-_a-zA-Z0-9])(for|let|return|where|if|then|else|order by|satisfies|every)(?![:\-_a-zA-Z0-9])</string>
</dict>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>support.type.xquery</string>
</dict>
</dict>
<key>match</key>
<string>(?<![:\-_a-zA-Z0-9])(element|attribute|document|document-node\(\)|empty-sequence\(\)|schema-element|schema-attribute|processing-instruction|comment|text|node)(?![:\-_a-zA-Z0-9])</string>
</dict>
<dict>
<key>match</key>
<string>:=</string>
<key>name</key>
<string>keyword.operator.assignment.xquery</string>
</dict>
<dict>
<key>match</key>
<string>(?<![:\-_a-zA-Z0-9])(\+|-|<=?|>=?|eq|ne|lt|le|ge|gt|\*|div|idiv|mod)(?![:\-_a-zA-Z0-9])</string>
<key>name</key>
<string>keyword.operator.arithmetic.xquery</string>
</dict>
<dict>
<key>match</key>
<string>(?<![:\-_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*\()</string>
<key>name</key>
<string>support.function.builtin.xquery</string>
</dict>
<dict>
<key>match</key>
<string>(?<![:\-_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*\()</string>
<key>name</key>
<string>support.function.marklogic.xquery</string>
</dict>
<dict>
<key>match</key>
<string>(?<![:\-_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*\()</string>
<key>name</key>
<string>support.function.cts.xquery</string>
</dict>
<dict>
<key>match</key>
<string>(?<![:\-_a-zA-Z0-9])(xdmp:([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*:)?([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*))\s*\(</string>
<key>name</key>
<string>invalid.illegal.function.xdmp</string>
</dict>
<dict>
<key>match</key>
<string>(?<![:\-_a-zA-Z0-9])(cts:([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*:)?([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*))\s*\(</string>
<key>name</key>
<string>invalid.illegal.function.cts</string>
</dict>
<dict>
<key>include</key>
<string>#string</string>
</dict>
<dict>
<key>begin</key>
<string>(\()</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.begin.xquery</string>
</dict>
</dict>
<key>end</key>
<string>(\))</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.end.xquery</string>
</dict>
</dict>
<key>name</key>
<string>meta</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>#function_call</string>
</dict>
</array>
<key>repository</key>
<dict>
<key>EntityDecl</key>
<dict>
<key>begin</key>
<string>(<!)(ENTITY)\s+(%\s+)?([:a-zA-Z_][:a-zA-Z0-9_.-]*)(\s+(?:SYSTEM|PUBLIC)\s+)?</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.entity.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.entity.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>variable.entity.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>keyword.entitytype.xml</string>
</dict>
</dict>
<key>end</key>
<string>(>)</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#doublequotedStringXml</string>
</dict>
<dict>
<key>include</key>
<string>#singlequotedStringXml</string>
</dict>
</array>
</dict>
<key>Xml</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>begin</key>
<string>(<\?)\s*([-_a-zA-Z0-9]+)</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
</dict>
<key>end</key>
<string>(\?>)</string>
<key>name</key>
<string>meta.tag.preprocessor.xml</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string> ([a-zA-Z-]+)</string>
<key>name</key>
<string>entity.other.attribute-name.xml</string>
</dict>
<dict>
<key>include</key>
<string>#doublequotedString</string>
</dict>
<dict>
<key>include</key>
<string>#singlequotedString</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(<!)(DOCTYPE)\s+([:a-zA-Z_][:a-zA-Z0-9_.-]*)</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>keyword.doctype.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>variable.documentroot.xml</string>
</dict>
</dict>
<key>end</key>
<string>\s*(>)</string>
<key>name</key>
<string>meta.tag.sgml.doctype.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#internalSubset</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string><[!%]--</string>
<key>captures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.comment.xml</string>
</dict>
</dict>
<key>end</key>
<string>--%?></string>
<key>name</key>
<string>comment.block.xml</string>
</dict>
<dict>
<key>begin</key>
<string><\?</string>
<key>captures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.processing-instruction.xml</string>
</dict>
</dict>
<key>end</key>
<string>\?></string>
<key>name</key>
<string>comment.processing-instruction.xml</string>
</dict>
<dict>
<key>begin</key>
<string>(<)((?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]+))(?=(\s[^>]*)?></\2>)</string>
<key>beginCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>entity.name.tag.namespace.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>entity.name.tag.localname.xml</string>
</dict>
</dict>
<key>end</key>
<string>(>)(<)(/)(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]+)(>)</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml meta.scope.between-tag-pair.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>entity.name.tag.namespace.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>entity.name.tag.localname.xml</string>
</dict>
<key>8</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>meta.tag.no-content.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#tagStuff</string>
</dict>
</array>
</dict>
<dict>
<key>begin</key>
<string>(</?)(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]+)</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.begin.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.name.tag.namespace.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>entity.name.tag.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>5</key>
<dict>
<key>name</key>
<string>entity.name.tag.localname.xml</string>
</dict>
</dict>
<key>end</key>
<string>(/?>)</string>
<key>endCaptures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.tag.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>meta.tag.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#tagStuff</string>
</dict>
</array>
</dict>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
<dict>
<key>begin</key>
<string><!\[CDATA\[</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>]]></string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>string.unquoted.cdata.xml</string>
</dict>
</array>
</dict>
<key>bare-ampersand</key>
<dict>
<key>match</key>
<string>&</string>
<key>name</key>
<string>invalid.illegal.bad-ampersand.xml</string>
</dict>
<key>block_comment</key>
<dict>
<key>begin</key>
<string>\(:</string>
<key>end</key>
<string>:\)</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#block_comment</string>
</dict>
</array>
</dict>
<key>code_block</key>
<dict>
<key>begin</key>
<string>\{</string>
<key>end</key>
<string>\}</string>
<key>name</key>
<string>meta.code-block.xquery</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>$self</string>
</dict>
</array>
</dict>
<key>doublequotedString</key>
<dict>
<key>begin</key>
<string>(?<![-_a-zA-Z0-9:'"]>)\s*"(?![\w\s()']*</[-_a-zA-Z0-9:])</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xquery</string>
</dict>
</dict>
<key>end</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xquery</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.xquery</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
</array>
</dict>
<key>doublequotedStringXml</key>
<dict>
<key>begin</key>
<string>"</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>"</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.double.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
<dict>
<key>include</key>
<string>#code_block</string>
</dict>
</array>
</dict>
<key>entity</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
</dict>
<key>match</key>
<string>(&)([:a-zA-Z_][:a-zA-Z0-9_.-]*|#[0-9]+|#x[0-9a-fA-F]+)(;)</string>
<key>name</key>
<string>constant.character.entity.xml</string>
</dict>
<key>function_call</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.parameters.begin.xquery</string>
</dict>
</dict>
<key>match</key>
<string>[\-_a-zA-Z0-9]+:[\-_a-zA-Z0-9]+(?=\()</string>
<key>name</key>
<string>support.function.xquery</string>
</dict>
<key>function_parameters</key>
<dict>
<key>match</key>
<string>\$([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*:)?([\-_a-zA-Z0-9][\-\._a-zA-Z0-9]*)</string>
<key>name</key>
<string>variable.parameter.xquery</string>
</dict>
<key>internalSubset</key>
<dict>
<key>begin</key>
<string>(\[)</string>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
</dict>
<key>end</key>
<string>(\])</string>
<key>name</key>
<string>meta.internalsubset.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#EntityDecl</string>
</dict>
<dict>
<key>include</key>
<string>#parameterEntity</string>
</dict>
</array>
</dict>
<key>parameterEntity</key>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.xml</string>
</dict>
</dict>
<key>match</key>
<string>(%)([:a-zA-Z_][:a-zA-Z0-9_.-]*)(;)</string>
<key>name</key>
<string>constant.character.parameter-entity.xml</string>
</dict>
<key>singlequotedString</key>
<dict>
<key>begin</key>
<string>(?<![-_a-zA-Z0-9:'"]>)\s*'(?![\w\s()"]*</[-_a-zA-Z0-9:])</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xquery</string>
</dict>
</dict>
<key>end</key>
<string>'</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xquery</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.single.xquery</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
</array>
</dict>
<key>singlequotedStringXml</key>
<dict>
<key>begin</key>
<string>'</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.xml</string>
</dict>
</dict>
<key>end</key>
<string>'</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.xml</string>
</dict>
</dict>
<key>name</key>
<string>string.quoted.single.xml</string>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#entity</string>
</dict>
<dict>
<key>include</key>
<string>#bare-ampersand</string>
</dict>
<dict>
<key>include</key>
<string>#code_block</string>
</dict>
</array>
</dict>
<key>string</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#singlequotedString</string>
</dict>
<dict>
<key>include</key>
<string>#doublequotedString</string>
</dict>
</array>
</dict>
<key>tagStuff</key>
<dict>
<key>patterns</key>
<array>
<dict>
<key>captures</key>
<dict>
<key>1</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.namespace.xml</string>
</dict>
<key>2</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.xml</string>
</dict>
<key>3</key>
<dict>
<key>name</key>
<string>punctuation.separator.namespace.xml</string>
</dict>
<key>4</key>
<dict>
<key>name</key>
<string>entity.other.attribute-name.localname.xml</string>
</dict>
</dict>
<key>match</key>
<string>(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9]+)=</string>
</dict>
<dict>
<key>include</key>
<string>#doublequotedStringXml</string>
</dict>
<dict>
<key>include</key>
<string>#singlequotedStringXml</string>
</dict>
</array>
</dict>
</dict>
<key>scopeName</key>
<string>source.xquery</string>
<key>uuid</key>
<string>cddd8a73-ed1e-4303-a649-a23e816fafa1</string>
</dict>
</plist>
================================================
FILE: package.json
================================================
{
"name": "xml",
"displayName": "XML Tools",
"description": "XML Formatting, XQuery, and XPath Tools for Visual Studio Code",
"version": "2.5.1",
"preview": false,
"publisher": "DotJoshJohnson",
"author": {
"name": "Josh Johnson",
"url": "https://github.com/DotJoshJohnson"
},
"galleryBanner": {
"color": "#FFFFFF",
"theme": "light"
},
"icon": "resources/xml.png",
"homepage": "https://github.com/DotJoshJohnson/vscode-xml",
"repository": {
"type": "git",
"url": "https://github.com/DotJoshJohnson/vscode-xml.git"
},
"bugs": {
"url": "https://github.com/DotJoshJohnson/vscode-xml/issues"
},
"engines": {
"vscode": "^1.22.2"
},
"categories": [
"Formatters",
"Programming Languages",
"Linters",
"Other"
],
"activationEvents": [
"onCommand:xmlTools.evaluateXPath",
"onCommand:xmlTools.executeXQuery",
"onCommand:xmlTools.formatAsXml",
"onCommand:xmlTools.textToXml",
"onCommand:xmlTools.xmlToText",
"onCommand:xmlTools.minifyXml",
"onLanguage:xml",
"onLanguage:xquery",
"onLanguage:xsl"
],
"main": "./out/extension",
"contributes": {
"commands": [
{
"command": "xmlTools.evaluateXPath",
"title": "XML Tools: Evaluate XPath"
},
{
"command": "xmlTools.executeXQuery",
"title": "XML Tools: Execute XQuery"
},
{
"command": "xmlTools.formatAsXml",
"title": "XML Tools: Format as XML"
},
{
"command": "xmlTools.textToXml",
"title": "XML Tools: Convert text to XML (<> -> <>)"
},
{
"command": "xmlTools.xmlToText",
"title": "XML Tools: Convert XML to text (<> -> <>)"
},
{
"command": "xmlTools.getCurrentXPath",
"title": "XML Tools: Get Current XPath"
},
{
"command": "xmlTools.minifyXml",
"title": "XML Tools: Minify XML"
}
],
"configuration": {
"title": "XML Tools Configuration",
"type": "object",
"properties": {
"xmlTools.enableXmlTreeView": {
"type": "boolean",
"default": true,
"description": "Enables the XML Document view in the explorer for XML documents.",
"scope": "window"
},
"xmlTools.enableXmlTreeViewMetadata": {
"type": "boolean",
"default": true,
"description": "Enables attribute and child element counts in the XML Document view.",
"scope": "window"
},
"xmlTools.enableXmlTreeViewCursorSync": {
"type": "boolean",
"default": false,
"description": "Enables auto-reveal of elements in the XML Document view when a start tag is clicked in the editor.",
"scope": "window"
},
"xmlTools.enforcePrettySelfClosingTagOnFormat": {
"type": "boolean",
"default": false,
"description": "Enforces a space before the forward slash at the end of a self-closing XML tag.",
"scope": "resource"
},
"xmlTools.ignoreDefaultNamespace": {
"type": "boolean",
"default": true,
"description": "Ignore default xmlns attributes when evaluating XPath.",
"scope": "window"
},
"xmlTools.persistXPathQuery": {
"type": "boolean",
"default": true,
"description": "Remember the last XPath query used.",
"scope": "window"
},
"xmlTools.removeCommentsOnMinify": {
"type": "boolean",
"default": false,
"description": "Remove XML comments during minification.",
"scope": "resource"
},
"xmlTools.splitAttributesOnFormat": {
"type": "boolean",
"default": false,
"description": "Put each attribute on a new line when formatting XML. Overrides `xmlTools.splitXmlnsOnFormat` if set to `true`.",
"scope": "resource"
},
"xmlTools.splitXmlnsOnFormat": {
"type": "boolean",
"default": true,
"description": "Put each xmlns attribute on a new line when formatting XML.",
"scope": "resource"
},
"xmlTools.xmlFormatterImplementation": {
"type": "string",
"enum": [
"classic",
"v2"
],
"default": "v2",
"description": "Supported XML Formatters: classic",
"scope": "window"
},
"xmlTools.xqueryExecutionArguments": {
"type": "array",
"default": [
"-xquery",
"$(script)",
"-in",
"$(input)",
"-out",
"$(input).output.xml"
],
"description": "Arguments to be passed to the XQuery execution engine.",
"scope": "window"
},
"xmlTools.xqueryExecutionEngine": {
"type": "string",
"default": "",
"description": "The full path to the executable to run when executing XQuery scripts.",
"scope": "window"
},
"xmlTools.xqueryExecutionInputLimit": {
"type": "integer",
"default": 100,
"description": "The maximum number of input files to enumerate when executing XQuery scripts.",
"scope": "window"
},
"xmlTools.xqueryExecutionInputSearchPattern": {
"type": "string",
"default": "**/*.xml",
"description": "The pattern used to search for input XML files when executing XQuery scripts.",
"scope": "window"
}
}
},
"grammars": [
{
"language": "xquery",
"path": "./languages/xquery/xquery.tmLanguage",
"scopeName": "source.xquery"
}
],
"keybindings": [
{
"key": "ctrl+shift+alt+x",
"command": "xmlTools.evaluateXPath"
},
{
"key": "ctrl+shift+alt+b",
"command": "xmlTools.formatAsXml"
}
],
"languages": [
{
"id": "xml",
"extensions": [
".config",
".csproj",
".xml",
".xsd",
".xsl",
".plist",
".mobileconfig"
]
},
{
"id": "xquery",
"aliases": [
"XQuery",
"xquery"
],
"extensions": [
".xq",
".xql",
".xqm",
".xqy",
".xquery"
],
"configuration": "./languages/xquery/xquery.json"
}
],
"menus": {
"commandPalette": [
{
"command": "xmlTools.evaluateXPath",
"when": "editorLangId == xml"
},
{
"command": "xmlTools.executeXQuery",
"when": "editorLangId == xquery"
},
{
"command": "xmlTools.getCurrentXPath",
"when": "editorLangId == xml"
},
{
"command": "xmlTools.minifyXml",
"when": "editorLangId == xml"
}
],
"editor/context": [
{
"command": "xmlTools.minifyXml",
"group": "1_modification@100",
"when": "editorLangId == 'xml'"
}
]
},
"views": {
"explorer": [
{
"id": "xmlTreeView",
"name": "XML Document",
"when": "xmlTreeViewEnabled"
}
]
}
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "npm run lint && tsc -p ./",
"watch": "tsc -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "npm run compile && mocha './out/test/**/*.js'",
"test-windows": "npm run compile && mocha ./out/test/**/*.js",
"lint": "tslint -p tslint.json --fix"
},
"devDependencies": {
"@types/mocha": "^2.2.42",
"@types/node": "^7.0.43",
"@types/xmldom": "^0.1.29",
"tslint": "^5.9.1",
"typescript": "^2.6.1",
"vscode": "^1.1.16"
},
"dependencies": {
"xmldom": "^0.1.27",
"xpath": "0.0.27",
"xqlint": "^0.4.1"
}
}
================================================
FILE: src/common/configuration.ts
================================================
import { workspace, Uri } from "vscode";
const ExtensionTopLevelSection = "xmlTools";
export class Configuration {
static get enableXmlTreeView(): boolean {
return this._getForWindow<boolean>("enableXmlTreeView");
}
static get enableXmlTreeViewMetadata(): boolean {
return this._getForWindow<boolean>("enableXmlTreeViewMetadata");
}
static get enableXmlTreeViewCursorSync(): boolean {
return this._getForWindow<boolean>("enableXmlTreeViewCursorSync");
}
static get ignoreDefaultNamespace(): boolean {
return this._getForWindow<boolean>("ignoreDefaultNamespace");
}
static get persistXPathQuery(): boolean {
return this._getForWindow<boolean>("persistXPathQuery");
}
static get xmlFormatterImplementation(): string {
return this._getForWindow<string>("xmlFormatterImplementation");
}
static get xqueryExecutionArguments(): string[] {
return this._getForWindow<string[]>("xqueryExecutionArguments");
}
static get xqueryExecutionEngine(): string {
return this._getForWindow<string>("xqueryExecutionEngine");
}
static get xqueryExecutionInputLimit(): number {
return this._getForWindow<number>("xqueryExecutionInputLimit");
}
static get xqueryExecutionInputSearchPattern(): string {
return this._getForWindow<string>("xqueryExecutionInputSearchPattern");
}
static enforcePrettySelfClosingTagOnFormat(resource: Uri): boolean {
return this._getForResource<boolean>("enforcePrettySelfClosingTagOnFormat", resource);
}
static removeCommentsOnMinify(resource: Uri): boolean {
return this._getForResource<boolean>("removeCommentsOnMinify", resource);
}
static splitAttributesOnFormat(resource: Uri): boolean {
return this._getForResource<boolean>("splitAttributesOnFormat", resource);
}
static splitXmlnsOnFormat(resource: Uri): boolean {
return this._getForResource<boolean>("splitXmlnsOnFormat", resource);
}
private static _getForResource<T>(section: string, resource: Uri): T {
return workspace.getConfiguration(ExtensionTopLevelSection, resource).get<T>(section);
}
private static _getForWindow<T>(section: string): T {
return workspace.getConfiguration(ExtensionTopLevelSection).get<T>(section);
}
}
================================================
FILE: src/common/create-document-selector.ts
================================================
import { DocumentFilter } from "vscode";
import * as constants from "../constants";
export function createDocumentSelector(language: string): DocumentFilter[] {
return [
{ language, scheme: constants.uriSchemes.file },
{ language, scheme: constants.uriSchemes.untitled },
];
}
================================================
FILE: src/common/extension-state.ts
================================================
import { ExtensionContext, Memento } from "vscode";
export class ExtensionState {
private static _context: ExtensionContext;
static get global(): Memento {
return this._context.globalState;
}
static get workspace(): Memento {
return this._context.workspaceState;
}
static configure(context: ExtensionContext): void {
this._context = context;
}
}
================================================
FILE: src/common/index.ts
================================================
export * from "./configuration";
export * from "./create-document-selector";
export * from "./extension-state";
export * from "./native-commands";
export * from "./xml-traverser";
================================================
FILE: src/common/native-commands.ts
================================================
import { commands } from "vscode";
export class NativeCommands {
static async cursorMove(to: string, by: string): Promise<void> {
await commands.executeCommand("cursorMove", {
to: to,
by: by
});
}
static openGlobalSettings(): void {
commands.executeCommand("workbench.action.openGlobalSettings");
}
static setContext(key: string, value: any): void {
commands.executeCommand("setContext", key, value);
}
}
================================================
FILE: src/common/xml-traverser.ts
================================================
import { Position } from "vscode";
import { DOMParser } from "xmldom";
export class XmlTraverser {
constructor(private _xmlDocument: Document) { }
get xmlDocument(): Document {
return this._xmlDocument;
}
set xmlDocument(value: Document) {
this._xmlDocument = value;
}
getChildAttributeArray(node: Element): any[] {
if (!node.attributes) {
return [];
}
const array = new Array<any>();
for (let i = 0; i < node.attributes.length; i++) {
array.push(node.attributes[i]);
}
return array;
}
getChildElementArray(node: Node): any[] {
if (!node.childNodes) {
return [];
}
const array = new Array<any>();
for (let i = 0; i < node.childNodes.length; i++) {
const child = node.childNodes[i];
if (this.isElement(child)) {
array.push(child);
}
}
return array;
}
getElementAtPosition(position: Position): Element {
const node = this.getNodeAtPosition(position);
return this.getNearestElementAncestor(node);
}
getNearestElementAncestor(node: Node): Element {
if (!this.isElement) {
return this.getNearestElementAncestor(node.parentNode);
}
return <Element>node;
}
getNodeAtPosition(position: Position): Node {
return this._getNodeAtPositionCore(position, this._xmlDocument.documentElement);
}
getSiblings(node: Node): Node[] {
if (this.isElement(node)) {
return this.getSiblingElements(node);
}
return this.getSiblingAttributes(node);
}
getSiblingAttributes(node: Node): Node[] {
return this.getChildAttributeArray(<Element>node.parentNode);
}
getSiblingElements(node: Node): Node[] {
return this.getChildElementArray(node.parentNode);
}
hasSimilarSiblings(node: Node): boolean {
if (!node || !node.parentNode || !this.isElement(node)) {
return false;
}
const siblings = this.getChildElementArray(<Element>node.parentNode);
return (siblings.filter(x => x.tagName === (node as Element).tagName).length > 1);
}
isElement(node: Node): boolean {
return (!!node && !!(node as Element).tagName);
}
private _getNodeAtPositionCore(position: Position, contextNode: Node): Node {
if (!contextNode) {
return undefined;
}
const lineNumber = (contextNode as any).lineNumber;
const columnNumber = (contextNode as any).columnNumber;
const columnRange = [columnNumber, (columnNumber + (this._getNodeWidthInCharacters(contextNode) - 1))];
// for some reason, xmldom sets the column number for attributes to the "="
if (!this.isElement(contextNode)) {
columnRange[0] = (columnRange[0] - contextNode.nodeName.length);
}
if (this._checkRange(lineNumber, position, columnRange)) {
return contextNode;
}
if (this.isElement(contextNode)) {
// if the element contains text, check to see if the cursor is present in the text
const textContent = (contextNode as Element).textContent;
if (textContent) {
columnRange[1] = (columnRange[1] + textContent.length);
if (this._checkRange(lineNumber, position, columnRange)) {
return contextNode;
}
}
const children = [...this.getChildAttributeArray(<Element>contextNode), ...this.getChildElementArray(contextNode)];
let result: Node;
for (let i = 0; i < children.length; i++) {
const child = children[i];
result = this._getNodeAtPositionCore(position, child);
if (result) {
return result;
}
}
}
return undefined;
}
private _checkRange(lineNumber: number, position: Position, columnRange: number[]): boolean {
return (lineNumber === (position.line + 1) && ((position.character + 1) >= columnRange[0] && (position.character + 1) < columnRange[1]));
}
private _getNodeWidthInCharacters(node: Node) {
if (this.isElement(node)) {
return (node.nodeName.length + 2);
}
else {
return (node.nodeName.length + node.nodeValue.length + 3);
}
}
}
================================================
FILE: src/completion/index.ts
================================================
export * from "./xquery-completion-item-provider";
================================================
FILE: src/completion/xquery-completion-item-provider.ts
================================================
import { CompletionItem, CompletionItemKind, CompletionItemProvider, Position, TextDocument } from "vscode";
const XQLint = require("xqlint").XQLint;
export class XQueryCompletionItemProvider implements CompletionItemProvider {
provideCompletionItems(document: TextDocument, position: Position): CompletionItem[] {
const completionItems = new Array<CompletionItem>();
const linter = new XQLint(document.getText());
linter.getCompletions({ line: position.line, col: position.character }).forEach((x: any) => {
completionItems.push(this._getCompletionItem(x));
});
return completionItems;
}
private _getCompletionItem(xqLintCompletionItem: any): CompletionItem {
const completionItem = new CompletionItem(xqLintCompletionItem.name);
completionItem.insertText = xqLintCompletionItem.value;
switch (xqLintCompletionItem.meta) {
// functions (always qualified with a colon)
case "function":
completionItem.kind = CompletionItemKind.Function;
const funcStart = (xqLintCompletionItem.value.indexOf(":") + 1);
const funcEnd = xqLintCompletionItem.value.indexOf("(");
completionItem.insertText = xqLintCompletionItem.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":
completionItem.kind = CompletionItemKind.Variable;
completionItem.insertText = xqLintCompletionItem.value.substring(1);
break;
// everything else
default:
completionItem.kind = CompletionItemKind.Text;
break;
}
return completionItem;
}
}
================================================
FILE: src/constants.ts
================================================
export namespace commands {
export const evaluateXPath = "xmlTools.evaluateXPath";
export const executeXQuery = "xmlTools.executeXQuery";
export const formatAsXml = "xmlTools.formatAsXml";
export const xmlToText = "xmlTools.xmlToText";
export const textToXml = "xmlTools.textToXml";
export const getCurrentXPath = "xmlTools.getCurrentXPath";
export const minifyXml = "xmlTools.minifyXml";
}
export namespace contextKeys {
export const xmlTreeViewEnabled = "xmlTreeViewEnabled";
}
export namespace diagnosticCollections {
export const xquery = "XQueryDiagnostics";
}
export namespace languageIds {
export const xml = "xml";
export const xsd = "xsd";
export const xquery = "xquery";
}
export namespace nativeCommands {
export const revealLine = "revealLine";
}
export namespace stateKeys {
export const xpathQueryHistory = "xpathQueryHistory";
export const xPathQueryLast = "xPathQueryLast";
}
export namespace uriSchemes {
export const file = "file";
export const untitled = "untitled";
}
export namespace views {
export const xmlTreeView = "xmlTreeView";
}
export namespace xmlFormatterImplementations {
export const classic = "classic";
export const v2 = "v2";
}
================================================
FILE: src/extension.ts
================================================
import {
commands, languages, window, workspace, ExtensionContext, Memento,
TextEditor, TextEditorSelectionChangeEvent, TextEditorSelectionChangeKind, DiagnosticCollection
} from "vscode";
import { createDocumentSelector, ExtensionState, Configuration } from "./common";
import { XQueryCompletionItemProvider } from "./completion";
import { XmlFormatterFactory, XmlFormattingEditProvider } from "./formatting";
import { formatAsXml, minifyXml, xmlToText, textToXml } from "./formatting/commands";
import { XQueryLinter } from "./linting";
import { XmlTreeDataProvider } from "./tree-view";
import { evaluateXPath, getCurrentXPath } from "./xpath/commands";
import { executeXQuery } from "./xquery-execution/commands";
import * as constants from "./constants";
let diagnosticCollectionXQuery: DiagnosticCollection;
export function activate(context: ExtensionContext) {
ExtensionState.configure(context);
const xmlXsdDocSelector = [...createDocumentSelector(constants.languageIds.xml), ...createDocumentSelector(constants.languageIds.xsd)];
const xqueryDocSelector = createDocumentSelector(constants.languageIds.xquery);
/* Completion Features */
context.subscriptions.push(
languages.registerCompletionItemProvider(xqueryDocSelector, new XQueryCompletionItemProvider(), ":", "$")
);
/* Formatting Features */
const xmlFormattingEditProvider = new XmlFormattingEditProvider(XmlFormatterFactory.getXmlFormatter());
context.subscriptions.push(
commands.registerTextEditorCommand(constants.commands.formatAsXml, formatAsXml),
commands.registerTextEditorCommand(constants.commands.xmlToText, xmlToText),
commands.registerTextEditorCommand(constants.commands.textToXml, textToXml),
commands.registerTextEditorCommand(constants.commands.minifyXml, minifyXml),
languages.registerDocumentFormattingEditProvider(xmlXsdDocSelector, xmlFormattingEditProvider),
languages.registerDocumentRangeFormattingEditProvider(xmlXsdDocSelector, xmlFormattingEditProvider)
);
/* Linting Features */
diagnosticCollectionXQuery = languages.createDiagnosticCollection(constants.diagnosticCollections.xquery);
context.subscriptions.push(
diagnosticCollectionXQuery,
window.onDidChangeActiveTextEditor(_handleChangeActiveTextEditor),
window.onDidChangeTextEditorSelection(_handleChangeTextEditorSelection)
);
/* Tree View Features */
const treeViewDataProvider = new XmlTreeDataProvider(context);
const treeView = window.createTreeView<Node>(constants.views.xmlTreeView, {
treeDataProvider: treeViewDataProvider
});
if (Configuration.enableXmlTreeViewCursorSync) {
window.onDidChangeTextEditorSelection(x => {
if (x.kind === TextEditorSelectionChangeKind.Mouse && x.selections.length > 0) {
treeView.reveal(treeViewDataProvider.getNodeAtPosition(x.selections[0].start));
}
});
}
context.subscriptions.push(
treeView
);
/* XPath Features */
context.subscriptions.push(
commands.registerTextEditorCommand(constants.commands.evaluateXPath, evaluateXPath),
commands.registerTextEditorCommand(constants.commands.getCurrentXPath, getCurrentXPath)
);
/* XQuery Features */
context.subscriptions.push(
commands.registerTextEditorCommand(constants.commands.executeXQuery, executeXQuery)
);
}
export function deactivate() {
// do nothing
}
function _handleContextChange(editor: TextEditor): void {
const supportedSchemes = [constants.uriSchemes.file, constants.uriSchemes.untitled];
if (!editor || !editor.document || supportedSchemes.indexOf(editor.document.uri.scheme) === -1) {
return;
}
switch (editor.document.languageId) {
case constants.languageIds.xquery:
diagnosticCollectionXQuery.set(editor.document.uri, new XQueryLinter().lint(editor.document.getText()));
break;
}
}
function _handleChangeActiveTextEditor(editor: TextEditor): void {
_handleContextChange(editor);
}
function _handleChangeTextEditorSelection(e: TextEditorSelectionChangeEvent): void {
_handleContextChange(e.textEditor);
}
================================================
FILE: src/formatting/commands/formatAsXml.ts
================================================
import { workspace } from "vscode";
import { ProviderResult, Range, TextEdit, TextEditor, TextEditorEdit } from "vscode";
import { NativeCommands } from "../../common";
import * as constants from "../../constants";
import { XmlFormatterFactory } from "../xml-formatter";
import { XmlFormattingEditProvider } from "../xml-formatting-edit-provider";
import { XmlFormattingOptionsFactory } from "../xml-formatting-options";
export function formatAsXml(editor: TextEditor, edit: TextEditorEdit): void {
const xmlFormattingEditProvider = new XmlFormattingEditProvider(XmlFormatterFactory.getXmlFormatter());
const formattingOptions = {
insertSpaces: <boolean>editor.options.insertSpaces,
tabSize: <number>editor.options.tabSize
};
let edits: ProviderResult<TextEdit[]>;
if (!editor.selection.isEmpty) {
edits = xmlFormattingEditProvider.provideDocumentRangeFormattingEdits(
editor.document,
new Range(editor.selection.start, editor.selection.end),
formattingOptions,
null);
}
else {
edits = xmlFormattingEditProvider.provideDocumentFormattingEdits(
editor.document,
formattingOptions,
null);
}
for (let i = 0; i < (edits as TextEdit[]).length; i++) {
const textEdit = (edits as TextEdit[])[i];
editor.edit(async (editBuilder) => {
editBuilder.replace(textEdit.range, textEdit.newText);
// wiggle the cursor to deselect the formatted XML (is there a non-hacky way to go about this?)
await NativeCommands.cursorMove("left", "character");
await NativeCommands.cursorMove("right", "character");
});
}
}
================================================
FILE: src/formatting/commands/index.ts
================================================
export * from "./formatAsXml";
export * from "./minifyXml";
export * from "./xmlToText";
export * from "./textToXml";
================================================
FILE: src/formatting/commands/minifyXml.ts
================================================
import { workspace } from "vscode";
import { ProviderResult, Range, TextEdit, TextEditor, TextEditorEdit } from "vscode";
import * as constants from "../../constants";
import { XmlFormatterFactory } from "../xml-formatter";
import { XmlFormattingEditProvider } from "../xml-formatting-edit-provider";
import { XmlFormattingOptionsFactory } from "../xml-formatting-options";
export function minifyXml(editor: TextEditor, edit: TextEditorEdit): void {
const xmlFormatter = XmlFormatterFactory.getXmlFormatter();
const xmlFormattingOptions = XmlFormattingOptionsFactory.getXmlFormattingOptions({
insertSpaces: <boolean>editor.options.insertSpaces,
tabSize: <number>editor.options.tabSize
}, editor.document);
const endPosition = editor.document.lineAt(editor.document.lineCount - 1).rangeIncludingLineBreak.end;
const range = new Range(editor.document.positionAt(0), endPosition);
edit.replace(range, xmlFormatter.minifyXml(editor.document.getText(), xmlFormattingOptions));
}
================================================
FILE: src/formatting/commands/textToXml.ts
================================================
import { workspace } from "vscode";
import { ProviderResult, Range, TextEdit, TextEditor, Selection } from "vscode";
import { NativeCommands } from "../../common";
import * as constants from "../../constants";
import { XmlFormatterFactory } from "../xml-formatter";
import { XmlFormattingEditProvider } from "../xml-formatting-edit-provider";
import { XmlFormattingOptionsFactory } from "../xml-formatting-options";
export function textToXml(textEditor: TextEditor): void {
textEditor.edit(textEdit => {
const selections = textEditor.selections;
selections.forEach(selection => {
if (selection.isEmpty) {
selection = new Selection(
textEditor.document.positionAt(0),
textEditor.document.positionAt(textEditor.document.getText().length)
);
}
const txt = textEditor.document.getText(new Range(selection.start, selection.end));
const transformed = txt
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/&/g, "&")
// tslint:disable-next-line
.replace(/"/g, '"')
.replace(/'/g, "'");
textEdit.replace(selection, transformed);
});
});
}
================================================
FILE: src/formatting/commands/xmlToText.ts
================================================
import { workspace } from "vscode";
import { ProviderResult, Range, TextEdit, TextEditor, Selection } from "vscode";
import { NativeCommands } from "../../common";
import * as constants from "../../constants";
import { XmlFormatterFactory } from "../xml-formatter";
import { XmlFormattingEditProvider } from "../xml-formatting-edit-provider";
import { XmlFormattingOptionsFactory } from "../xml-formatting-options";
export function xmlToText(textEditor: TextEditor): void {
textEditor.edit(textEdit => {
const selections = textEditor.selections;
selections.forEach(selection => {
if (selection.isEmpty) {
selection = new Selection(
textEditor.document.positionAt(0),
textEditor.document.positionAt(textEditor.document.getText().length)
);
}
const txt = textEditor.document.getText(new Range(selection.start, selection.end));
const transformed = txt
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/&/g, "&")
.replace(/"/g, """)
.replace(/'/g, "'");
textEdit.replace(selection, transformed);
});
});
}
================================================
FILE: src/formatting/formatters/classic-xml-formatter.ts
================================================
import { XmlFormatter } from "../xml-formatter";
import { XmlFormattingOptions } from "../xml-formatting-options";
export class ClassicXmlFormatter implements XmlFormatter {
formatXml(xml: string, options: XmlFormattingOptions): string {
xml = this.minifyXml(xml, options);
xml = xml.replace(/</g, "~::~<");
if (options.splitXmlnsOnFormat) {
xml = xml
.replace(/xmlns\:/g, "~::~xmlns:")
.replace(/xmlns\=/g, "~::~xmlns=");
}
const parts: string[] = xml.split("~::~");
let inComment = false;
let level = 0;
let output = "";
for (let i = 0; i < parts.length; i++) {
// <!
if (parts[i].search(/<!/) > -1) {
output += this._getIndent(options, level, parts[i]);
inComment = true;
// end <!
if (parts[i].search(/-->/) > -1 || parts[i].search(/\]>/) > -1 || parts[i].search(/!DOCTYPE/) > -1) {
inComment = false;
}
} else if (parts[i].search(/-->/) > -1 || parts[i].search(/\]>/) > -1) {
output += parts[i];
inComment = false;
} else if (/^<(\w|:)/.test(parts[i - 1]) && /^<\/(\w|:)/.test(parts[i])
&& /^<[\w:\-\.\,\/]+/.exec(parts[i - 1])[0] === /^<\/[\w:\-\.\,]+/.exec(parts[i])[0].replace("/", "")) {
output += parts[i];
if (!inComment) { level--; }
} else if (parts[i].search(/<(\w|:)/) > -1 && parts[i].search(/<\//) === -1 && parts[i].search(/\/>/) === -1) {
output = (!inComment) ? output += this._getIndent(options, level++, parts[i]) : output += parts[i];
} else if (parts[i].search(/<(\w|:)/) > -1 && parts[i].search(/<\//) > -1) {
output = (!inComment) ? output += this._getIndent(options, level, parts[i]) : output += parts[i];
} else if (parts[i].search(/<\//) > -1) {
output = (!inComment) ? output += this._getIndent(options, --level, parts[i]) : output += parts[i];
} else if (parts[i].search(/\/>/) > -1 && (!options.splitXmlnsOnFormat || parts[i].search(/xmlns(:|=)/) === -1)) {
output = (!inComment) ? output += this._getIndent(options, level, parts[i]) : output += parts[i];
} else if (parts[i].search(/\/>/) > -1 && parts[i].search(/xmlns(:|=)/) > -1 && options.splitXmlnsOnFormat) {
output = (!inComment) ? output += this._getIndent(options, level--, parts[i]) : output += parts[i];
} else if (parts[i].search(/<\?/) > -1) {
output += this._getIndent(options, level, parts[i]);
} else if (options.splitXmlnsOnFormat && (parts[i].search(/xmlns\:/) > -1 || parts[i].search(/xmlns\=/) > -1)) {
output += this._getIndent(options, level, parts[i]);
} else {
output += parts[i];
}
}
// remove leading newline
if (output[0] === options.newLine) {
output = output.slice(1);
} else if (output.substring(0, 1) === options.newLine) {
output = output.slice(2);
}
return output;
}
minifyXml(xml: string, options: XmlFormattingOptions): string {
xml = this._stripLineBreaks(options, xml); // all line breaks outside of CDATA elements and comments
xml = (options.removeCommentsOnMinify) ? xml.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g, "") : xml;
xml = xml.replace(/>\s{0,}</g, "><"); // insignificant whitespace between tags
xml = xml.replace(/"\s+(?=[^\s]+=)/g, "\" "); // spaces between attributes
xml = xml.replace(/"\s+(?=>)/g, "\""); // spaces between the last attribute and tag close (>)
xml = xml.replace(/"\s+(?=\/>)/g, "\" "); // spaces between the last attribute and tag close (/>)
xml = xml.replace(/[^ <>="]\s+[^ <>="]+=/g, (match: string) => { // spaces between the node name and the first attribute
return match.replace(/\s+/g, " ");
});
return xml;
}
private _getIndent(options: XmlFormattingOptions, level: number, trailingValue?: string): string {
trailingValue = trailingValue || "";
const indentPattern = (options.editorOptions.preferSpaces) ? " ".repeat(options.editorOptions.tabSize) : "\t";
return `${options.newLine}${indentPattern.repeat(level)}${trailingValue}`;
}
/**
* Removes line breaks outside of CDATA, comment, and xml:space="preserve" blocks.
*/
private _stripLineBreaks(options: XmlFormattingOptions, xml: string): string {
let output = "";
const inTag = false;
const inTagName = false;
let inCdataOrComment = false;
const inAttribute = false;
let preserveSpace = false;
let level = 0;
let levelpreserveSpaceActivated = 0;
for (let i = 0; i < xml.length; i++) {
const char: string = xml.charAt(i);
const prev: string = xml.charAt(i - 1);
const next: string = xml.charAt(i + 1);
// CDATA and comments
if (char === "!" && (xml.substr(i, 8) === "![CDATA[" || xml.substr(i, 3) === "!--")) {
inCdataOrComment = true;
}
else if (char === "]" && (xml.substr(i, 3) === "]]>")) {
inCdataOrComment = false;
}
else if (char === "-" && (xml.substr(i, 3) === "-->")) {
inCdataOrComment = false;
}
// xml:space="preserve"
if (char === ">" && prev !== "/") {
level++;
}
else if (!inCdataOrComment && char === "/" && (prev === "<" || next === ">")) {
level--;
}
if (char === "x" && (xml.substr(i, 20).toLowerCase() === `xml:space="preserve"`)) {
preserveSpace = true;
levelpreserveSpaceActivated = level;
}
else if (!inCdataOrComment && preserveSpace && (char === "/" && (prev === "<" || next === ">")) && (level === levelpreserveSpaceActivated)) {
preserveSpace = false;
}
if (char.search(/[\r\n]/g) > -1 && !inCdataOrComment && !preserveSpace) {
if (/\r/.test(char) && /\S|\r|\n/.test(prev) && /\S|\r|\n/.test(xml.charAt(i + options.newLine.length))) {
output += char;
}
else if (/\n/.test(char) && /\S|\r|\n/.test(xml.charAt(i - options.newLine.length)) && /\S|\r|\n/.test(next)) {
output += char;
}
continue;
}
output += char;
}
return output;
}
}
================================================
FILE: src/formatting/formatters/index.ts
================================================
export * from "./classic-xml-formatter";
export * from "./v2-xml-formatter";
================================================
FILE: src/formatting/formatters/v2-xml-formatter.ts
================================================
import { XmlFormatter } from "../xml-formatter";
import { XmlFormattingOptions } from "../xml-formatting-options";
import { ClassicXmlFormatter } from "./classic-xml-formatter";
const MagicalStringOfWonders = "~::~MAAAGIC~::~";
/* tslint:disable no-use-before-declare */
export class V2XmlFormatter implements XmlFormatter {
formatXml(xml: string, options: XmlFormattingOptions): string {
// this replaces all "<" brackets inside of comments and CDATA to a magical string
// so the following minification steps don't mess with comment and CDATA formatting
xml = this._sanitizeCommentsAndCDATA(xml);
// remove whitespace from between tags, except for line breaks
xml = xml.replace(/>\s{0,}</g, (match: string) => {
return match.replace(/[^\S\r\n]/g, "");
});
// do some light minification to get rid of insignificant whitespace
xml = xml.replace(/"\s+(?=[^\s]+=)/g, "\" "); // spaces between attributes
xml = xml.replace(/"\s+(?=>)/g, "\""); // spaces between the last attribute and tag close (>)
xml = xml.replace(/"\s+(?=\/>)/g, "\" "); // spaces between the last attribute and tag close (/>)
xml = xml.replace(/(?!<!\[CDATA\[)[^ <>="]\s+[^ <>="]+=(?![^<]*?\]\]>)/g, (match: string) => { // spaces between the node name and the first attribute
return match.replace(/\s+/g, " ");
});
// the coast is clear - we can drop those "<" brackets back in
xml = this._unsanitizeCommentsAndCDATA(xml);
let output = "";
let indentLevel = options.initialIndentLevel || 0;
let attributeQuote = "";
let lineBreakSpree = false;
let lastWordCharacter: string | undefined;
let inMixedContent = false;
const locationHistory: Location[] = [Location.Text];
function isLastNonTextLocation(loc: Location): boolean {
for (let i = (locationHistory.length - 1); i >= 0; i--) {
if (locationHistory[i] !== Location.Text) {
return (loc === locationHistory[i]);
}
}
return false;
}
function isLocation(loc: Location): boolean {
return loc === locationHistory[locationHistory.length - 1];
}
function refreshMixedContentFlag(): void {
inMixedContent = (isLastNonTextLocation(Location.StartTag) || isLastNonTextLocation(Location.EndTag)) && lastWordCharacter !== undefined;
}
function setLocation(loc: Location): void {
if (loc === Location.Text) {
lastWordCharacter = undefined;
}
locationHistory.push(loc);
}
// NOTE: all "exiting" checks should appear after their associated "entering" checks
for (let i = 0; i < xml.length; i++) {
const cc = xml[i];
const nc = xml.charAt(i + 1);
const nnc = xml.charAt(i + 2);
const pc = xml.charAt(i - 1);
const ppc = xml.charAt(i - 2);
// entering CData
if (isLocation(Location.Text) && cc === "<" && nc === "!" && nnc === "[") {
if (pc === ">" && ppc !== "/") {
output += "<";
}
else {
output += `${this._getIndent(options, indentLevel)}<`;
}
setLocation(Location.CData);
}
// exiting CData
else if (isLocation(Location.CData) && cc === "]" && nc === "]" && nnc === ">") {
output += "]]>";
i += 2;
setLocation(Location.Text);
}
// entering Comment
else if (isLocation(Location.Text) && cc === "<" && nc === "!" && nnc === "-") {
output += `${this._getIndent(options, indentLevel)}<`;
setLocation(Location.Comment);
}
// exiting Comment
else if (isLocation(Location.Comment) && cc === "-" && nc === "-" && nnc === ">") {
output += "-->";
i += 2;
setLocation(Location.Text);
}
// entering SpecialTag
else if (isLocation(Location.Text) && cc === "<" && (nc === "!" || nc === "?")) {
output += `${this._getIndent(options, indentLevel)}<`;
setLocation(Location.SpecialTag);
}
// exiting SpecialTag
else if (isLocation(Location.SpecialTag) && cc === ">") {
output += `>`;
setLocation(Location.Text);
}
// entering StartTag.StartTagName
else if (isLocation(Location.Text) && cc === "<" && ["/", "!"].indexOf(nc) === -1) {
refreshMixedContentFlag();
// if this occurs after another tag, prepend a line break
// but do not add one if the previous tag was self-closing (it already adds its own)
if (pc === ">" && ppc !== "/" && !inMixedContent) {
output += `${options.newLine}${this._getIndent(options, indentLevel)}<`;
}
else if (!inMixedContent) {
// removing trailing non-breaking whitespace here prevents endless indentations (issue #193)
output = this._removeTrailingNonBreakingWhitespace(output);
output += `${this._getIndent(options, indentLevel)}<`;
}
else {
output += "<";
indentLevel--;
}
indentLevel++;
setLocation(Location.StartTagName);
}
// exiting StartTag.StartTagName, enter StartTag
else if (isLocation(Location.StartTagName) && cc === " ") {
output += " ";
setLocation(Location.StartTag);
}
// entering StartTag.Attribute
else if (isLocation(Location.StartTag) && [" ", "/", ">"].indexOf(cc) === -1) {
if (locationHistory[locationHistory.length - 2] === Location.AttributeValue
&& ((options.splitXmlnsOnFormat
&& xml.substr(i, 5).toLowerCase() === "xmlns")
|| options.splitAttributesOnFormat)) {
// trim the end of output here to ensure there is no trailing whitespace (issue #288)
output = this._removeTrailingNonBreakingWhitespace(output);
output += `${options.newLine}${this._getIndent(options, indentLevel)}`;
}
output += cc;
setLocation(Location.Attribute);
}
// entering StartTag.Attribute.AttributeValue
else if (isLocation(Location.Attribute) && (cc === "\"" || cc === "'")) {
output += cc;
setLocation(Location.AttributeValue);
attributeQuote = cc;
}
// exiting StartTag.Attribute.AttributeValue, entering StartTag
else if (isLocation(Location.AttributeValue) && cc === attributeQuote) {
output += cc;
setLocation(Location.StartTag);
attributeQuote = undefined;
}
// approaching the end of a self-closing tag where there was no whitespace (issue #149)
else if ((isLocation(Location.StartTag) || isLocation(Location.StartTagName))
&& cc === "/"
&& pc !== " "
&& options.enforcePrettySelfClosingTagOnFormat) {
output += " /";
}
// exiting StartTag or StartTag.StartTagName, entering Text
else if ((isLocation(Location.StartTag) || isLocation(Location.StartTagName)) && cc === ">") {
// if this was a self-closing tag, we need to decrement the indent level and add a newLine
if (pc === "/") {
indentLevel--;
output += ">";
// only add a newline here if one doesn't already exist (issue #147)
if (nc !== "\r" && nc !== "\n") {
output += options.newLine;
}
}
else {
output += ">";
}
// don't go directly from StartTagName to Text; go through StartTag first
if (isLocation(Location.StartTagName)) {
setLocation(Location.StartTag);
}
setLocation(Location.Text);
}
// entering EndTag
else if (isLocation(Location.Text) && cc === "<" && nc === "/") {
if (!inMixedContent) {
indentLevel--;
}
refreshMixedContentFlag();
// if the end tag immediately follows a line break, just add an indentation
// if the end tag immediately follows another end tag or a self-closing tag (issue #185), add a line break and indent
// otherwise, this should be treated as a same-line end tag(ex. <element>text</element>)
if ((pc === "\n" || lineBreakSpree) && !inMixedContent) {
// removing trailing non-breaking whitespace here prevents endless indentations (issue #193)
output = this._removeTrailingNonBreakingWhitespace(output);
output += `${this._getIndent(options, indentLevel)}<`;
lineBreakSpree = false;
}
else if (isLastNonTextLocation(Location.EndTag) && !inMixedContent) {
output += `${options.newLine}${this._getIndent(options, indentLevel)}<`;
}
else if (pc === ">" && ppc === "/" && !inMixedContent) {
output += `${this._getIndent(options, indentLevel)}<`;
}
else {
output += "<";
}
setLocation(Location.EndTag);
}
// exiting EndTag, entering Text
else if (isLocation(Location.EndTag) && cc === ">") {
output += ">";
setLocation(Location.Text);
inMixedContent = false;
}
// Text
else {
if (cc === "\n") {
lineBreakSpree = true;
lastWordCharacter = undefined;
}
else if (lineBreakSpree && /\S/.test(cc)) {
lineBreakSpree = false;
}
if (/[\w\d]/.test(cc)) {
lastWordCharacter = cc;
}
output += cc;
}
}
return output;
}
minifyXml(xml: string, options: XmlFormattingOptions): string {
return new ClassicXmlFormatter().minifyXml(xml, options);
}
private _getIndent(options: XmlFormattingOptions, indentLevel: number): string {
return ((options.editorOptions.insertSpaces) ? " ".repeat(options.editorOptions.tabSize) : "\t").repeat(Math.max(indentLevel, 0));
}
private _removeTrailingNonBreakingWhitespace(text: string): string {
return text.replace(/[^\r\n\S]+$/, "");
}
private _sanitizeCommentsAndCDATA(xml: string): string {
let output = "";
let inCommentOrCDATA = false;
for (let i = 0; i < xml.length; i++) {
const cc = xml[i];
const nc = xml.charAt(i + 1);
const nnc = xml.charAt(i + 2);
const pc = xml.charAt(i - 1);
if (!inCommentOrCDATA && cc === "<" && nc === "!" && (nnc === "-" || nnc === "[")) {
inCommentOrCDATA = true;
output += (nnc === "-") ? "<!--" : "<![CDATA[";
i += (nnc === "-") ? 3 : 8;
}
else if (inCommentOrCDATA && cc === "<") {
output += MagicalStringOfWonders;
}
else if (inCommentOrCDATA && (cc === "-" && nc === "-" && nnc === ">") || (cc === "]" && nc === "]" && nnc === ">")) {
inCommentOrCDATA = false;
output += (cc === "-") ? "-->" : "]]>";
i += 2;
}
else {
output += cc;
}
}
return output;
}
private _unsanitizeCommentsAndCDATA(xml: string): string {
return xml.replace(new RegExp(MagicalStringOfWonders, "g"), "<");
}
}
enum Location {
Attribute,
AttributeValue,
CData,
Comment,
EndTag,
SpecialTag,
StartTag,
StartTagName,
Text
}
================================================
FILE: src/formatting/index.ts
================================================
export * from "./xml-formatter";
export * from "./xml-formatting-edit-provider";
export * from "./xml-formatting-options";
================================================
FILE: src/formatting/xml-formatter.ts
================================================
import { window, workspace } from "vscode";
import { Configuration, ExtensionState } from "../common";
import * as constants from "../constants";
import { ClassicXmlFormatter } from "./formatters/classic-xml-formatter";
import { V2XmlFormatter } from "./formatters/v2-xml-formatter";
import { XmlFormattingOptions } from "./xml-formatting-options";
export interface XmlFormatter {
formatXml(xml: string, options: XmlFormattingOptions): string;
minifyXml(xml: string, options: XmlFormattingOptions): string;
}
export class XmlFormatterFactory {
private static _xmlFormatter: XmlFormatter;
static getXmlFormatter(): XmlFormatter {
if (XmlFormatterFactory._xmlFormatter) {
return XmlFormatterFactory._xmlFormatter;
}
const xmlFormatterImplementationSetting = Configuration.xmlFormatterImplementation;
let xmlFormatterImplementation: XmlFormatter;
switch (xmlFormatterImplementationSetting) {
case constants.xmlFormatterImplementations.classic: xmlFormatterImplementation = new ClassicXmlFormatter(); break;
case constants.xmlFormatterImplementations.v2:
default: xmlFormatterImplementation = new V2XmlFormatter(); break;
}
return (XmlFormatterFactory._xmlFormatter = xmlFormatterImplementation);
}
}
================================================
FILE: src/formatting/xml-formatting-edit-provider.ts
================================================
import { workspace } from "vscode";
import {
CancellationToken, DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider, EndOfLine,
FormattingOptions, ProviderResult, Range, TextDocument, TextEdit
} from "vscode";
import * as constants from "../constants";
import { XmlFormatter } from "./xml-formatter";
import { XmlFormattingOptionsFactory } from "./xml-formatting-options";
export class XmlFormattingEditProvider implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider {
constructor(
public xmlFormatter: XmlFormatter
) { }
provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
const lastLine = document.lineAt(document.lineCount - 1);
const documentRange = new Range(document.positionAt(0), lastLine.range.end);
return this.provideDocumentRangeFormattingEdits(document, documentRange, options, token);
}
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
const allXml = document.getText();
let selectedXml = document.getText(range);
const extFormattingOptions = XmlFormattingOptionsFactory.getXmlFormattingOptions(options, document);
const selectionStartOffset = document.offsetAt(range.start);
let tabCount = 0;
let spaceCount = 0;
for (let i = (selectionStartOffset - 1); i >= 0; i--) {
const cc = allXml.charAt(i);
if (/\t/.test(cc)) {
tabCount++;
}
else if (/ /.test(cc)) {
spaceCount++;
}
else {
break;
}
}
if (options.insertSpaces) {
extFormattingOptions.initialIndentLevel = Math.ceil(spaceCount / (options.tabSize || 1));
}
else {
extFormattingOptions.initialIndentLevel = tabCount;
}
selectedXml = this.xmlFormatter.formatXml(selectedXml, extFormattingOptions);
// we need to remove the leading whitespace because the formatter will add an indent before the first element
selectedXml = selectedXml.replace(/^\s+/, "");
return [TextEdit.replace(range, selectedXml)];
}
}
================================================
FILE: src/formatting/xml-formatting-options.ts
================================================
import { EndOfLine, FormattingOptions, TextDocument } from "vscode";
import { Configuration } from "../common";
import * as constants from "../constants";
export interface XmlFormattingOptions {
editorOptions: FormattingOptions;
enforcePrettySelfClosingTagOnFormat: boolean;
newLine: string;
removeCommentsOnMinify: boolean;
splitAttributesOnFormat: boolean;
splitXmlnsOnFormat: boolean;
initialIndentLevel?: number;
}
export class XmlFormattingOptionsFactory {
static getXmlFormattingOptions(formattingOptions: FormattingOptions, document: TextDocument): XmlFormattingOptions {
return {
editorOptions: formattingOptions,
enforcePrettySelfClosingTagOnFormat: Configuration.enforcePrettySelfClosingTagOnFormat(document.uri),
newLine: (document.eol === EndOfLine.CRLF) ? "\r\n" : "\n",
removeCommentsOnMinify: Configuration.removeCommentsOnMinify(document.uri),
splitAttributesOnFormat: Configuration.splitAttributesOnFormat(document.uri),
splitXmlnsOnFormat: Configuration.splitXmlnsOnFormat(document.uri),
initialIndentLevel: 0
};
}
}
================================================
FILE: src/linting/index.ts
================================================
export * from "./xquery-linter";
================================================
FILE: src/linting/xquery-linter.ts
================================================
import { Diagnostic, DiagnosticSeverity, Position, Range } from "vscode";
const XQLint = require("xqlint").XQLint;
export class XQueryLinter {
static SEVERITY_WARNING = 1;
static SEVERITY_ERROR = 2;
lint(text: string): Diagnostic[] {
const linter = new XQLint(text);
const diagnostics = new Array<Diagnostic>();
linter.getErrors().forEach((error: any) => {
diagnostics.push(new Diagnostic(
new Range(
new Position(error.pos.sl, error.pos.sc),
new Position(error.pos.el, error.pos.ec)
),
error.message,
DiagnosticSeverity.Error
));
});
linter.getWarnings().forEach((warning: any) => {
diagnostics.push(new Diagnostic(
new Range(
new Position(warning.pos.sl, warning.pos.sc),
new Position(warning.pos.el, warning.pos.ec)
),
warning.message,
DiagnosticSeverity.Warning
));
});
return diagnostics;
}
}
================================================
FILE: src/test/extension.test.ts
================================================
import * as assert from "assert";
import { FormattingOptions } from "vscode";
import { TestDataLoader } from "./test-utils/test-data-loader";
import { XmlFormatter, XmlFormattingOptions } from "../formatting";
import { V2XmlFormatter } from "../formatting/formatters";
describe("V2XmlFormatter", () => {
const xmlFormatter = new V2XmlFormatter();
describe("#formatXml(xml, options)", () => {
const options = {
editorOptions: {
insertSpaces: true,
tabSize: 4
},
enforcePrettySelfClosingTagOnFormat: false,
newLine: "\r\n",
removeCommentsOnMinify: false,
splitAttributesOnFormat: false,
splitXmlnsOnFormat: true
};
it("should handle basic XML", () => {
testFormatter(xmlFormatter, options, "basic");
});
it("should handle unicode element names", () => {
testFormatter(xmlFormatter, options, "unicode");
});
it("should handle self-closing elements", () => {
testFormatter(xmlFormatter, options, "self-closing");
});
it("should handle text-only lines", () => {
testFormatter(xmlFormatter, options, "text-only-line");
});
it("should handle preformatted xml", () => {
testFormatter(xmlFormatter, options, "preformatted");
});
it("should preserve line breaks between elements", () => {
testFormatter(xmlFormatter, options, "preserve-breaks");
});
it("should maintain comment formatting", () => {
testFormatter(xmlFormatter, options, "maintain-comment-formatting");
});
it("should handle single-quotes in attributes", () => {
testFormatter(xmlFormatter, options, "single-quotes");
});
it("should not add extra line breaks before start tags", () => {
testFormatter(xmlFormatter, options, "issue-178");
});
it("should allow users to enforce space before self-closing tag slash", () => {
options.enforcePrettySelfClosingTagOnFormat = true;
testFormatter(xmlFormatter, options, "issue-149");
options.enforcePrettySelfClosingTagOnFormat = false;
});
it("should properly format closing tag after self-closing tag", () => {
testFormatter(xmlFormatter, options, "issue-185");
});
it("should support single quotes within double-quoptes attributes and vice-versa", () => {
testFormatter(xmlFormatter, options, "issue-187");
});
it("should not ruin attributes with unusual characters", () => {
testFormatter(xmlFormatter, options, "issue-189");
});
it("should not add extra line breaks before closing tags", () => {
testFormatter(xmlFormatter, options, "issue-193");
});
it("should not add extra whitespace before CDATA", () => {
testFormatter(xmlFormatter, options, "issue-194");
});
it("should support mixed content", () => {
testFormatter(xmlFormatter, options, "issue-200");
});
it("should not remove spaces between the node name and the first attribute within CDATA", () => {
testFormatter(xmlFormatter, options, "issue-227");
});
it("should handle mixed content as a child of another element", () => {
testFormatter(xmlFormatter, options, "issue-257");
});
it("should not touch CDATA content", () => {
testFormatter(xmlFormatter, options, "issue-293");
});
it("should not add trailing whitespace", () => {
testFormatter(xmlFormatter, options, "issue-288");
});
});
describe("#minifyXml(xml, options)", () => {
const options = {
editorOptions: {
insertSpaces: true,
tabSize: 4
},
enforcePrettySelfClosingTagOnFormat: false,
newLine: "\r\n",
removeCommentsOnMinify: false,
splitAttributesOnFormat: false,
splitXmlnsOnFormat: true
};
it("should preserve whitespace on minify if xml:space is set to 'preserve-whitespace'", () => {
testMinifier(xmlFormatter, options, "issue-262");
});
});
});
function testFormatter(xmlFormatter: XmlFormatter, options: XmlFormattingOptions, fileLabel: string): void {
const expectedFormattedXml = TestDataLoader.load(`${fileLabel}.formatted.xml`).replace(/\r/g, "");
const unformattedXml = TestDataLoader.load(`${fileLabel}.unformatted.xml`);
const actualFormattedXml = xmlFormatter.formatXml(unformattedXml, options).replace(/\r/g, "");
// tslint:disable-next-line
assert.ok((actualFormattedXml === expectedFormattedXml), `Actual formatted XML does not match expected formatted XML.\n\nACTUAL\n${actualFormattedXml.replace(/\s/g, "~ws~")}\n\nEXPECTED\n${expectedFormattedXml.replace(/\s/g, "~ws~")}`);
}
function testMinifier(xmlFormatter: XmlFormatter, options: XmlFormattingOptions, fileLabel: string): void {
const expectedMinifiedXml = TestDataLoader.load(`${fileLabel}.minified.xml`).replace(/\r/g, "");
const unminifiedXml = TestDataLoader.load(`${fileLabel}.unminified.xml`);
const actualMinifiedXml = xmlFormatter.minifyXml(unminifiedXml, options).replace(/\r/g, "");
// tslint:disable-next-line
assert.ok((actualMinifiedXml === expectedMinifiedXml), `Actual minified XML does not match expected minified XML.\n\nACTUAL\n${actualMinifiedXml.replace(/\s/g, "~ws~")}\n\nEXPECTED\n${expectedMinifiedXml.replace(/\s/g, "~ws~")}`);
}
================================================
FILE: src/test/test-data/basic.formatted.xml
================================================
<root>
<element>text</element>
</root>
================================================
FILE: src/test/test-data/basic.unformatted.xml
================================================
<root><element>text</element></root>
================================================
FILE: src/test/test-data/issue-149.formatted.xml
================================================
<root>
<entry>
<field1>One</field1>
<field2 />
<field3>Three</field3>
<field4 />
<field5>Five</field5>
</entry>
</root>
================================================
FILE: src/test/test-data/issue-149.unformatted.xml
================================================
<root><entry><field1>One</field1><field2/><field3>Three</field3><field4/><field5>Five</field5></entry></root>
================================================
FILE: src/test/test-data/issue-178.formatted.xml
================================================
<root>
<entry>
<field1>One</field1>
<field2/>
<field3>Three</field3>
<field4/>
<field5>Five</field5>
</entry>
</root>
================================================
FILE: src/test/test-data/issue-178.unformatted.xml
================================================
<root><entry><field1>One</field1><field2/><field3>Three</field3><field4/><field5>Five</field5></entry></root>
================================================
FILE: src/test/test-data/issue-185.formatted.xml
================================================
<test>
<example>
<one/>
</example>
</test>
================================================
FILE: src/test/test-data/issue-185.unformatted.xml
================================================
<test><example><one/></example></test>
================================================
FILE: src/test/test-data/issue-187.formatted.xml
================================================
<Project>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)'=='Release' ">
<DebugSymbols>false</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup Condition=" '$(Configuration)'=='Release' ">
<Content Remove="appsettings.Development.json" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)'=='Debug' ">
<Content Remove="appsettings.Production.json" />
</ItemGroup>
</Project>
================================================
FILE: src/test/test-data/issue-187.unformatted.xml
================================================
<Project>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)'=='Release' ">
<DebugSymbols>false</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup Condition=" '$(Configuration)'=='Release' ">
<Content Remove="appsettings.Development.json" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)'=='Debug' ">
<Content Remove="appsettings.Production.json" />
</ItemGroup>
</Project>
================================================
FILE: src/test/test-data/issue-189.formatted.xml
================================================
<!DOCTYPE xml>
<core:FragmentDefinition xmlns="sap.m"
xmlns:core="sap.ui.core">
<Text text="{parts: ['i18n>dialog.countdown.text','view>/Countdown'],formatter: 'jQuery.sap.formatMessage'}" />
</core:FragmentDefinition>
================================================
FILE: src/test/test-data/issue-189.unformatted.xml
================================================
<!DOCTYPE xml>
<core:FragmentDefinition xmlns="sap.m"
xmlns:core="sap.ui.core">
<Text text="{parts: ['i18n>dialog.countdown.text','view>/Countdown'],formatter: 'jQuery.sap.formatMessage'}" />
</core:FragmentDefinition>
================================================
FILE: src/test/test-data/issue-193.formatted.xml
================================================
<xsl:template name="btn-export-excel-pdf">
<div class="row">
<div class="col-md button-wrapper text-center">
<a class="btn btn-outline-info" role="button" href="javascript:template.printToPdf()" target="_blank">
<i class="far fa-file-pdf"> </i> Export to PDF
</a>  
<a class="btn btn-outline-info" role="button" href="javascript:template.exportToExcel()" target="_blank">
<i class="far fa-file-excel"> </i> Export to EXCEL
</a>
</div>
</div>
</xsl:template>
================================================
FILE: src/test/test-data/issue-193.unformatted.xml
================================================
<xsl:template name="btn-export-excel-pdf">
<div class="row">
<div class="col-md button-wrapper text-center">
<a class="btn btn-outline-info" role="button" href="javascript:template.printToPdf()" target="_blank">
<i class="far fa-file-pdf"> </i> Export to PDF
</a>  
<a class="btn btn-outline-info" role="button" href="javascript:template.exportToExcel()" target="_blank">
<i class="far fa-file-excel"> </i> Export to EXCEL
</a>
</div>
</div>
</xsl:template>
================================================
FILE: src/test/test-data/issue-194.formatted.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<madeup>
<some>
<element>This is ok</element>
<other><![CDATA[Here is my cdata]]></other>
</some>
</madeup>
================================================
FILE: src/test/test-data/issue-194.unformatted.xml
================================================
<?xml version="1.0" encoding="utf-8"?><madeup><some><element>This is ok</element><other><![CDATA[Here is my cdata]]></other></some></madeup>
================================================
FILE: src/test/test-data/issue-200.formatted.xml
================================================
<mixed>beginning text<inner>
<a>data</a>
<b>another data</b>
</inner>end text</mixed>
================================================
FILE: src/test/test-data/issue-200.unformatted.xml
================================================
<mixed>beginning text<inner><a>data</a><b>another data</b></inner>end text</mixed>
================================================
FILE: src/test/test-data/issue-227.formatted.xml
================================================
<Job>
<SQLQuery test="">
<SQLSelect Test="test" test="test">
<![CDATA[
select
*
from test
where
aaa.aaa='AAA' and
isnull(BBB.BBB,0)=0 and
isnull(CCTestC.CCC,0)=1 and
DDD.DDD is null and
exists (select 1 from EEE where EEE.EEE=EEE.EEE and EEE is null) and
exists (select 1 from FFF where FFF.FFF=FFF.FFF) and
'{GGG}' like '%'+GGG.GGG+'%'
]]>
</SQLSelect>
</SQLQuery>
</Job>
================================================
FILE: src/test/test-data/issue-227.unformatted.xml
================================================
<Job>
<SQLQuery test="">
<SQLSelect Test="test" test="test">
<![CDATA[
select
*
from test
where
aaa.aaa='AAA' and
isnull(BBB.BBB,0)=0 and
isnull(CCTestC.CCC,0)=1 and
DDD.DDD is null and
exists (select 1 from EEE where EEE.EEE=EEE.EEE and EEE is null) and
exists (select 1 from FFF where FFF.FFF=FFF.FFF) and
'{GGG}' like '%'+GGG.GGG+'%'
]]>
</SQLSelect>
</SQLQuery>
</Job>
================================================
FILE: src/test/test-data/issue-257.formatted.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<file>
<xsl:apply-templates />
</file>
</xsl:template>
<xsl:template match="*">
<xsl:message terminate="no">
WARNING: Unmatched element: <xsl:value-of select="name()"/>
</xsl:message>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
================================================
FILE: src/test/test-data/issue-257.unformatted.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<file>
<xsl:apply-templates />
</file>
</xsl:template>
<xsl:template match="*">
<xsl:message terminate="no">
WARNING: Unmatched element: <xsl:value-of select="name()"/>
</xsl:message>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
================================================
FILE: src/test/test-data/issue-262.minified.xml
================================================
<tests><test>1.
2.
3.
4.</test><test xml:space="preserve">1.
2.
3.
4.</test><test>1. 2. 3. 4.</test><test xml:space="preserve">1.
2.
3.
4.</test></tests>
================================================
FILE: src/test/test-data/issue-262.unminified.xml
================================================
<tests>
<test>1.
2.
3.
4.</test>
<test xml:space="preserve">1.
2.
3.
4.</test>
<test>1.
2.
3.
4.</test>
<test xml:space="preserve">1.
2.
3.
4.</test>
</tests>
================================================
FILE: src/test/test-data/issue-288.formatted.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
xmlns:admin="http://webns.net/mvcb/">
</rdf:RDF>
================================================
FILE: src/test/test-data/issue-288.unformatted.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
xmlns:admin="http://webns.net/mvcb/">
</rdf:RDF>
================================================
FILE: src/test/test-data/issue-293.formatted.xml
================================================
<xml>
<element><![CDATA[asdf]]></element>
<element><![CDATA[<secondXml>
<formattedNode>val</formattedNode>
</secondXml>]]></element>
</xml>
================================================
FILE: src/test/test-data/issue-293.unformatted.xml
================================================
<xml>
<element><![CDATA[asdf]]></element>
<element><![CDATA[<secondXml>
<formattedNode>val</formattedNode>
</secondXml>]]></element>
</xml>
================================================
FILE: src/test/test-data/maintain-comment-formatting.formatted.xml
================================================
<root>
<element>text</element>
<!--
<Description>
Any description.
</Description>
<Keyword UUID="fd8e6b13-9865-4d8c-9ecd-5ff08a0cf2e2"/>
<Parameters>
<Parameter Name="ParameterName1">The Parameter Name.</Parameter>
<Parameter Name="ParameterName2" PossibleValues="Val1,Val2" DefaultValue="Val1"/>
</Parameters>
-->
</root>
================================================
FILE: src/test/test-data/maintain-comment-formatting.unformatted.xml
================================================
<root>
<element>text</element>
<!--
<Description>
Any description.
</Description>
<Keyword UUID="fd8e6b13-9865-4d8c-9ecd-5ff08a0cf2e2"/>
<Parameters>
<Parameter Name="ParameterName1">The Parameter Name.</Parameter>
<Parameter Name="ParameterName2" PossibleValues="Val1,Val2" DefaultValue="Val1"/>
</Parameters>
-->
</root>
================================================
FILE: src/test/test-data/preformatted.formatted.xml
================================================
<root>
<element>text</element>
<element>text</element>
<element>text</element>
<element>text</element>
<element>
<element2>text</element2>
</element2>
</root>
================================================
FILE: src/test/test-data/preformatted.unformatted.xml
================================================
<root>
<element>text</element>
<element>text</element>
<element>text</element>
<element>text</element>
<element>
<element2>text</element2>
</element2>
</root>
================================================
FILE: src/test/test-data/preserve-breaks.formatted.xml
================================================
<root>
<element>text</element>
<element>text</element>
<element>text</element>
<element>text</element>
<element>
<element2>text</element2>
</element2>
</root>
================================================
FILE: src/test/test-data/preserve-breaks.unformatted.xml
================================================
<root>
<element>text</element>
<element>text</element>
<element>text</element>
<element>text</element>
<element>
<element2>text</element2>
</element2>
</root>
================================================
FILE: src/test/test-data/self-closing.formatted.xml
================================================
<Node>
<Node name="testChild"/>
</Node>
================================================
FILE: src/test/test-data/self-closing.unformatted.xml
================================================
<Node><Node name="testChild"/></Node>
================================================
FILE: src/test/test-data/single-quotes.formatted.xml
================================================
<root>
<element attr='1' />
<element attr='2' />
</root>
================================================
FILE: src/test/test-data/single-quotes.unformatted.xml
================================================
<root>
<element attr='1' />
<element attr='2' />
</root>
================================================
FILE: src/test/test-data/text-only-line.formatted.xml
================================================
<Tag>
<Tag2>
Text1
Text2
</Tag2>
</Tag>
================================================
FILE: src/test/test-data/text-only-line.unformatted.xml
================================================
<Tag>
<Tag2>
Text1
Text2
</Tag2>
</Tag>
================================================
FILE: src/test/test-data/unicode.formatted.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Имя>
<element>text</element>
</Имя>
================================================
FILE: src/test/test-data/unicode.unformatted.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Имя><element>text</element></Имя>
================================================
FILE: src/test/test-utils/test-data-loader.ts
================================================
import * as fs from "fs";
export class TestDataLoader {
static load(fileName: string): string {
return fs.readFileSync(`${__dirname}/../../../src/test/test-data/${fileName}`, "UTF-8");
}
}
================================================
FILE: src/tree-view/index.ts
================================================
export * from "./xml-tree-data-provider";
================================================
FILE: src/tree-view/xml-tree-data-provider.ts
================================================
import { window, workspace } from "vscode";
import {
Event, EventEmitter, ExtensionContext, Position, TextEditor, TreeDataProvider,
TreeItem, TreeItemCollapsibleState
} from "vscode";
import * as path from "path";
import { DOMParser } from "xmldom";
import { Configuration, NativeCommands, XmlTraverser } from "../common";
import * as constants from "../constants";
export class XmlTreeDataProvider implements TreeDataProvider<any> {
private _onDidChangeTreeData: EventEmitter<any> = new EventEmitter<any>();
private _xmlDocument: Document;
private _xmlTraverser: XmlTraverser;
constructor(private _context: ExtensionContext) {
window.onDidChangeActiveTextEditor(() => {
this._refreshTree();
});
workspace.onDidChangeTextDocument(() => {
this._refreshTree();
});
this._refreshTree();
}
onDidChangeTreeData = this._onDidChangeTreeData.event;
get activeEditor(): TextEditor {
return window.activeTextEditor || null;
}
getTreeItem(element: Node): TreeItem | Thenable<TreeItem> {
const enableMetadata = Configuration.enableXmlTreeViewMetadata;
const enableSync = Configuration.enableXmlTreeViewCursorSync;
const treeItem = new TreeItem(element.localName);
if (!this._xmlTraverser.isElement(element)) {
treeItem.label = `${element.localName} = "${element.nodeValue}"`;
}
else if (enableMetadata) {
const childAttributes = this._xmlTraverser.getChildAttributeArray(<Element>element);
const childElements = this._xmlTraverser.getChildElementArray(<Element>element);
const totalChildren = (childAttributes.length + childElements.length);
if (totalChildren > 0) {
treeItem.label += " (";
if (childAttributes.length > 0) {
treeItem.label += `attributes: ${childAttributes.length}, `;
treeItem.collapsibleState = TreeItemCollapsibleState.Collapsed;
}
if (childElements.length > 0) {
treeItem.label += `children: ${childElements.length}, `;
treeItem.collapsibleState = TreeItemCollapsibleState.Collapsed;
}
treeItem.label = treeItem.label.substr(0, treeItem.label.length - 2);
treeItem.label += ")";
}
if (this._xmlTraverser.hasSimilarSiblings(<Element>element) && enableSync) {
treeItem.label += ` [line ${(element as any).lineNumber}]`;
}
}
treeItem.command = {
command: constants.nativeCommands.revealLine,
title: "",
arguments: [{
lineNumber: (element as any).lineNumber - 1,
at: "top"
}]
};
treeItem.iconPath = this._getIcon(element);
return treeItem;
}
getChildren(element?: Node): Node[] | Thenable<Node[]> {
if (!this._xmlDocument) {
this._refreshTree();
}
if (this._xmlTraverser.isElement(element)) {
return [].concat(this._xmlTraverser.getChildAttributeArray(<Element>element), this._xmlTraverser.getChildElementArray(<Element>element));
}
else if (this._xmlDocument) {
return [this._xmlDocument.lastChild];
}
else {
return [];
}
}
getParent(element: Node): Node {
if ((!element || !element.parentNode || !element.parentNode.parentNode) && !(element as any).ownerElement) {
return undefined;
}
return element.parentNode || (element as any).ownerElement;
}
getNodeAtPosition(position: Position): Node {
return this._xmlTraverser.getNodeAtPosition(position);
}
private _getIcon(element: Node): any {
let type = "element";
if (!this._xmlTraverser.isElement(element)) {
type = "attribute";
}
const icon = {
dark: this._context.asAbsolutePath(path.join("resources", "icons", `${type}.dark.svg`)),
light: this._context.asAbsolutePath(path.join("resources", "icons", `${type}.light.svg`))
};
return icon;
}
private _refreshTree(): void {
if (!this.activeEditor || this.activeEditor.document.languageId !== constants.languageIds.xml) {
NativeCommands.setContext(constants.contextKeys.xmlTreeViewEnabled, false);
this._xmlDocument = null;
this._onDidChangeTreeData.fire();
return;
}
const enableTreeView = Configuration.enableXmlTreeView;
NativeCommands.setContext(constants.contextKeys.xmlTreeViewEnabled, enableTreeView);
const xml = this.activeEditor.document.getText();
try {
this._xmlDocument = new DOMParser({
errorHandler: () => {
throw new Error("Invalid Document");
},
locator: {}
}).parseFromString(xml, "text/xml");
}
catch {
this._xmlDocument = new DOMParser().parseFromString("<InvalidDocument />", "text/xml");
}
finally {
this._xmlTraverser = this._xmlTraverser || new XmlTraverser(this._xmlDocument);
this._xmlTraverser.xmlDocument = this._xmlDocument;
}
this._onDidChangeTreeData.fire();
}
}
================================================
FILE: src/xpath/commands/evaluateXPath.ts
================================================
import { window } from "vscode";
import { TextEditor, TextEditorEdit, ViewColumn } from "vscode";
import { Configuration, ExtensionState } from "../../common";
import * as constants from "../../constants";
import { EvaluatorResult, EvaluatorResultType, XPathEvaluator } from "../xpath-evaluator";
class HistoricQuery {
constructor(uri: string, query: string) {
this.uri = uri;
this.query = query;
}
uri: string;
query: string;
}
export async function evaluateXPath(editor: TextEditor, edit: TextEditorEdit): Promise<void> {
// if there is no workspace, we will track queries in the global Memento
const memento = ExtensionState.workspace || ExtensionState.global;
// get the xpath persistence setting
const persistQueries = Configuration.persistXPathQuery;
// get the last query if there is one for this document
// if not, try pulling the last query ran, regardless of document
// NOTE: if the user has focus on the output channel when opening the xquery prompt, the channel is the "active" document
const history = memento.get<HistoricQuery[]>(constants.stateKeys.xpathQueryHistory, new Array<HistoricQuery>());
const globalLastQuery = memento.get<string>(constants.stateKeys.xPathQueryLast, "");
const lastQuery = history.find(x => {
return (x.uri === editor.document.uri.toString());
});
// set the inital display value and prompt the user
let query = (lastQuery) ? lastQuery.query : globalLastQuery;
query = await window.showInputBox({
placeHolder: "XPath Query",
prompt: "Please enter an XPath query to evaluate.",
value: query
});
// showInputBox() will return undefined if the user dimissed the prompt
if (!query) {
return;
}
const ignoreDefaultNamespace = Configuration.ignoreDefaultNamespace;
// run the query
const xml = editor.document.getText();
let evalResult: EvaluatorResult;
try {
evalResult = XPathEvaluator.evaluate(query, xml, ignoreDefaultNamespace);
}
catch (error) {
console.error(error);
window.showErrorMessage(`Something went wrong while evaluating the XPath: ${error}`);
return;
}
// show the results to the user
const outputChannel = window.createOutputChannel("XPath Results");
outputChannel.clear();
outputChannel.appendLine(`XPath Query: ${query}`);
outputChannel.append("\n");
if (evalResult.type === EvaluatorResultType.NODE_COLLECTION) {
(evalResult.result as Node[]).forEach((node: any) => {
outputChannel.appendLine(`[Line ${node.lineNumber}] ${node.localName}: ${node.textContent}`);
});
}
else {
outputChannel.appendLine(`[Result]: ${evalResult.result}`);
}
outputChannel.show(false);
if (persistQueries) {
const historicQuery = new HistoricQuery(editor.document.uri.toString(), query);
const affectedIndex = history.findIndex(x => x.uri === historicQuery.uri);
if (affectedIndex === -1) {
history.push(historicQuery);
}
else {
history[affectedIndex].query = query;
}
memento.update(constants.stateKeys.xpathQueryHistory, history);
memento.update(constants.stateKeys.xPathQueryLast, query);
}
}
================================================
FILE: src/xpath/commands/getCurrentXPath.ts
================================================
import { window } from "vscode";
import { TextEditor, TextEditorEdit } from "vscode";
import { DOMParser } from "xmldom";
import { XPathBuilder } from "../xpath-builder";
export function getCurrentXPath(editor: TextEditor, edit: TextEditorEdit): void {
if (!editor.selection) {
window.showInformationMessage("Please put your cursor in an element or attribute name.");
return;
}
const document = new DOMParser().parseFromString(editor.document.getText());
const xpath = new XPathBuilder(document).build(editor.selection.start);
window.showInputBox({
value: xpath,
valueSelection: undefined
});
}
================================================
FILE: src/xpath/commands/index.ts
================================================
export * from "./evaluateXPath";
export * from "./getCurrentXPath";
================================================
FILE: src/xpath/index.ts
================================================
export * from "./xpath-builder";
export * from "./xpath-evaluator";
================================================
FILE: src/xpath/xpath-builder.ts
================================================
import { Position } from "vscode";
import { DOMParser } from "xmldom";
import { XmlTraverser } from "../common";
export class XPathBuilder {
private _xmlTraverser: XmlTraverser;
constructor(private _xmlDocument: Document) {
this._xmlTraverser = new XmlTraverser(this._xmlDocument);
}
build(position: Position): string {
const selectedNode = this._xmlTraverser.getNodeAtPosition(position);
return this._buildCore(selectedNode);
}
private _buildCore(selectedNode: Node): string {
if (selectedNode === this._xmlDocument.documentElement) {
return `/${selectedNode.nodeName}`;
}
if (!this._xmlTraverser.isElement(selectedNode)) {
return `${this._buildCore((selectedNode as any).ownerElement)}/@${selectedNode.nodeName}`;
}
else if (this._xmlTraverser.hasSimilarSiblings(selectedNode)) {
const siblings = this._xmlTraverser.getSiblings(selectedNode);
const xPathIndex = (siblings.indexOf(selectedNode) + 1);
return `${this._buildCore(selectedNode.parentNode)}/${selectedNode.nodeName}[${xPathIndex}]`;
}
else {
return `${this._buildCore(selectedNode.parentNode)}/${selectedNode.nodeName}`;
}
}
}
================================================
FILE: src/xpath/xpath-evaluator.ts
================================================
import * as xpath from "xpath";
import { SelectedValue, XPathSelect } from "xpath";
import { DOMParser } from "xmldom";
export class EvaluatorResult {
type: EvaluatorResultType;
result: Node[] | number | string | boolean;
}
export class EvaluatorResultType {
static SCALAR_TYPE = 0;
static NODE_COLLECTION = 1;
}
export class XPathResultTypes {
static ANY_TYPE = 0;
static NUMBER_TYPE = 1;
static STRING_TYPE = 2;
static BOOLEAN_TYPE = 3;
static UNORDERED_NODE_ITERATOR_TYPE = 4;
static ORDERED_NODE_ITERATOR_TYPE = 5;
static UNORDERED_NODE_SNAPSHOT_TYPE = 6;
static ORDERED_NODE_SNAPSHOT_TYPE = 7;
static ANY_UNORDERED_NODE_TYPE = 8;
static FIRST_ORDERED_NODE_TYPE = 9;
}
export class XPathEvaluator {
static evaluate(query: string, xml: string, ignoreDefaultNamespace: boolean): EvaluatorResult {
if (ignoreDefaultNamespace) {
xml = xml.replace(/xmlns=".+"/g, (match: string) => {
return match.replace(/xmlns/g, "xmlns:default");
});
}
const nodes = new Array<Node>();
const xdoc: Document = new DOMParser().parseFromString(xml, "text/xml");
const resolver = (xpath as any).createNSResolver(xdoc);
const xPathResult = xpath.evaluate(query, xdoc, resolver, 0, null);
const evaluatorResult = new EvaluatorResult();
evaluatorResult.type = EvaluatorResultType.SCALAR_TYPE;
switch (xPathResult.resultType) {
case XPathResultTypes.NUMBER_TYPE:
evaluatorResult.result = xPathResult.numberValue;
break;
case XPathResultTypes.STRING_TYPE:
evaluatorResult.result = xPathResult.stringValue;
break;
case XPathResultTypes.BOOLEAN_TYPE:
evaluatorResult.result = xPathResult.booleanValue;
break;
case XPathResultTypes.UNORDERED_NODE_ITERATOR_TYPE:
case XPathResultTypes.ORDERED_NODE_ITERATOR_TYPE:
evaluatorResult.result = xPathResult.booleanValue;
let node: Node;
while (node = xPathResult.iterateNext()) {
nodes.push(node);
}
evaluatorResult.result = nodes;
evaluatorResult.type = EvaluatorResultType.NODE_COLLECTION;
break;
}
return evaluatorResult;
}
}
================================================
FILE: src/xquery-execution/child-process.ts
================================================
const child_process = require("child_process");
export class ChildProcess {
static async spawn(executable: string, args: string[]): Promise<void> {
return new Promise<void>((resolve, reject) => {
let output = "";
const handle = child_process.spawn(executable, args);
handle.stdout.on("data", (data: string) => {
output += data;
});
handle.stderr.on("data", (data: string) => {
output += data;
});
handle.on("close", (code: string) => {
if (code === "0") {
resolve();
}
else {
reject({ code: code, message: output });
}
});
});
}
}
================================================
FILE: src/xquery-execution/commands/executeXQuery.ts
================================================
import { window, workspace } from "vscode";
import { Disposable, Range, TextEditor, TextEditorEdit, Uri } from "vscode";
import * as constants from "../../constants";
import { ChildProcess } from "../child-process";
import { Configuration, NativeCommands } from "../../common";
export async function executeXQuery(editor: TextEditor, edit: TextEditorEdit): Promise<void> {
// this disposable will be used for creating status bar messages
let disposable: Disposable;
if (editor.document.languageId !== constants.languageIds.xquery) {
window.showErrorMessage("This action can only be performed on an XQuery file.");
return;
}
const executable = Configuration.xqueryExecutionEngine;
let args = Configuration.xqueryExecutionArguments || [];
if (!executable || executable === "") {
const action = await window.showWarningMessage("An XQuery execution engine has not been defined.", "Define Now");
if (action === "Define Now") {
NativeCommands.openGlobalSettings();
}
return;
}
let inputFile: Uri;
disposable = window.setStatusBarMessage("Searching for XML files in folder...");
const searchPattern = Configuration.xqueryExecutionInputSearchPattern;
const inputLimit = Configuration.xqueryExecutionInputLimit;
const files = await workspace.findFiles(searchPattern, "", inputLimit);
disposable.dispose();
// user does not have a folder open - prompt for file name
if (typeof files === "undefined") {
window.showErrorMessage("You must have a folder opened in VS Code to use this feature.");
return;
}
// if there is only one XML file, default it
// otherwise, prompt the user to select one from the open folder
if (files.length > 1) {
const qpItems = new Array<any>();
files.forEach((file) => {
const filename = file.fsPath.replace("\\", "/");
qpItems.push({ // must implement vscode.QuickPickItem
label: filename.substring(filename.lastIndexOf("/") + 1),
description: file.fsPath,
file: file
});
});
const selection = await window.showQuickPick(qpItems, { placeHolder: "Please select an input file." });
if (!selection) {
return;
}
inputFile = selection.file;
}
else {
inputFile = files[0];
}
// prompt for output file name
let outputPath: string = null;
let outputPathPos = -1;
for (let i = 0; i < args.length; i++) {
if (i > 0) {
if (args[i].search(/out|result/) !== -1) {
outputPath = args[i];
outputPathPos = i;
}
}
}
if (outputPath) {
outputPath = await window.showInputBox({
placeHolder: "ex. C:\\TEMP\XQueryOutput\\MyOutputFile.xml",
prompt: "Please specify the output file path. Existing file behavior is determined by the execution engine you have specified.",
value: outputPath
});
args[outputPathPos] = outputPath;
}
// call out to the execution engine
disposable = window.setStatusBarMessage("Executing XQuery Script...");
args = args.map<string>((value: string) => {
return value
.replace("$(script)", editor.document.uri.fsPath)
.replace("$(input)", inputFile.fsPath)
.replace("$(project)", (workspace.workspaceFolders) ? workspace.workspaceFolders[0].uri.fsPath : "");
});
try {
await ChildProcess.spawn(executable, args);
}
catch (error) {
if (error.message.search(/[Ll]ine:?\s*\d+/gm) > -1) {
const match: RegExpExecArray = /[Ll]ine:?\s*\d+/gm.exec(error.message);
const line: number = (Number.parseInt(match[0].replace(/([Ll]ine:?\s*)|\s/, "")) - 1);
const selection: string = await window.showErrorMessage(error.message, `Go to Line ${line}`);
if (selection === `Go to Line ${line}`) {
editor.revealRange(new Range(line, 0, line, 0));
}
}
else {
window.showErrorMessage(error.message);
}
}
finally {
disposable.dispose();
}
}
================================================
FILE: src/xquery-execution/commands/index.ts
================================================
export * from "./executeXQuery";
================================================
FILE: src/xquery-execution/index.ts
================================================
export * from "./child-process";
================================================
FILE: tsconfig.json
================================================
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "out",
"lib": [
"dom",
"es6"
],
"sourceMap": true,
"rootDir": "src",
"strict": true,
"strictNullChecks": false
},
"exclude": [
"node_modules",
".vscode-test"
]
}
================================================
FILE: tslint.json
================================================
{
"rules": {
"arrow-return-shorthand": true,
"callable-types": true,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"deprecation": {
"severity": "warn"
},
"eofline": true,
"forin": true,
"import-blacklist": [
true,
"rxjs",
"rxjs/Rx"
],
"import-spacing": true,
"indent": [
true,
"spaces",
4
],
"interface-over-type-literal": true,
"label-position": true,
"max-line-length": [
true,
165
],
"member-access": false,
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-super": true,
"no-empty": false,
"no-empty-interface": true,
"no-eval": true,
"no-inferrable-types": [
true,
"ignore-params"
],
"no-misused-new": true,
"no-non-null-assertion": true,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unnecessary-initializer": true,
"no-unused-expression": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"prefer-const": true,
"quotemark": [
true,
"double"
],
"radix": true,
"semicolon": [
true,
"always"
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"unified-signatures": true,
"variable-name": false,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}
gitextract_05bouxhz/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report.md │ │ ├── feature-request.md │ │ └── xml-formatter.md │ └── workflows/ │ ├── release.yml │ └── test.yml ├── .gitignore ├── .vscode/ │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── languages/ │ └── xquery/ │ ├── xquery.json │ └── xquery.tmLanguage ├── package.json ├── src/ │ ├── common/ │ │ ├── configuration.ts │ │ ├── create-document-selector.ts │ │ ├── extension-state.ts │ │ ├── index.ts │ │ ├── native-commands.ts │ │ └── xml-traverser.ts │ ├── completion/ │ │ ├── index.ts │ │ └── xquery-completion-item-provider.ts │ ├── constants.ts │ ├── extension.ts │ ├── formatting/ │ │ ├── commands/ │ │ │ ├── formatAsXml.ts │ │ │ ├── index.ts │ │ │ ├── minifyXml.ts │ │ │ ├── textToXml.ts │ │ │ └── xmlToText.ts │ │ ├── formatters/ │ │ │ ├── classic-xml-formatter.ts │ │ │ ├── index.ts │ │ │ └── v2-xml-formatter.ts │ │ ├── index.ts │ │ ├── xml-formatter.ts │ │ ├── xml-formatting-edit-provider.ts │ │ └── xml-formatting-options.ts │ ├── linting/ │ │ ├── index.ts │ │ └── xquery-linter.ts │ ├── test/ │ │ ├── extension.test.ts │ │ ├── test-data/ │ │ │ ├── basic.formatted.xml │ │ │ ├── basic.unformatted.xml │ │ │ ├── issue-149.formatted.xml │ │ │ ├── issue-149.unformatted.xml │ │ │ ├── issue-178.formatted.xml │ │ │ ├── issue-178.unformatted.xml │ │ │ ├── issue-185.formatted.xml │ │ │ ├── issue-185.unformatted.xml │ │ │ ├── issue-187.formatted.xml │ │ │ ├── issue-187.unformatted.xml │ │ │ ├── issue-189.formatted.xml │ │ │ ├── issue-189.unformatted.xml │ │ │ ├── issue-193.formatted.xml │ │ │ ├── issue-193.unformatted.xml │ │ │ ├── issue-194.formatted.xml │ │ │ ├── issue-194.unformatted.xml │ │ │ ├── issue-200.formatted.xml │ │ │ ├── issue-200.unformatted.xml │ │ │ ├── issue-227.formatted.xml │ │ │ ├── issue-227.unformatted.xml │ │ │ ├── issue-257.formatted.xml │ │ │ ├── issue-257.unformatted.xml │ │ │ ├── issue-262.minified.xml │ │ │ ├── issue-262.unminified.xml │ │ │ ├── issue-288.formatted.xml │ │ │ ├── issue-288.unformatted.xml │ │ │ ├── issue-293.formatted.xml │ │ │ ├── issue-293.unformatted.xml │ │ │ ├── maintain-comment-formatting.formatted.xml │ │ │ ├── maintain-comment-formatting.unformatted.xml │ │ │ ├── preformatted.formatted.xml │ │ │ ├── preformatted.unformatted.xml │ │ │ ├── preserve-breaks.formatted.xml │ │ │ ├── preserve-breaks.unformatted.xml │ │ │ ├── self-closing.formatted.xml │ │ │ ├── self-closing.unformatted.xml │ │ │ ├── single-quotes.formatted.xml │ │ │ ├── single-quotes.unformatted.xml │ │ │ ├── text-only-line.formatted.xml │ │ │ ├── text-only-line.unformatted.xml │ │ │ ├── unicode.formatted.xml │ │ │ └── unicode.unformatted.xml │ │ └── test-utils/ │ │ └── test-data-loader.ts │ ├── tree-view/ │ │ ├── index.ts │ │ └── xml-tree-data-provider.ts │ ├── xpath/ │ │ ├── commands/ │ │ │ ├── evaluateXPath.ts │ │ │ ├── getCurrentXPath.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── xpath-builder.ts │ │ └── xpath-evaluator.ts │ └── xquery-execution/ │ ├── child-process.ts │ ├── commands/ │ │ ├── executeXQuery.ts │ │ └── index.ts │ └── index.ts ├── tsconfig.json └── tslint.json
SYMBOL INDEX (109 symbols across 26 files)
FILE: src/common/configuration.ts
class Configuration (line 5) | class Configuration {
method enableXmlTreeView (line 6) | static get enableXmlTreeView(): boolean {
method enableXmlTreeViewMetadata (line 10) | static get enableXmlTreeViewMetadata(): boolean {
method enableXmlTreeViewCursorSync (line 14) | static get enableXmlTreeViewCursorSync(): boolean {
method ignoreDefaultNamespace (line 18) | static get ignoreDefaultNamespace(): boolean {
method persistXPathQuery (line 22) | static get persistXPathQuery(): boolean {
method xmlFormatterImplementation (line 26) | static get xmlFormatterImplementation(): string {
method xqueryExecutionArguments (line 30) | static get xqueryExecutionArguments(): string[] {
method xqueryExecutionEngine (line 34) | static get xqueryExecutionEngine(): string {
method xqueryExecutionInputLimit (line 38) | static get xqueryExecutionInputLimit(): number {
method xqueryExecutionInputSearchPattern (line 42) | static get xqueryExecutionInputSearchPattern(): string {
method enforcePrettySelfClosingTagOnFormat (line 46) | static enforcePrettySelfClosingTagOnFormat(resource: Uri): boolean {
method removeCommentsOnMinify (line 50) | static removeCommentsOnMinify(resource: Uri): boolean {
method splitAttributesOnFormat (line 54) | static splitAttributesOnFormat(resource: Uri): boolean {
method splitXmlnsOnFormat (line 58) | static splitXmlnsOnFormat(resource: Uri): boolean {
method _getForResource (line 62) | private static _getForResource<T>(section: string, resource: Uri): T {
method _getForWindow (line 66) | private static _getForWindow<T>(section: string): T {
FILE: src/common/create-document-selector.ts
function createDocumentSelector (line 5) | function createDocumentSelector(language: string): DocumentFilter[] {
FILE: src/common/extension-state.ts
class ExtensionState (line 3) | class ExtensionState {
method global (line 6) | static get global(): Memento {
method workspace (line 10) | static get workspace(): Memento {
method configure (line 14) | static configure(context: ExtensionContext): void {
FILE: src/common/native-commands.ts
class NativeCommands (line 3) | class NativeCommands {
method cursorMove (line 4) | static async cursorMove(to: string, by: string): Promise<void> {
method openGlobalSettings (line 11) | static openGlobalSettings(): void {
method setContext (line 15) | static setContext(key: string, value: any): void {
FILE: src/common/xml-traverser.ts
class XmlTraverser (line 4) | class XmlTraverser {
method constructor (line 6) | constructor(private _xmlDocument: Document) { }
method xmlDocument (line 8) | get xmlDocument(): Document {
method xmlDocument (line 12) | set xmlDocument(value: Document) {
method getChildAttributeArray (line 16) | getChildAttributeArray(node: Element): any[] {
method getChildElementArray (line 30) | getChildElementArray(node: Node): any[] {
method getElementAtPosition (line 48) | getElementAtPosition(position: Position): Element {
method getNearestElementAncestor (line 54) | getNearestElementAncestor(node: Node): Element {
method getNodeAtPosition (line 62) | getNodeAtPosition(position: Position): Node {
method getSiblings (line 66) | getSiblings(node: Node): Node[] {
method getSiblingAttributes (line 74) | getSiblingAttributes(node: Node): Node[] {
method getSiblingElements (line 78) | getSiblingElements(node: Node): Node[] {
method hasSimilarSiblings (line 82) | hasSimilarSiblings(node: Node): boolean {
method isElement (line 92) | isElement(node: Node): boolean {
method _getNodeAtPositionCore (line 96) | private _getNodeAtPositionCore(position: Position, contextNode: Node):...
method _checkRange (line 143) | private _checkRange(lineNumber: number, position: Position, columnRang...
method _getNodeWidthInCharacters (line 147) | private _getNodeWidthInCharacters(node: Node) {
FILE: src/completion/xquery-completion-item-provider.ts
class XQueryCompletionItemProvider (line 5) | class XQueryCompletionItemProvider implements CompletionItemProvider {
method provideCompletionItems (line 7) | provideCompletionItems(document: TextDocument, position: Position): Co...
method _getCompletionItem (line 18) | private _getCompletionItem(xqLintCompletionItem: any): CompletionItem {
FILE: src/extension.ts
function activate (line 19) | function activate(context: ExtensionContext) {
function deactivate (line 80) | function deactivate() {
function _handleContextChange (line 85) | function _handleContextChange(editor: TextEditor): void {
function _handleChangeActiveTextEditor (line 99) | function _handleChangeActiveTextEditor(editor: TextEditor): void {
function _handleChangeTextEditorSelection (line 103) | function _handleChangeTextEditorSelection(e: TextEditorSelectionChangeEv...
FILE: src/formatting/commands/formatAsXml.ts
function formatAsXml (line 11) | function formatAsXml(editor: TextEditor, edit: TextEditorEdit): void {
FILE: src/formatting/commands/minifyXml.ts
function minifyXml (line 10) | function minifyXml(editor: TextEditor, edit: TextEditorEdit): void {
FILE: src/formatting/commands/textToXml.ts
function textToXml (line 11) | function textToXml(textEditor: TextEditor): void {
FILE: src/formatting/commands/xmlToText.ts
function xmlToText (line 11) | function xmlToText(textEditor: TextEditor): void {
FILE: src/formatting/formatters/classic-xml-formatter.ts
class ClassicXmlFormatter (line 4) | class ClassicXmlFormatter implements XmlFormatter {
method formatXml (line 6) | formatXml(xml: string, options: XmlFormattingOptions): string {
method minifyXml (line 68) | minifyXml(xml: string, options: XmlFormattingOptions): string {
method _getIndent (line 82) | private _getIndent(options: XmlFormattingOptions, level: number, trail...
method _stripLineBreaks (line 93) | private _stripLineBreaks(options: XmlFormattingOptions, xml: string): ...
FILE: src/formatting/formatters/v2-xml-formatter.ts
class V2XmlFormatter (line 8) | class V2XmlFormatter implements XmlFormatter {
method formatXml (line 9) | formatXml(xml: string, options: XmlFormattingOptions): string {
method minifyXml (line 293) | minifyXml(xml: string, options: XmlFormattingOptions): string {
method _getIndent (line 297) | private _getIndent(options: XmlFormattingOptions, indentLevel: number)...
method _removeTrailingNonBreakingWhitespace (line 301) | private _removeTrailingNonBreakingWhitespace(text: string): string {
method _sanitizeCommentsAndCDATA (line 305) | private _sanitizeCommentsAndCDATA(xml: string): string {
method _unsanitizeCommentsAndCDATA (line 341) | private _unsanitizeCommentsAndCDATA(xml: string): string {
type Location (line 346) | enum Location {
FILE: src/formatting/xml-formatter.ts
type XmlFormatter (line 10) | interface XmlFormatter {
class XmlFormatterFactory (line 15) | class XmlFormatterFactory {
method getXmlFormatter (line 18) | static getXmlFormatter(): XmlFormatter {
FILE: src/formatting/xml-formatting-edit-provider.ts
class XmlFormattingEditProvider (line 11) | class XmlFormattingEditProvider implements DocumentFormattingEditProvide...
method constructor (line 13) | constructor(
method provideDocumentFormattingEdits (line 17) | provideDocumentFormattingEdits(document: TextDocument, options: Format...
method provideDocumentRangeFormattingEdits (line 24) | provideDocumentRangeFormattingEdits(document: TextDocument, range: Ran...
FILE: src/formatting/xml-formatting-options.ts
type XmlFormattingOptions (line 6) | interface XmlFormattingOptions {
class XmlFormattingOptionsFactory (line 16) | class XmlFormattingOptionsFactory {
method getXmlFormattingOptions (line 17) | static getXmlFormattingOptions(formattingOptions: FormattingOptions, d...
FILE: src/linting/xquery-linter.ts
class XQueryLinter (line 5) | class XQueryLinter {
method lint (line 9) | lint(text: string): Diagnostic[] {
FILE: src/test/extension.test.ts
function testFormatter (line 134) | function testFormatter(xmlFormatter: XmlFormatter, options: XmlFormattin...
function testMinifier (line 144) | function testMinifier(xmlFormatter: XmlFormatter, options: XmlFormatting...
FILE: src/test/test-utils/test-data-loader.ts
class TestDataLoader (line 3) | class TestDataLoader {
method load (line 4) | static load(fileName: string): string {
FILE: src/tree-view/xml-tree-data-provider.ts
class XmlTreeDataProvider (line 13) | class XmlTreeDataProvider implements TreeDataProvider<any> {
method constructor (line 18) | constructor(private _context: ExtensionContext) {
method activeEditor (line 32) | get activeEditor(): TextEditor {
method getTreeItem (line 36) | getTreeItem(element: Node): TreeItem | Thenable<TreeItem> {
method getChildren (line 87) | getChildren(element?: Node): Node[] | Thenable<Node[]> {
method getParent (line 105) | getParent(element: Node): Node {
method getNodeAtPosition (line 113) | getNodeAtPosition(position: Position): Node {
method _getIcon (line 117) | private _getIcon(element: Node): any {
method _refreshTree (line 132) | private _refreshTree(): void {
FILE: src/xpath/commands/evaluateXPath.ts
class HistoricQuery (line 9) | class HistoricQuery {
method constructor (line 10) | constructor(uri: string, query: string) {
function evaluateXPath (line 19) | async function evaluateXPath(editor: TextEditor, edit: TextEditorEdit): ...
FILE: src/xpath/commands/getCurrentXPath.ts
function getCurrentXPath (line 7) | function getCurrentXPath(editor: TextEditor, edit: TextEditorEdit): void {
FILE: src/xpath/xpath-builder.ts
class XPathBuilder (line 6) | class XPathBuilder {
method constructor (line 10) | constructor(private _xmlDocument: Document) {
method build (line 14) | build(position: Position): string {
method _buildCore (line 20) | private _buildCore(selectedNode: Node): string {
FILE: src/xpath/xpath-evaluator.ts
class EvaluatorResult (line 5) | class EvaluatorResult {
class EvaluatorResultType (line 10) | class EvaluatorResultType {
class XPathResultTypes (line 15) | class XPathResultTypes {
class XPathEvaluator (line 28) | class XPathEvaluator {
method evaluate (line 29) | static evaluate(query: string, xml: string, ignoreDefaultNamespace: bo...
FILE: src/xquery-execution/child-process.ts
class ChildProcess (line 3) | class ChildProcess {
method spawn (line 4) | static async spawn(executable: string, args: string[]): Promise<void> {
FILE: src/xquery-execution/commands/executeXQuery.ts
function executeXQuery (line 9) | async function executeXQuery(editor: TextEditor, edit: TextEditorEdit): ...
Condensed preview — 100 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (165K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug-report.md",
"chars": 412,
"preview": "---\nname: Bug Report\nabout: Something (aside from the formatter) isn't working right!\n---\n\n**Description**\nWhat seems to"
},
{
"path": ".github/ISSUE_TEMPLATE/feature-request.md",
"chars": 193,
"preview": "---\nname: Feature Request\nabout: Suggest a New Feature\n\n---\n\n**Description**\nWhat would you like to see added to XML Too"
},
{
"path": ".github/ISSUE_TEMPLATE/xml-formatter.md",
"chars": 460,
"preview": "---\nname: XML Formatter Bug\nabout: Report an issue with the XML formatter.\n---\n\n#### Description\nWhat seems to be the pr"
},
{
"path": ".github/workflows/release.yml",
"chars": 515,
"preview": "name: \"Release to Marketplace\"\n\non:\n push:\n tags:\n - \"v*\"\n\njobs:\n release:\n runs-on: \"ubuntu-latest\"\n st"
},
{
"path": ".github/workflows/test.yml",
"chars": 372,
"preview": "name: \"Run Tests\"\n\non:\n pull_request:\n branches:\n - \"master\"\n\njobs:\n test:\n runs-on: \"ubuntu-latest\"\n st"
},
{
"path": ".gitignore",
"chars": 39,
"preview": "out\nnode_modules\n.vscode-test/\n/*.vsix\n"
},
{
"path": ".vscode/launch.json",
"chars": 1030,
"preview": "// A launch configuration that compiles the extension and then opens it inside a new window\n{\n \"version\": \"0.1.0\",\n "
},
{
"path": ".vscode/settings.json",
"chars": 315,
"preview": "// Place your settings in this file to overwrite default and user settings.\n{\n \"files.exclude\": {\n \"out\": fals"
},
{
"path": ".vscode/tasks.json",
"chars": 494,
"preview": "// See https://go.microsoft.com/fwlink/?LinkId=733558\n// for the documentation about the tasks.json format\n{\n \"versio"
},
{
"path": ".vscodeignore",
"chars": 112,
"preview": ".vscode/**\n.vscode-test/**\nout/test/**\nout/**/*.map\nsrc/**\n.gitignore\ntsconfig.json\nvsc-extension-quickstart.md\n"
},
{
"path": "CHANGELOG.md",
"chars": 99,
"preview": "Detailed release notes are available [here](https://github.com/DotJoshJohnson/vscode-xml/releases)."
},
{
"path": "CONTRIBUTING.md",
"chars": 1940,
"preview": "# Contributing to XML Tools\nWelcome and thank you for contributing to **XML Tools for Visual Studio Code**! This documen"
},
{
"path": "LICENSE",
"chars": 1078,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Josh Johnson\n\nPermission is hereby granted, free of charge, to any person obta"
},
{
"path": "README.md",
"chars": 3168,
"preview": "# XML Tools for Visual Studio Code\n[-$(Build.SourceVersion)$(Rev:.r)\"\npr:\n - master\n \ntrigger:\n - \"refs/tags/*\"\n\npool:\n "
},
{
"path": "languages/xquery/xquery.json",
"chars": 291,
"preview": "{\n \"comments\": {\n \"lineComment\": [\"(:\", \":)\"],\n \"blockComment\": [ \"(:~\", \"~:)\"]\n },\n \"brackets\": "
},
{
"path": "languages/xquery/xquery.tmLanguage",
"chars": 41680,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "package.json",
"chars": 10066,
"preview": "{\n \"name\": \"xml\",\n \"displayName\": \"XML Tools\",\n \"description\": \"XML Formatting, XQuery, and XPath Tools for Vis"
},
{
"path": "src/common/configuration.ts",
"chars": 2370,
"preview": "import { workspace, Uri } from \"vscode\";\n\nconst ExtensionTopLevelSection = \"xmlTools\";\n\nexport class Configuration {\n "
},
{
"path": "src/common/create-document-selector.ts",
"chars": 303,
"preview": "import { DocumentFilter } from \"vscode\";\n\nimport * as constants from \"../constants\";\n\nexport function createDocumentSele"
},
{
"path": "src/common/extension-state.ts",
"chars": 402,
"preview": "import { ExtensionContext, Memento } from \"vscode\";\n\nexport class ExtensionState {\n private static _context: Extensio"
},
{
"path": "src/common/index.ts",
"chars": 180,
"preview": "export * from \"./configuration\";\nexport * from \"./create-document-selector\";\nexport * from \"./extension-state\";\nexport *"
},
{
"path": "src/common/native-commands.ts",
"chars": 488,
"preview": "import { commands } from \"vscode\";\n\nexport class NativeCommands {\n static async cursorMove(to: string, by: string): P"
},
{
"path": "src/common/xml-traverser.ts",
"chars": 4517,
"preview": "import { Position } from \"vscode\";\nimport { DOMParser } from \"xmldom\";\n\nexport class XmlTraverser {\n\n constructor(pri"
},
{
"path": "src/completion/index.ts",
"chars": 51,
"preview": "export * from \"./xquery-completion-item-provider\";\n"
},
{
"path": "src/completion/xquery-completion-item-provider.ts",
"chars": 1927,
"preview": "import { CompletionItem, CompletionItemKind, CompletionItemProvider, Position, TextDocument } from \"vscode\";\n\nconst XQLi"
},
{
"path": "src/constants.ts",
"chars": 1252,
"preview": "export namespace commands {\n export const evaluateXPath = \"xmlTools.evaluateXPath\";\n export const executeXQuery = "
},
{
"path": "src/extension.ts",
"chars": 4249,
"preview": "import {\n commands, languages, window, workspace, ExtensionContext, Memento,\n TextEditor, TextEditorSelectionChang"
},
{
"path": "src/formatting/commands/formatAsXml.ts",
"chars": 1731,
"preview": "import { workspace } from \"vscode\";\nimport { ProviderResult, Range, TextEdit, TextEditor, TextEditorEdit } from \"vscode\""
},
{
"path": "src/formatting/commands/index.ts",
"chars": 118,
"preview": "export * from \"./formatAsXml\";\nexport * from \"./minifyXml\";\nexport * from \"./xmlToText\";\nexport * from \"./textToXml\";\n"
},
{
"path": "src/formatting/commands/minifyXml.ts",
"chars": 1019,
"preview": "import { workspace } from \"vscode\";\nimport { ProviderResult, Range, TextEdit, TextEditor, TextEditorEdit } from \"vscode\""
},
{
"path": "src/formatting/commands/textToXml.ts",
"chars": 1314,
"preview": "import { workspace } from \"vscode\";\nimport { ProviderResult, Range, TextEdit, TextEditor, Selection } from \"vscode\";\n\nim"
},
{
"path": "src/formatting/commands/xmlToText.ts",
"chars": 1270,
"preview": "import { workspace } from \"vscode\";\nimport { ProviderResult, Range, TextEdit, TextEditor, Selection } from \"vscode\";\n\nim"
},
{
"path": "src/formatting/formatters/classic-xml-formatter.ts",
"chars": 6829,
"preview": "import { XmlFormatter } from \"../xml-formatter\";\nimport { XmlFormattingOptions } from \"../xml-formatting-options\";\n\nexpo"
},
{
"path": "src/formatting/formatters/index.ts",
"chars": 77,
"preview": "export * from \"./classic-xml-formatter\";\nexport * from \"./v2-xml-formatter\";\n"
},
{
"path": "src/formatting/formatters/v2-xml-formatter.ts",
"chars": 12814,
"preview": "import { XmlFormatter } from \"../xml-formatter\";\nimport { XmlFormattingOptions } from \"../xml-formatting-options\";\nimpor"
},
{
"path": "src/formatting/index.ts",
"chars": 123,
"preview": "export * from \"./xml-formatter\";\nexport * from \"./xml-formatting-edit-provider\";\nexport * from \"./xml-formatting-options"
},
{
"path": "src/formatting/xml-formatter.ts",
"chars": 1329,
"preview": "import { window, workspace } from \"vscode\";\n\nimport { Configuration, ExtensionState } from \"../common\";\nimport * as cons"
},
{
"path": "src/formatting/xml-formatting-edit-provider.ts",
"chars": 2374,
"preview": "import { workspace } from \"vscode\";\nimport {\n CancellationToken, DocumentFormattingEditProvider, DocumentRangeFormatt"
},
{
"path": "src/formatting/xml-formatting-options.ts",
"chars": 1174,
"preview": "import { EndOfLine, FormattingOptions, TextDocument } from \"vscode\";\n\nimport { Configuration } from \"../common\";\nimport "
},
{
"path": "src/linting/index.ts",
"chars": 33,
"preview": "export * from \"./xquery-linter\";\n"
},
{
"path": "src/linting/xquery-linter.ts",
"chars": 1132,
"preview": "import { Diagnostic, DiagnosticSeverity, Position, Range } from \"vscode\";\n\nconst XQLint = require(\"xqlint\").XQLint;\n\nexp"
},
{
"path": "src/test/extension.test.ts",
"chars": 5730,
"preview": "import * as assert from \"assert\";\nimport { FormattingOptions } from \"vscode\";\n\nimport { TestDataLoader } from \"./test-ut"
},
{
"path": "src/test/test-data/basic.formatted.xml",
"chars": 42,
"preview": "<root>\n <element>text</element>\n</root>"
},
{
"path": "src/test/test-data/basic.unformatted.xml",
"chars": 36,
"preview": "<root><element>text</element></root>"
},
{
"path": "src/test/test-data/issue-149.formatted.xml",
"chars": 167,
"preview": "<root>\n <entry>\n <field1>One</field1>\n <field2 />\n <field3>Three</field3>\n <field4 />\n "
},
{
"path": "src/test/test-data/issue-149.unformatted.xml",
"chars": 109,
"preview": "<root><entry><field1>One</field1><field2/><field3>Three</field3><field4/><field5>Five</field5></entry></root>"
},
{
"path": "src/test/test-data/issue-178.formatted.xml",
"chars": 165,
"preview": "<root>\n <entry>\n <field1>One</field1>\n <field2/>\n <field3>Three</field3>\n <field4/>\n "
},
{
"path": "src/test/test-data/issue-178.unformatted.xml",
"chars": 109,
"preview": "<root><entry><field1>One</field1><field2/><field3>Three</field3><field4/><field5>Five</field5></entry></root>"
},
{
"path": "src/test/test-data/issue-185.formatted.xml",
"chars": 58,
"preview": "<test>\n <example>\n <one/>\n </example>\n</test>"
},
{
"path": "src/test/test-data/issue-185.unformatted.xml",
"chars": 38,
"preview": "<test><example><one/></example></test>"
},
{
"path": "src/test/test-data/issue-187.formatted.xml",
"chars": 652,
"preview": "<Project>\n <PropertyGroup>\n <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n "
},
{
"path": "src/test/test-data/issue-187.unformatted.xml",
"chars": 652,
"preview": "<Project>\n <PropertyGroup>\n <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n "
},
{
"path": "src/test/test-data/issue-189.formatted.xml",
"chars": 226,
"preview": "<!DOCTYPE xml>\n<core:FragmentDefinition xmlns=\"sap.m\"\n xmlns:core=\"sap.ui.core\">\n <Text text=\"{parts: ['i18n>dialo"
},
{
"path": "src/test/test-data/issue-189.unformatted.xml",
"chars": 226,
"preview": "<!DOCTYPE xml>\n<core:FragmentDefinition xmlns=\"sap.m\"\n xmlns:core=\"sap.ui.core\">\n <Text text=\"{parts: ['i18n>dialo"
},
{
"path": "src/test/test-data/issue-193.formatted.xml",
"chars": 729,
"preview": "<xsl:template name=\"btn-export-excel-pdf\">\n <div class=\"row\">\n <div class=\"col-md button-wrapper text-center\">"
},
{
"path": "src/test/test-data/issue-193.unformatted.xml",
"chars": 699,
"preview": "<xsl:template name=\"btn-export-excel-pdf\">\n <div class=\"row\">\n <div class=\"col-md button-wrapper text-center\">\n "
},
{
"path": "src/test/test-data/issue-194.formatted.xml",
"chars": 170,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<madeup>\n <some>\n <element>This is ok</element>\n <other><![CDATA"
},
{
"path": "src/test/test-data/issue-194.unformatted.xml",
"chars": 140,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><madeup><some><element>This is ok</element><other><![CDATA[Here is my cdata]]></ot"
},
{
"path": "src/test/test-data/issue-200.formatted.xml",
"chars": 93,
"preview": "<mixed>beginning text<inner>\n <a>data</a>\n <b>another data</b>\n</inner>end text</mixed>"
},
{
"path": "src/test/test-data/issue-200.unformatted.xml",
"chars": 82,
"preview": "<mixed>beginning text<inner><a>data</a><b>another data</b></inner>end text</mixed>"
},
{
"path": "src/test/test-data/issue-227.formatted.xml",
"chars": 409,
"preview": "<Job>\n <SQLQuery test=\"\">\n <SQLSelect Test=\"test\" test=\"test\">\n <![CDATA[\nselect\n*\nfrom test\nwhere\n"
},
{
"path": "src/test/test-data/issue-227.unformatted.xml",
"chars": 409,
"preview": "<Job>\n <SQLQuery test=\"\">\n <SQLSelect Test=\"test\" test=\"test\">\n <![CDATA[\nselect\n*\nfrom test"
},
{
"path": "src/test/test-data/issue-257.formatted.xml",
"chars": 533,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsl:stylesheet version=\"2.0\"\n xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform"
},
{
"path": "src/test/test-data/issue-257.unformatted.xml",
"chars": 534,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsl:stylesheet version=\"2.0\" \n xmlns:xsl=\"http://www.w3.org/1999/XSL/Transfor"
},
{
"path": "src/test/test-data/issue-262.minified.xml",
"chars": 156,
"preview": "<tests><test>1.\n2.\n3.\n4.</test><test xml:space=\"preserve\">1.\n2.\n3.\n4.</test><test>1. 2. 3. 4.</test><test xml:space=\"pre"
},
{
"path": "src/test/test-data/issue-262.unminified.xml",
"chars": 164,
"preview": "<tests>\n<test>1.\n2.\n3.\n4.</test>\n<test xml:space=\"preserve\">1.\n2.\n3.\n4.</test>\n<test>1.\n 2.\n 3.\n 4.</test>\n<test xml:spa"
},
{
"path": "src/test/test-data/issue-288.formatted.xml",
"chars": 424,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n xmlns=\"http"
},
{
"path": "src/test/test-data/issue-288.unformatted.xml",
"chars": 424,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n xmlns=\"http"
},
{
"path": "src/test/test-data/issue-293.formatted.xml",
"chars": 151,
"preview": "<xml>\n <element><![CDATA[asdf]]></element>\n <element><![CDATA[<secondXml>\n <formattedNode>val</formattedNode>\n<"
},
{
"path": "src/test/test-data/issue-293.unformatted.xml",
"chars": 151,
"preview": "<xml>\n <element><![CDATA[asdf]]></element>\n <element><![CDATA[<secondXml>\n <formattedNode>val</formattedNode>\n<"
},
{
"path": "src/test/test-data/maintain-comment-formatting.formatted.xml",
"chars": 410,
"preview": "<root>\n <element>text</element>\n <!--\n <Description>\n Any description.\n </Description>\n "
},
{
"path": "src/test/test-data/maintain-comment-formatting.unformatted.xml",
"chars": 410,
"preview": "<root>\n <element>text</element>\n <!--\n <Description>\n Any description.\n </Description>\n "
},
{
"path": "src/test/test-data/preformatted.formatted.xml",
"chars": 190,
"preview": "<root>\n <element>text</element>\n <element>text</element>\n <element>text</element>\n <element>text</element>\n "
},
{
"path": "src/test/test-data/preformatted.unformatted.xml",
"chars": 190,
"preview": "<root>\n <element>text</element>\n <element>text</element>\n <element>text</element>\n <element>text</element>\n "
},
{
"path": "src/test/test-data/preserve-breaks.formatted.xml",
"chars": 193,
"preview": "<root>\n <element>text</element>\n <element>text</element>\n\n <element>text</element>\n <element>text</element>\n"
},
{
"path": "src/test/test-data/preserve-breaks.unformatted.xml",
"chars": 193,
"preview": "<root>\n <element>text</element>\n <element>text</element>\n\n <element>text</element>\n <element>text</element>\n"
},
{
"path": "src/test/test-data/self-closing.formatted.xml",
"chars": 43,
"preview": "<Node>\n <Node name=\"testChild\"/>\n</Node>"
},
{
"path": "src/test/test-data/self-closing.unformatted.xml",
"chars": 37,
"preview": "<Node><Node name=\"testChild\"/></Node>"
},
{
"path": "src/test/test-data/single-quotes.formatted.xml",
"chars": 64,
"preview": "<root>\n <element attr='1' />\n <element attr='2' />\n</root>"
},
{
"path": "src/test/test-data/single-quotes.unformatted.xml",
"chars": 64,
"preview": "<root>\n <element attr='1' />\n <element attr='2' />\n</root>"
},
{
"path": "src/test/test-data/text-only-line.formatted.xml",
"chars": 47,
"preview": "<Tag>\n <Tag2>\nText1\nText2\n </Tag2>\n</Tag>"
},
{
"path": "src/test/test-data/text-only-line.unformatted.xml",
"chars": 39,
"preview": "<Tag>\n<Tag2>\nText1\nText2\n</Tag2>\n</Tag>"
},
{
"path": "src/test/test-data/unicode.formatted.xml",
"chars": 79,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Имя>\n <element>text</element>\n</Имя>"
},
{
"path": "src/test/test-data/unicode.unformatted.xml",
"chars": 73,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Имя><element>text</element></Имя>"
},
{
"path": "src/test/test-utils/test-data-loader.ts",
"chars": 206,
"preview": "import * as fs from \"fs\";\n\nexport class TestDataLoader {\n static load(fileName: string): string {\n return fs.r"
},
{
"path": "src/tree-view/index.ts",
"chars": 42,
"preview": "export * from \"./xml-tree-data-provider\";\n"
},
{
"path": "src/tree-view/xml-tree-data-provider.ts",
"chars": 5484,
"preview": "import { window, workspace } from \"vscode\";\nimport {\n Event, EventEmitter, ExtensionContext, Position, TextEditor, Tr"
},
{
"path": "src/xpath/commands/evaluateXPath.ts",
"chars": 3339,
"preview": "import { window } from \"vscode\";\nimport { TextEditor, TextEditorEdit, ViewColumn } from \"vscode\";\n\nimport { Configuratio"
},
{
"path": "src/xpath/commands/getCurrentXPath.ts",
"chars": 656,
"preview": "import { window } from \"vscode\";\nimport { TextEditor, TextEditorEdit } from \"vscode\";\nimport { DOMParser } from \"xmldom\""
},
{
"path": "src/xpath/commands/index.ts",
"chars": 68,
"preview": "export * from \"./evaluateXPath\";\nexport * from \"./getCurrentXPath\";\n"
},
{
"path": "src/xpath/index.ts",
"chars": 68,
"preview": "export * from \"./xpath-builder\";\nexport * from \"./xpath-evaluator\";\n"
},
{
"path": "src/xpath/xpath-builder.ts",
"chars": 1290,
"preview": "import { Position } from \"vscode\";\nimport { DOMParser } from \"xmldom\";\n\nimport { XmlTraverser } from \"../common\";\n\nexpor"
},
{
"path": "src/xpath/xpath-evaluator.ts",
"chars": 2436,
"preview": "import * as xpath from \"xpath\";\nimport { SelectedValue, XPathSelect } from \"xpath\";\nimport { DOMParser } from \"xmldom\";\n"
},
{
"path": "src/xquery-execution/child-process.ts",
"chars": 794,
"preview": "const child_process = require(\"child_process\");\n\nexport class ChildProcess {\n static async spawn(executable: string, "
},
{
"path": "src/xquery-execution/commands/executeXQuery.ts",
"chars": 4276,
"preview": "import { window, workspace } from \"vscode\";\nimport { Disposable, Range, TextEditor, TextEditorEdit, Uri } from \"vscode\";"
},
{
"path": "src/xquery-execution/commands/index.ts",
"chars": 33,
"preview": "export * from \"./executeXQuery\";\n"
},
{
"path": "src/xquery-execution/index.ts",
"chars": 33,
"preview": "export * from \"./child-process\";\n"
},
{
"path": "tsconfig.json",
"chars": 361,
"preview": "{\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"target\": \"es6\",\n \"outDir\": \"out\",\n \"lib\""
},
{
"path": "tslint.json",
"chars": 2948,
"preview": "{\n \"rules\": {\n \"arrow-return-shorthand\": true,\n \"callable-types\": true,\n \"class-name\": true,\n "
}
]
About this extraction
This page contains the full source code of the DotJoshJohnson/vscode-xml GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 100 files (144.1 KB), approximately 40.3k tokens, and a symbol index with 109 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.