-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: [WIP] convert Maven XML dependencies on paste
Signed-off-by: Fred Bricon <fbricon@gmail.com>
- Loading branch information
Showing
5 changed files
with
199 additions
and
26 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { XMLParser } from "fast-xml-parser"; | ||
import { CancellationToken, DataTransfer, DocumentPasteEdit, DocumentPasteEditProvider, DocumentPasteProviderMetadata, ExtensionContext, languages, Range, TextDocument } from "vscode"; | ||
import { isJBangFile, SUPPORTED_LANGUAGES } from "./JBangUtils"; | ||
|
||
const TEXT_MIMETYPE: string = "text/plain"; | ||
const MIMETYPES: DocumentPasteProviderMetadata = { | ||
pasteMimeTypes: [TEXT_MIMETYPE] | ||
}; | ||
|
||
|
||
export class DependencyPasteEditProvider implements DocumentPasteEditProvider { | ||
|
||
/** | ||
* `DocumentPasteEditProvider` that delegates to jdt.ls to make any changes necessary to the pasted text and add any additional workspace edits. | ||
*/ | ||
|
||
async provideDocumentPasteEdits(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, token: CancellationToken): Promise<DocumentPasteEdit | undefined> { | ||
if (!isJBangFile(document.getText())){ | ||
return undefined; | ||
} | ||
const pasteContent = dataTransfer.get(TEXT_MIMETYPE); | ||
if (!pasteContent) { | ||
return undefined; | ||
} | ||
const pastedText: string = (await pasteContent.asString()).trim(); | ||
|
||
// don't try to provide for multi character inserts; the implementation will get messy and the feature won't be that helpful | ||
if (!pastedText || token.isCancellationRequested || ranges.length !== 1) { | ||
return undefined; | ||
} | ||
|
||
const range = ranges[0]; | ||
if (range.start.character > 0) { | ||
//Only paste on the 1st column, for now | ||
return undefined; | ||
} | ||
const line = range.start.line; | ||
const targetLine = document.lineAt(line); | ||
if (!targetLine.isEmptyOrWhitespace) { | ||
return undefined; | ||
} | ||
let dependencies:any; | ||
let xml: any; | ||
if (pastedText.startsWith("<dependency>") | ||
|| pastedText.startsWith("<dependencies>") | ||
|| pastedText.startsWith("<dependencyManagement>")) { | ||
xml = new XMLParser().parse(pastedText); | ||
if (xml.dependency) { | ||
dependencies = xml.dependency; | ||
} else if (xml.dependencies?.dependency) { | ||
dependencies = xml.dependencies.dependency; | ||
} else if (xml.dependencyManagement?.dependencies?.dependency) { | ||
dependencies = xml.dependencyManagement.dependencies.dependency; | ||
} | ||
} | ||
|
||
if (!dependencies) { | ||
return undefined; | ||
} | ||
if (Array.isArray(dependencies)){ | ||
return new DocumentPasteEdit(dependencies.map(d => this.toJBangDependency(d)).join('\n')); | ||
} else { | ||
return new DocumentPasteEdit(this.toJBangDependency(dependencies)); | ||
} | ||
|
||
// either the handler returns null or encounters problems, fall back to return undefined to let VS Code ignore this handler | ||
return undefined; | ||
} | ||
|
||
|
||
private toJBangDependency(dependency: any): string { | ||
const suffix = dependency?.type === 'pom'? '@pom':''; | ||
const version = dependency?.version ? dependency.version: "LATEST"; | ||
return `//DEPS ${dependency.groupId}:${dependency.artifactId}:${version}${suffix}`; | ||
} | ||
|
||
/** | ||
* Registers the DependencyPasteEditProvider and sets it up to be disposed. | ||
* | ||
* @param context the extension context | ||
*/ | ||
public initialize(context: ExtensionContext) { | ||
if (languages.registerDocumentPasteEditProvider) { | ||
const dependencyPasteEditProvider = new DependencyPasteEditProvider(); | ||
SUPPORTED_LANGUAGES.forEach(languageId => { | ||
context.subscriptions.push( | ||
languages.registerDocumentPasteEditProvider(languageId, dependencyPasteEditProvider, MIMETYPES) | ||
); | ||
}); | ||
} | ||
} | ||
} | ||
|
||
export default new DependencyPasteEditProvider(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
declare module 'vscode' { | ||
|
||
// https://github.com/microsoft/vscode/issues/30066/ | ||
|
||
/** | ||
* Provider invoked when the user copies and pastes code. | ||
*/ | ||
interface DocumentPasteEditProvider { | ||
|
||
/** | ||
* Optional method invoked after the user copies text in a file. | ||
* | ||
* During {@link prepareDocumentPaste}, an extension can compute metadata that is attached to | ||
* a {@link DataTransfer} and is passed back to the provider in {@link provideDocumentPasteEdits}. | ||
* | ||
* @param document Document where the copy took place. | ||
* @param ranges Ranges being copied in the `document`. | ||
* @param dataTransfer The data transfer associated with the copy. You can store additional values on this for later use in {@link provideDocumentPasteEdits}. | ||
* @param token A cancellation token. | ||
*/ | ||
prepareDocumentPaste?(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, token: CancellationToken): void | Thenable<void>; | ||
|
||
/** | ||
* Invoked before the user pastes into a document. | ||
* | ||
* In this method, extensions can return a workspace edit that replaces the standard pasting behavior. | ||
* | ||
* @param document Document being pasted into | ||
* @param ranges Currently selected ranges in the document. | ||
* @param dataTransfer The data transfer associated with the paste. | ||
* @param token A cancellation token. | ||
* | ||
* @return Optional workspace edit that applies the paste. Return undefined to use standard pasting. | ||
*/ | ||
provideDocumentPasteEdits(document: TextDocument, ranges: readonly Range[], dataTransfer: DataTransfer, token: CancellationToken): ProviderResult<DocumentPasteEdit>; | ||
} | ||
|
||
/** | ||
* An operation applied on paste | ||
*/ | ||
class DocumentPasteEdit { | ||
/** | ||
* The text or snippet to insert at the pasted locations. | ||
*/ | ||
insertText: string | SnippetString; | ||
|
||
/** | ||
* An optional additional edit to apply on paste. | ||
*/ | ||
additionalEdit?: WorkspaceEdit; | ||
|
||
/** | ||
* @param insertText The text or snippet to insert at the pasted locations. | ||
*/ | ||
constructor(insertText: string | SnippetString); | ||
} | ||
|
||
interface DocumentPasteProviderMetadata { | ||
/** | ||
* Mime types that `provideDocumentPasteEdits` should be invoked for. | ||
* | ||
* Use the special `files` mimetype to indicate the provider should be invoked if any files are present in the `DataTransfer`. | ||
*/ | ||
readonly pasteMimeTypes: readonly string[]; | ||
} | ||
|
||
namespace languages { | ||
export function registerDocumentPasteEditProvider(selector: DocumentSelector, provider: DocumentPasteEditProvider, metadata: DocumentPasteProviderMetadata): Disposable; | ||
} | ||
} |