Create File/Folder (FAYT)

Simple FAYT script that allows you to create a file or folder. This project is largely my attempt to port @Hurpin's indispensable Better "New Text Document" Script into FAYT

Creates a folder by default. Supports creating nested folders, and files of any type. E.g. including ".ext" creates a file of that type instead. If you wish to write contents to that file, insert a : (followed by the content).

The default activation key is //. After that you just enter the command in the filter bar that pops up. Requires version 13.19.2 to have // as the activation key. If you are on an earlier version, you can change the key in Preferences/Quick Keys.

14/11/25

  • I have found that '.' actually works better as the activation key.

Examples:

Create file type

  • Name.txt: content. Blah blah blah

Create folder

  • Folder name

Create nested folders

  • Folder1/Folder2/Folder3

FAYT_Create.opusscriptinstall (1.8 KB)

// J.Fourie 
// Create File/Folder FAYT v1.3
// Folder by default, file if one dot, write content after colon. Supports nested folders.
// E.g. //MyFolder/SubFolder
// E.g. //Note.txt: Quick notes go here.

if (!String.prototype.trim) {
    String.prototype.trim = function () {
        return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
    };
}

var fsu = DOpus.FSUtil();

function OnInit(initData) {
    initData.name = "FAYT:Create";
    initData.version = "1.1";
    initData.desc = "Quick folder creation by default, file if one dot. Supports :content. Now supports nested folders. Folder does NOT auto-open.";
    initData.min_version = "13";
    initData.default_enable = true;
}

function OnAddCommands(addCmdData) {
    var c = addCmdData.AddCommand();
    c.name = "FAYT:Create";
    c.method = "OnFAYT";
    c.hide = true;

    var f = c.fayt;
    f.enable = true;
    f.key = "//";  // Activation key
    f.realtime = true;
    f.wantempty = true;
}

function OnFAYT(data) {
    if (data.key !== "return") return;

    var tab = data.tab;
    if (!tab) return;

    var cmdline = String(data.cmdline || "").trim();

    // Remove leading // if present
    if (cmdline.indexOf("//") === 0) {
        cmdline = cmdline.slice(2);
    }

    cmdline = cmdline.trim();
    if (!cmdline) return;

    // Split name and content at the first colon
    var idx = cmdline.indexOf(":");
    var rawName = (idx >= 0 ? cmdline.slice(0, idx) : cmdline).trim();
    var content = (idx >= 0 ? cmdline.slice(idx + 1) : "").trim();

    // Clean path and allow nested folders
    rawName = rawName.replace(/[\\:\*\?"<>\|]/g, "").replace(/\//g, "\\");

    if (!rawName) rawName = "NewFile";

    var parts = rawName.split(".");
    var isFile = (parts.length === 2); // one dot only

    var baseDir = String(tab.path);
    var target = uniqueName(baseDir, rawName, isFile);

    if (isFile) {
        // Create parent folders if needed
        var parent = fsu.NewPath(target).Parent;
        if (parent && parent.IsValid && !fsu.Exists(parent)) {
            var cmd = DOpus.Create().Command();
            cmd.ClearFiles();
            cmd.AddLine('CreateFolder NAME="' + String(parent) + '"');
            cmd.Run();
        }

        // Create the file
        var fh = fsu.OpenFile(target, "w");
        if (fh && fh.error === 0) {
            if (content) fh.Write(content);
            fh.Close();
            DOpus.Output("[Created File] " + target);
        } else {
            DOpus.Output("[ERROR] Failed to create file: " + target);
        }
    } else {
        var cmd2 = DOpus.Create().Command();
        cmd2.RunCommand('CreateFolder NAME="' + target + '"');
        DOpus.Output("[Created Folder] " + target);
    }

    tab.CloseFAYT();
}

function uniqueName(basePath, relPath, isFile) {
    var path = fsu.NewPath(basePath);
    var name = relPath;
    var base = name, ext = "";

    var sep = name.lastIndexOf("\\");
    var folder = (sep >= 0 ? name.slice(0, sep) : "");
    name = (sep >= 0 ? name.slice(sep + 1) : name);

    var dot = name.lastIndexOf(".");
    if (isFile && dot > 0) {
        base = name.slice(0, dot);
        ext = name.slice(dot);
    } else {
        base = name;
    }

    var sub = fsu.NewPath(basePath);
    if (folder) sub.Add(folder);
    var full = sub + "\\" + base + ext;

    for (var i = 2; fsu.Exists(full); i++) {
        full = sub + "\\" + base + " (" + i + ")" + ext;
    }

    return full;
}


1 Like

Well, at least you made me discover @Hurpin ‘s script (I hadn’t see yet that one).

But I’m not a FAYT user, so I’m not sure what it does exactly. But I’ll find out in time.

1 Like

Neat. I will check this out. Glad my better new text document thingy is helpful/inspiring. I feel like it should've been a standard feature 30 years ago. Lol

2 Likes

@jfour18
How do you use this? Where does the code go? Thanks

In preferences go to quick keys. You have to press an activation key, and then you just type it. I forget the default activation key, but i have mine bound to //.

really nice feature)

command "//test.txt" creates one folder "true" and one file "test.txt". any way to fix?

I'll have a look when im at my pc later today.

Fixed. It was the result of changing the activation key from ? to //. I had tested it with the original ?. I have updated the original post with updated script. It also now sets // to the activation key by default.

Maybe you can join a script file and explain what to do with it like here:

And that the default quick key is //

:wink:

1 Like

Good idea. I have updated the original post.

1 Like

Here is a .js file to add to the scripts folder.

Create File-Folder (FAYT).js.txt (3.5 KB)

1 Like

Thanks, but I know how it works.
I was suggesting putting a file in the first post, first to make it easier to install and especially for beginners.

@AlbatorV
As I can't edit the OP, I thought I would do the next best thing.

I misses the first part of your comment. Will do when im back at my pc :slight_smile: