Hello,
1) Regarding why de-indenting End isn't working, I would first suggest you put a breakpoint on that line to see if it's even called when you expect, such as when pressing Enter. If it is, then see what the indent amount result you are returning is, and if it's what you expect. If it is a value one too many (which keeps the End line indented from the base line index) then you would need to step through your GetIndentAmount logic and debug why it's not de-indenting a level.
2) For the second question, our VBIndentProvider does this kind of thing to watch for space being typed:
protected virtual void OnDocumentTextChanged(SyntaxEditor editor, EditorSnapshotChangedEventArgs e) {
if ((editor != null) && (!editor.Document.IsReadOnly) && (e != null) && (e.TextChange != null) && (e.TextChange.Source == editor.ActiveView) && (e.TextChange.Operations?.Count == 1)) {
var typedText = e.TypedText;
switch (typedText) {
case " ":
this.AutoIndent(editor, new TextSnapshotOffset(e.NewSnapshot, e.TextChange.Operations[0].InsertionEndOffset), s => {
// Ensure the comparison is case-insensitive
if (s != null)
s = s.ToUpperInvariant();
switch (s) {
case "CASE ":
case "CATCH ":
case "ELSE ":
case "ELSEIF ":
case "END ": // Shouldn't have a line terminator after though
case "FINALLY ":
case "LOOP ":
case "NEXT ":
return true;
default:
return false;
}
});
break;
}
}
}
Where it's calling an AutoIndent method that looks at the characters before the space and makes sure they match one of those case statements. That way, we aren't indenting all the time at spaces, only when appropriate, after one of those keywords.
And our AutoIndent method is:
private void AutoIndent(SyntaxEditor editor, TextSnapshotOffset snapshotOffset, Func<string, bool> predicate) {
if (editor == null)
throw new ArgumentNullException("editor");
if ((!snapshotOffset.IsDeleted) && (snapshotOffset.Offset > 0)) {
// Get the snapshot line
var snapshotLine = snapshotOffset.Snapshot.Lines[snapshotOffset.Position.Line];
// If there is a predicate, use it to validate whether the auto-indent should occur
var firstNonWhitespaceCharacterOffset = snapshotLine.FirstNonWhitespaceCharacterOffset;
if (predicate != null) {
var lineStartText = snapshotOffset.Snapshot.GetSubstring(new TextRange(snapshotLine.StartOffset, snapshotOffset.Offset)).TrimStart();
if (!predicate(lineStartText))
return;
}
// Get the current and desired indent amounts
var indentAmount = snapshotLine.IndentAmount;
var desiredIndentAmount = this.GetIndentAmount(new TextSnapshotOffset(snapshotOffset.Snapshot, firstNonWhitespaceCharacterOffset), indentAmount);
if (indentAmount != desiredIndentAmount) {
// Generate the auto-indent text
string indentText = StringHelper.GetIndentText(editor.Document.AutoConvertTabsToSpaces, editor.Document.TabSize, desiredIndentAmount);
// Indent
var textChange = snapshotOffset.Snapshot.CreateTextChange(TextChangeTypes.AutoIndent, new TextChangeOptions() { RetainSelection = true });
textChange.ReplaceText(new TextRange(snapshotLine.StartOffset, firstNonWhitespaceCharacterOffset), indentText);
textChange.Apply();
}
}
}