вот так я реализовал 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;
}
код выглядит неопрятно, и мне интересно, есть ли лучший способ