private void textEditor_TextArea_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Right && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control && (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) { string xml = _editor.Document.Text; int offset = _editor.CaretOffset; try { if (XParser.IsClosingElement(xml, offset)) { int i = xml.IndexOf('>', offset); if (i > 0) { _editor.CaretOffset = i + 1; } } else if (XParser.IsInsideElementDeclaration(xml, offset)) { if (XParser.IsInsideAttributeKey(xml, offset)) { int i = xml.IndexOf('=', offset); if (i > 0) { _editor.CaretOffset = i + 1; } } else if (XParser.IsInsideAttributeValue(xml, offset)) { int i = xml.IndexOf('>', offset); if (i > 0) { _editor.CaretOffset = i + 1; } } else { //element name int i = xml.IndexOf('>', offset); if (i > 0) { _editor.CaretOffset = i + 1; } } } else if (XParser.IsInsideComment(xml, offset)) { int i = xml.IndexOf("-->", offset); if (i > 0) { _editor.CaretOffset = i + 4; } } else { //text, goto next element int i = xml.IndexOf('<', offset); if (i > 0) { if (i == offset) { i = xml.IndexOf('>', offset); } _editor.CaretOffset = i + 1; } } } catch { Debug.Fail(""); } e.Handled = true; } }
private bool completeBasedOnTextEntered(TextCompositionEventArgs e) { try { switch (e.Text) { case ">": { //auto-insert closing element int offset = _editor.CaretOffset; string s = XParser.GetElementAtCursor(_editor.Text, offset - 1); if (!string.IsNullOrWhiteSpace(s) && "!--" != s) { if (!XParser.IsClosingElement(_editor.Text, offset - 1, s)) { string endElement = "</" + s + ">"; var rightOfCursor = _editor.Text.Substring(offset, Math.Max(0, Math.Min(endElement.Length + 50, _editor.Text.Length) - offset - 1)).TrimStart(); if (!rightOfCursor.StartsWith(endElement)) { _editor.TextArea.Document.Insert(offset, endElement); _editor.CaretOffset = offset; return(true); } } } break; } case "/": { //insert name of closing element int offset = _editor.CaretOffset; if (offset > 1 && _editor.Text[offset - 2] == '<') { //expand to closing tag string s = XParser.GetParentElementAtCursor(_editor.Text, offset - 1); if (!string.IsNullOrEmpty(s)) { showCompletion(new List <ICompletionData> { new MyCompletionData(s + ">") }); return(true); } } if (_editor.Text.Length > offset + 2 && _editor.Text[offset] == '>') { //remove closing tag if exist string s = XParser.GetElementAtCursor(_editor.Text, offset - 1); if (!string.IsNullOrWhiteSpace(s)) { //search closing end tag. Element must be empty (whitespace allowed) //"<hallo> </hallo>" --> enter '/' --> "<hallo/> " string expectedEndTag = "</" + s + ">"; for (int i = offset + 1; i < _editor.Text.Length - expectedEndTag.Length + 1; i++) { if (!char.IsWhiteSpace(_editor.Text[i])) { if (_editor.Text.Substring(i, expectedEndTag.Length) == expectedEndTag) { //remove already existing endTag _editor.Document.Remove(i, expectedEndTag.Length); } break; } } } } break; } case "!": { int offset = _editor.CaretOffset; if (offset > 1 && _editor.Text[offset - 2] == '<') { _editor.TextArea.Document.Insert(offset, "-- "); _editor.CaretOffset = offset + 2; return(true); } break; } case "\"": { //auto-insert closing apostroph int offset = _editor.CaretOffset; int countApostroph = 0; for (int i = offset; i >= 0; i--) { char charAtCursor = _editor.Text[i]; if (charAtCursor == '\"') { countApostroph++; } else if (charAtCursor == '<') { break; } } bool oddLeft = (countApostroph % 2 == 1); for (int i = offset; i < _editor.Text.Length; i++) { char charAtCursor = _editor.Text[i]; if (charAtCursor == '\"') { countApostroph++; } else if (charAtCursor == '>') { break; } } bool oddRight = (countApostroph % 2 == 1); if (oddLeft && oddRight) { _editor.TextArea.Document.Insert(offset, "\""); _editor.CaretOffset = offset; return(true); } break; } case " ": { //when user writes an element/attribute, completion shall pop up on whitespace bool result = checkAttributeCompletion(); if (result) { return(true); } break; } case "<": { if (_schemaParser == null) { return(false); } int offset = _editor.CaretOffset; string parent = XParser.GetParentElementAtCursor(_editor.Text, offset); XsdElement[] names; if (parent == "") { IXsdNode root = _schemaParser.GetVirtualRoot(); names = getChildNames(root); } else { IList <IXsdNode> all = _schemaParser.GetAllNodes(); IXsdNode node = getNodeWithName(all, parent); if (node != null) { names = getChildNames(node); } else { names = null; } } if (names != null && names.Length > 0) { IList <ICompletionData> data = new List <ICompletionData>(); foreach (XsdElement name in names) { if (name.Annotation != null && name.Annotation.Count > 0) { StringBuilder sb = new StringBuilder(); foreach (string ann in name.Annotation) { sb.AppendLine(ann); } data.Add(new MyCompletionData(name.Name, sb.ToString())); } else { data.Add(new MyCompletionData(name.Name)); } } showCompletion(data); return(true); } break; } } } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error"); } return(false); }