Skip to content

Commit

Permalink
XML Formatter (microsoft#6182)
Browse files Browse the repository at this point in the history
* add xml formatter extenstion

* remove unused imports
  • Loading branch information
Anthony Dresser authored Jun 27, 2019
1 parent 20bbaa3 commit 7b6181d
Show file tree
Hide file tree
Showing 16 changed files with 109 additions and 196 deletions.
11 changes: 0 additions & 11 deletions ThirdPartyNotices.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ expressly granted herein, whether by implication, estoppel or otherwise.
node-fetch: https://github.com/bitinn/node-fetch
node-pty: https://github.com/Tyriar/node-pty
nsfw: https://github.com/Axosoft/nsfw
pretty-data: https://github.com/vkiryukhin/pretty-data
primeng: https://github.com/primefaces/primeng
process-nextick-args: https://github.com/calvinmetcalf/process-nextick-args
pty.js: https://github.com/chjj/pty.js
Expand Down Expand Up @@ -1420,16 +1419,6 @@ SOFTWARE.
=========================================
END OF nsfw NOTICES AND INFORMATION

%% pretty-data NOTICES AND INFORMATION BEGIN HERE
=========================================
License: Dual licensed under the MIT and GPL licenses:

http://www.opensource.org/licenses/mit-license.php

http://www.gnu.org/licenses/gpl.html
=========================================
END OF pretty-data NOTICES AND INFORMATION

%% primeng NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Expand Down
10 changes: 10 additions & 0 deletions extensions/xml-language-features/.vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
test/**
src/**
tsconfig.json
out/test/**
out/**
extension.webpack.config.js
cgmanifest.json
yarn.lock
preview-src/**
webpack.config.js
20 changes: 20 additions & 0 deletions extensions/xml-language-features/extension.webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

//@ts-check

'use strict';

const withDefaults = require('../shared.webpack.config');

module.exports = withDefaults({
context: __dirname,
resolve: {
mainFields: ['module', 'main']
},
entry: {
extension: './src/extension.ts',
}
});
27 changes: 27 additions & 0 deletions extensions/xml-language-features/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "xml-language-features",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "microsoft",
"engines": {
"vscode": "^1.20.0"
},
"main": "./out/extension",
"categories": [
"Programming Languages"
],
"activationEvents": [
"onLanguage:xml"
],
"scripts": {
"compile": "gulp compile-extension:markdown-language-features && npm run build-preview",
"watch": "npm run build-preview && gulp watch-extension:markdown-language-features",
"vscode:prepublish": "npm run build-ext && npm run build-preview",
"build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown-language-features ./tsconfig.json",
"build-preview": "webpack --mode development"
},
"dependencies": {
"tsxml": "^0.1.0"
}
}
4 changes: 4 additions & 0 deletions extensions/xml-language-features/package.nls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"displayName": "XML Language Features",
"description": "Provides rich language support for XML."
}
18 changes: 18 additions & 0 deletions extensions/xml-language-features/src/extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import * as xml from 'tsxml';

export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider({ language: 'xml' }, {
provideDocumentFormattingEdits: document => format(document)
}));
}

function format(document: vscode.TextDocument): vscode.ProviderResult<vscode.TextEdit[]> {
const range = new vscode.Range(0, 0, document.lineCount, document.lineAt(document.lineCount - 1).range.end.character);
return xml.Compiler.formatXmlString(document.getText()).then(formatted => [new vscode.TextEdit(range, formatted)]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,5 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

declare module 'pretty-data' {
export interface PrettyData {
xml(input: string): string;
}
export var pd: PrettyData;
}
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
13 changes: 13 additions & 0 deletions extensions/xml-language-features/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../shared.tsconfig.json",
"compilerOptions": {
"outDir": "./out",
"experimentalDecorators": true,
"typeRoots": [
"./node_modules/@types"
]
},
"include": [
"src/**/*"
]
}
8 changes: 8 additions & 0 deletions extensions/xml-language-features/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


tsxml@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/tsxml/-/tsxml-0.1.0.tgz#d73f14a0d844af51edc0b98bdb52634a41b9b0d4"
integrity sha1-1z8UoNhEr1HtwLmL21JjSkG5sNQ=
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"native-watchdog": "1.0.0",
"ng2-charts": "^1.6.0",
"node-pty": "0.9.0-beta9",
"pretty-data": "^0.40.0",
"reflect-metadata": "^0.1.8",
"rxjs": "5.4.0",
"sanitize-html": "^1.19.1",
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap-window.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ exports.load = function (modulePaths, resultCallback, options) {
'@angular/router',
'angular2-grid',
'ansi_up',
'pretty-data',
'html-query-plan',
'ng2-charts',
'rxjs/Observable',
Expand Down
79 changes: 0 additions & 79 deletions src/sql/platform/node/resultSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,12 @@ import { SaveResultsRequestParams } from 'azdata';
import { IQueryManagementService } from 'sql/platform/query/common/queryManagement';
import { ISaveRequest, SaveFormat } from 'sql/workbench/parts/grid/common/interfaces';

import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWindowsService, IWindowService, FileFilter } from 'vs/platform/windows/common/windows';
import { Registry } from 'vs/platform/registry/common/platform';
import { URI } from 'vs/base/common/uri';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { Schemas } from 'vs/base/common/network';
import * as path from 'vs/base/common/path';
import * as nls from 'vs/nls';
import * as pretty from 'pretty-data';

import Severity from 'vs/base/common/severity';
import { INotificationService } from 'vs/platform/notification/common/notification';
Expand All @@ -38,21 +34,18 @@ let prevSavePath: string;
*/
export class ResultSerializer {
public static tempFileCount: number = 1;
private static MAX_FILENAMES = 100;

private _uri: string;
private _filePath: string;

constructor(
@IInstantiationService private _instantiationService: IInstantiationService,
@IOutputService private _outputService: IOutputService,
@IQueryManagementService private _queryManagementService: IQueryManagementService,
@IConfigurationService private _workspaceConfigurationService: IConfigurationService,
@IEditorService private _editorService: IEditorService,
@IWorkspaceContextService private _contextService: IWorkspaceContextService,
@IWindowsService private _windowsService: IWindowsService,
@IWindowService private _windowService: IWindowService,
@IUntitledEditorService private _untitledEditorService: IUntitledEditorService,
@INotificationService private _notificationService: INotificationService
) { }

Expand All @@ -72,59 +65,6 @@ export class ResultSerializer {
});
}

/**
* Open a xml/json link - Opens the content in a new editor pane
*/
public openLink(content: string, columnName: string, linkType: string): void {
let fileMode: string = undefined;
let fileUri = this.getUntitledFileUri(columnName);

if (linkType === SaveFormat.XML) {
fileMode = SaveFormat.XML;
try {
content = pretty.pd.xml(content);
} catch (e) {
// If Xml fails to parse, fall back on original Xml content
}
} else if (linkType === SaveFormat.JSON) {
let jsonContent: string = undefined;
fileMode = SaveFormat.JSON;
try {
jsonContent = JSON.parse(content);
} catch (e) {
// If Json fails to parse, fall back on original Json content
}
if (jsonContent) {
// If Json content was valid and parsed, pretty print content to a string
content = JSON.stringify(jsonContent, undefined, 4);
}
}

this.openUntitledFile(fileMode, content, fileUri);
}

private getUntitledFileUri(columnName: string): URI {
let fileName = columnName;

let uri: URI = URI.from({ scheme: Schemas.untitled, path: fileName });

// If the current filename is taken, try another up to a max number
if (this._untitledEditorService.exists(uri)) {
let i = 1;
while (i < ResultSerializer.MAX_FILENAMES
&& this._untitledEditorService.exists(uri)) {
fileName = [columnName, i.toString()].join('-');
uri = URI.from({ scheme: Schemas.untitled, path: fileName });
i++;
}
if (this._untitledEditorService.exists(uri)) {
// If this fails, return undefined and let the system figure out the right name
uri = undefined;
}
}
return uri;
}

private ensureOutputChannelExists(): void {
Registry.as<IOutputChannelRegistry>(OutputExtensions.OutputChannels)
.registerChannel({
Expand Down Expand Up @@ -387,23 +327,4 @@ export class ResultSerializer {
});
}
}

/**
* Open the saved file in a new vscode editor pane
*/
private openUntitledFile(fileMode: string, contents: string, fileUri: URI = undefined): void {
const input = this._untitledEditorService.createOrGet(fileUri, fileMode, contents);

this._editorService.openEditor(input, { pinned: true })
.then(
(success) => {
},
(error: any) => {
this._notificationService.notify({
severity: Severity.Error,
message: error
});
}
);
}
}
10 changes: 0 additions & 10 deletions src/sql/workbench/parts/grid/services/dataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,6 @@ export class DataService {
serializer.saveResults(this._uri, saveRequest);
}

/**
* send request to open content in new editor
* @param content The content to be opened
* @param columnName The column name of the content
*/
openLink(content: string, columnName: string, linkType: string): void {
let serializer = this._instantiationService.createInstance(ResultSerializer);
serializer.openLink(content, columnName, linkType);
}

/**
* Sends a copy request
* @param selection The selection range to copy
Expand Down
60 changes: 0 additions & 60 deletions src/sql/workbench/parts/grid/views/gridParentComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { IGridInfo, IGridDataSet, SaveFormat } from 'sql/workbench/parts/grid/co
import * as Utils from 'sql/platform/connection/common/utils';
import { DataService } from 'sql/workbench/parts/grid/services/dataService';
import * as actions from 'sql/workbench/parts/grid/views/gridActions';
import * as Services from 'sql/base/browser/ui/table/formatters';
import * as GridContentEvents from 'sql/workbench/parts/grid/common/gridContentEvents';
import { ResultsVisibleContext, ResultsGridFocussedContext, ResultsMessagesFocussedContext, QueryEditorVisibleContext } from 'sql/workbench/parts/query/common/queryContext';
import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService';
Expand Down Expand Up @@ -487,65 +486,6 @@ export abstract class GridParentComponent {
sel.addRange(range);
}

/**
* Add handler for clicking on xml link
*/
xmlLinkHandler = (cellRef: string, row: number, dataContext: JSON, colDef: any) => {
const self = this;

let value = self.getCellValueString(dataContext, colDef);
if (value.startsWith('<ShowPlanXML') && colDef.name !== 'XML Showplan') {
self.handleQueryPlanLink(cellRef, value);
} else {
self.handleLink(cellRef, row, dataContext, colDef, 'xml');
}
}

/**
* Add handler for clicking on json link
*/
jsonLinkHandler = (cellRef: string, row: number, dataContext: JSON, colDef: any) => {
const self = this;
self.handleLink(cellRef, row, dataContext, colDef, 'json');
}

private handleQueryPlanLink(cellRef: string, value: string): void {
const self = this;
jQuery(cellRef).children('.xmlLink').click(function (): void {
self.queryEditorService.newQueryPlanEditor(value);
});
}

private handleLink(cellRef: string, row: number, dataContext: JSON, colDef: any, linkType: string): void {
const self = this;
let value = self.getCellValueString(dataContext, colDef);
jQuery(cellRef).children('.xmlLink').click(function (): void {
self.dataService.openLink(value, colDef.name, linkType);
});
}

private getCellValueString(dataContext: JSON, colDef: any): string {
let returnVal = '';
let value = dataContext[colDef.field];
if (Services.DBCellValue.isDBCellValue(value)) {
returnVal = value.displayValue;
} else if (typeof value === 'string') {
returnVal = value;
}
return returnVal;
}

/**
* Return asyncPostRender handler based on type
*/
public linkHandler(type: string): Function {
if (type === 'xml') {
return this.xmlLinkHandler;
} else { // default to JSON handler
return this.jsonLinkHandler;
}
}

keyEvent(e: KeyboardEvent): void {
if (this.tryHandleKeyEvent(new StandardKeyboardEvent(e))) {
e.preventDefault();
Expand Down
Loading

0 comments on commit 7b6181d

Please sign in to comment.