Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make hint labels more like Vimium #27

Merged
merged 1 commit into from
Jan 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions src/HuntAndPeck/Services/HintLabelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,42 +12,50 @@ internal class HintLabelService : IHintLabelService
/// <summary>
/// Gets available hint strings
/// </summary>
/// <remarks>Adapted from vimium to give a consistent experience, see https://github.com/philc/vimium/blob/master/content_scripts/link_hints.coffee </remarks>
/// <remarks>Adapted from vimium to give a consistent experience, see https://github.com/philc/vimium/blob/master/content_scripts/link_hints.js </remarks>
/// <param name="hintCount">The number of hints</param>
/// <returns>A list of hint strings</returns>
public IList<string> GetHintStrings(int hintCount)
{
var hintStrings = new List<string>();
if (hintCount <= 0)
{
return hintStrings;
}

var hintCharacters = new[] { 's', 'a', 'd', 'f', 'j', 'k', 'l', 'e', 'w', 'c', 'm', 'p', 'g', 'h' };
var digitsNeeded = (int)Math.Ceiling(Math.Log(hintCount) / Math.Log(hintCharacters.Length));

var shortHintCount = Math.Floor((Math.Pow(hintCharacters.Length, digitsNeeded) - hintCount) / hintCharacters.Length);
var wholeHintCount = (int)Math.Pow(hintCharacters.Length, digitsNeeded);
var shortHintCount = (wholeHintCount - hintCount) / hintCharacters.Length;
var longHintCount = hintCount - shortHintCount;

var hintStrings = new List<string>();

if (digitsNeeded > 1)
var longHintPrefixCount = wholeHintCount / hintCharacters.Length - shortHintCount;
for (int i = 0, j = 0; i < longHintCount; ++i, ++j)
{
for (var i = 0; i < shortHintCount; ++i)
hintStrings.Add(new string(NumberToHintString(j, hintCharacters, digitsNeeded).Reverse().ToArray()));
if (longHintPrefixCount > 0 && (i + 1) % longHintPrefixCount == 0)
{
hintStrings.Add(NumberToHintString(i, hintCharacters, digitsNeeded - 1));
j += shortHintCount;
}
}

var start = (int)(shortHintCount * hintCharacters.Length);
for (var i = start; i < (start + longHintCount); ++i)
if (digitsNeeded > 1)
{
hintStrings.Add(NumberToHintString(i, hintCharacters, digitsNeeded));
for (var i = 0; i < shortHintCount; ++i)
{
hintStrings.Add(new string(NumberToHintString(i + longHintPrefixCount, hintCharacters, digitsNeeded - 1).Reverse().ToArray()));
}
}

// Note that shuffle is lazy evaluated. Sigh.
return hintStrings.ToList();
}

/// <summary>
/// Converts a number like "8" into a hint string like "JK". This is used to sequentially generate all of the
/// hint text. The hint string will be "padded with zeroes" to ensure its length is >= numHintDigits.
/// </summary>
/// <remarks>Adapted from vimium to give a consistent experience, see https://github.com/philc/vimium/blob/master/content_scripts/link_hints.coffee</remarks>
/// <remarks>Adapted from vimium to give a consistent experience, see https://github.com/philc/vimium/blob/master/content_scripts/link_hints.js</remarks>
/// <param name="number">The number</param>
/// <param name="characterSet">The set of characters</param>
/// <param name="noHintDigits">The number of hint digits</param>
Expand Down