Shortening Long File Paths

We're working on a little shell utility that displays paths in a menu. Some of these paths can get rather long, so I cooked up this little regular expression to shorten them. It's a replacement, so you call it like this:

static string PathShortener(string path)
{
    
const string pattern = @"^(w+:|)([^]+[^]+).*([^]+[^]+)$";
    
const string replacement = "$1$2...$3";
    
if (Regex.IsMatch(path, pattern))
    {
        
return Regex.Replace(path, pattern, replacement);
    }
    
else
    {
        
return path;
    }          
}

So, for these paths:

C:Documents and SettingsjatwoodMy DocumentsVisual Studio 2005SimpleEncryptionUnitTestsUnitTests.vb
wumpuspublicHilo DeliverablesHilo FinalIntroductionCodeIntroApp_Themescellphonephoto-small.jpg

The result is:

C:Documents and Settingsjatwood...UnitTestsUnitTests.vb
wumpuspublic...cellphonephoto-small.jpg

The general strategy is to keep the first two folders at the beginning, replace the middle with an ellipsis, and leave the final folder and filename on the end.

After spending an hour dinking around with this and testing it on a bunch of paths, a colleague pointed me to the Windows API call PathCompactPathEx, which (almost) does the same thing. Doh!

[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx([Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);

static string PathShortener(string path, int length)
{
    
StringBuilder sb = new StringBuilder();
    
PathCompactPathEx(sb, path, length, 0);
    
return sb.ToString();
}

As you can see from the API definition for PathCompactPathEx, this works a little differently. It lets you set an absolute length for the path, and displays as many characters as it can with a "best fit" placement of the ellipsis. Here's the output for our two paths:

C:Documents and Settingsjatwood...UnitTests.vb
wumpuspublicHilo Deliverab...photo-small.jpg

So, which to choose? CompactPathEx guarantees that the paths will always be exactly (x) characters while displaying as much as it can, but it may not be able to split cleanly. My regex always splits cleanly, but makes no guarantees on length.

And obviously, if you're not running Windows, or if you don't care for p/invoke, the API call is clearly out.

Read more

Stay Gold, America

We are at an unprecedented point in American history, and I'm concerned we may lose sight of the American Dream.

By Jeff Atwood · · Comments

The Great Filter Comes For Us All

With a 13 billion year head start on evolution, why haven't any other forms of life in the universe contacted us by now? (Arrival is a fantastic movie. Watch it, but don't stop there - read the Story of Your Life novella it was based on

By Jeff Atwood · · Comments

I Fight For The Users

If you haven't been able to keep up with my blistering pace of one blog post per year, I don't blame you. There's a lot going on right now. It's a busy time. But let's pause and take a moment

By Jeff Atwood · · Comments

The 2030 Self-Driving Car Bet

It's my honor to announce that John Carmack and I have initiated a friendly bet of $10,000* to the 501(c)(3) charity of the winner’s choice: By January 1st, 2030, completely autonomous self-driving cars meeting SAE J3016 level 5 will be commercially available for passenger

By Jeff Atwood · · Comments