Skip to content

Commit

Permalink
Added File Bunny: Move Folder command.
Browse files Browse the repository at this point in the history
  • Loading branch information
robole committed Jun 11, 2024
1 parent f1fe58a commit bff3439
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 7 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/-0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.4.0] - 2024-06-11

### Added

- Added `File Bunny: Move Folder` command.

### Changed

- Added another subheading level to the "Commands" section in the README. A level 2 section for "File Actions" and "Folder Actions".

## [2.3.0] - 2024-06-06

### Changed
Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ You may want to edit a file in an app specific to that file type. For example, I

The following commands can be run from the Command Palette (`Ctrl+Shift+P`). They are categorised below:

### File actions on the current workspace
### File actions

#### File actions on the current workspace

1. `File Bunny: Open File`: Choose a file to open from the current workspace.
1. `File Bunny: Open File to the Right`: Choose a file to open from the current workspace, and split it to the right of the active editor.
Expand All @@ -96,7 +98,7 @@ The following commands can be run from the Command Palette (`Ctrl+Shift+P`). The
1. `File Bunny: Duplicate File`: Choose a file to duplicate to another location in the current workspace.
1. `File Bunny: Delete File`: Choose a file to delete from the current workspace. The file is put into the trash (recycle bin).

### File actions on the active file
#### File actions on the active file

1. `File Bunny: Open Active File in External Default App`: Open the active file in the system default app.
1. `File Bunny: Move Active File`: Move the active file to another location in the current workspace.
Expand All @@ -106,13 +108,18 @@ The following commands can be run from the Command Palette (`Ctrl+Shift+P`). The

### Folder actions

There are 2 contexts for the folder actions: system (any folder anywhere) and current workspace (folders within open workspace).

#### Folder actions on system

1. `File Bunny: Open Folder`: Choose a folder to open as the workspace.

### Folder actions on the current workspace
#### Folder actions on the current workspace

1. `File Bunny: Open Workspace Folder in External Default App`: Open the current workspace folder in the system file explorer.
1. `File Bunny: Open Folder in External Default App`: Open a folder from the current workspace in the system file explorer.
1. `File Bunny: Create New Folder`: Create a new folder in the current workspace.
1. `File Bunny: Move Folder`: Move a folder from the current workspace, and place it somewhere else in the current workspace. ![recently added](img/new.png)
1. `File Bunny: Duplicate Folder`: Duplicate a folder from the current workspace, and place it somewhere in the current workspace.
1. `File Bunny: Delete Folder`: Delete a folder from the current workspace.

Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"description": "Perform file actions quickly with keyboard-driven file selection. 🐰⌨️",
"icon": "img/logo.png",
"version": "2.3.0",
"version": "2.4.0",
"engines": {
"vscode": "^1.84.0",
"node": ">=12"
Expand Down Expand Up @@ -197,6 +197,11 @@
"category": "File Bunny",
"title": "Create New Folder"
},
{
"command": "filebunny.moveFolder",
"category": "File Bunny",
"title": "Move Folder"
},
{
"command": "filebunny.duplicateFolder",
"category": "File Bunny",
Expand Down
14 changes: 11 additions & 3 deletions src/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,27 +168,34 @@ function activate(context) {
);

let disposable24 = vscode.commands.registerCommand(
"filebunny.moveFolder",
async () => {
await folderAction.moveFolder();
}
);

let disposable25 = vscode.commands.registerCommand(
"filebunny.duplicateFolder",
async () => {
await folderAction.duplicateFolder();
}
);

let disposable25 = vscode.commands.registerCommand(
let disposable26 = vscode.commands.registerCommand(
"filebunny.deleteFolder",
async () => {
await folderAction.deleteFolder();
}
);

let disposable26 = vscode.commands.registerCommand(
let disposable27 = vscode.commands.registerCommand(
"filebunny.openFileExternal",
async () => {
await fileAction.openFileExternal();
}
);

let disposable27 = vscode.commands.registerCommand(
let disposable28 = vscode.commands.registerCommand(
"filebunny.openFolderExternal",
async () => {
await folderAction.openFolderExternal();
Expand Down Expand Up @@ -223,6 +230,7 @@ function activate(context) {
disposable25,
disposable26,
disposable27,
disposable28,
];
}

Expand Down
14 changes: 14 additions & 0 deletions src/folderAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const Browser = require("./browser");
const globPicker = require("./globPicker");
const NewFolderPicker = require("./newFolderPicker");
const DuplicateFolderPicker = require("./duplicateFolderPicker");
const MoveFolderPicker = require("./moveFolderPicker");
const fileSystem = require("./fileSystem");

async function openRecentFolder() {
Expand Down Expand Up @@ -73,6 +74,18 @@ async function createFolder() {
await picker.run();
}

async function moveFolder() {
if (util.isWorkspaceOpen() === false) {
vscode.window.showWarningMessage(
"Cannot move a folder. There is no workspace open."
);
return;
}

let picker = new MoveFolderPicker();
await picker.run();
}

async function duplicateFolder() {
if (util.isWorkspaceOpen() === false) {
vscode.window.showWarningMessage(
Expand Down Expand Up @@ -177,6 +190,7 @@ module.exports = {
openRecentFolder,
openFolder,
createFolder,
moveFolder,
duplicateFolder,
deleteFolder,
openWorkspaceFolderExternal,
Expand Down
166 changes: 166 additions & 0 deletions src/moveFolderPicker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// @ts-nocheck
// eslint-disable-next-line node/no-missing-require, import/no-unresolved
const vscode = require("vscode");
const nodePath = require("path");
const Step = require("./step");
const globPicker = require("./globPicker");
const MultiStepPicker = require("./multiStepPicker");
const configuration = require("./configuration");
const util = require("./util");

class MoveFolderPicker extends MultiStepPicker {
constructor() {
let steps = [
new Step(1, `Move Folder`, "Pick a folder to move", []),
new Step(
2,
`Move to`,
"Pick a location for the moved folder",
[],
[vscode.QuickInputButtons.Back]
),
];

super(steps);

if (vscode.workspace.workspaceFolders !== undefined) {
this.rootFolder = vscode.workspace.workspaceFolders[0].uri.fsPath;
}

let disposable1 = this.picker.onDidChangeValue(
this.onDidChangeValue.bind(this)
);
this.disposables.push(disposable1);

let disposable2 = this.picker.onDidChangeActive(
this.onDidChangeActive.bind(this)
);
this.disposables.push(disposable2);
}

async run() {
if (vscode.workspace.workspaceFolders === undefined) {
return;
}
this.picker.show();

this.picker.busy = true;

let absoluteExcludes = configuration.getAbsoluteExcludes(this.rootFolder);

let folderList = await globPicker.getFilesRecursivelyAsPickerItems(
this.rootFolder,
{
showFiles: false,
showFolders: true,
excludes: absoluteExcludes,
includeTopFolder: true,
topFolderDescription: "Workspace Root",
}
);
this.steps[0].items = folderList;
this.steps[1].items = folderList;

this.setCurrentStep(this.steps[0]);
this.picker.busy = false;
}

async onDidAccept() {
if (this.currentStepNum === 1) {
let pickedItem = this.picker.selectedItems[0].name;

let currentIndex = this.currentStepNum - 1;
this.steps[currentIndex].value = pickedItem;

this.absoluteFromPath = nodePath.join(
this.rootFolder,
this.steps[0].value
);

this.picker.value = "";
this.setCurrentStep(this.steps[currentIndex + 1]);
} else if (this.currentStepNum === 2) {
let pickedItem = this.picker.selectedItems[0].name;

let currentIndex = this.currentStepNum - 1;
this.steps[currentIndex].value = pickedItem;
this.move();
}
}

goBack() {
if (this.currentStepNum > 1) {
let previousIndex = this.currentStepNum - 2;
let currentIndex = this.currentStepNum - 1;

this.picker.enabled = false;
this.steps[currentIndex].value = "";
this.setCurrentStep(this.steps[previousIndex]);

// required to clear filter if text was entered in last step
setTimeout(() => {
this.picker.value = this.steps[previousIndex].value;
this.picker.items = this.steps[previousIndex].items;
}, 20);
this.picker.enabled = true;
}
}

onDidChangeValue() {
this.onDidChangeActive(); // same behaviour desirable for any input change
}

onDidChangeActive() {
if (this.currentStepNum === 1) {
let folderName = this.picker.activeItems[0].name;
let truncatedName = util.truncateName(folderName);
this.setTitle(`Move '${truncatedName}'`);
} else if (this.currentStepNum === 2) {
let truncatedFromFolder = util.truncateName(this.steps[0].value);
let truncatedToFolder = util.truncateName(
this.picker.activeItems[0].name
);

this.setTitle(`Move '${truncatedFromFolder}' to '${truncatedToFolder}'`);
}
}

setTitle(value) {
this.picker.title = value;
}

async move() {
let absoluteFromUri = vscode.Uri.file(this.absoluteFromPath);

let absoluteToPath;
let toFolder = nodePath.basename(this.absoluteFromPath);

if (this.steps[1].value === globPicker.currentFolderName) {
absoluteToPath = nodePath.join(this.rootFolder, toFolder);
} else {
absoluteToPath = nodePath.join(
this.rootFolder,
this.steps[1].value,
toFolder
);
}

let absoluteToUri = vscode.Uri.file(absoluteToPath);

try {
await vscode.workspace.fs.copy(absoluteFromUri, absoluteToUri, {
overwrite: false,
});
await vscode.workspace.fs.delete(absoluteFromUri, {
recursive: true,
boolean: true,
});
} catch (err) {
vscode.window.showErrorMessage(err.message);
}

this.close();
}
}

module.exports = MoveFolderPicker;

0 comments on commit bff3439

Please sign in to comment.