mirror of
https://github.com/godotengine/godot-vscode-plugin.git
synced 2025-12-31 13:48:24 +03:00
Improve dragging items from Scene Preview into source code (#661)
Co-authored-by: David Kincaid <daelonsuzuka@gmail.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import {
|
||||
register_command,
|
||||
createLogger,
|
||||
make_docs_uri,
|
||||
node_name_to_snake,
|
||||
} from "../utils";
|
||||
import { SceneParser } from "./parser";
|
||||
import type { SceneNode, Scene } from "./types";
|
||||
@@ -93,6 +94,8 @@ export class ScenePreviewProvider
|
||||
): void | Thenable<void> {
|
||||
data.set("godot/path", new vscode.DataTransferItem(source[0].relativePath));
|
||||
data.set("godot/class", new vscode.DataTransferItem(source[0].className));
|
||||
data.set("godot/unique", new vscode.DataTransferItem(source[0].unique));
|
||||
data.set("godot/label", new vscode.DataTransferItem(source[0].label));
|
||||
}
|
||||
|
||||
public provideDocumentDropEdits(
|
||||
@@ -101,15 +104,43 @@ export class ScenePreviewProvider
|
||||
dataTransfer: vscode.DataTransfer,
|
||||
token: vscode.CancellationToken,
|
||||
): vscode.ProviderResult<vscode.DocumentDropEdit> {
|
||||
const path = dataTransfer.get("godot/path").value;
|
||||
const className = dataTransfer.get("godot/class").value;
|
||||
const path: string = dataTransfer.get("godot/path").value;
|
||||
const className: string = dataTransfer.get("godot/class").value;
|
||||
const line = document.lineAt(position.line);
|
||||
const unique = dataTransfer.get("godot/unique").value === "true";
|
||||
const label: string = dataTransfer.get("godot/label").value;
|
||||
|
||||
// TODO: compare the source scene to the target file
|
||||
// What should happen when you drag a node into a script that isn't the
|
||||
// "main" script for that scene?
|
||||
// Attempt to calculate a relative path that resolves correctly?
|
||||
|
||||
if (className) {
|
||||
// For the root node, the path is empty and needs to be replaced with the node name
|
||||
const savePath = path || label;
|
||||
|
||||
if (path && className) {
|
||||
if (document.languageId === "gdscript") {
|
||||
return new vscode.DocumentDropEdit(`$${path}`);
|
||||
let qualifiedPath = `$${savePath}`;
|
||||
|
||||
if (unique) {
|
||||
// For unique nodes, we can use the % syntax and drop the full path
|
||||
qualifiedPath = `%${label}`;
|
||||
}
|
||||
|
||||
if (line.text === "") {
|
||||
// We assume that if the user is dropping a node in an empty line, they are at the top of
|
||||
// the script and want to declare an onready variable
|
||||
return new vscode.DocumentDropEdit(
|
||||
`@onready var ${node_name_to_snake(label)}: ${className} = ${qualifiedPath}`,
|
||||
);
|
||||
}
|
||||
|
||||
// In any other place, we assume the user wants to get a reference to the node itself
|
||||
return new vscode.DocumentDropEdit(qualifiedPath);
|
||||
}
|
||||
|
||||
if (document.languageId === "csharp") {
|
||||
return new vscode.DocumentDropEdit(`GetNode<${className}>("${path}")`);
|
||||
return new vscode.DocumentDropEdit(`GetNode<${className}>("${savePath}")`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,3 +42,22 @@ export function make_docs_uri(path: string, fragment?: string) {
|
||||
fragment: fragment,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to convert a conventional node name to a snake_case variable name.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* nodeNameToVar("MyNode") // my_node
|
||||
* nodeNameToVar("Sprite2D") // sprite_2d
|
||||
* nodeNameToVar("UI") // ui
|
||||
* ```
|
||||
*/
|
||||
export function node_name_to_snake(name: string): string {
|
||||
const snakeCase: string = name.replace(/([a-z])([A-Z0-9])/g, "$1_$2").toLowerCase();
|
||||
|
||||
if (snakeCase.startsWith("_")) {
|
||||
return snakeCase.substring(1);
|
||||
}
|
||||
return snakeCase;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user