Skip to content

Instantly share code, notes, and snippets.

@ErnSur
Created July 1, 2023 08:28
Show Gist options
  • Save ErnSur/842d72606159fdd865979c4d9db21a18 to your computer and use it in GitHub Desktop.
Save ErnSur/842d72606159fdd865979c4d9db21a18 to your computer and use it in GitHub Desktop.
Implementation of the `UnityEditor.ObjectNames.NicifyVariableName` algorithm
using System.Text;
namespace QuickEye.Utility
{
public static class TextUtils
{
public static string NicifyVariableName(string input)
{
var result = new StringBuilder(input.Length * 2);
var prevIsLetter = false;
var prevIsLetterUpper = false;
var prevIsDigit = false;
var prevIsStartOfWord = false;
var prevIsNumberWord = false;
var firstCharIndex = 0;
if (input.StartsWith('_'))
firstCharIndex = 1;
else if (input.StartsWith("m_"))
firstCharIndex = 2;
for (var i = input.Length - 1; i >= firstCharIndex; i--)
{
var currentChar = input[i];
var currIsLetter = char.IsLetter(currentChar);
if (i == firstCharIndex && currIsLetter)
currentChar = char.ToUpper(currentChar);
var currIsLetterUpper = char.IsUpper(currentChar);
var currIsDigit = char.IsDigit(currentChar);
var currIsSpacer = currentChar == ' ' || currentChar == '_';
var addSpace = (currIsLetter && !currIsLetterUpper && prevIsLetterUpper) ||
(currIsLetter && prevIsLetterUpper && prevIsStartOfWord) ||
(currIsDigit && prevIsStartOfWord) ||
(!currIsDigit && prevIsNumberWord) ||
(currIsLetter && !currIsLetterUpper && prevIsDigit);
if (!currIsSpacer && addSpace)
{
result.Insert(0, ' ');
}
result.Insert(0, currentChar);
prevIsStartOfWord = currIsLetter && currIsLetterUpper && prevIsLetter && !prevIsLetterUpper;
prevIsNumberWord = currIsDigit && prevIsLetter && !prevIsLetterUpper;
prevIsLetterUpper = currIsLetter && currIsLetterUpper;
prevIsLetter = currIsLetter;
prevIsDigit = currIsDigit;
}
return result.ToString();
}
}
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace QuickEye.Utility.Tests.Editor
{
public class TextUtilsTests
{
[TestCaseSource(nameof(GetTestCases))]
[TestCaseSource(nameof(GetTestCases2))]
public void Should_OutputMatchUnityEditorMethod_When_NicifyClassName(string input)
{
var expected = UnityEditor.ObjectNames.NicifyVariableName(input);
var actual = TextUtils.NicifyVariableName(input);
Assert.AreEqual(expected, actual);
}
private static IEnumerable GetTestCases()
{
yield return "className2Number";
yield return "className2number";
yield return "_className2number_";
yield return "m_className2number_";
yield return "_m_className2number_";
yield return " _className2number_ ";
yield return "_ className2number _";
yield return "className22Number";
yield return "className222Number";
yield return "className22number";
yield return "className222number";
yield return "className23";
yield return "clasSName23";
yield return "clasSDKName23";
yield return "Class_Name_23";
yield return "SDKName";
yield return "SDK_Name";
yield return "sDK_Name";
yield return "G2A";
yield return "SDK2";
yield return "SDK22";
yield return "SDK2a";
yield return "SDK22a";
yield return "SDk2";
yield return "SDk22";
yield return "SDk2a";
yield return "SDk22a";
yield return "SDK22a2a";
yield return "SDK2a2a";
yield return "SDk2";
yield return "SDk22";
yield return "SDk22a";
yield return "SD K2";
yield return "SD k2";
yield return "SDK2a";
yield return "SDk2A";
yield return "SD2A";
yield return "2 A2 a";
}
private static IEnumerable<string> GetTestCases2()
{
var str = "m_AAA02_";
var results =
from e in Enumerable.Range(0, 1 << str.Length)
let p = from b in Enumerable.Range(0, str.Length)
select (e & (1 << b)) == 0 ? (char?)null : str[b]
select string.Join(string.Empty, p);
return results;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment