Skip to content

Commit

Permalink
feat: drag and drop snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
zjffun committed Apr 13, 2024
1 parent 0136a6c commit d3c08b6
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

# [Unreleased]

# v0.3.2

- Added features drag and drop snippets.
- Added features paste snippets after the selected snippet.
- Fixed bug copy snippets when selected workspaces or extensions.

# v0.3.1

Fixed set currentWebviewPanel to null when dispose.
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@ Search workspace, user or extension snippets.

![search](images/search.webp)

### Copy&Paste snippets
### Copy & Paste snippets

Copy&Paste snippets across workspace, user or extension.

## Darg & Drop snippets

Drag&Drop snippets across workspace, user or extension.

## Settings

### `snippetsManager.autoCloseSnippetBodyEditor`
Expand Down
4 changes: 4 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@

复制粘贴工作区、用户或拓展程序的代码片段。

## 拖拽代码片段

拖拽工作区、用户或拓展程序的代码片段。

## 配置

### `snippetsManager.autoCloseSnippetBodyEditor`
Expand Down
1 change: 1 addition & 0 deletions src/CodeSnippetsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ export class CodeSnippetsService {

tree.push({
name: folder.name,
isWorkspace: true,
children: workspaceSnippetFiles,
});
}
Expand Down
97 changes: 97 additions & 0 deletions src/core/moveSnippets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import * as vscode from "vscode";
import { ISnippet, ISnippetExtra } from "..";
import { CodeSnippetsService } from "../CodeSnippetsService";

export const movingSnippetsMimeType =
"application/vnd.code.tree.snippetsmanager-moving-snippets";

export default async (
targetSnippet: ISnippetExtra,
sourceSnippets: ISnippet[]
) => {
if (!targetSnippet.uri) {
return;
}

if (!sourceSnippets.length) {
return;
}

const snippetsTextDoc = await vscode.workspace.openTextDocument(
targetSnippet.uri
);

const codeSnippetsService = new CodeSnippetsService(snippetsTextDoc);

const targetSnippetIndex = targetSnippet.index || 0;

if (
sourceSnippets.length === 1 &&
sourceSnippets[0].uri?.toString() === targetSnippet.uri?.toString()
) {
// moving one snippet within the same file
const snippet = sourceSnippets[0];

if (snippet.name && snippet.index !== targetSnippetIndex) {
await codeSnippetsService.delete(snippet.name);
await codeSnippetsService.insert(snippet, {
index: targetSnippetIndex,
});
}
} else {
let currentTargetIndex = targetSnippet.index;
if (currentTargetIndex === undefined) {
currentTargetIndex = 0;
} else {
currentTargetIndex++;
}

for (const snippet of sourceSnippets) {
if (!snippet.uri || !snippet.name) {
continue;
}

if (snippet.uri.toString() === targetSnippet.uri?.toString()) {
// If the snippet is the same as the target snippet, update it position (delete then insert)

if (snippet.name) {
if (
snippet.index !== undefined &&
snippet.index <= targetSnippetIndex
) {
currentTargetIndex--;
}

await codeSnippetsService.delete(snippet.name);

await codeSnippetsService.insert(snippet, {
index: currentTargetIndex,
});
}
} else {
// If the snippet is not the same as the target snippet, move it (insert then delete)
await codeSnippetsService.insert(snippet, {
index: currentTargetIndex,
});

const sourceSnippetsTextDoc = await vscode.workspace.openTextDocument(
snippet.uri
);

const sourceCodeSnippetsService = new CodeSnippetsService(
sourceSnippetsTextDoc
);

await sourceCodeSnippetsService.delete(snippet.name);
}

currentTargetIndex++;
}
}

// Can't use refreshAllView directly because of circular dependency
const { default: refreshAllView } = await import("../views/refreshAllView");
refreshAllView();

return true;
};
1 change: 1 addition & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface ISnippets {
export interface ISnippetContainer {
name: string;
isFile?: boolean;
isWorkspace?: boolean;
isExtension?: boolean;
uri?: vscode.Uri;
children: ISnippetContainer[] | ISnippet[];
Expand Down
5 changes: 3 additions & 2 deletions src/utils/getSnippets.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { ISnippet, ISnippetContainer } from "..";

export default function getSnippets(
snippet: ISnippet,
snippet: ISnippet | undefined,
snippets: (ISnippet | ISnippetContainer)[]
) {
if (snippets) {
const result = snippets.filter(
(s) =>
!(s as ISnippetContainer).isFile &&
!(s as ISnippetContainer).isExtension
!(s as ISnippetContainer).isExtension &&
!(s as ISnippetContainer).isWorkspace
);
return result as ISnippet[];
}
Expand Down
50 changes: 50 additions & 0 deletions src/views/BasicSnippetsExplorerView.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as vscode from "vscode";
import moveSnippets, { movingSnippetsMimeType } from "../core/moveSnippets";
import getSnippets from "../utils/getSnippets";
import { ISnippet, ISnippetContainer } from "..";

export class SnippetTreeItem extends vscode.TreeItem {
Expand Down Expand Up @@ -31,6 +33,54 @@ export default abstract class BasicSnippetsExplorerView
treeDataProvider: that,
showCollapseAll: true,
canSelectMany: true,
dragAndDropController: {
dragMimeTypes: [movingSnippetsMimeType],
dropMimeTypes: [movingSnippetsMimeType],
handleDrag(
source: (ISnippet | ISnippetContainer)[],
dataTransfer,
token
) {
const snippets = getSnippets(undefined, source);

if (!snippets.length) {
token.isCancellationRequested = true;
return;
}

dataTransfer.set(
movingSnippetsMimeType,
new vscode.DataTransferItem(snippets)
);
},
async handleDrop(
target: ISnippet | ISnippetContainer,
dataTransfer,
token
) {
if (
(target as ISnippetContainer)?.isWorkspace ||
(target as ISnippetContainer)?.isExtension
) {
token.isCancellationRequested = true;
return;
}

let snippets = dataTransfer.get(movingSnippetsMimeType)?.value;

if (typeof snippets === "string") {
snippets = JSON.parse(snippets, function (key, value) {
if (key === "uri") {
return vscode.Uri.from(value);
}

return value;
});
}

await moveSnippets(target, snippets);
},
},
});
}, 0);
}
Expand Down

0 comments on commit d3c08b6

Please sign in to comment.