Repository: veler/DevToys
File: src/dev/impl/DevToys/ViewModels/Tools/Text/StringUtilities/StringUtilitiesToolViewModel.cs (C#)

Code before:
        #endregion

        #region AlphabetizeLastCommand

        public IRelayCommand AlphabetizeLastCommand { get; }

        private void ExecuteAlphabetizeLastCommand()
        {
            string? text = _textBackup;
            if (text is null)
            {
                return;
            }

            var lines = text.Split('\r').ToList();
            lines.Sort((line1, line2) =>
            {
                string? line1LastWord = line1.Split(' ', ',').LastOrDefault();
                string? line2LastWord = line2.Split(' ', ',').LastOrDefault();

                if (string.Equals(line1LastWord, line2LastWord, StringComparison.CurrentCulture))
                {
                    return 0;
                }

                var newList = new List<string> { line1LastWord, line2LastWord }.OrderBy(word => word).ToList();
                return newList.IndexOf(line1LastWord) == 0 ? -1 : 1;
            });
            text = string.Join('\r', lines);

            lock (_lockObject)
            {
                _forbidBackup = true;
                Text = text;
                _forbidBackup = false;
            }
        }

        #endregion

        #region ReverseAlphabetizeLastCommand

        public IRelayCommand ReverseAlphabetizeLastCommand { get; }

        private void ExecuteReverseAlphabetizeLastCommand()
        {
            string? text = _textBackup;
            if (text is null)
            {
                return;
            }

Review comment (suggestion):
This feels weird, can we use `string.Compare` directly instead? We should be able to replace these two entire lines with something like `string.Compare(line1LastWord, line2LastWord, StringComparison.CurrentCulture) == 0 ? -1 : 1`

Code after:
        {
            string? text = _textBackup;
            if (text is null)
            {
                return;
            }

            IOrderedEnumerable<string> lines = text.Split('\r').OrderBy(_ => _random.Next());
            text = string.Join('\r', lines);

            SetTextWithoutBackup(text);
        }

        #endregion

        private void SetTextWithoutBackup(string? text)
        {
            lock (_lockObject)
            {
                _forbidBackup = true;
                Text = text;
                _forbidBackup = false;
            }
        }

        private string SnakeConstantKebabCobolCaseConverter(string text, char spaceReplacement, bool isUpperCase)
        {
            var snakeCaseStringBuilder = new StringBuilder();

            bool nextNonLetterOrDigitShouldBeIgnored = true;
            for (int i = 0; i < text.Length; i++)
            {
                char currentChar = text[i];
                if (char.IsLetterOrDigit(currentChar))
                {
                    nextNonLetterOrDigitShouldBeIgnored = false;
                    if (isUpperCase)
                    {
                        snakeCaseStringBuilder.Append(char.ToUpperInvariant(currentChar));
                    }
                    else
                    {
                        snakeCaseStringBuilder.Append(char.ToLowerInvariant(currentChar));
                    }
                }
                else if (currentChar == '\r')
                {
                    nextNonLetterOrDigitShouldBeIgnored = true;
                    snakeCaseStringBuilder.Append(currentChar);
                }
                else if (!nextNonLetterOrDigitShouldBeIgnored)