Skip to content

Commit

Permalink
Merge branch 'master' of github.com:shirou/vscode-dired
Browse files Browse the repository at this point in the history
  • Loading branch information
shirou committed Jan 7, 2023
2 parents cbcc079 + f772759 commit 4d427b0
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 49 deletions.
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
"version": "0.1.0",
"configurations": [

{
"name": "Launch Extension",
"type": "extensionHost",
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
"command": "extension.dired.createDir",
"when": "dired.open && !findWidgetVisible && !inQuickOpen"
},
{
"key": "ctrl+x =",
"command": "extension.dired.createFile",
"when": "dired.open && !findWidgetVisible && !inQuickOpen"
},
{
"key": "shift+r",
"command": "extension.dired.rename",
Expand Down
61 changes: 61 additions & 0 deletions src/autocompletedInputBox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as vscode from 'vscode';

export function defaultFinishCondition(self: vscode.QuickPick<vscode.QuickPickItem>) {
if (self.selectedItems.length == 0 || self.selectedItems[0].label == self.value) {
return true;
}
else {
self.value = self.selectedItems[0].label;
return false;
}
}

export async function autocompletedInputBox<T>(
arg: {
completion: (userinput: string) => Iterable<vscode.QuickPickItem>,
withSelf?: undefined | ((self: vscode.QuickPick<vscode.QuickPickItem>) => any),
stopWhen?: undefined | ((self: vscode.QuickPick<vscode.QuickPickItem>) => boolean)
}) {
const completionFunc = arg.completion;
const processSelf = arg.withSelf;

let finishCondition = defaultFinishCondition;
if (arg.stopWhen != undefined)
finishCondition = defaultFinishCondition


const quickPick = vscode.window.createQuickPick();
quickPick.canSelectMany = false;
let disposables: vscode.Disposable[] = [];
let result = quickPick.value;
if (processSelf !== undefined)
processSelf(quickPick);

let makeTask = () => new Promise<void>(resolve => {
disposables.push(
quickPick.onDidChangeValue(directoryOrFile => {
quickPick.items = Array.from(completionFunc(quickPick.value))
return 0;
}),
quickPick.onDidAccept(() => {
if (finishCondition(quickPick)) {
result = quickPick.value;
quickPick.hide();
resolve();
}
}),
quickPick.onDidHide(() => {
quickPick.dispose();
resolve();
})
);
quickPick.show();
});
try {
await makeTask();
}
finally {
disposables.forEach(d => d.dispose());
}
return quickPick.value;
}
104 changes: 96 additions & 8 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import FileItem from './fileItem';

import * as fs from 'fs';
import * as path from 'path';
import { autocompletedInputBox } from './autocompletedInputBox';

export interface ExtensionInternal {
DiredProvider: DiredProvider,
Expand Down Expand Up @@ -70,14 +71,12 @@ export function activate(context: vscode.ExtensionContext): ExtensionInternal {
provider.toggleDotFiles();
});

const commandCreateDir = vscode.commands.registerCommand("extension.dired.createDir", () => {
vscode.window.showInputBox()
.then((dirName) => {
if (!dirName) {
return;
}
provider.createDir(dirName);
});
const commandCreateDir = vscode.commands.registerCommand("extension.dired.createDir", async () => {
let dirName = await vscode.window.showInputBox({ prompt: "Directory name" });
if (!dirName) {
return;
}
await provider.createDir(dirName);
});
const commandRename = vscode.commands.registerCommand("extension.dired.rename", () => {
vscode.window.showInputBox()
Expand Down Expand Up @@ -116,12 +115,101 @@ export function activate(context: vscode.ExtensionContext): ExtensionInternal {
vscode.commands.executeCommand('workbench.action.closeActiveEditor');
});

const commandCreateFile = vscode.commands.registerCommand("extension.dired.createFile", async () => {
function* completionFunc(filePathOrDirPath: string): IterableIterator<vscode.QuickPickItem> {
let dirname: string;
if (!path.isAbsolute(filePathOrDirPath)) {
if (provider.dirname == undefined)
return
filePathOrDirPath = path.join(provider.dirname, filePathOrDirPath);
}
try {
let stat = fs.statSync(filePathOrDirPath);
if (stat.isDirectory()) {
dirname = filePathOrDirPath;
yield {
detail: "Open " + path.basename(filePathOrDirPath) + "/",
label: filePathOrDirPath,
buttons: [ { iconPath: vscode.ThemeIcon.Folder } ]
};
}
else {
yield {
detail: "Open " + path.basename(filePathOrDirPath),
label: filePathOrDirPath,
buttons: [ { iconPath: vscode.ThemeIcon.File } ]
};

dirname = path.dirname(filePathOrDirPath);
}
}
catch
{
yield {
detail: "Create " + path.basename(filePathOrDirPath),
label: filePathOrDirPath,
buttons: [ { iconPath: vscode.ThemeIcon.File } ]
}
dirname = path.dirname(filePathOrDirPath);
try {
fs.accessSync(filePathOrDirPath, fs.constants.F_OK);
}
catch
{
return;
}
}
for (let name of fs.readdirSync(dirname)) {
const fullpath = path.join(dirname, name);
if (fs.statSync(fullpath).isDirectory())
yield {
label: fullpath, detail: "Open " + name + "/",
buttons: [ { iconPath: vscode.ThemeIcon.Folder } ]
}
else
yield {
label: fullpath, detail: "Open" + name,
buttons: [ { iconPath: vscode.ThemeIcon.File } ]
}
}
}
function processSelf(self: vscode.QuickPick<vscode.QuickPickItem>) {
self.placeholder = "Create File or Open"
}
let fileName = await autocompletedInputBox(
{
completion: completionFunc,
withSelf: processSelf,
});
vscode.window.showInformationMessage(fileName);
let isDirectory = false;

try {
let stat = await fs.promises.stat(fileName);
if (stat.isDirectory())
isDirectory = true;
}
catch {
await fs.promises.mkdir(path.dirname(fileName), { recursive: true })
await fs.promises.writeFile(fileName, "");
}

if (isDirectory) {
provider.openDir(fileName)
}
else {
await provider.createFile(fileName)
}

});

context.subscriptions.push(
provider,
commandOpen,
commandEnter,
commandToggleDotFiles,
commandCreateDir,
commandCreateFile,
commandRename,
commandCopy,
commandGoUpDir,
Expand Down
28 changes: 14 additions & 14 deletions src/fileItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export default class FileItem {
}

public line(): string {
const u = (this._username + " ").substr(0, 8);
const g = (this._groupname + " ").substr(0, 8);
const u = (this._username + " ").substring(0, 8);
const g = (this._groupname + " ").substring(0, 8);
const size = this.pad(this._size, 8, " ");
const month = this.pad(this._month, 2, "0");
const day = this.pad(this._day, 2, "0");
Expand All @@ -74,18 +74,18 @@ export default class FileItem {
}

public static parseLine(dir: string, line: string): FileItem {
const filename = line.substr(52);
const username = line.substr(13, 8);
const groupname = line.substr(22, 8);
const size = parseInt(line.substr(31, 8));
const month = parseInt(line.substr(40, 2));
const day = parseInt(line.substr(43, 2));
const hour = parseInt(line.substr(46, 2));
const min = parseInt(line.substr(49, 2));
const modeStr = line.substr(2, 10);
const isDirectory = (modeStr.substr(0, 1) === "d");
const isFile = (modeStr.substr(0, 1) === "-");
const isSelected = (line.substr(0, 1) === "*");
const filename = line.substring(52);
const username = line.substring(13, 13 + 8);
const groupname = line.substring(22, 22 + 8);
const size = parseInt(line.substring(31, 31 + 8));
const month = parseInt(line.substring(40, 40 + 2));
const day = parseInt(line.substring(43, 43 + 2));
const hour = parseInt(line.substring(46, 46 + 2));
const min = parseInt(line.substring(49, 49 + 2));
const modeStr = line.substring(2, 2 + 10);
const isDirectory = (modeStr.substring(0, 0 + 1) === "d");
const isFile = (modeStr.substring(0, 1) === "-");
const isSelected = (line.substring(0, 1) === "*");

return new FileItem(
dir,
Expand Down
19 changes: 9 additions & 10 deletions src/idResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as readline from 'readline';
import * as path from 'path'

export class IDResolver {
private _user_cache = new Map<Number, string>();
Expand All @@ -20,19 +21,17 @@ export class IDResolver {
}

private create(user: boolean){
let path: string;
if (user) {
path = '/etc/passwd';
} else {
path = '/etc/group';
}
// create a cache file in the user's home directory for Windows and Unix
const home = require('os').homedir();
const cache_file = user ? '.vscode-dired-user-cache' : '.vscode-dired-group-cache';
const cache_path = path.join(home, cache_file);

if (fs.existsSync(path) === false) {
vscode.window.showErrorMessage(`Could not get stat of ${path}`);
return;
if (fs.existsSync(cache_file) === false) {
// create empty file
fs.writeFileSync(cache_path, '');
}
const rl = readline.createInterface({
input: fs.createReadStream(path),
input: fs.createReadStream(cache_file),
});
rl.on('line', (line:string) => {
const l = line.split(":", 3);
Expand Down
Loading

0 comments on commit 4d427b0

Please sign in to comment.