I decided to reply here in case someone else is interested.
Unfortunately, I don't know Delphi. The closest is that I've implemented this algorithm in is perhaps C#. I've included the scoring code.
Essentially, each character from the pattern must be in the file name or the score is -1 (no match). Each gap except the first incurs a penalty of (gapPenalty + gap length) unless there is a space character in the input pattern at this point. (The first gap incurs a penalty of (gap length) number of points). The best score is 0.
What you do, is:
1. Take each file name and assign a score to it.
2. Remove any files with score -1 (non matching).
3. Sort the rest according to the score, lowest first.
4. Present this list to the user
The best scoring file is preselected, but the user can select any other score with the up or down arrow keys (or use the mouse). Return commits the current selection.
For some things (like history) it makes sense to reverse the file path that you use for scoring, i.e. make "C:\Folder\Temp" into "Temp\Folder\C:". (You don't necessarily need to display the same path to the user that you use for scoring.)
For demonstration videos, check out screencasts of emacs users that use the plugin "ido.el" which uses a similar algorithm. It really makes you fly through a file system at amazing speeds, and is really good for selecting things from the history.
Code: Select all
private static int score(string fileName, string pattern)
fileName = fileName.ToLower();
pattern = pattern.ToLower();
int i = -1;
int expectedIndex = -1;
int score = 0;
const int gapPenalty = 20;
foreach(char c in pattern)
if (c == ' ')
i = i + 1;
expectedIndex = -1;
int index = fileName.IndexOf(c, i+1);
if (index == -1) return -1;
if (i == -1)
score = index;
else if (expectedIndex != -1 && index != expectedIndex)
score += gapPenalty + (index - expectedIndex);
i = index;
expectedIndex = index + 1;
I am happy to provide more information, or a port to Delphi if need be. I really like this feature and would really love for it to be in FreeCommander.