Writing a path and saving it

Hi everyone!

I am in the middle of a project that involves navigating a lot of directories to find my files. I was thinking it would be nice to implement a feature that would save my last selected path and open to it via FileDialog, the next time I use SC.

My thinking is that I will likely need to use Document to set a string of the PathName somewhere in the .scd file. I am having a little trouble getting Document to behave usefully, though - is there a way to set a string on a specified line of code? I was thinking

Document.current.setLine(30).string_("test path", -1, 1)

But this doesn’t seem to operate as one might expect.

Also, I am curious to know if there is a better solution for this problem - I suspect this approach might be unorthodox.

Thanks for the help!

Maybe it is easier to create an external file like last_used_path which only contains the string of the last path - load and save this after each usage?

Modifying the source code by line referencing sounds prone to errors :slight_smile:

2 Likes

Supercollider IDE does have a ‘session’ mode which lets you do this, I’ve used it a few times but never seen someone talk about it!?


This is how I manage projects, making sure to not have any global variables in any file but main.scd.
The goal is to put everything needed for the project here so you can move the directory around later and so you don’t have to go file hunting.

/my_project
   /audio
      /fileA.wav
      /fileB.wav
   /effectdefs
   /synthdefs
   /patterns ... or whatever
   main.scd   <-- the file you load when you want to start the project

This way, if you name the file nicely, you can just turn directories into dictionaries… e.g.,

~audio = PathName(thisProcess.nowExecutingPath.dirname +/+ "/audio")
.entries
.collect({ |path|
	path.fileNameWithoutExtension.asSymbol -> Buffer.read(s, path.asAbsolutePath)
})
.asEvent;

~audio[\fileA];   // names are the same as the file
~audio[\fileB];
1 Like

I really simple tool for this kind of thing is the Archive class.

Archive.put(\lastPath, "/last/opened/path");
Archive.write(); // now your path is saved to disk

// immediately after OR the next time you launch sc, you can recall it with:
Archive.at(\test);

So maybe something like this?

Dialog.openPanel(
    okFunc: {
        |path|
        Archive.put(\myProject, \mostRecentPath, path);
        Archive.write;
    },
    path: Archive.at(\myProject, \mostRecentPath) ?? { "~/Desktop".standardizePath }
)
1 Like

Though I don’t think this is the BEST approach - just to answer your question specifically: you can only really get and set the entire contents of a Document. You need to figure out lines yourself:

~docString = Document.currentDocument.string;
// modify ~docString to look like what you want
Document.currentDocument.string = ~docString

I’ve done what you’re describing once in a while - it’s a bit easier if you have something to search for rather than just using lines. The you can use e.g. use findRegexp to find where to replace the text.

//  <LAST USED PATH>
~last_path = "/asdf/asdf/asdf"
// </LAST USED PATH>
~found = ~str.findRegexp("// <LAST USED PATH>\n(.*)\n// </LAST USED PATH>");