[Monodevelop-patches-list] r711 - in trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor: . CodeCompletion Gui
commit-watcher at mono-cvs.ximian.com
commit-watcher at mono-cvs.ximian.com
Thu Jan 29 10:59:07 EST 2004
Author: tberman
Date: 2004-01-29 10:59:07 -0500 (Thu, 29 Jan 2004)
New Revision: 711
Added:
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionData.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionDataProvider.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CommentCompletionDataProvider.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionWindow.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/DeclarationViewWindow.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionData.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionDataProvider.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TemplateCompletionDataProvider.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TextUtilities.cs
Modified:
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorDisplayBinding.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorView.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorWidget.cs
trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile
Log:
some pieces of code complete *DISPLAY* work in the new source editor.
ben, you need to look at why the parser doesnt seem to work.
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionData.cs (from rev 704, trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionData.cs)
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionData.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionData.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,270 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Xml;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.IO;
+
+using SharpDevelop.Internal.Parser;
+using ICSharpCode.TextEditor;
+using ICSharpCode.SharpDevelop.Services;
+using ICSharpCode.Core.Services;
+using ICSharpCode.TextEditor.Gui.CompletionWindow;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ class CodeCompletionData : ICompletionDataWithMarkup
+ {
+ static ClassBrowserIconsService classBrowserIconService = (ClassBrowserIconsService)ServiceManager.Services.GetService(typeof(ClassBrowserIconsService));
+ static IParserService parserService = (IParserService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IParserService));
+ static AmbienceService ambienceService = (AmbienceService)ServiceManager.Services.GetService(typeof(AmbienceService));
+
+ int imageIndex;
+ int overloads;
+ string text;
+ string description;
+ string pango_description;
+ string documentation;
+ string completionString;
+ IClass c;
+ bool convertedDocumentation = false;
+
+ static IAmbience PangoAmbience {
+ get {
+ IAmbience asvc = ambienceService.CurrentAmbience;
+ asvc.ConversionFlags |= ConversionFlags.IncludePangoMarkup;
+ return asvc;
+ }
+ }
+
+ public int Overloads {
+ get {
+ return overloads;
+ }
+ set {
+ overloads = value;
+ }
+ }
+
+ public int ImageIndex {
+ get {
+ return imageIndex;
+ }
+ set {
+ imageIndex = value;
+ }
+ }
+
+ public string[] Text {
+ get {
+ return new string[] { text };
+ }
+ set {
+ text = value[0];
+ }
+ }
+ public string Description {
+ get {
+ // get correct delegate description (when description is requested)
+ // in the classproxies aren't methods saved, therefore delegate methods
+ // must be get through the real class instead out of the proxy
+ //
+ // Mike
+ if (c is ClassProxy && c.ClassType == ClassType.Delegate) {
+ description = ambienceService.CurrentAmbience.Convert(parserService.GetClass(c.FullyQualifiedName));
+ pango_description = PangoAmbience.Convert(parserService.GetClass(c.FullyQualifiedName));
+ c = null;
+ }
+
+ // don't give a description string, if no documentation or description is provided
+ if (description.Length + documentation.Length == 0) {
+ return null;
+ }
+ if (!convertedDocumentation) {
+ convertedDocumentation = true;
+ try {
+ documentation = GetDocumentation(documentation);
+ // new (by G.B.)
+ // XmlDocument doc = new XmlDocument();
+ // doc.LoadXml("<doc>" + documentation + "</doc>");
+ // XmlNode root = doc.DocumentElement;
+ // XmlNode paramDocu = root.SelectSingleNode("summary");
+ // documentation = paramDocu.InnerXml;
+ } catch (Exception e) {
+ Console.WriteLine(e.ToString());
+ }
+ }
+ return (description + (overloads > 0 ? " (+" + overloads + " overloads)" : String.Empty) + "\n" + documentation).Trim ();
+ }
+ set {
+ description = value;
+ }
+ }
+
+ public string DescriptionPango {
+ get {
+ // get correct delegate description (when description is requested)
+ // in the classproxies aren't methods saved, therefore delegate methods
+ // must be get through the real class instead out of the proxy
+ //
+ // Mike
+ if (c is ClassProxy && c.ClassType == ClassType.Delegate) {
+ description = ambienceService.CurrentAmbience.Convert(parserService.GetClass(c.FullyQualifiedName));
+ pango_description = PangoAmbience.Convert(parserService.GetClass(c.FullyQualifiedName));
+ c = null;
+ }
+
+ // don't give a description string, if no documentation or description is provided
+ if (description.Length + documentation.Length == 0) {
+ return null;
+ }
+ if (!convertedDocumentation) {
+ convertedDocumentation = true;
+ try {
+ documentation = GetDocumentation(documentation);
+ // new (by G.B.)
+ // XmlDocument doc = new XmlDocument();
+ // doc.LoadXml("<doc>" + documentation + "</doc>");
+ // XmlNode root = doc.DocumentElement;
+ // XmlNode paramDocu = root.SelectSingleNode("summary");
+ // documentation = paramDocu.InnerXml;
+ } catch (Exception e) {
+ Console.WriteLine(e.ToString());
+ }
+ }
+ return (pango_description + (overloads > 0 ? " (+" + overloads + " overloads)" : String.Empty) + "\n" + documentation).Trim ();
+ }
+ set {
+ description = value;
+ }
+ }
+
+ public CodeCompletionData(string s, int imageIndex)
+ {
+ description = pango_description = documentation = String.Empty;
+ text = s;
+ completionString = s;
+ this.imageIndex = imageIndex;
+ }
+
+ public CodeCompletionData(IClass c)
+ {
+ // save class (for the delegate description shortcut
+ this.c = c;
+ imageIndex = classBrowserIconService.GetIcon(c);
+ text = c.Name;
+ completionString = c.Name;
+ description = ambienceService.CurrentAmbience.Convert(c);
+ pango_description = PangoAmbience.Convert(c);
+ documentation = c.Documentation;
+ }
+
+ public CodeCompletionData(IMethod method)
+ {
+ imageIndex = classBrowserIconService.GetIcon(method);
+ text = method.Name;
+ description = ambienceService.CurrentAmbience.Convert(method);
+ pango_description = PangoAmbience.Convert (method);
+ completionString = method.Name;
+ documentation = method.Documentation;
+ }
+
+ public CodeCompletionData(IField field)
+ {
+ imageIndex = classBrowserIconService.GetIcon(field);
+ text = field.Name;
+ description = ambienceService.CurrentAmbience.Convert(field);
+ pango_description = PangoAmbience.Convert (field);
+ completionString = field.Name;
+ documentation = field.Documentation;
+ }
+
+ public CodeCompletionData(IProperty property)
+ {
+ imageIndex = classBrowserIconService.GetIcon(property);
+ text = property.Name;
+ description = ambienceService.CurrentAmbience.Convert(property);
+ pango_description = PangoAmbience.Convert (property);
+ completionString = property.Name;
+ documentation = property.Documentation;
+ }
+
+ public CodeCompletionData(IEvent e)
+ {
+ imageIndex = classBrowserIconService.GetIcon(e);
+ text = e.Name;
+ description = ambienceService.CurrentAmbience.Convert(e);
+ pango_description = PangoAmbience.Convert (e);
+ completionString = e.Name;
+ documentation = e.Documentation;
+ }
+
+ public void InsertAction(SourceEditorView control)
+ {
+ //((SharpDevelopTextAreaControl)control).ActiveTextAreaControl.TextArea.InsertString(completionString);
+ }
+
+ public static string GetDocumentation(string doc)
+ {
+ System.IO.StringReader reader = new System.IO.StringReader("<docroot>" + doc + "</docroot>");
+ XmlTextReader xml = new XmlTextReader(reader);
+ StringBuilder ret = new StringBuilder();
+ Regex whitespace = new Regex(@"\s+");
+
+ try {
+ xml.Read();
+ do {
+ if (xml.NodeType == XmlNodeType.Element) {
+ string elname = xml.Name.ToLower();
+ if (elname == "remarks") {
+ ret.Append("Remarks:\n");
+ } else if (elname == "example") {
+ ret.Append("Example:\n");
+ } else if (elname == "exception") {
+ ret.Append("Exception: " + GetCref(xml["cref"]) + ":\n");
+ } else if (elname == "returns") {
+ ret.Append("Returns: ");
+ } else if (elname == "see") {
+ ret.Append(GetCref(xml["cref"]) + xml["langword"]);
+ } else if (elname == "seealso") {
+ ret.Append("See also: " + GetCref(xml["cref"]) + xml["langword"]);
+ } else if (elname == "paramref") {
+ ret.Append(xml["name"]);
+ } else if (elname == "param") {
+ ret.Append(xml["name"].Trim() + ": ");
+ } else if (elname == "value") {
+ ret.Append("Value: ");
+ }
+ } else if (xml.NodeType == XmlNodeType.EndElement) {
+ string elname = xml.Name.ToLower();
+ if (elname == "para" || elname == "param") {
+ ret.Append("\n");
+ }
+ } else if (xml.NodeType == XmlNodeType.Text) {
+ ret.Append(whitespace.Replace(xml.Value, " "));
+ }
+ } while(xml.Read());
+ } catch {
+ return doc;
+ }
+ return ret.ToString();
+ }
+
+ static string GetCref(string cref)
+ {
+ if (cref == null) return "";
+ if (cref.Length < 2) return cref;
+ if (cref.Substring(1, 1) == ":") return cref.Substring(2, cref.Length - 2);
+ return cref;
+ }
+
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionDataProvider.cs (from rev 704, trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionDataProvider.cs)
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionDataProvider.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionDataProvider.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,156 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Drawing;
+using System.Diagnostics;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Xml;
+
+using ICSharpCode.Core.Properties;
+using ICSharpCode.SharpDevelop.Internal.Templates;
+using ICSharpCode.TextEditor.Document;
+using ICSharpCode.TextEditor;
+using ICSharpCode.Core.Services;
+using ICSharpCode.SharpDevelop.Services;
+using SharpDevelop.Internal.Parser;
+using ICSharpCode.TextEditor.Gui.CompletionWindow;
+using ICSharpCode.SharpDevelop.Gui;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ /// <summary>
+ /// Data provider for code completion.
+ /// </summary>
+ public class CodeCompletionDataProvider : ICompletionDataProvider
+ {
+ static ClassBrowserIconsService classBrowserIconService = (ClassBrowserIconsService)ServiceManager.Services.GetService(typeof(ClassBrowserIconsService));
+// static AmbienceService ambienceService = (AmbienceService)ServiceManager.Services.GetService(typeof(AmbienceService));
+ Hashtable insertedElements = new Hashtable();
+ Hashtable insertedPropertiesElements = new Hashtable();
+ Hashtable insertedEventElements = new Hashtable();
+
+ public Gdk.Pixbuf[] ImageList {
+ get {
+ PixbufList list = classBrowserIconService.ImageList;
+ return (Gdk.Pixbuf[])list.ToArray (typeof(Gdk.Pixbuf));
+ }
+ }
+
+ int caretLineNumber;
+ int caretColumn;
+ string fileName;
+
+ ArrayList completionData = null;
+
+ public ICompletionData[] GenerateCompletionData(string fileName, SourceEditorView textArea, char charTyped)
+ {
+ //FIXME: THIS IS A HACK
+ string lang = "C#";
+ Console.WriteLine ("resolve " + lang);
+ Console.WriteLine ("nm " + fileName);
+ completionData = new ArrayList();
+ this.fileName = fileName;
+
+ Gtk.TextIter insertIter = textArea.Buffer.GetIterAtMark (textArea.Buffer.InsertMark);
+
+ // the parser works with 1 based coordinates
+
+ caretLineNumber = insertIter.Line + 1;
+ caretColumn = insertIter.LineOffset + 1;
+ string expression = TextUtilities.GetExpressionBeforeOffset (textArea, insertIter.Offset);
+ ResolveResult results;
+
+ if (expression.Length == 0) {
+ return null;
+ }
+ IParserService parserService = (IParserService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IParserService));
+ if (charTyped == ' ') {
+ if (expression == "using" || expression.EndsWith(" using") || expression.EndsWith("\tusing")|| expression.EndsWith("\nusing")|| expression.EndsWith("\rusing")) {
+ string[] namespaces = parserService.GetNamespaceList("");
+// AddResolveResults(new ResolveResult(namespaces, ShowMembers.Public));
+ AddResolveResults(new ResolveResult(namespaces));
+// IParseInformation info = parserService.GetParseInformation(fileName);
+// ICompilationUnit unit = info.BestCompilationUnit as ICompilationUnit;
+// if (unit != null) {
+// foreach (IUsing u in unit.Usings) {
+// if (u.Region.IsInside(caretLineNumber, caretColumn)) {
+// foreach (string usingStr in u.Usings) {
+// results = parserService.Resolve(usingStr, caretLineNumber, caretColumn, fileName);
+// AddResolveResults(results);
+// }
+// if (u.Aliases[""] != null) {
+// results = parserService.Resolve(u.Aliases[""].ToString(), caretLineNumber, caretColumn, fileName);
+// AddResolveResults(results);
+// }
+// }
+// }
+// }
+ }
+ } else {
+ //FIXME: I added the null check, #D doesnt need it, why do we?
+ if (fileName != null) {
+ Console.WriteLine ("resolve " + lang);
+ results = parserService.Resolve(expression,
+ caretLineNumber,
+ caretColumn,
+ fileName,
+ textArea.Buffer.Text,
+ lang);
+ AddResolveResults(results);
+ }
+ }
+
+ return (ICompletionData[])completionData.ToArray(typeof(ICompletionData));
+ }
+
+ void AddResolveResults(ResolveResult results)
+ {
+ if (results != null) {
+ completionData.Capacity += results.Namespaces.Count +
+ results.Members.Count;
+
+ if (results.Namespaces != null && results.Namespaces.Count > 0) {
+ foreach (string s in results.Namespaces) {
+ completionData.Add(new CodeCompletionData(s, classBrowserIconService.NamespaceIndex));
+ }
+ }
+ if (results.Members != null && results.Members.Count > 0) {
+ foreach (object o in results.Members) {
+ if (o is IClass) {
+ completionData.Add(new CodeCompletionData((IClass)o));
+ } else if (o is IProperty) {
+ IProperty property = (IProperty)o;
+ if (property.Name != null && insertedPropertiesElements[property.Name] == null) {
+ completionData.Add(new CodeCompletionData(property));
+ insertedPropertiesElements[property.Name] = property;
+ }
+ } else if (o is IMethod) {
+ IMethod method = (IMethod)o;
+ if (method.Name != null && insertedElements[method.Name] == null && !method.IsConstructor) {
+ completionData.Add(new CodeCompletionData(method));
+ insertedElements[method.Name] = method;
+ }
+ } else if (o is IField) {
+ completionData.Add(new CodeCompletionData((IField)o));
+ } else if (o is IEvent) {
+ IEvent e = (IEvent)o;
+ if (e.Name != null && insertedEventElements[e.Name] == null) {
+ completionData.Add(new CodeCompletionData(e));
+ insertedEventElements[e.Name] = e;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CommentCompletionDataProvider.cs (from rev 704, trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/CommentCompletionDataProvider.cs)
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/CommentCompletionDataProvider.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CommentCompletionDataProvider.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,128 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Collections;
+
+using ICSharpCode.Core.Properties;
+using ICSharpCode.SharpDevelop.Internal.Templates;
+using ICSharpCode.TextEditor.Document;
+using ICSharpCode.TextEditor;
+using ICSharpCode.Core.Services;
+using ICSharpCode.SharpDevelop.Services;
+
+using SharpDevelop.Internal.Parser;
+using ICSharpCode.TextEditor.Gui.CompletionWindow;
+using ICSharpCode.SharpDevelop.Gui;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ /// <summary>
+ /// Data provider for code completion.
+ /// </summary>
+ public class CommentCompletionDataProvider : ICompletionDataProvider
+ {
+ static ClassBrowserIconsService classBrowserIconService = (ClassBrowserIconsService)ServiceManager.Services.GetService(typeof(ClassBrowserIconsService));
+ static IParserService parserService = (IParserService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IParserService));
+
+ int caretLineNumber;
+ int caretColumn;
+
+ string[][] commentTags = new string[][] {
+ new string[] {"c", "marks text as code"},
+ new string[] {"code", "marks text as code"},
+ new string[] {"example", "A description of the code example\n(must have a <code> tag inside)"},
+ new string[] {"exception cref=\"\"", "description to an exception thrown"},
+ new string[] {"list type=\"\"", "A list"},
+ new string[] {"listheader", "The header from the list"},
+ new string[] {"item", "A list item"},
+ new string[] {"term", "A term in a list"},
+ new string[] {"description", "A description to a term in a list"},
+ new string[] {"param name=\"\"", "A description for a parameter"},
+ new string[] {"paramref name=\"\"", "A reference to a parameter"},
+ new string[] {"permission cref=\"\"", ""},
+ new string[] {"remarks", "Gives description for a member"},
+ new string[] {"include file=\"\" path=\"\"", "Includes comments from other files"},
+ new string[] {"returns", "Gives description for a return value"},
+ new string[] {"see cref=\"\"", "A reference to a member"},
+ new string[] {"seealso cref=\"\"", "A reference to a member in the seealso section"},
+ new string[] {"summary", "A summary of the object"},
+ new string[] {"value", "A description of a property"}
+ };
+
+ public Gdk.Pixbuf[] ImageList {
+ get {
+ PixbufList list = classBrowserIconService.ImageList;
+ return (Gdk.Pixbuf[])list.ToArray (typeof (Gdk.Pixbuf));
+ }
+ }
+
+ /// <remarks>
+ /// Returns true, if the given coordinates (row, column) are in the region.
+ /// </remarks>
+ bool IsBetween(int row, int column, IRegion region)
+ {
+ return row >= region.BeginLine && (row <= region.EndLine || region.EndLine == -1);
+ }
+
+ public ICompletionData[] GenerateCompletionData(string fileName, SourceEditorView textArea, char charTyped)
+ {
+ /*caretLineNumber = textArea.Caret.Line;
+ caretColumn = textArea.Caret.Column;
+ LineSegment caretLine = textArea.Document.GetLineSegment(caretLineNumber);
+ string lineText = textArea.Document.GetText(caretLine.Offset, caretLine.Length);
+ if (!lineText.Trim().StartsWith("///")) {
+ return null;
+ }
+ */
+ ArrayList completionData = new ArrayList();
+ /*foreach (string[] tag in commentTags) {
+ completionData.Add(new CommentCompletionData(tag[0], tag[1]));
+ }*/
+ return (ICompletionData[])completionData.ToArray(typeof(ICompletionData));
+ }
+
+ class CommentCompletionData : ICompletionData
+ {
+ string text;
+ string description;
+
+ public int ImageIndex {
+ get {
+ return classBrowserIconService.MethodIndex;
+ }
+ }
+
+ public string[] Text {
+ get {
+ return new string[] { text };
+ }
+ }
+
+ public string Description {
+ get {
+ return description;
+ }
+ }
+
+ public void InsertAction(SourceEditorView control)
+ {
+ //((SharpDevelopTextAreaControl)control).ActiveTextAreaControl.TextArea.InsertString(text);
+ }
+
+ public CommentCompletionData(string text, string description)
+ {
+ this.text = text;
+ this.description = description;
+ }
+ }
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionWindow.cs (from rev 704, trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/CompletionWindow.cs)
===================================================================
--- trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/CompletionWindow.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionWindow.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,329 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Collections;
+
+using ICSharpCode.TextEditor;
+
+using Gtk;
+using GtkSharp;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ public class CompletionWindow : Window
+ {
+ const int DeclarationIndent = 1;
+ static GLib.GType type;
+ Gtk.TreeViewColumn complete_column;
+
+ ICompletionDataProvider completionDataProvider;
+ SourceEditorView control;
+ Gtk.TreeView listView;
+ Gtk.TreeStore store;
+ DeclarationViewWindow declarationviewwindow = new DeclarationViewWindow();
+ Gdk.Pixbuf[] imgList;
+ int insertLength = 0;
+
+ string GetTypedString()
+ {
+ TextIter startIter = control.Buffer.GetIterAtMark (control.Buffer.InsertMark);
+ TextIter offsetIter = control.Buffer.GetIterAtOffset (startIter.Offset - insertLength);
+ return control.Buffer.GetText (offsetIter, startIter, true);
+ }
+
+ void DeleteInsertion()
+ {
+ if (insertLength > 0) {
+ TextIter startIter = control.Buffer.GetIterAtMark (control.Buffer.InsertMark);
+ TextIter offsetIter = control.Buffer.GetIterAtOffset (startIter.Offset - insertLength);
+ int newPos = offsetIter.Offset;
+ control.Buffer.Delete (offsetIter, startIter);
+ control.Buffer.MoveMark (control.Buffer.InsertMark, control.Buffer.GetIterAtOffset (newPos));
+ }
+ }
+
+ // Lame fix. The backspace press event is not being caught. The release event yes, though
+ // ???
+ void ListKeyreleaseEvent(object sender, KeyReleaseEventArgs ex) {
+ if (ex.Event.Key == Gdk.Key.BackSpace) {
+ //Console.WriteLine("Got BackSpace on key release");
+ //new ICSharpCode.TextEditor.Actions.Backspace().Execute(control.ActiveTextAreaControl.TextArea);
+ if (insertLength > 0) {
+ --insertLength;
+ } else {
+ // no need to delete here (insertLength <= 0)
+ LostFocusListView(null, null);
+ }
+ }
+ }
+ void ListKeypressEvent(object sender, KeyPressEventArgs ex)
+ {
+ Gdk.Key key = ex.Event.Key;
+ char val = (char) key;
+ Console.WriteLine("Got Press event ({0}). Key {1}", ex, key);
+ switch (key) {
+ case Gdk.Key.Shift_L:
+ case Gdk.Key.Shift_R:
+ case Gdk.Key.Control_L:
+ case Gdk.Key.Control_R:
+ ex.RetVal = true;
+ return;
+
+ case Gdk.Key.Escape:
+ Console.WriteLine("Got Escape");
+ LostFocusListView(null, null);
+ ex.RetVal = true;
+ return;
+
+ case Gdk.Key.BackSpace:
+ Console.WriteLine("Got BackSpace on key press");
+ //new ICSharpCode.TextEditor.Actions.Backspace().Execute(control.ActiveTextAreaControl.TextArea);
+ if (insertLength > 0) {
+ --insertLength;
+ } else {
+ // no need to delete here (insertLength <= 0)
+ LostFocusListView(null, null);
+ }
+ break;
+
+ default:
+ Console.WriteLine("Got key: {0}", key);
+ if (val != '_' && !Char.IsLetterOrDigit(val)) {
+ if (listView.Selection.CountSelectedRows() > 0) {
+ ActivateItem(null, null);
+ } else {
+ LostFocusListView(null, null);
+ }
+
+ control.Buffer.InsertAtCursor (val.ToString ());
+ ex.RetVal = true;
+ return;
+ } else {
+ control.Buffer.InsertAtCursor (val.ToString ());
+ ++insertLength;
+ }
+ break;
+ }
+
+ // select the current typed word
+ int lastSelected = -1;
+ int capitalizationIndex = -1;
+
+ string typedString = GetTypedString();
+ TreeIter iter;
+ int i = 0;
+ for (store.GetIterFirst(out iter); store.IterNext(out iter) == true; i++) {
+ string text = (string)store.GetValue(iter, 0);
+
+ if (text.ToUpper().StartsWith(typedString.ToUpper())) {
+ int currentCapitalizationIndex = 0;
+ for (int j = 0; j < typedString.Length && j < text.Length; ++j) {
+ if (typedString[j] == text[j]) {
+ ++currentCapitalizationIndex;
+ }
+ }
+
+ if (currentCapitalizationIndex > capitalizationIndex) {
+ lastSelected = i;
+ capitalizationIndex = currentCapitalizationIndex;
+ }
+ }
+ }
+
+ listView.Selection.UnselectAll();
+ if (lastSelected != -1) {
+ TreePath path = new TreePath("" + (lastSelected + 1));
+ listView.Selection.SelectPath(path);
+ listView.SetCursor (path, complete_column, false);
+ listView.ScrollToCell(path, null, false, 0, 0);
+ }
+
+ ex.RetVal = true;
+ }
+
+ void InitializeControls()
+ {
+ RequestSize = new Size (340, 210 - 85);
+ Decorated = false;
+ SkipPagerHint = true;
+ SkipTaskbarHint = true;
+ TypeHint = Gdk.WindowTypeHint.Dialog;
+
+ store = new Gtk.TreeStore (typeof (string), typeof (Gdk.Pixbuf), typeof(ICompletionData));
+ listView = new Gtk.TreeView (store);
+
+ listView.HeadersVisible = false;
+
+ complete_column = new Gtk.TreeViewColumn ();
+ complete_column.Title = "completion";
+
+ Gtk.CellRendererPixbuf pix_render = new Gtk.CellRendererPixbuf ();
+ complete_column.PackStart (pix_render, false);
+ complete_column.AddAttribute (pix_render, "pixbuf", 1);
+
+ Gtk.CellRendererText text_render = new Gtk.CellRendererText ();
+ complete_column.PackStart (text_render, true);
+ complete_column.AddAttribute (text_render, "text", 0);
+
+ listView.AppendColumn (complete_column);
+
+ Gtk.ScrolledWindow scroller = new Gtk.ScrolledWindow ();
+ scroller.Add (listView);
+
+ Gtk.Frame frame = new Gtk.Frame ();
+ frame.Add (scroller);
+ this.Add(frame);
+
+ imgList = completionDataProvider.ImageList;
+ listView.KeyPressEvent += new KeyPressEventHandler(ListKeypressEvent);
+ listView.KeyReleaseEvent += new KeyReleaseEventHandler(ListKeyreleaseEvent);
+ listView.FocusOutEvent += new FocusOutEventHandler(LostFocusListView);
+ listView.RowActivated += new RowActivatedHandler(ActivateItem);
+ listView.AddEvents ((int) (Gdk.EventMask.KeyPressMask));
+ }
+
+ /// <remarks>
+ /// Shows the filled completion window, if it has no items it isn't shown.
+ /// </remarks>
+ public void ShowCompletionWindow(char firstChar)
+ {
+ FillList(true, firstChar);
+
+ TreeIter iter;
+ if (store.GetIterFirst(out iter) == false) {
+ control.GrabFocus();
+ return;
+ }
+
+ //Point caretPos = control.ActiveTextAreaControl.Caret.Position;
+ //Point visualPos = new Point(control.ActiveTextAreaControl.TextArea.TextView.GetDrawingXPos(caretPos.Y, caretPos.X) + control.ActiveTextAreaControl.TextArea.TextView.DrawingPosition.X,
+ // (int)((1 + caretPos.Y) * control.ActiveTextAreaControl.TextArea.TextView.FontHeight) - control.ActiveTextAreaControl.TextArea.VirtualTop.Y - 1 + control.ActiveTextAreaControl.TextArea.TextView.DrawingPosition.Y);
+
+ int tx, ty;
+ //control.ActiveTextAreaControl.TextArea.GdkWindow.GetOrigin(out tx, out ty);
+ //Move(tx + visualPos.X, ty + visualPos.Y);
+ listView.Selection.Changed += new EventHandler (RowActivated);
+ ShowAll ();
+ }
+ string fileName;
+
+ static CompletionWindow ()
+ {
+ type = RegisterGType (typeof (CompletionWindow));
+ }
+
+ /// <remarks>
+ /// Creates a new Completion window and puts it location under the caret
+ /// </remarks>
+ public CompletionWindow (SourceEditorView control, string fileName, ICompletionDataProvider completionDataProvider) : base (type)
+ {
+ this.fileName = fileName;
+ this.completionDataProvider = completionDataProvider;
+ this.control = control;
+
+ InitializeControls();
+ }
+
+ /// <remarks>
+ /// Creates a new Completion window at a given location
+ /// </remarks>
+ CompletionWindow (SourceEditorView control, Point location, ICompletionDataProvider completionDataProvider) : base (type)
+ {
+ this.completionDataProvider = completionDataProvider;
+ this.control = control;
+
+ InitializeControls();
+ }
+
+ void ActivateItem(object sender, RowActivatedArgs e)
+ {
+ if (listView.Selection.CountSelectedRows() > 0) {
+ TreeModel foo;
+ TreeIter iter;
+ listView.Selection.GetSelected(out foo, out iter);
+ ICompletionData data = (ICompletionData) store.GetValue(iter, 2);
+ DeleteInsertion();
+ data.InsertAction(control);
+ LostFocusListView(null, null);
+ }
+ }
+
+ void LostFocusListView(object sender, FocusOutEventArgs e)
+ {
+ control.HasFocus = true;
+ declarationviewwindow.HideAll ();
+ Hide();
+ }
+
+ void FillList(bool firstTime, char ch)
+ {
+ ICompletionData[] completionData = completionDataProvider.GenerateCompletionData(fileName, control, ch);
+ Console.WriteLine ("testing");
+ if (completionData == null || completionData.Length == 0) {
+ return;
+ }
+
+ foreach (ICompletionData data in completionData) {
+ store.AppendValues (data.Text[0], imgList[data.ImageIndex], data);
+ }
+ // sort here
+ store.SetSortColumnId (0, SortType.Ascending);
+ }
+
+ void RowActivated (object sender, EventArgs a)
+ {
+ Gtk.TreeIter iter;
+ Gtk.TreeModel model;
+
+ if (listView.Selection.GetSelected (out model, out iter)){
+ ICompletionData data = (ICompletionData) store.GetValue (iter, 2);
+
+ //FIXME: This code is buggy, and generates a bad placement sometimes when you jump a lot. but it is better than 0,0
+
+ Gtk.TreePath path = store.GetPath (iter);
+ Gdk.Rectangle rect;
+ rect = listView.GetCellArea (path, (Gtk.TreeViewColumn)listView.Columns[0]);
+
+ int x, y;
+ listView.TreeToWidgetCoords (rect.x, rect.y, out x, out y);
+
+ int listpos_x, listpos_y;
+ GetPosition (out listpos_x, out listpos_y);
+ int vert = listpos_y + rect.y;
+
+ if (vert > listpos_y + listView.GdkWindow.Size.Height) {
+ vert = listpos_y + listView.GdkWindow.Size.Height - rect.height;
+ } else if (vert < listpos_y) {
+ vert = listpos_y;
+ }
+
+ //FIXME: This is a bad calc, its always on the right, it needs to test if thats too big, and if so, place on the left;
+ int horiz = listpos_x + listView.GdkWindow.Size.Width + 30;
+ ICompletionDataWithMarkup wMarkup = data as ICompletionDataWithMarkup;
+ declarationviewwindow.Destroy ();
+ if (wMarkup != null) {
+ declarationviewwindow = new DeclarationViewWindow ();
+ declarationviewwindow.DescriptionMarkup = wMarkup.DescriptionPango;
+ } else {
+ declarationviewwindow = new DeclarationViewWindow ();
+ declarationviewwindow.DescriptionMarkup = data.Description;
+ }
+
+ declarationviewwindow.ShowAll ();
+ if (listView.Screen.Width <= horiz + declarationviewwindow.GdkWindow.FrameExtents.Width) {
+ horiz = listpos_x - declarationviewwindow.GdkWindow.FrameExtents.Width - 10;
+ }
+ declarationviewwindow.Move (horiz, vert);
+ }
+ }
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/DeclarationViewWindow.cs (from rev 704, trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/DeclarationViewWindow.cs)
===================================================================
--- trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/DeclarationViewWindow.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/DeclarationViewWindow.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,44 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Collections;
+
+using ICSharpCode.TextEditor.Document;
+using ICSharpCode.TextEditor.Util;
+using ICSharpCode.TextEditor;
+
+using Gtk;
+using GtkSharp;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ public class DeclarationViewWindow : Gtk.Window
+ {
+ Label label;
+
+ public string DescriptionMarkup {
+ get {
+ return label.Text;
+ }
+
+ set {
+ label.Markup = value;
+ //QueueDraw ();
+ }
+ }
+
+ public DeclarationViewWindow () : base (WindowType.Popup)
+ {
+ Gtk.Frame frame = new Gtk.Frame ();
+ frame.Add (label = new Label (""));
+ Add (frame);
+ }
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionData.cs (from rev 704, trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/ICompletionData.cs)
===================================================================
--- trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/ICompletionData.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionData.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,40 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Collections;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ public interface ICompletionData
+ {
+ int ImageIndex {
+ get;
+ }
+
+ string[] Text {
+ get;
+ }
+
+ string Description {
+ get;
+ }
+
+ void InsertAction(SourceEditorView control);
+ }
+
+ public interface ICompletionDataWithMarkup : ICompletionData
+ {
+ string DescriptionPango {
+ get;
+ }
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionDataProvider.cs (from rev 704, trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/ICompletionDataProvider.cs)
===================================================================
--- trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Gui/CompletionWindow/ICompletionDataProvider.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionDataProvider.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,29 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Collections;
+
+using ICSharpCode.TextEditor.Document;
+
+using Gdk;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ public interface ICompletionDataProvider
+ {
+ Pixbuf[] ImageList {
+ get;
+ }
+
+ ICompletionData[] GenerateCompletionData(string fileName, SourceEditorView textArea, char charTyped);
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TemplateCompletionDataProvider.cs (from rev 704, trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/TemplateCompletionDataProvider.cs)
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/TextEditor/Gui/Editor/CompletionWindow/TemplateCompletionDataProvider.cs 2004-01-28 17:48:17 UTC (rev 704)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TemplateCompletionDataProvider.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,78 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Drawing;
+using System.Reflection;
+using System.Collections;
+
+using ICSharpCode.Core.Properties;
+using ICSharpCode.SharpDevelop.Internal.Templates;
+using ICSharpCode.TextEditor.Document;
+using ICSharpCode.TextEditor;
+using ICSharpCode.TextEditor.Gui.CompletionWindow;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ public class TemplateCompletionDataProvider : ICompletionDataProvider
+ {
+ public Gdk.Pixbuf[] ImageList {
+ get {
+ return null;
+ }
+ }
+
+ public ICompletionData[] GenerateCompletionData(string fileName, SourceEditorView textArea, char charTyped)
+ {
+ CodeTemplateGroup templateGroup = CodeTemplateLoader.GetTemplateGroupPerFilename(fileName);
+ if (templateGroup == null) {
+ return null;
+ }
+ ArrayList completionData = new ArrayList();
+ foreach (CodeTemplate template in templateGroup.Templates) {
+ completionData.Add(new TemplateCompletionData(template));
+ }
+
+ return (ICompletionData[])completionData.ToArray(typeof(ICompletionData));
+ }
+
+ class TemplateCompletionData : ICompletionData
+ {
+ CodeTemplate template;
+
+ public int ImageIndex {
+ get {
+ return 0;
+ }
+ }
+
+ public string[] Text {
+ get {
+ return new string[] { template.Shortcut, template.Description };
+ }
+ }
+
+ public string Description {
+ get {
+ return template.Text;
+ }
+ }
+
+ public void InsertAction(SourceEditorView control)
+ {
+ //((SharpDevelopTextAreaControl)control).InsertTemplate(template);
+ }
+
+ public TemplateCompletionData(CodeTemplate template)
+ {
+ this.template = template;
+ }
+ }
+ }
+}
Copied: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TextUtilities.cs (from rev 707, trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Document/TextUtilities.cs)
===================================================================
--- trunk/MonoDevelop/src/Libraries/ICSharpCode.TextEditor/src/Document/TextUtilities.cs 2004-01-29 00:36:54 UTC (rev 707)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TextUtilities.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -0,0 +1,405 @@
+// <file>
+// <copyright see="prj:///doc/copyright.txt"/>
+// <license see="prj:///doc/license.txt"/>
+// <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+// <version value="$version"/>
+// </file>
+
+using System;
+using System.Text;
+using System.Diagnostics;
+
+using ICSharpCode.TextEditor.Undo;
+
+using MonoDevelop.SourceEditor.Gui;
+
+namespace MonoDevelop.SourceEditor.CodeCompletion
+{
+ public sealed class TextUtilities
+ {
+
+ /// <remarks>
+ /// This function takes a string and converts the whitespace in front of
+ /// it to tabs. If the length of the whitespace at the start of the string
+ /// was not a whole number of tabs then there will still be some spaces just
+ /// before the text starts.
+ /// the output string will be of the form:
+ /// 1. zero or more tabs
+ /// 2. zero or more spaces (less than tabIndent)
+ /// 3. the rest of the line
+ /// </remarks>
+/* public static string LeadingWhiteSpaceToTabs(string line, int tabIndent) {
+ StringBuilder sb = new StringBuilder(line.Length);
+ int consecutiveSpaces = 0;
+ int i = 0;
+ for(i = 0; i < line.Length; i++) {
+ if(line[i] == ' ') {
+ consecutiveSpaces++;
+ if(consecutiveSpaces == tabIndent) {
+ sb.Append('\t');
+ consecutiveSpaces = 0;
+ }
+ }
+ else if(line[i] == '\t') {
+ sb.Append('\t');
+ // if we had say 3 spaces then a tab and tabIndent was 4 then
+ // we would want to simply replace all of that with 1 tab
+ consecutiveSpaces = 0;
+ }
+ else {
+ break;
+ }
+ }
+ if(i < line.Length) {
+ sb.Append(line.Substring(i-consecutiveSpaces));
+ }
+ return sb.ToString();
+ }
+*/
+
+ public static bool IsLetterDigitOrUnderscore(char c)
+ {
+ if(!Char.IsLetterOrDigit(c)) {
+ return c == '_';
+ }
+ return true;
+ }
+
+ public enum CharacterType {
+ LetterDigitOrUnderscore,
+ WhiteSpace,
+ Other
+ }
+
+ /// <remarks>
+ /// This method returns the expression before a specified offset.
+ /// That method is used in code completion to determine the expression given
+ /// to the parser for type resolve.
+ /// </remarks>
+ public static string GetExpressionBeforeOffset(SourceEditorView textArea, int offset)
+ {
+ while (offset - 1 > 0) {
+ switch (textArea.Buffer.Text[offset - 1]) {
+ case '}':
+ goto done;
+// offset = SearchBracketBackward(document, offset - 2, '{','}');
+// break;
+ case ']':
+ offset = SearchBracketBackward(textArea, offset - 2, '[',']');
+ break;
+ case ')':
+ offset = SearchBracketBackward(textArea, offset - 2, '(',')');
+ break;
+ case '.':
+ --offset;
+ break;
+ case '"':
+ return "\"\"";
+ case '\'':
+ return "'a'";
+ case '>':
+ if (textArea.Buffer.Text[offset - 2] == '-') {
+ offset -= 2;
+ break;
+ }
+ goto done;
+ default:
+ if (Char.IsWhiteSpace(textArea.Buffer.Text[offset - 1])) {
+ --offset;
+ break;
+ }
+ int start = offset - 1;
+ if (!IsLetterDigitOrUnderscore(textArea.Buffer.Text[start])) {
+ goto done;
+ }
+
+ while (start > 0 && IsLetterDigitOrUnderscore(textArea.Buffer.Text[start - 1])) {
+ --start;
+ }
+
+ Console.WriteLine("{0} -- {1}", offset, start);
+ Gtk.TextIter startIter = textArea.Buffer.GetIterAtOffset (start);
+ Gtk.TextIter endIter = textArea.Buffer.GetIterAtOffset (offset);
+ string word = textArea.Buffer.GetText (startIter, endIter, false).Trim();
+ Console.WriteLine("word >{0}<", word);
+ switch (word) {
+ case "ref":
+ case "out":
+ case "in":
+ case "return":
+ case "throw":
+ case "case":
+ goto done;
+ }
+
+ if (word.Length > 0 && !IsLetterDigitOrUnderscore(word[0])) {
+ goto done;
+ }
+ offset = start;
+ break;
+ }
+ }
+ done:
+// Console.WriteLine("ofs : {0} cart:{1}", offset, document.Caret.Offset);
+// Console.WriteLine("return:" + document.GetText(offset, document.Caret.Offset - offset).Trim());
+ Gtk.TextIter start_Iter = textArea.Buffer.GetIterAtMark (textArea.Buffer.InsertMark);
+ Gtk.TextIter offset_Iter = textArea.Buffer.GetIterAtOffset (start_Iter.Offset - offset);
+ return textArea.Buffer.GetText (start_Iter, offset_Iter, false ).Trim();
+ }
+
+/*
+ public static CharacterType GetCharacterType(char c)
+ {
+ if(IsLetterDigitOrUnderscore(c))
+ return CharacterType.LetterDigitOrUnderscore;
+ if(Char.IsWhiteSpace(c))
+ return CharacterType.WhiteSpace;
+ return CharacterType.Other;
+ }
+
+ public static int GetFirstNonWSChar(IDocument document, int offset)
+ {
+ while (offset < document.TextLength && Char.IsWhiteSpace(document.GetCharAt(offset))) {
+ ++offset;
+ }
+ return offset;
+ }
+
+ public static int FindWordEnd(IDocument document, int offset)
+ {
+ LineSegment line = document.GetLineSegmentForOffset(offset);
+ int endPos = line.Offset + line.Length;
+ while (offset < endPos && IsLetterDigitOrUnderscore(document.GetCharAt(offset))) {
+ ++offset;
+ }
+
+ return offset;
+ }
+
+ public static int FindWordStart(IDocument document, int offset)
+ {
+ LineSegment line = document.GetLineSegmentForOffset(offset);
+
+ while (offset > line.Offset && !IsLetterDigitOrUnderscore(document.GetCharAt(offset - 1))) {
+ --offset;
+ }
+
+ return offset;
+ }
+
+ // go forward to the start of the next word
+ // if the cursor is at the start or in the middle of a word we move to the end of the word
+ // and then past any whitespace that follows it
+ // if the cursor is at the start or in the middle of some whitespace we move to the start of the
+ // next word
+ public static int FindNextWordStart(IDocument document, int offset)
+ {
+ int originalOffset = offset;
+ LineSegment line = document.GetLineSegmentForOffset(offset);
+ int endPos = line.Offset + line.Length;
+ // lets go to the end of the word, whitespace or operator
+ CharacterType t = GetCharacterType(document.GetCharAt(offset));
+ while (offset < endPos && GetCharacterType(document.GetCharAt(offset)) == t) {
+ ++offset;
+ }
+
+ // now we're at the end of the word, lets find the start of the next one by skipping whitespace
+ while (offset < endPos && GetCharacterType(document.GetCharAt(offset)) == CharacterType.WhiteSpace) {
+ ++offset;
+ }
+
+ return offset;
+ }
+
+ // go back to the start of the word we are on
+ // if we are already at the start of a word or if we are in whitespace, then go back
+ // to the start of the previous word
+ public static int FindPrevWordStart(IDocument document, int offset)
+ {
+ int originalOffset = offset;
+ LineSegment line = document.GetLineSegmentForOffset(offset);
+ if (offset > 0) {
+ CharacterType t = GetCharacterType(document.GetCharAt(offset - 1));
+ while (offset > line.Offset && GetCharacterType(document.GetCharAt(offset - 1)) == t) {
+ --offset;
+ }
+
+ // if we were in whitespace, and now we're at the end of a word or operator, go back to the beginning of it
+ if(t == CharacterType.WhiteSpace && offset > line.Offset) {
+ t = GetCharacterType(document.GetCharAt(offset - 1));
+ while (offset > line.Offset && GetCharacterType(document.GetCharAt(offset - 1)) == t) {
+ --offset;
+ }
+ }
+ }
+
+ return offset;
+ }
+
+ public static string GetLineAsString(IDocument document, int lineNumber)
+ {
+ LineSegment line = document.GetLineSegment(lineNumber);
+ return document.GetText(line.Offset, line.Length);
+ }
+*/
+ static bool ScanLineComment(SourceEditorView document, int offset)
+ {
+ while (offset > 0 && offset < document.Buffer.Text.Length) {
+ char ch = document.Buffer.Text[offset];
+ switch (ch) {
+ case '\r':
+ case '\n':
+ return false;
+ case '/':
+ if (document.Buffer.Text[offset + 1] == '/') {
+ return true;
+ }
+ break;
+ }
+ --offset;
+ }
+ return false;
+ }
+
+ public static int SearchBracketBackward(SourceEditorView document, int offset, char openBracket, char closingBracket)
+ {
+ int brackets = -1;
+
+ bool inString = false;
+ bool inChar = false;
+
+ bool blockComment = false;
+
+ while (offset >= 0 && offset < document.Buffer.Text.Length) {
+ char ch = document.Buffer.Text[offset];
+ switch (ch) {
+ case '/':
+ if (blockComment) {
+ if (document.Buffer.Text[offset + 1]== '*') {
+ blockComment = false;
+ }
+ }
+ if (!inString && !inChar && offset + 1 < document.Buffer.Text.Length) {
+ if (offset > 0 && document.Buffer.Text[offset - 1] == '*') {
+ blockComment = true;
+ }
+ }
+ break;
+ case '"':
+ if (!inChar && !blockComment && !ScanLineComment(document, offset)) {
+ inString = !inString;
+ }
+ break;
+ case '\'':
+ if (!inString && !blockComment && !ScanLineComment(document, offset)) {
+ inChar = !inChar;
+ }
+ break;
+ default :
+ if (ch == closingBracket) {
+ if (!(inString || inChar || blockComment) && !ScanLineComment(document, offset)) {
+ --brackets;
+ }
+ } else if (ch == openBracket) {
+ if (!(inString || inChar || blockComment) && !ScanLineComment(document, offset)) {
+ ++brackets;
+ if (brackets == 0) {
+ return offset;
+ }
+ }
+ }
+ break;
+ }
+ --offset;
+ }
+ return - 1;
+ }
+/*
+ public static int SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket)
+ {
+ int brackets = 1;
+
+ bool inString = false;
+ bool inChar = false;
+
+ bool lineComment = false;
+ bool blockComment = false;
+
+ if (offset >= 0) {
+ while (offset < document.TextLength) {
+ char ch = document.GetCharAt(offset);
+ switch (ch) {
+ case '\r':
+ case '\n':
+ lineComment = false;
+ break;
+ case '/':
+ if (blockComment) {
+ Debug.Assert(offset > 0);
+ if (document.GetCharAt(offset - 1) == '*') {
+ blockComment = false;
+ }
+ }
+ if (!inString && !inChar && offset + 1 < document.TextLength) {
+ if (!blockComment && document.GetCharAt(offset + 1) == '/') {
+ lineComment = true;
+ }
+ if (!lineComment && document.GetCharAt(offset + 1) == '*') {
+ blockComment = true;
+ }
+ }
+ break;
+ case '"':
+ if (!(inChar || lineComment || blockComment)) {
+ inString = !inString;
+ }
+ break;
+ case '\'':
+ if (!(inString || lineComment || blockComment)) {
+ inChar = !inChar;
+ }
+ break;
+ default :
+ if (ch == openBracket) {
+ if (!(inString || inChar || lineComment || blockComment)) {
+ ++brackets;
+ }
+ } else if (ch == closingBracket) {
+ if (!(inString || inChar || lineComment || blockComment)) {
+ --brackets;
+ if (brackets == 0) {
+ return offset;
+ }
+ }
+ }
+ break;
+ }
+ ++offset;
+ }
+ }
+ return -1;
+ }
+
+ /// <remarks>
+ /// Returns true, if the line lineNumber is empty or filled with whitespaces.
+ /// </remarks>
+ public static bool IsEmptyLine(IDocument document, int lineNumber)
+ {
+ return IsEmptyLine(document, document.GetLineSegment(lineNumber));
+ }
+
+ /// <remarks>
+ /// Returns true, if the line lineNumber is empty or filled with whitespaces.
+ /// </remarks>
+ public static bool IsEmptyLine(IDocument document, LineSegment line)
+ {
+ for (int i = line.Offset; i < line.Offset + line.Length; ++i) {
+ char ch = document.GetCharAt(i);
+ if (!Char.IsWhiteSpace(ch)) {
+ return false;
+ }
+ }
+ return true;
+ }*/
+ }
+}
Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorDisplayBinding.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorDisplayBinding.cs 2004-01-29 02:37:09 UTC (rev 710)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorDisplayBinding.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -82,7 +82,7 @@
public SourceEditorDisplayBindingWrapper ()
{
- se = new SourceEditor ();
+ se = new SourceEditor (this);
se.Buffer.ModifiedChanged += new EventHandler (OnModifiedChanged);
se.Buffer.MarkSet += new MarkSetHandler (OnMarkSet);
se.Buffer.Changed += new EventHandler (OnChanged);
Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorView.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorView.cs 2004-01-29 02:37:09 UTC (rev 710)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorView.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -5,21 +5,27 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
+
+using MonoDevelop.SourceEditor.CodeCompletion;
namespace MonoDevelop.SourceEditor.Gui {
public class SourceEditorView : SourceView {
private static GLib.GType type;
- SourceEditorBuffer buf;
+ SourceEditorBuffer buf;
+ public readonly SourceEditor ParentEditor;
+
+ CompletionWindow completionWindow;
static SourceEditorView ()
{
type = RegisterGType (typeof (SourceEditorView));
}
- public SourceEditorView (SourceEditorBuffer buf) : base (type)
+ public SourceEditorView (SourceEditorBuffer buf, SourceEditor parent) : base (type)
{
+ this.ParentEditor = parent;
Buffer = this.buf = buf;
AutoIndent = true;
SmartHomeEnd = true;
@@ -52,6 +58,16 @@
}
break;
}
+
+ switch ((char)key) {
+ //FIXME: ' ' needs to do extra parsing
+ case ' ':
+ case '.':
+ Console.WriteLine ("About to show completion Window");
+ completionWindow = new CompletionWindow (this, ParentEditor.DisplayBinding.ContentName, new CodeCompletionDataProvider ());
+ completionWindow.ShowCompletionWindow ((char)key);
+ break;
+ }
base.OnKeyPressEvent (ref evnt);
return false;
@@ -145,4 +161,4 @@
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorWidget.cs
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorWidget.cs 2004-01-29 02:37:09 UTC (rev 710)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorWidget.cs 2004-01-29 15:59:07 UTC (rev 711)
@@ -11,12 +11,14 @@
public readonly SourceEditorBuffer Buffer;
public readonly SourceEditorView View;
+ public readonly SourceEditorDisplayBindingWrapper DisplayBinding;
- public SourceEditor ()
+ public SourceEditor (SourceEditorDisplayBindingWrapper bind)
{
+ DisplayBinding = bind;
Buffer = new SourceEditorBuffer ();
- View = new SourceEditorView (Buffer);
+ View = new SourceEditorView (Buffer, this);
Buffer.Highlight = true;
@@ -94,4 +96,4 @@
"...................................."
};
}
-}
\ No newline at end of file
+}
Modified: trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile
===================================================================
--- trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile 2004-01-29 02:37:09 UTC (rev 710)
+++ trunk/MonoDevelop/src/AddIns/DisplayBindings/SourceEditor/Makefile 2004-01-29 15:59:07 UTC (rev 711)
@@ -7,4 +7,5 @@
/r:../../../../build/bin/MonoDevelop.Core.dll \
/r:../../../../build/bin/MonoDevelop.TextEditor.dll \
/r:../../../../build/bin/MonoDevelop.Base.dll \
- /r:../../../../build/bin/MonoDevelop.Gui.Utils.dll
+ /r:../../../../build/bin/MonoDevelop.Gui.Utils.dll \
+ /r:System.Drawing.dll
More information about the Monodevelop-patches-list
mailing list