-
-
Notifications
You must be signed in to change notification settings - Fork 416
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Support Drag and Drop component into template (#3692)
- Loading branch information
1 parent
03a9f11
commit fd38ed0
Showing
7 changed files
with
172 additions
and
18 deletions.
There are no files selected for viewing
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,64 @@ | ||
import { GetDragAndDragImportEditsRequest, TagNameCasing } from '@vue/language-server'; | ||
import * as vscode from 'vscode'; | ||
import type { BaseLanguageClient, DocumentFilter, InsertTextFormat } from 'vscode-languageclient'; | ||
import { tagNameCasings } from './nameCasing'; | ||
import { config } from '../config'; | ||
|
||
export async function register(context: vscode.ExtensionContext, client: BaseLanguageClient) { | ||
|
||
const selectors: DocumentFilter[] = [{ language: 'vue' }]; | ||
|
||
if (config.server.petiteVue.supportHtmlFile) { | ||
selectors.push({ language: 'html' }); | ||
} | ||
if (config.server.vitePress.supportMdFile) { | ||
selectors.push({ language: 'markdown' }); | ||
} | ||
|
||
context.subscriptions.push( | ||
vscode.languages.registerDocumentDropEditProvider( | ||
selectors, | ||
{ | ||
async provideDocumentDropEdits(document, _position, dataTransfer) { | ||
for (const [mimeType, item] of dataTransfer) { | ||
if (mimeType === 'text/uri-list') { | ||
const uri = item.value as string; | ||
if ( | ||
uri.endsWith('.vue') | ||
|| (uri.endsWith('.md') && config.server.vitePress.supportMdFile) | ||
) { | ||
const response = await client.sendRequest(GetDragAndDragImportEditsRequest.type, { | ||
uri: document.uri.toString(), | ||
importUri: uri, | ||
casing: tagNameCasings.get(document.uri.toString()) ?? TagNameCasing.Pascal, | ||
}); | ||
if (!response) { | ||
return; | ||
} | ||
const additionalEdit = new vscode.WorkspaceEdit(); | ||
for (const edit of response.additionalEdits) { | ||
additionalEdit.replace( | ||
document.uri, | ||
new vscode.Range( | ||
edit.range.start.line, | ||
edit.range.start.character, | ||
edit.range.end.line, | ||
edit.range.end.character, | ||
), | ||
edit.newText | ||
); | ||
} | ||
return { | ||
insertText: response.insertTextFormat === 2 satisfies typeof InsertTextFormat.Snippet | ||
? new vscode.SnippetString(response.insertText) | ||
: response.insertText, | ||
additionalEdit, | ||
}; | ||
} | ||
} | ||
} | ||
}, | ||
} | ||
), | ||
); | ||
} |
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
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,65 @@ | ||
import { ServiceContext } from '@volar/language-service'; | ||
import { VueFile } from '@vue/language-core'; | ||
import { camelize, capitalize, hyphenate } from '@vue/shared'; | ||
import { posix as path } from 'path'; | ||
import type * as vscode from 'vscode-languageserver-protocol'; | ||
import { createAddComponentToOptionEdit, getLastImportNode } from '../plugins/vue-extract-file'; | ||
import { TagNameCasing } from '../types'; | ||
|
||
export function getDragImportEdits( | ||
ts: typeof import('typescript/lib/tsserverlibrary'), | ||
ctx: ServiceContext, | ||
uri: string, | ||
importUri: string, | ||
casing: TagNameCasing | ||
): { | ||
insertText: string; | ||
insertTextFormat: vscode.InsertTextFormat; | ||
additionalEdits: vscode.TextEdit[]; | ||
} | undefined { | ||
|
||
let baseName = importUri.substring(importUri.lastIndexOf('/') + 1); | ||
baseName = baseName.substring(0, baseName.lastIndexOf('.')); | ||
|
||
const newName = capitalize(camelize(baseName)); | ||
const document = ctx!.getTextDocument(uri)!; | ||
const [vueFile] = ctx!.documents.getVirtualFileByUri(document.uri) as [VueFile, any]; | ||
const { sfc } = vueFile; | ||
const script = sfc.scriptSetup ?? sfc.script; | ||
|
||
if (!sfc.template || !script) | ||
return; | ||
|
||
const lastImportNode = getLastImportNode(ts, script.ast); | ||
const edits: vscode.TextEdit[] = [ | ||
{ | ||
range: lastImportNode ? { | ||
start: document.positionAt(script.startTagEnd + lastImportNode.end), | ||
end: document.positionAt(script.startTagEnd + lastImportNode.end), | ||
} : { | ||
start: document.positionAt(script.startTagEnd), | ||
end: document.positionAt(script.startTagEnd), | ||
}, | ||
newText: `\nimport ${newName} from './${path.relative(path.dirname(uri), importUri) || importUri.substring(importUri.lastIndexOf('/') + 1)}'`, | ||
}, | ||
]; | ||
|
||
if (sfc.script) { | ||
const edit = createAddComponentToOptionEdit(ts, sfc.script.ast, newName); | ||
if (edit) { | ||
edits.push({ | ||
range: { | ||
start: document.positionAt(sfc.script.startTagEnd + edit.range.start), | ||
end: document.positionAt(sfc.script.startTagEnd + edit.range.end), | ||
}, | ||
newText: edit.newText, | ||
}); | ||
} | ||
} | ||
|
||
return { | ||
insertText: `<${casing === TagNameCasing.Kebab ? hyphenate(newName) : newName}$0 />`, | ||
insertTextFormat: 2 satisfies typeof vscode.InsertTextFormat.Snippet, | ||
additionalEdits: edits, | ||
}; | ||
} |
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 |
---|---|---|
@@ -1,6 +1,7 @@ | ||
export * from '@volar/language-service'; | ||
export * from '@vue/language-core'; | ||
export * from './ideFeatures/nameCasing'; | ||
export * from './ideFeatures/dragImport'; | ||
export * from './languageService'; | ||
export { TagNameCasing, AttrNameCasing } from './types'; | ||
export { Provide } from './plugins/vue'; |
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