c# - 有没有更好的方法来实现 Shift+Tab 或减少缩进?

标签 c# wpf

这就是我实现 Shift-Tab 或减少缩进的方式... screenr 上的结果

if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift && e.Key == Key.Tab)
{
    // Shift+Tab
    int selStart = txtEditor.SelectionStart;
    int selLength = txtEditor.SelectionLength;
    string selText = txtEditor.SelectedText;
    string text = txtEditor.Text;

    // find new lines that are followed by 1 or more spaces
    Regex regex = new Regex(Environment.NewLine + @"(\s+)");
    Match m = regex.Match(selText);
    string spaces;
    while (m.Success)
    {
        GroupCollection grps = m.Groups;
        spaces = grps[1].Value;
        int i = 0;
        // remove 1 space on each loop to a max of 4 spaces
        while (i < 4 && spaces.Length > 0)
        {
            spaces = spaces.Remove(0, 1);
            i++;
        }
        // update spaces in selText
        selText = selText.Remove(grps[1].Index, grps[1].Length).Insert(grps[1].Index, spaces);

        m = regex.Match(selText, grps[1].Index + spaces.Length);
    }

    // commit changes to selText to text 
    text = text.Remove(selStart, selLength).Insert(selStart, selText);

    // decrease indent of 1st line
    // - find 1st character of selection
    regex = new Regex(@"\w");
    m = regex.Match(text, selStart);
    int start = selStart;
    if (m.Success) {
        start = m.Index;
    }
    // - start search for spaces 
    regex = new Regex(Environment.NewLine + @"(\s+)", RegexOptions.RightToLeft);
    m = regex.Match(text, start);
    if (m.Success) {
        spaces = m.Groups[1].Value;
        int i = 0;
        while (i < 4 && spaces.Length > 0) {
            spaces = spaces.Remove(0, 1); // remove 1 space
            i++;
        }
        text = text.Remove(m.Groups[1].Index, m.Groups[1].Length).Insert(m.Groups[1].Index, spaces);
        selStart = m.Groups[1].Index;
    }

    txtEditor.Text = text;
    txtEditor.SelectionStart = selStart;
    txtEditor.SelectionLength = selText.Length;
    e.Handled = true;
}

代码看起来很乱,我想知道是否有更好的方法。

最佳答案

就我个人而言,我不会使用 Regex为此。

未经测试,可能需要修改:

public static class StringExtensions
{
 // Removes leading white-spaces in a string up to a maximum
 // of 'level' characters
 public static string ReduceIndent(this string line, int level)
 { 
   // Produces an IEnumerable<char> with the characters 
   // of the string verbatim, other than leading white-spaces
   var unindentedChars = line.SkipWhile((c, index) => char.IsWhiteSpace(c) && index < level);

   return new string(unindentedChars.ToArray());
 }


 // Applies a transformation to each line of a string and returns the
 // transformed string
 public static string LineTransform(this string text, Func<string,string> transform)
 {
   //Splits the string into an array of lines
   var lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

   //Applies the transformation to each line
   var transformedLines = lines.Select(transform);

   //Joins the transformed lines into a new string
   return string.Join(Environment.NewLine, transformedLines.ToArray());
 } 
}
 ... 

if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift && e.Key == Key.Tab)
{                             
  // Reduces the indent level of the selected text by applying the
  // 'ReduceIndent' transformation to each line of the text.
  string replacement = txtEditor.SelectedText
                                .LineTransform(line => line.ReduceIndent(4));

  int selStart = txtEditor.SelectionStart;
  int selLength = txtEditor.SelectionLength;

  txtEditor.Text = txtEditor.Text
                            .Remove(selStart, selLength)
                            .Insert(selStart, replacement);

  txtEditor.SelectionStart = selStart;
  txtEditor.SelectionLength = replacement.Length;
  e.Handled = true;
}   

编辑:

根据OP的要求向代码添加了注释。

了解更多信息:

关于c# - 有没有更好的方法来实现 Shift+Tab 或减少缩进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3574257/

相关文章:

c# - 不断检查 SQL Server 连接的标准方法是什么?

c# - 如何在 WPF 文本可编辑组合框中设置插入符位置

wpf - 无法在 powershell 中加载 XAML

c# - Lync 2013 无法显示自定义状态

c# - 无法加载文件或程序集 Microsoft.ReportViewer.ProcessingObjectModel,版本 = 13.0.0.0

c# - DataContext.CreateDatabase 正在创建具有随机顺序列的数据库

c# - 在 System.Data.DataTable 中将列定义为可为空

c# - ResourceProviderFactory 周期刷新

c# - WPF&MVVM : Library System. Windows.Interactivity 不再可用?

c# - 使用计时器,如何在时间过去后从另一个用户控件运行功能