Paste at selected location in expandable folders

Hi,

I created this script in order to be able to paste into expandable branch folders within a lister view. This allows one to easily transfer files between expandable lister folders with the CTRL+V hotkey.

Its behaviour is different from PASTE USESEL in that PASTE USESEL is only able to paste into the currently selected folder. Whereas this script also allows you to paste at the location of the currently selected file. It also automatically expands the branch folder when pasting.

Code below (To install, add to your Ctrl+V hotkey)

Original commands version: (Standard Function)

Code
@set selFilePath {filepath|regex="(.*\\).*"|to="\1"}
@set pasteDir "{=seldirs == 1 ? filepath$ : (selfiles == 1 ? $selFilePath : sourcepath$)=}"

Go EXPANDBRANCH PATH {$pasteDir}
Clipboard PASTE COPYCOMMANDARGS="TO="{$pasteDir}""

Smart Selection Version: (JScript)

Update 2025-06-04: I finished an updated Smart Selection version with the help of Leo's JScript example. This version is JScript and smartly chooses the Paste location based on the selected items.

How it works:

  • The outer folder common to all selected items becomes the "Selected Location"
  • The paste occurs into that "Selected Location"

Advantages:

  • Whereas the original version allows one to paste at the location of a single file or folder, this version allows one to paste at the location of whatever items are selected, however many they are.
  • It's designed to intuitively paste where you want it based on what items you've selected.

What this means:

  • If a single folder is selected, the paste occurs into that folder.
  • If multiple files or folders are selected, the paste occurs into their common parent directory.
  • If no files or folders are selected, the paste occurs into the current lister directory.

DCF Here: Smart_Paste_Into_Expandable_Folders.dcf (5.8 KB)

Code Here (JScript)
/**
 * Smart Paste Into Expandable Folders v4.
 * Allows one to paste into expandable folders at the location of the currently selected items.
 * If no files or folders are selected, the paste occurs into the main lister directory.
 */
function OnClick(clickData) {
  var cmd = clickData.func.command;
  var path = clickData.func.sourcetab.path;
  var tab = clickData.func.sourcetab;
  
  path = GetSelectedLocation(path, tab); //The paste directory becomes the outermost folder common to all selected items
  
  cmd.SetSource(path);
  cmd.AddLine('Go EXPANDBRANCH PATH "' + path + '"');
  cmd.AddLine('Clipboard PASTE');
  
  cmd.Run();
}


/**
 * GetSelectedLocation: Smartly chooses a "Selected Location" to act in based on the selected items.
 * @returns - The path of the smartly chosen "Selected Location".
 * How it works: 
 * - The outermost folder common to all selected items becomes the "Selected Location"
 * - This allows one to paste into a subfolder when all currently selected files/folders are either the folder itself or its subcontents. 
 */
function GetSelectedLocation(path, tab) {
  //Get the outermost currently selected folder.
  path = "" + path; //Ensures we're dealing with a string, not a path object.
  var selectedLocation = undefined;
  var outerMostFolder = undefined;

  for (var eSel = new Enumerator(tab.selected); !eSel.atEnd(); eSel.moveNext())
  {
    var item = eSel.item();
    var itemPath = "" + item.realpath;
    if (item.is_dir) itemPath = (itemPath + "\\").replace("\\\\", "\\"); //Ensure the path ends in a backslash.
    var itemFolder = itemPath.substr(0, itemPath.lastIndexOf("\\") + 1); //Get path part only, (not filename).
    
    if (!outerMostFolder) outerMostFolder = itemFolder;
    else if (outerMostFolder != itemFolder) {
      if (itemFolder.indexOf(outerMostFolder) >= 0) {
        //The current outerMostFolder is indeed the outerMost of these two.
      } else if (outerMostFolder.indexOf(itemFolder) >= 0) {
        //The current folder is outer.
        outerMostFolder = itemFolder;
      } else {
        //Neither folder is outer so go up until reach a common folder.
        while (itemFolder.indexOf(outerMostFolder) < 0 && outerMostFolder.indexOf("\\") > 0) {
          outerMostFolder = GoUp(outerMostFolder);
        }
      }
    }
  }
  
  if (outerMostFolder != undefined && outerMostFolder.indexOf(path) >= 0) {
    //The outermost folder is within the path, so all is well.
    path = outerMostFolder; //Set the path to the outermost selected folder.
    path = (path + "\\").replace("\\\\", "\\"); //Ensure path ends in backslash.
  } else {
    //The outerMostFolder was somehow not within the path, so fallback to using the existing path (the sourcetab location).
    outerMostFolder = path;
  }
  return path;
}

/**
 * GoUp: Takes a path as input and returns the path of the folder containing it (goes one folder up).
 * @param path - The input folder path: a folder path must end with a backslash for this function to work.
 */
function GoUp(path) {
  return path.substr(0, path.lastIndexOf("\\", path.lastIndexOf("\\")-1)+1);
}



1 Like

Here's the same command but converted into a script.

This should solve the problems discussed in Clipboard PASTE fails with CUT/PASTE when setting TO= directory to subdirectory

Here's a .dcf file you can drag to a toolbar:

Here's the code inside the .dcf file, to show how it works:

function OnClick(clickData)
{
	var tab = clickData.func.sourcetab;
	var cmd = clickData.func.command;

	if (tab.selected_dirs.count == 1)
	{
		cmd.RunCommand('Go EXPANDBRANCH');
		cmd.SetSource(tab.selected_dirs(0));
	}
	else if (tab.selected_files.count == 1)
	{
		cmd.SetSource(tab.selected_files(0).path);
	}

	cmd.ClearFiles();
	cmd.RunCommand('Clipboard PASTE COPYCOMMANDARGS="UPDATESECURITY=YES"');
}
3 Likes

Thanks, that fixed one works great as a Lister hotkey. Set it to CTRL+SHIFT+V to retain the oem paste but really comes in handy.

1 Like

Thanks, that is extremely helpful for my existing smart selection script, I was not aware that one could set the source in that way (with SetSource) to set the paste-to directory. :grinning_face:

Side note, I can't remember why I decided to add the UPDATESECURITY=yes part other than that's how I wanted it to behave, however looking at the Preferences setting "Update permissions/encryption to match destination" (screenshot below), that seems to be the equivalent to setting the default behaviour of UPDATESECURITY, is that correct? (If so I can probably remove that part of the code)

Correct.

Cool. I've updated my "Smart Selection" version with your fixes and shared it in the original post.

I've also removed the UPDATESECURITY part since that isn't needed.

...

Smart selection version:

  • The folder common to all selected items becomes the paste location.
  • It allows one to paste into a subfolder when all currently selected files/folders are either the folder itself or its subcontents.
1 Like