/// <summary> /// Insert e.g. * or + on the freshly created line in order to continue e.g. the multiline comment or string. /// </summary> bool FixLineStart(int lineNumber) { if (lineNumber > DocumentLocation.MinLine) { var line = textEditorData.Document.GetLine(lineNumber); if (line == null) { return(false); } var prevLine = textEditorData.Document.GetLine(lineNumber - 1); if (prevLine == null) { return(false); } string trimmedPreviousLine = textEditorData.Document.GetTextAt(prevLine).TrimStart(); // DDoc tag const string singleLineDDocOpener = "///"; if (trimmedPreviousLine.StartsWith(singleLineDDocOpener)) { if (textEditorData.GetTextAt(line.Offset, line.Length).TrimStart().StartsWith(singleLineDDocOpener)) { return(false); } textEditorData.EnsureCaretIsNotVirtual(); var sb = new StringBuilder(); sb.Append(prevLine.GetIndentation(textEditorData.Document)); sb.Append(singleLineDDocOpener); int i = 3; for (; i < trimmedPreviousLine.Length && trimmedPreviousLine[i] == ' '; i++) { ; } sb.Append(' ', i - 3); int indentSize = line.GetIndentation(textEditorData.Document).Length; textEditorData.Replace(line.Offset, indentSize, sb.ToString()); textEditorData.Caret.Offset = line.Offset + sb.Length; return(true); } //multi-line comments else if (stateTracker.Engine.IsInsideMultiLineComment && Policy.InsertStarAtCommentNewLine) { var commentChar = stateTracker.Engine.IsInsideNestedComment ? "+" : "*"; if (textEditorData.GetTextAt(line.Offset, line.Length).TrimStart().StartsWith(commentChar)) { return(false); } textEditorData.EnsureCaretIsNotVirtual(); string commentPrefix = string.Empty; if (trimmedPreviousLine.StartsWith(commentChar + " ")) { commentPrefix = commentChar + " "; } else if (trimmedPreviousLine.StartsWith("/" + commentChar + commentChar) || trimmedPreviousLine.StartsWith("/" + commentChar)) { commentPrefix = " " + commentChar + " "; } else if (trimmedPreviousLine.StartsWith(commentChar)) { commentPrefix = commentChar; } int indentSize = line.GetIndentation(textEditorData.Document).Length; var insertedText = prevLine.GetIndentation(textEditorData.Document) + commentPrefix; textEditorData.Replace(line.Offset, indentSize, insertedText); textEditorData.Caret.Offset = line.Offset + insertedText.Length; return(true); } } return(false); }
public bool FixLineStart (TextEditorData textEditorData, IStateMachineIndentEngine stateTracker, int lineNumber) { if (lineNumber > DocumentLocation.MinLine) { DocumentLine line = textEditorData.Document.GetLine (lineNumber); if (line == null) return false; DocumentLine prevLine = textEditorData.Document.GetLine (lineNumber - 1); if (prevLine == null) return false; string trimmedPreviousLine = textEditorData.Document.GetTextAt (prevLine).TrimStart (); //xml doc comments //check previous line was a doc comment //check there's a following line? if (trimmedPreviousLine.StartsWith ("///", StringComparison.Ordinal)) { if (textEditorData.GetTextAt (line.Offset, line.Length).TrimStart ().StartsWith ("///", StringComparison.Ordinal)) return false; //check that the newline command actually inserted a newline textEditorData.EnsureCaretIsNotVirtual (); var nextLineSegment = textEditorData.Document.GetLine (lineNumber + 1); string nextLine = nextLineSegment != null ? textEditorData.Document.GetTextAt (nextLineSegment).TrimStart () : ""; if (trimmedPreviousLine.Length > "///".Length || nextLine.StartsWith ("///", StringComparison.Ordinal)) { var insertionPoint = textEditorData.Caret.Offset; int inserted = textEditorData.Insert (insertionPoint, "/// "); textEditorData.Caret.Offset = insertionPoint + inserted; return true; } //multi-line comments } else if (stateTracker.IsInsideMultiLineComment) { if (textEditorData.GetTextAt (line.Offset, line.Length).TrimStart ().StartsWith ("*", StringComparison.Ordinal)) return false; textEditorData.EnsureCaretIsNotVirtual (); string commentPrefix = string.Empty; if (trimmedPreviousLine.StartsWith ("* ", StringComparison.Ordinal)) { commentPrefix = "* "; } else if (trimmedPreviousLine.StartsWith ("/**", StringComparison.Ordinal) || trimmedPreviousLine.StartsWith ("/*", StringComparison.Ordinal)) { commentPrefix = " * "; } else if (trimmedPreviousLine.StartsWith ("*", StringComparison.Ordinal)) { commentPrefix = "*"; } int indentSize = line.GetIndentation (textEditorData.Document).Length; var insertedText = prevLine.GetIndentation (textEditorData.Document) + commentPrefix; textEditorData.Replace (line.Offset, indentSize, insertedText); textEditorData.Caret.Offset = line.Offset + insertedText.Length; return true; } else if (wasInStringLiteral) { var lexer = new CSharpCompletionEngineBase.MiniLexer (textEditorData.Document.GetTextAt (0, prevLine.EndOffset)); lexer.Parse (); if (!lexer.IsInString) return false; textEditorData.EnsureCaretIsNotVirtual (); textEditorData.Insert (prevLine.Offset + prevLine.Length, "\" +"); int indentSize = line.GetIndentation (textEditorData.Document).Length; var insertedText = prevLine.GetIndentation (textEditorData.Document) + (trimmedPreviousLine.StartsWith ("\"", StringComparison.Ordinal) ? "" : "\t") + "\""; textEditorData.Replace (line.Offset, indentSize, insertedText); return true; } } return false; }
void ICompletionWidget.SetCompletionText(CodeCompletionContext ctx, string partial_word, string complete_word) { TextEditorData data = this.GetTextEditorData(); if (data == null || data.Document == null) { return; } int triggerOffset = ctx.TriggerOffset; int length = String.IsNullOrEmpty(partial_word) ? 0 : partial_word.Length; bool blockMode = false; if (data.IsSomethingSelected) { blockMode = data.MainSelection.SelectionMode == Mono.TextEditor.SelectionMode.Block; if (blockMode) { data.Caret.PreserveSelection = true; triggerOffset = data.Caret.Offset - length; } else { if (data.SelectionRange.Offset < ctx.TriggerOffset) { triggerOffset = ctx.TriggerOffset - data.SelectionRange.Length; } data.DeleteSelectedText(); } length = 0; } // | in the completion text now marks the caret position int idx = complete_word.IndexOf('|'); if (idx >= 0) { complete_word = complete_word.Remove(idx, 1); } else { idx = complete_word.Length; } triggerOffset += data.EnsureCaretIsNotVirtual(); data.Document.EndAtomicUndo(); if (blockMode) { data.Document.BeginAtomicUndo(); int minLine = data.MainSelection.MinLine; int maxLine = data.MainSelection.MaxLine; int column = triggerOffset - data.Document.GetLineByOffset(triggerOffset).Offset; for (int lineNumber = minLine; lineNumber <= maxLine; lineNumber++) { LineSegment lineSegment = data.Document.GetLine(lineNumber); if (lineSegment == null) { continue; } int offset = lineSegment.Offset + column; data.Replace(offset, length, complete_word); } data.Caret.Offset = triggerOffset + idx; int minColumn = System.Math.Min(data.MainSelection.Anchor.Column, data.MainSelection.Lead.Column); data.MainSelection.Anchor = new DocumentLocation(data.Caret.Line == minLine ? maxLine : minLine, minColumn); data.MainSelection.Lead = new DocumentLocation(data.Caret.Line, this.Caret.Column); data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine); data.Caret.PreserveSelection = false; } else { //string word = GetWordBeforeCaret (editor).Trim (); //if (word.Length > 0) // offset = DeleteWordBeforeCaret (editor); //int triggerOffset2 =FindPrevWordOffset(triggerOffset); int triggerOffset2 = FindPrevWordOffset(this.Caret.Offset); string word = FindPrevWord(this.Caret.Offset); length = word.Length; /*if (triggerOffset2 != triggerOffset){ * this.Remove (triggerOffset2, triggerOffset - triggerOffset2); * this.Caret.Offset = triggerOffset2; * }*/ data.Replace(triggerOffset2, length, complete_word); data.Caret.Offset = triggerOffset2 + idx; //data.Replace (triggerOffset, length, complete_word); //data.Caret.Offset = triggerOffset + idx; data.Document.BeginAtomicUndo(); } data.Document.CommitLineUpdate(data.Caret.Line); }