ICompletionDataList GenerateCompletionData(CodeCompletionContext completionContext, PythonModule module, TextEditorData editor, char completionChar) { var triggerWord = GetTriggerWord (editor, completionContext); // Its annoying when the data is poped up during an assignment such as: // abc = _ if (completionChar == '=' && String.IsNullOrEmpty (triggerWord)) return null; var triggerLine = editor.GetLineText (completionContext.TriggerLine); // if completionChar is ' ' and it is not a known completion type // that we can handle, return as early as possible if (completionChar == ' ') { if (!triggerWord.Contains ('.') && !triggerLine.StartsWith ("class") && !triggerLine.StartsWith ("def") && !triggerLine.StartsWith ("from") && !triggerLine.StartsWith ("import")) return null; } // "self." if (module != null && triggerWord == "self" && completionChar == '.') { var klass = GetClass (module, completionContext.TriggerLine); if (klass == null) return null; // nothing to complete, self not in a class return new CompletionDataList (SelfDotCompletionData (klass)); } var inFrom = triggerLine.StartsWith ("from "); var inClass = triggerLine.StartsWith ("class ") || (triggerLine.StartsWith ("class") && completionChar == ' '); var inDef = triggerLine.StartsWith ("def ") || (triggerLine.StartsWith ("def") && completionChar == ' '); var parts = triggerLine.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // "from blah " if (inFrom && parts.Length == 2 && completionChar == ' ') { return new CompletionDataList (new CompletionData[] { new CompletionData ("import") }); } // "from blah import " else if (inFrom && parts.Length > 2) { triggerWord = parts [1] + "."; return new CompletionDataList ( from ParserItem item in m_site.Database.Find (triggerWord) where !item.FullName.Substring (triggerWord.Length).Contains ('.') select CreateCompletionData (item, triggerWord)) ; } // if we are in a new class line and not to '(' yet // we cannot complete anything at this time, finish now if (inClass && parts.Length < 2) return null; // if we are in a new def line, the only time we can complete // is after an equal '='. so ignore space trigger if (inDef && completionChar == ' ') return null; else if (inDef && completionChar == '=') triggerWord = ""; if (inClass) { if (completionChar == '(') triggerWord = ""; else triggerWord = triggerLine.Substring (triggerLine.LastIndexOf ('(') + 1); } // limit the depth of search to number of "." in trigger // "xml." has depth of 1 so anything matching ^xml. and no more . with match int depth = 0; foreach (var c in triggerWord) if (c == '.') depth++; // anything in the sqlite store if (!String.IsNullOrEmpty (triggerWord)) { // todo: try to complete on class/module/func/attr data return new CompletionDataList ( from ParserItem item in m_site.Database.Find (triggerWord, ParserItemType.Any, depth) select CreateCompletionData (item, triggerWord)) ; } ParserItemType itemType = String.IsNullOrEmpty (triggerWord) ? ParserItemType.Module : ParserItemType.Any; return new CompletionDataList ( from ParserItem item in m_site.Database.Find ("", itemType, depth) select CreateCompletionData (item, triggerWord)) ; }
static string GetTriggerWord(TextEditorData editor, CodeCompletionContext completionContext) { // Get the line of text for our current line // and trim off everything after the cursor var line = editor.GetLineText (completionContext.TriggerLine); line = line.Substring (0, completionContext.TriggerLineOffset - 1); // Walk backwards looking for split chars and then trim the // beginning of the line off for (int i = line.Length - 1; i >= 0; i--) { switch (line [i]) { case ' ': case '(': case '\t': case '=': return line.Substring (i + 1, line.Length - 1 - i); default: break; } } return line; }
public static void SortSelectedLines(TextEditorData data) { var start = data.MainSelection.Start; var end = data.MainSelection.End; var caret = data.Caret.Location; int startLine = start.Line; int endLine = end.Line; if (startLine == endLine) { return; } int length = 0; var lines = new string[endLine - startLine + 1]; for (int i = startLine; i <= endLine; i++) { //get lines *with* line endings var lineText = data.GetLineText(i, true); lines[i - startLine] = lineText; length += lineText.Length; } var linesUnsorted = new string[lines.Length]; Array.Sort(lines, StringComparer.Ordinal); bool changed = false; for (int i = 0; i <= lines.Length; i++) { //can't simply use reference comparison as Array.Sort is not stable if (string.Equals(lines[i], linesUnsorted[i], StringComparison.Ordinal)) { continue; } changed = true; break; } if (!changed) { return; } var sb = new StringBuilder(); for (int i = 0; i < lines.Length; i++) { sb.Append(lines[i]); } var startOffset = data.Document.LocationToOffset(new TextLocation(startLine, 0)); data.Replace(startOffset, length, sb.ToString()); data.Caret.Location = LimitColumn(data, caret); data.SetSelection(LimitColumn(data, start), LimitColumn(data, end)); }
// Snatched from DefaultFormattingStrategy private string GetIndent (TextEditorData d, int lineNumber, int terminateIndex) { string lineText = d.GetLineText (lineNumber); if(terminateIndex > 0) lineText = terminateIndex < lineText.Length ? lineText.Substring(0, terminateIndex) : lineText; StringBuilder whitespaces = new StringBuilder (); foreach (char ch in lineText) { if (!char.IsWhiteSpace (ch)) break; whitespaces.Append (ch); } return whitespaces.ToString (); }
public static void SortSelectedLines (TextEditorData data) { var start = data.MainSelection.Start; var end = data.MainSelection.End; var caret = data.Caret.Location; int startLine = start.Line; int endLine = end.Line; if (startLine == endLine) return; int length = 0; var lines = new string[endLine - startLine + 1]; for (int i = startLine; i <= endLine; i++) { //get lines *with* line endings var lineText = data.GetLineText (i, true); lines [i - startLine] = lineText; length += lineText.Length; } var linesUnsorted = new string[lines.Length]; Array.Sort (lines, StringComparer.Ordinal); bool changed = false; for (int i = 0; i <= lines.Length; i++) { //can't simply use reference comparison as Array.Sort is not stable if (string.Equals (lines [i], linesUnsorted [i], StringComparison.Ordinal)) { continue; } changed = true; break; } if (!changed) { return; } var sb = new StringBuilder (); for (int i = 0; i < lines.Length; i++) { sb.Append (lines [i]); } var startOffset = data.Document.LocationToOffset (new TextLocation (startLine, 0)); data.Replace (startOffset, length, sb.ToString ()); data.Caret.Location = LimitColumn (data, caret); data.SetSelection (LimitColumn (data, start), LimitColumn (data, end)); }