Remember selection in each folder

Go inside folder, select something, press Backspace (Go UP BACK), press Enter to return to folder.
Is it possible to restore the selection in this case?

If you push Enter it always reads a fresh copy of the folder.

If you click the Back button to go back down to where you were, the previous selection is remembered.

But it's possible to write a script that saves on select and restores on entering folder?

A script could probably do that, yeah. Or the script could remember where you went back from and change what happens when you enter the folder to a Back command instead.

This seems to be working :slight_smile:

function OnBeforeFolderChange(beforeFolderChangeData) {
	if (beforeFolderChangeData.action == "refresh") return;
	var tab = beforeFolderChangeData.tab;
	var selected = tab.selected;
	var path = "SavedSelection:" + tab.path;
	if (selected.count == 0) {
		DOpus.Vars.Delete(path);
	} else {
		var file = selected(0).realpath.filepart;
		if (file.indexOf("|") >= 0) file = file.split("|")[1];
		DOpus.Vars.Set(path, file);
		DOpus.Vars(path).persist = true;
	}
}

function OnAfterFolderChange(afterFolderChangeData) {
	var ignoreActions = DOpus.Create.StringSetI("parent", "back", "forward", "refresh");
	if (ignoreActions.exists(afterFolderChangeData.action)) return;
	var tab = afterFolderChangeData.tab;
	var path = "SavedSelection:" + tab.path;
	var cmd = DOpus.Create.Command();
	cmd.SetSourceTab(tab);
	if (DOpus.Vars.Exists(path))
		cmd.RunCommand("Select \"" + DOpus.Vars.Get(path) + "\" EXACT DESELECTNOMATCH MAKEVISIBLE");
	else
		cmd.RunCommand("Select First");
}

Nicely done!

Do you only want to save a single selection? You can store a list of selected items in the vars object if you need to.

It might also make more sense to use the Tab.Vars object rather than the global DOpus.Vars so the selection stays local to the tab (unless you want it to be applied in other tabs as well, of course).

Or Lister.Vars... Is this correct for persistent vars? Doesn't work if I close layout's lister.

Code
function OnBeforeFolderChange(beforeFolderChangeData) {
	if (beforeFolderChangeData.action == "refresh") return;
	var tab = beforeFolderChangeData.tab;
	var selected = tab.selected;
	var path = "SavedSelection:" + tab.path;
	var vars = tab.lister.vars;
	if (selected.count == 0) {
		vars.Delete(path);
	} else {
		vars.Set(path, selected(0).realpath.filepart);
		vars(path).persist = true;
	}
}

function OnAfterFolderChange(afterFolderChangeData) {
	var ignoreActions = DOpus.Create.StringSetI("parent", "back", "forward", "refresh");
	if (ignoreActions.exists(afterFolderChangeData.action)) return;
	var tab = afterFolderChangeData.tab;
	var path = "SavedSelection:" + tab.path;
	var vars = tab.lister.vars;
	var cmd = DOpus.Create.Command();
	cmd.SetSourceTab(tab);
	if (vars.Exists(path))
		cmd.RunCommand("Select \"" + vars.Get(path) + "\" EXACT DESELECTNOMATCH MAKEVISIBLE");
	else
		cmd.RunCommand("Select First");
}

You'd need to re-save the layout after setting the vars if you wanted the tab-based vars to persist through the window being closed and re-created.

(Other things like Folder Tab Groups also persist tab variables when saved/loaded.)

If you want that then your old method is probably better than what I was suggesting, at least unless you also wanted individual windows or tabs to remember different selections for the same folders as each other.

(Doing both at once is probably possible, but would be a lot more complex.)

Yes, adding persist to original code works, but second one doesn't work even after saving layout.
Doesn't matter, I won't be saving it manually each time anyway, and remembering selection during a single session is enough, it won't make vars pile up :slight_smile:

BTW, script fails to work with mtp:// files, they have prefixes in filename, e.g. ?o446?|music
Added some string splitting :thinking:

The ?o446?| type prefixes with MTP files are because MTP allows two files/folders with the same name in the same path, so internally we add something to ensure they're unique.