[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