[MonoDevelop] Removing SourceEditor{View,
Buffer} dependancy from CompletionListWindow.
Peter Johanson
latexer at gentoo.org
Tue Jul 19 21:31:39 EDT 2005
On Tue, Jul 19, 2005 at 10:52:02AM +0200, Lluis Sanchez wrote:
> Hi,
>
> The patch looks like a good start. Here are some comments:
>
> * prepareCompletionDetails -> PrepareCompletionDetails
>
> * You should avoid using a property like ICompletionWidget.Text.
> Loading the entire file text in memory is a bad practice. I know
> we are doing it in other places but it shouldn't be done. In
> most of cases you can use methods such as for example: string
> GetText (int startOffset, int endOffset).
>
> * Methods in TextUtilities should take a ICompletionWidget as
> parameter and use its methods to get the text it needs. The same
> for ICompletionDataProvider, TemplateCompletionDataProvider and
> CommentCompletionDataProvider.
>
> * Please give more meaningful names to ICompletionWidget
> properties (what does X and Y refer to?).
>
> * ICompletionData.InsertAction should also take a
> ICompletionWidget as parameter.
>
> * CompletionWindow.cs is obsolete, it can be removed.
>
Ok, attached are two new versions of the patches implementing the points
above. Further thoughts?
-pete
--
Peter Johanson
<latexer at gentoo.org>
-------------- next part --------------
Index: Core/src/MonoDevelop.Base/Services/ParserService/DefaultParserService.cs
===================================================================
--- Core/src/MonoDevelop.Base/Services/ParserService/DefaultParserService.cs (revision 2671)
+++ Core/src/MonoDevelop.Base/Services/ParserService/DefaultParserService.cs (working copy)
@@ -255,8 +255,6 @@
IProjectService projectService = Runtime.ProjectService;
projectService.CombineOpened += new CombineEventHandler(OnCombineOpened);
projectService.CombineClosed += new CombineEventHandler(OnCombineClosed);
- projectService.ReferenceAddedToProject += new ProjectReferenceEventHandler (OnProjectReferencesChanged);
- projectService.ReferenceRemovedFromProject += new ProjectReferenceEventHandler (OnProjectReferencesChanged);
}
internal IProgressMonitor GetParseProgressMonitor ()
@@ -367,6 +365,8 @@
GetDatabase (re.Uri);
project.NameChanged += new CombineEntryRenamedEventHandler (OnProjectRenamed);
+ project.ReferenceAddedToProject += new ProjectReferenceEventHandler (OnProjectReferencesChanged);
+ project.ReferenceRemovedFromProject += new ProjectReferenceEventHandler (OnProjectReferencesChanged);
}
}
@@ -389,6 +389,8 @@
string uri = "Project:" + project.Name;
UnloadDatabase (uri);
project.NameChanged -= new CombineEntryRenamedEventHandler (OnProjectRenamed);
+ project.ReferenceAddedToProject -= new ProjectReferenceEventHandler (OnProjectReferencesChanged);
+ project.ReferenceRemovedFromProject -= new ProjectReferenceEventHandler (OnProjectReferencesChanged);
}
void CleanUnusedDatabases ()
Index: Core/src/MonoDevelop.Base/Gui/Completion/ICompletionWidget.cs
===================================================================
--- Core/src/MonoDevelop.Base/Gui/Completion/ICompletionWidget.cs (revision 0)
+++ Core/src/MonoDevelop.Base/Gui/Completion/ICompletionWidget.cs (revision 0)
@@ -0,0 +1,32 @@
+
+using System;
+using MonoDevelop.Internal.Project;
+using Gtk;
+
+namespace MonoDevelop.Gui.Completion
+{
+
+ public interface ICompletionWidget
+ {
+ string Text { get; }
+ int TextLength { get; }
+ string GetText (int startOffset, int endOffset);
+ char GetChar (int offset);
+
+ string CompletionText { get; }
+
+ void SetCompletionText (string partial_word, string complete_word);
+
+ void InsertAtCursor (string text);
+
+ int TriggerOffset { get; }
+ int TriggerLine { get; }
+ int TriggerLineOffset { get; }
+
+ int TriggerXCoord { get; }
+ int TriggerYCoord { get; }
+ int TriggerTextHeight { get; }
+
+ Gtk.Style GtkStyle { get; }
+ }
+}
Index: Core/src/MonoDevelop.Base/Makefile.am
===================================================================
--- Core/src/MonoDevelop.Base/Makefile.am (revision 2671)
+++ Core/src/MonoDevelop.Base/Makefile.am (working copy)
@@ -87,6 +87,7 @@
Gui/Components/SdMenuCheckBox.cs \
Gui/Components/SdMenuCommand.cs \
Gui/Components/SdToolbarCommand.cs \
+Gui/Completion/ICompletionWidget.cs \
Gui/WorkbenchWindowCollection.cs \
Gui/WorkbenchSingleton.cs \
Gui/IMementoCapable.cs \
Index: Core/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorView.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorView.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/Gui/SourceEditorView.cs (working copy)
@@ -10,6 +10,7 @@
using MonoDevelop.Core.AddIns;
using MonoDevelop.Internal.Templates;
using MonoDevelop.Internal.Parser;
+using MonoDevelop.Internal.Project;
using MonoDevelop.Core.Services;
using MonoDevelop.SourceEditor.CodeCompletion;
using MonoDevelop.SourceEditor.InsightWindow;
@@ -17,6 +18,7 @@
using MonoDevelop.EditorBindings.FormattingStrategy;
using MonoDevelop.Gui.Utils;
using MonoDevelop.Gui;
+using MonoDevelop.Gui.Completion;
using MonoDevelop.Services;
using MonoDevelop.Commands;
using MonoDevelop.DefaultEditor;
@@ -25,7 +27,7 @@
namespace MonoDevelop.SourceEditor.Gui
{
- public class SourceEditorView : SourceView, IFormattableDocument
+ public class SourceEditorView : SourceView, IFormattableDocument, ICompletionWidget
{
public readonly SourceEditor ParentEditor;
internal IFormattingStrategy fmtr;
@@ -194,8 +196,8 @@
return;
triggerIter.ForwardChar ();
-// CompletionWindow.ShowWindow (triggerChar, triggerIter, true, new CodeCompletionDataProvider (true), this);
- CompletionListWindow.ShowWindow (triggerChar, triggerIter, new CodeCompletionDataProvider (true), this);
+ PrepareCompletionDetails(triggerIter);
+ CompletionListWindow.ShowWindow (triggerChar, new CodeCompletionDataProvider (true), this, this.ParentEditor.DisplayBinding.Project, this.ParentEditor.DisplayBinding.ContentName);
}
bool MonodocResolver ()
@@ -375,8 +377,8 @@
case '.':
bool retval = base.OnKeyPressEvent (evnt);
if (EnableCodeCompletion && PeekCharIsWhitespace ()) {
-// CompletionWindow.ShowWindow ((char)key, buf.GetIterAtMark (buf.InsertMark), false, new CodeCompletionDataProvider (), this);
- CompletionListWindow.ShowWindow ((char)key, buf.GetIterAtMark (buf.InsertMark), new CodeCompletionDataProvider (), this);
+ PrepareCompletionDetails(buf.GetIterAtMark (buf.InsertMark));
+ CompletionListWindow.ShowWindow ((char)key, new CodeCompletionDataProvider (), this, this.ParentEditor.DisplayBinding.Project, this.ParentEditor.DisplayBinding.ContentName);
}
return retval;
/*case '(':
@@ -582,6 +584,20 @@
end.ForwardToLineEnd ();
Buffer.MoveMark ("selection_bound", end);
}
+
+ void PrepareCompletionDetails(TextIter iter)
+ {
+ Gdk.Rectangle rect = GetIterLocation (Buffer.GetIterAtMark (Buffer.InsertMark));
+ int wx, wy;
+ BufferToWindowCoords (Gtk.TextWindowType.Widget, rect.X, rect.Y + rect.Height, out wx, out wy);
+ int tx, ty;
+ GdkWindow.GetOrigin (out tx, out ty);
+
+ this.completionX = tx + wx;
+ this.completionY = ty + wy;
+ this.textHeight = rect.Height;
+ this.triggerMark = buf.CreateMark (null, iter, true);
+ }
#endregion
#region IFormattableDocument
@@ -661,7 +677,118 @@
offset = begin.Offset;
len = begin.CharsInLine;
}
+#endregion
+#region ICompletionWidget
+
+ private int completionX;
+ int ICompletionWidget.TriggerXCoord
+ {
+ get
+ {
+ return completionX;
+ }
+ }
+
+ private int completionY;
+ int ICompletionWidget.TriggerYCoord
+ {
+ get
+ {
+ return completionY;
+ }
+ }
+
+ private int textHeight;
+ int ICompletionWidget.TriggerTextHeight
+ {
+ get
+ {
+ return textHeight;
+ }
+ }
+
+ string ICompletionWidget.CompletionText
+ {
+ get
+ {
+ return Buffer.GetText (Buffer.GetIterAtMark (triggerMark), Buffer.GetIterAtMark (Buffer.InsertMark), false);
+ }
+ }
+
+ void ICompletionWidget.SetCompletionText (string partial_word, string complete_word)
+ {
+ TextIter offsetIter = buf.GetIterAtMark(triggerMark);
+ TextIter endIter = buf.GetIterAtOffset (offsetIter.Offset + partial_word.Length);
+ buf.MoveMark (buf.InsertMark, offsetIter);
+ buf.Delete (ref offsetIter, ref endIter);
+ buf.InsertAtCursor (complete_word);
+ }
+
+ void ICompletionWidget.InsertAtCursor (string text)
+ {
+ buf.InsertAtCursor (text);
+ }
+
+ string ICompletionWidget.Text
+ {
+ get
+ {
+ return buf.Text;
+ }
+ }
+
+ int ICompletionWidget.TextLength
+ {
+ get
+ {
+ return buf.EndIter.Offset + 1;
+ }
+ }
+
+ char ICompletionWidget.GetChar (int offset)
+ {
+ return buf.GetIterAtOffset (offset).Char[0];
+ }
+
+ string ICompletionWidget.GetText (int startOffset, int endOffset)
+ {
+ return buf.GetText(buf.GetIterAtOffset (startOffset), buf.GetIterAtOffset(endOffset), true);
+ }
+
+ private TextMark triggerMark;
+ int ICompletionWidget.TriggerOffset
+ {
+ get
+ {
+ return buf.GetIterAtMark (triggerMark).Offset;
+ }
+ }
+
+ int ICompletionWidget.TriggerLine
+ {
+ get
+ {
+ return buf.GetIterAtMark (triggerMark).Line;
+ }
+ }
+
+ int ICompletionWidget.TriggerLineOffset
+ {
+ get
+ {
+ return buf.GetIterAtMark (triggerMark).LineOffset;
+ }
+ }
+
+ Gtk.Style ICompletionWidget.GtkStyle
+ {
+ get
+ {
+ return Style.Copy();
+ }
+ }
+
bool PeekCharIsWhitespace ()
{
TextIter start = buf.GetIterAtMark (buf.InsertMark);
Index: Core/src/AddIns/DisplayBindings/SourceEditor/InsightWindow/IndexerInsightDataProvider.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/InsightWindow/IndexerInsightDataProvider.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/InsightWindow/IndexerInsightDataProvider.cs (working copy)
@@ -17,6 +17,8 @@
using MonoDevelop.Internal.Parser;
using MonoDevelop.Internal.Project;
+using MonoDevelop.Gui.Completion;
+
using MonoDevelop.SourceEditor.Gui;
using MonoDevelop.SourceEditor.CodeCompletion;
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionData.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionData.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionData.cs (working copy)
@@ -10,6 +10,8 @@
using System.Reflection;
using System.Collections;
+using MonoDevelop.Gui.Completion;
+
using MonoDevelop.SourceEditor.Gui;
namespace MonoDevelop.SourceEditor.CodeCompletion
@@ -33,7 +35,7 @@
get;
}
- void InsertAction(SourceEditorView control);
+ void InsertAction(ICompletionWidget widget);
}
public interface ICompletionDataWithMarkup : ICompletionData
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionListWindow.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionListWindow.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionListWindow.cs (working copy)
@@ -5,6 +5,7 @@
using MonoDevelop.SourceEditor.Gui;
using MonoDevelop.Internal.Project;
using MonoDevelop.Gui;
+using MonoDevelop.Gui.Completion;
namespace MonoDevelop.SourceEditor.CodeCompletion
{
@@ -12,8 +13,7 @@
{
string fileName;
Project project;
- SourceEditorView control;
- TextMark triggeringMark;
+ ICompletionWidget completionWidget;
ICompletionData[] completionData;
DeclarationViewWindow declarationviewwindow = new DeclarationViewWindow ();
static DataComparer dataComparer = new DataComparer ();
@@ -40,14 +40,13 @@
SizeAllocated += new SizeAllocatedHandler (ListSizeChanged);
}
- public static void ShowWindow (char firstChar, TextIter trigIter, ICompletionDataProvider provider, SourceEditorView ctrl)
+ public static void ShowWindow (char firstChar, ICompletionDataProvider provider, ICompletionWidget completionWidget, Project project, string fileName)
{
- if (!wnd.ShowListWindow (firstChar, trigIter, provider, ctrl))
+ if (!wnd.ShowListWindow (firstChar, provider, completionWidget, project, fileName))
return;
// makes control-space in midle of words to work
- TextBuffer buf = wnd.control.Buffer;
- string text = buf.GetText (trigIter, buf.GetIterAtMark (buf.InsertMark), false);
+ string text = wnd.completionWidget.CompletionText;
if (text.Length == 0)
return;
@@ -63,32 +62,25 @@
wnd.PartialWord = wnd.CompleteWord;
}
- bool ShowListWindow (char firstChar, TextIter trigIter, ICompletionDataProvider provider, SourceEditorView ctrl)
+ bool ShowListWindow (char firstChar, ICompletionDataProvider provider, ICompletionWidget completionWidget, Project project, string fileName)
{
- this.control = ctrl;
- this.fileName = ctrl.ParentEditor.DisplayBinding.ContentName;
- this.project = ctrl.ParentEditor.DisplayBinding.Project;
- triggeringMark = control.Buffer.CreateMark (null, trigIter, true);
+ this.completionWidget = completionWidget;
+ this.fileName = fileName;
+ this.project = project;
- completionData = provider.GenerateCompletionData (project, fileName, ctrl, firstChar, triggeringMark);
+ completionData = provider.GenerateCompletionData (project, fileName, completionWidget, firstChar);
+
if (completionData == null || completionData.Length == 0) return false;
- this.Style = ctrl.Style.Copy();
+ this.Style = completionWidget.GtkStyle;
Array.Sort (completionData, dataComparer);
DataProvider = this;
- Gdk.Rectangle rect = control.GetIterLocation (control.Buffer.GetIterAtMark (triggeringMark));
- int wx, wy;
- control.BufferToWindowCoords (Gtk.TextWindowType.Widget, rect.X /*+ rect.Width*/, rect.Y + rect.Height, out wx, out wy);
+ int x = completionWidget.TriggerXCoord;
+ int y = completionWidget.TriggerYCoord;
- int tx, ty;
- control.GdkWindow.GetOrigin (out tx, out ty);
-
- int x = tx + wx;
- int y = ty + wy;
-
int w, h;
GetSize (out w, out h);
@@ -96,8 +88,10 @@
x = Screen.Width - w;
if ((y + h) > Screen.Height)
- y = y - rect.Height - h;
-
+ {
+ y = y - completionWidget.TriggerTextHeight - h;
+ }
+
Move (x, y);
Show ();
@@ -140,11 +134,7 @@
void UpdateWord ()
{
- TextIter offsetIter = wnd.control.Buffer.GetIterAtMark (wnd.triggeringMark);
- TextIter endIter = wnd.control.Buffer.GetIterAtOffset (offsetIter.Offset + wnd.PartialWord.Length);
- wnd.control.Buffer.MoveMark (wnd.control.Buffer.InsertMark, offsetIter);
- wnd.control.Buffer.Delete (ref offsetIter, ref endIter);
- wnd.control.Buffer.InsertAtCursor (wnd.CompleteWord);
+ completionWidget.SetCompletionText(wnd.PartialWord, wnd.CompleteWord);
}
public new void Hide ()
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionData.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionData.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionData.cs (working copy)
@@ -14,6 +14,7 @@
using MonoDevelop.Internal.Parser;
using MonoDevelop.Services;
+using MonoDevelop.Gui.Completion;
using MonoDevelop.Core.Services;
using MonoDevelop.SourceEditor.Gui;
@@ -219,9 +220,9 @@
documentation = "";
}
- public void InsertAction (SourceEditorView control)
+ public void InsertAction (ICompletionWidget widget)
{
- control.Buffer.InsertAtCursor (completionString);
+ widget.InsertAtCursor (completionString);
}
public static string GetDocumentation (string doc)
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TextUtilities.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TextUtilities.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TextUtilities.cs (working copy)
@@ -8,6 +8,7 @@
using System;
using System.Text;
using System.Diagnostics;
+using MonoDevelop.Gui.Completion;
using MonoDevelop.SourceEditor.Gui;
namespace MonoDevelop.SourceEditor.CodeCompletion
@@ -74,23 +75,21 @@
/// 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)
+ //public static string GetExpressionBeforeOffset(string text, int offset)
+ public static string GetExpressionBeforeOffset(ICompletionWidget widget, int offset)
{
- // FIXME: we should actually use GtkTextIter's
- string text = textArea.Buffer.Text;
int origOffset = offset;
while (offset - 1 > 0) {
- switch (text [offset - 1]) {
+ switch (widget.GetChar (offset - 1)) {
case '}':
goto done;
-// offset = SearchBracketBackward(document, offset - 2, '{','}');
// break;
case ']':
- offset = SearchBracketBackward(textArea, offset - 2, '[',']');
+ offset = SearchBracketBackward(widget, offset - 2, '[',']');
break;
case ')':
- offset = SearchBracketBackward(textArea, offset - 2, '(',')');
+ offset = SearchBracketBackward(widget, offset - 2, '(',')');
break;
case '.':
--offset;
@@ -100,30 +99,28 @@
case '\'':
return "'a'";
case '>':
- if (text [offset - 2] == '-') {
+ if (widget.GetChar (offset - 2) == '-') {
offset -= 2;
break;
}
goto done;
default:
- if (Char.IsWhiteSpace (text [offset - 1])) {
+ if (Char.IsWhiteSpace (widget.GetChar (offset - 1))) {
--offset;
break;
}
int start = offset - 1;
- if (!IsLetterDigitOrUnderscore (text [start])) {
+ if (!IsLetterDigitOrUnderscore (widget.GetChar (start))) {
goto done;
}
- while (start > 0 && IsLetterDigitOrUnderscore (text[start - 1])) {
+ while (start > 0 && IsLetterDigitOrUnderscore (widget.GetChar(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);
+ Console.WriteLine("{0} -- {1}", offset, start);
+ string word = widget.GetText (start, offset);
+ Console.WriteLine("word >{0}<", word);
switch (word) {
case "ref":
case "out":
@@ -142,11 +139,8 @@
}
}
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.GetIterAtOffset (origOffset);
- Gtk.TextIter offset_Iter = textArea.Buffer.GetIterAtOffset (offset);
- return textArea.Buffer.GetText (start_Iter, offset_Iter, false ).Trim();
+// Console.WriteLine("offset : {0} origOffset: {1}", offset, origOffset);
+ return offset - origOffset > 0 ? widget.GetText(origOffset, offset).Trim() : "";
}
/*
@@ -244,18 +238,16 @@
return document.GetText(line.Offset, line.Length);
}
*/
- static bool ScanLineComment(SourceEditorView document, int offset)
+ static bool ScanLineComment(ICompletionWidget widget, int offset)
{
- // FIXME: use iters
- string text = document.Buffer.Text;
- while (offset > 0 && offset < text.Length) {
- char ch = text [offset];
+ while (offset > 0 && offset < widget.TextLength) {
+ char ch = widget.GetChar (offset);
switch (ch) {
case '\r':
case '\n':
return false;
case '/':
- if (text[offset + 1] == '/') {
+ if (widget.GetChar (offset + 1) == '/') {
return true;
}
break;
@@ -265,47 +257,46 @@
return false;
}
- public static int SearchBracketBackward(SourceEditorView document, int offset, char openBracket, char closingBracket)
+ public static int SearchBracketBackward(ICompletionWidget widget, int offset, char openBracket, char closingBracket)
{
// FIXME: use iters
- string text = document.Buffer.Text;
int brackets = -1;
bool inString = false;
bool inChar = false;
bool blockComment = false;
- while (offset >= 0 && offset < text.Length) {
- char ch = text [offset];
+ while (offset >= 0 && offset < widget.TextLength) {
+ char ch = widget.GetChar(offset);
switch (ch) {
case '/':
if (blockComment) {
- if (text [offset + 1]== '*') {
+ if (widget.GetChar(offset + 1)== '*') {
blockComment = false;
}
}
- if (!inString && !inChar && offset + 1 < text.Length) {
- if (offset > 0 && text [offset - 1] == '*') {
+ if (!inString && !inChar && offset + 1 < widget.TextLength) {
+ if (offset > 0 && widget.GetChar(offset - 1) == '*') {
blockComment = true;
}
}
break;
case '"':
- if (!inChar && !blockComment && !ScanLineComment(document, offset)) {
+ if (!inChar && !blockComment && !ScanLineComment(widget, offset)) {
inString = !inString;
}
break;
case '\'':
- if (!inString && !blockComment && !ScanLineComment(document, offset)) {
+ if (!inString && !blockComment && !ScanLineComment(widget, offset)) {
inChar = !inChar;
}
break;
default :
if (ch == closingBracket) {
- if (!(inString || inChar || blockComment) && !ScanLineComment(document, offset)) {
+ if (!(inString || inChar || blockComment) && !ScanLineComment(widget, offset)) {
--brackets;
}
} else if (ch == openBracket) {
- if (!(inString || inChar || blockComment) && !ScanLineComment(document, offset)) {
+ if (!(inString || inChar || blockComment) && !ScanLineComment(widget, offset)) {
++brackets;
if (brackets == 0) {
return offset;
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionWindow.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionWindow.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CompletionWindow.cs (working copy)
@@ -1,427 +0,0 @@
-// <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.Collections;
-
-using Gtk;
-using MonoDevelop.SourceEditor.Gui;
-using MonoDevelop.Internal.Project;
-using MonoDevelop.Gui;
-
-namespace MonoDevelop.SourceEditor.CodeCompletion
-{
- public class CompletionWindow : Window
- {
- const int DeclarationIndent = 1;
- TreeViewColumn complete_column;
-
- ICompletionDataProvider completionDataProvider;
- SourceEditorView control;
- TreeView listView;
- ListStore store;
- TextMark triggeringMark;
- int origOffset;
- int num_in = 0;
- DeclarationViewWindow declarationviewwindow = new DeclarationViewWindow ();
- string fileName;
- Project project;
-
- static CompletionWindow wnd;
-
- static CompletionWindow ()
- {
- wnd = new CompletionWindow ();
- }
-
- string GetTypedString ()
- {
- TextIter startIter = control.Buffer.GetIterAtMark (control.Buffer.InsertMark);
- TextIter offsetIter = control.Buffer.GetIterAtMark (triggeringMark);
- return control.Buffer.GetText (offsetIter, startIter, true);
- }
-
- int insertLength {
- get {
- TextIter startIter = control.Buffer.GetIterAtMark (control.Buffer.InsertMark);
- return startIter.Offset - origOffset;
- }
- }
-
- void DeleteInsertion()
- {
- TextIter startIter = control.Buffer.GetIterAtMark (control.Buffer.InsertMark);
- TextIter offsetIter = control.Buffer.GetIterAtMark (triggeringMark);
- if (startIter.Offset > offsetIter.Offset) {
- int newPos = offsetIter.Offset;
- control.Buffer.Delete (ref offsetIter, ref startIter);
- control.Buffer.MoveMark (control.Buffer.InsertMark, control.Buffer.GetIterAtOffset (newPos));
- }
- }
-
- protected override bool OnKeyPressEvent (Gdk.EventKey e)
- {
- uint state = (uint)e.State;
- state &= 1101u;
-
- switch (state) {
- case 0: //NORMAL
- switch ((char)e.Key) {
- case '.':
- case ' ':
- case ';':
- case '(':
- case '[':
- case ',':
- control.SimulateKeyPress (ref e);
- LostFocusListView (null, null);
- return true;
-
- case (char) Gdk.Key.Return:
- case (char) Gdk.Key.ISO_Enter:
- case (char) Gdk.Key.Key_3270_Enter:
- case (char) Gdk.Key.KP_Enter:
- KeyPressEventArgs fake_args = new KeyPressEventArgs ();
- fake_args.Args = new object[] { e };
- ListKeypressEvent (null, fake_args);
- return true;
-
- case (char) Gdk.Key.BackSpace:
- num_in--;
- control.SimulateKeyPress (ref e);
- if (insertLength <= -1) {
- LostFocusListView (null, null);
- return true;
- }
- RowActivated (null, null);
- return true;
- }
- break;
- case 1: //SHIFT
- switch ((char)e.Key) {
- case 'P':
- case 'N':
- KeyPressEventArgs fake_args = new KeyPressEventArgs ();
- fake_args.Args = new object[] { e };
- ListKeypressEvent (null, fake_args);
- return true;
- }
- break;
- }
- return base.OnKeyPressEvent (e);
- }
-
- void ListKeypressEvent (object sender, KeyPressEventArgs ex)
- {
- Gdk.Key key = ex.Event.Key;
- char val = (char) 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:
- LostFocusListView (null, null);
- ex.RetVal = true;
- return;
-
- default:
- if (val != '_' && !Char.IsLetterOrDigit (val)) {
- TreeModel mdl;
- TreeIter itr;
- if (listView.Selection.GetSelected (out mdl, out itr)) {
- ActivateItem (null, null);
- } else {
- LostFocusListView (null, null);
- }
-
- ex.RetVal = true;
- return;
- } else {
- control.Buffer.InsertAtCursor (val.ToString ());
- }
- break;
- }
-
- num_in++;
-
- ShuffleSelection (false);
-
- ex.RetVal = true;
- }
-
- bool ShuffleSelection (bool magic)
- {
- // select the current typed word
- int lastSelected = -1;
- int capitalizationIndex = -1;
- int numOfHits = 0;
-
- string typedString = GetTypedString ();
- TreeIter iter;
- int i = 0;
- store.GetIterFirst (out iter);
- do {
- 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) {
- numOfHits++;
- }
-
- if (currentCapitalizationIndex > capitalizationIndex) {
- lastSelected = i;
- capitalizationIndex = currentCapitalizationIndex;
- }
- }
- i++;
- } while (store.IterNext (ref iter) == true);
-
- if (lastSelected != -1) {
- listView.Selection.UnselectAll ();
- TreePath path = new TreePath (lastSelected.ToString ());
- listView.SetCursor (path, complete_column, false);
- listView.ScrollToCell (path, null, false, 0, 0);
- if (magic && numOfHits == 1) {
- ActivateItem (null, null);
- LostFocusListView (null, null);
- return true;
- }
- }
- if (numOfHits == 0) {
- control.buf.DropCompleteAhead ();
- listView.Selection.UnselectAll ();
- }
- return false;
- }
-
- void InitializeControls ()
- {
- Decorated = false;
- SkipPagerHint = true;
- SkipTaskbarHint = true;
- TypeHint = Gdk.WindowTypeHint.Dialog;
-
- TransientFor = (Gtk.Window)WorkbenchSingleton.Workbench;
-
- store = new Gtk.ListStore (typeof (string), typeof (Gdk.Pixbuf), typeof(ICompletionData));
- listView = new Gtk.TreeView (store);
- listView.HeadersVisible = false;
-
- complete_column = new 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.HscrollbarPolicy = Gtk.PolicyType.Never;
- scroller.Add (listView);
-
- Gtk.Frame frame = new Gtk.Frame ();
- frame.Add (scroller);
- this.Add (frame);
-
- listView.KeyPressEvent += new KeyPressEventHandler (ListKeypressEvent);
- this.FocusOutEvent += new FocusOutEventHandler (LostFocusListView);
- this.AddEvents ((int) (Gdk.EventMask.LeaveNotifyMask));
- 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 static void ShowWindow (char firstChar, TextIter trigIter, bool magic, ICompletionDataProvider provider, SourceEditorView ctrl)
- {
- wnd.ShowCompletionWindow (firstChar, trigIter, magic, provider, ctrl);
- }
-
- void ShowCompletionWindow (char firstChar, TextIter trigIter, bool magic, ICompletionDataProvider provider, SourceEditorView ctrl)
- {
- this.completionDataProvider = provider;
- this.control = ctrl;
- this.fileName = ctrl.ParentEditor.DisplayBinding.ContentName;
- this.project = ctrl.ParentEditor.DisplayBinding.Project;
- this.store.Clear ();
- control.buf.StartAtomicUndo ();
- triggeringMark = control.Buffer.CreateMark (null, trigIter, true);
- origOffset = trigIter.Offset;
- FillList (true, firstChar);
-
- TreeIter iter;
- if (store.GetIterFirst (out iter) == false) {
- listView.FocusOutEvent -= new FocusOutEventHandler (LostFocusListView);
- control.buf.EndAtomicUndo ();
- control.GrabFocus ();
- return;
- }
-
- listView.Selection.Changed -= new EventHandler (RowActivated);
- if (magic) {
- if (ShuffleSelection (true))
- return;
- }
-
- Gdk.Rectangle rect = control.GetIterLocation (control.Buffer.GetIterAtMark (triggeringMark));
-
- int wx, wy;
- control.BufferToWindowCoords (Gtk.TextWindowType.Widget, rect.X /*+ rect.Width*/, rect.Y + rect.Height, out wx, out wy);
-
- int tx, ty;
- control.GdkWindow.GetOrigin (out tx, out ty);
-
- ShowAll ();
- Move (tx + wx, ty + wy);
- Present ();
- listView.GrabFocus ();
- listView.Selection.Changed += new EventHandler (RowActivated);
- RowActivated (null, null);
- }
-
- /// <remarks>
- /// Creates a new Completion window and puts it location under the caret
- /// </remarks>
- CompletionWindow () : base (Gtk.WindowType.Toplevel)
- {
- InitializeControls ();
- }
-
- void ActivateItem (object sender, RowActivatedArgs e)
- {
- TreeModel foo;
- TreeIter iter;
- if (listView.Selection.GetSelected (out foo, out iter)) {
- ICompletionData data = (ICompletionData) store.GetValue (iter, 2);
- control.buf.DropCompleteAhead ();
- DeleteInsertion ();
- data.InsertAction (control);
- LostFocusListView (null, null);
- }
- }
-
- void LostFocusListView (object sender, FocusOutEventArgs e)
- {
- control.buf.DropCompleteAhead ();
- control.buf.EndAtomicUndo ();
- listView.FocusOutEvent -= new FocusOutEventHandler (LostFocusListView);
- control.HasFocus = true;
- declarationviewwindow.HideAll ();
- this.Hide ();
- }
-
- void FillList (bool firstTime, char ch)
- {
- ICompletionData[] completionData = completionDataProvider.GenerateCompletionData(project, fileName, control, ch, triggeringMark);
- if (completionData == null || completionData.Length == 0) {
- return;
- }
-
- foreach (ICompletionData data in completionData) {
- store.AppendValues (data.Text[0], RenderIcon (data.Image, Gtk.IconSize.Menu, ""), 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);
- if (data == null)
- return;
-
- int inst = insertLength;
- if (inst == -1) {
- LostFocusListView (null, null);
- return;
- }
- if (inst >= 1) {
- DeleteInsertion ();
- int l = inst > data.CompletionString.Length ? data.CompletionString.Length : inst;
- control.buf.InsertAtCursor (data.CompletionString.Substring (0, l));
- }
- control.buf.DropCompleteAhead ();
- if (data.CompletionString.Length > inst) {
- control.buf.DropCompleteAhead ();
- control.buf.CompleteAhead (data.CompletionString.Substring(inst));
- }
- // This code is for sizing the treeview properly.
- Gtk.TreePath path = store.GetPath (iter);
- Gdk.Rectangle backRect = listView.GetBackgroundArea (path, (Gtk.TreeViewColumn)listView.Columns[0]);
-
- listView.HeightRequest = (backRect.Height * 5) + 2;
-
- // FIXME: This code is buggy, and generates a bad placement sometimes when you jump a lot.
- // but it is better than 0,0
- // This code is for sizing the treeview properly.
-
- Gdk.Rectangle rect = listView.GetCellArea (path, (Gtk.TreeViewColumn)listView.Columns[0]);
- int listpos_x = 0, listpos_y = 0;
- while (listpos_x == 0)
- GetPosition (out listpos_x, out listpos_y);
- int vert = listpos_y + rect.Y;
-
- int lvWidth, lvHeight;
- listView.GdkWindow.GetSize (out lvWidth, out lvHeight);
- if (vert >= listpos_y + lvHeight - 2) {
- vert = listpos_y + lvHeight - 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 + lvWidth + 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;
- }
-
- if (declarationviewwindow.DescriptionMarkup.Length == 0)
- return;
-
- declarationviewwindow.ShowAll ();
-
- int dvwWidth, dvwHeight;
-
- declarationviewwindow.GdkWindow.GetSize (out dvwWidth, out dvwHeight);
- if (listView.Screen.Width <= horiz + dvwWidth) {
- horiz = listpos_x - dvwWidth - 10;
- }
-
- declarationviewwindow.Move (horiz, vert);
- }
- }
- }
-}
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CommentCompletionDataProvider.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CommentCompletionDataProvider.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CommentCompletionDataProvider.cs (working copy)
@@ -13,6 +13,7 @@
using MonoDevelop.Core.Properties;
using MonoDevelop.Core.Services;
using MonoDevelop.Gui;
+using MonoDevelop.Gui.Completion;
using MonoDevelop.Internal.Templates;
using MonoDevelop.Services;
@@ -63,7 +64,7 @@
return row >= region.BeginLine && (row <= region.EndLine || region.EndLine == -1);
}
- public ICompletionData[] GenerateCompletionData (Project project, string fileName, SourceEditorView textArea, char charTyped, Gtk.TextMark triggerMark)
+ public ICompletionData[] GenerateCompletionData (Project project, string fileName, ICompletionWidget widget, char charTyped)
{
/*caretLineNumber = textArea.Caret.Line;
caretColumn = textArea.Caret.Column;
@@ -114,7 +115,7 @@
}
}
- public void InsertAction (SourceEditorView control)
+ public void InsertAction (ICompletionWidget widget)
{
//((SharpDevelopTextAreaControl)control).ActiveTextAreaControl.TextArea.InsertString(text);
}
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionDataProvider.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionDataProvider.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/ICompletionDataProvider.cs (working copy)
@@ -10,6 +10,7 @@
using System.Reflection;
using System.Collections;
using MonoDevelop.Internal.Project;
+using MonoDevelop.Gui.Completion;
using Gdk;
@@ -17,6 +18,6 @@
namespace MonoDevelop.SourceEditor.CodeCompletion {
public interface ICompletionDataProvider {
- ICompletionData[] GenerateCompletionData(Project project, string fileName, SourceEditorView textArea, char charTyped, Gtk.TextMark mark);
+ ICompletionData[] GenerateCompletionData(Project project, string fileName, ICompletionWidget widget, char charTyped);
}
}
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionDataProvider.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionDataProvider.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/CodeCompletionDataProvider.cs (working copy)
@@ -16,6 +16,7 @@
using MonoDevelop.Core.Properties;
using MonoDevelop.Core.Services;
using MonoDevelop.Gui;
+using MonoDevelop.Gui.Completion;
using MonoDevelop.Internal.Templates;
using MonoDevelop.Services;
using MonoDevelop.Internal.Parser;
@@ -55,29 +56,26 @@
ArrayList completionData = null;
- public ICompletionData[] GenerateCompletionData(Project project, string fileName, SourceEditorView textArea, char charTyped, TextMark triggerMark)
+ public ICompletionData[] GenerateCompletionData(Project project, string fileName, ICompletionWidget widget, char charTyped)
{
completionData = new ArrayList();
this.fileName = fileName;
- Gtk.TextIter insertIter = textArea.Buffer.GetIterAtMark (triggerMark);
-
// the parser works with 1 based coordinates
-
- caretLineNumber = insertIter.Line + 1;
- caretColumn = insertIter.LineOffset + 1;
+ caretLineNumber = widget.TriggerLine + 1;
+ caretColumn = widget.TriggerLineOffset + 1;
//string expression = TextUtilities.GetExpressionBeforeOffset (textArea, insertIter.Offset);
ResolveResult results;
IParserService parserService = (IParserService)MonoDevelop.Core.Services.ServiceManager.GetService(typeof(IParserService));
IExpressionFinder expressionFinder = parserService.GetExpressionFinder(fileName);
- string expression = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset(textArea, insertIter.Offset) : expressionFinder.FindExpression(textArea.Buffer.GetText(textArea.Buffer.StartIter, insertIter, true), insertIter.Offset - 2);
+ string expression = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset(widget, widget.TriggerOffset) : expressionFinder.FindExpression(widget.GetText (0, widget.TriggerOffset), widget.TriggerOffset - 2);
if (expression == null) return null;
Console.WriteLine ("Expr: |{0}|", expression);
//FIXME: This chartyped check is a fucking *HACK*
if (expression == "is" || expression == "as") {
- string expr = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset (textArea, insertIter.Offset - 3) : expressionFinder.FindExpression (textArea.Buffer.GetText (textArea.Buffer.StartIter, insertIter, true), insertIter.Offset - 5);
- AddResolveResults (parserService.IsAsResolve (project, expr, caretLineNumber, caretColumn, fileName, textArea.Buffer.Text));
+ string expr = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset (widget, widget.TriggerOffset - 3) : expressionFinder.FindExpression (widget.GetText (0, widget.TriggerOffset), widget.TriggerOffset - 5);
+ AddResolveResults (parserService.IsAsResolve (project, expr, caretLineNumber, caretColumn, fileName, widget.GetText (0, widget.TextLength)));
return (ICompletionData[])completionData.ToArray (typeof (ICompletionData));
}
if (ctrlspace && charTyped != '.') {
@@ -92,7 +90,7 @@
} else {
//FIXME: I added the null check, #D doesnt need it, why do we?
if (fileName != null) {
- results = parserService.Resolve(project, expression, caretLineNumber, caretColumn, fileName, textArea.Buffer.Text);
+ results = parserService.Resolve(project, expression, caretLineNumber, caretColumn, fileName, widget.GetText (0, widget.TextLength));
AddResolveResults(results);
}
}
Index: Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TemplateCompletionDataProvider.cs
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TemplateCompletionDataProvider.cs (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/CodeCompletion/TemplateCompletionDataProvider.cs (working copy)
@@ -15,6 +15,7 @@
using MonoDevelop.Internal.Project;
using MonoDevelop.SourceEditor.Gui;
using Stock = MonoDevelop.Gui.Stock;
+using MonoDevelop.Gui.Completion;
namespace MonoDevelop.SourceEditor.CodeCompletion
{
@@ -27,7 +28,7 @@
}
}
- public ICompletionData[] GenerateCompletionData(Project project, string fileName, SourceEditorView textArea, char charTyped, Gtk.TextMark triggerMark)
+ public ICompletionData[] GenerateCompletionData(Project project, string fileName, ICompletionWidget widget, char charTyped)
{
CodeTemplateGroup templateGroup = CodeTemplateLoader.GetTemplateGroupPerFilename(fileName);
if (templateGroup == null) {
@@ -74,7 +75,7 @@
}
}
- public void InsertAction(SourceEditorView control)
+ public void InsertAction(ICompletionWidget widget)
{
//((SharpDevelopTextAreaControl)control).InsertTemplate(template);
}
Index: Core/src/AddIns/DisplayBindings/SourceEditor/Makefile.am
===================================================================
--- Core/src/AddIns/DisplayBindings/SourceEditor/Makefile.am (revision 2671)
+++ Core/src/AddIns/DisplayBindings/SourceEditor/Makefile.am (working copy)
@@ -5,7 +5,6 @@
FILES = \
CodeCompletion/CodeCompletionData.cs \
CodeCompletion/ICompletionData.cs \
-CodeCompletion/CompletionWindow.cs \
CodeCompletion/CompletionListWindow.cs \
CodeCompletion/ListWindow.cs \
CodeCompletion/TextUtilities.cs \
-------------- next part --------------
Index: Extras/BooBinding/Gui/IShellModel.boo
===================================================================
--- Extras/BooBinding/Gui/IShellModel.boo (revision 2671)
+++ Extras/BooBinding/Gui/IShellModel.boo (working copy)
@@ -20,6 +20,7 @@
namespace BooBinding.Gui
import System
+import System.Collections
import BooBinding.Properties
interface IShellModel:
@@ -45,9 +46,16 @@
pass
Properties as ShellProperties:
- get:
- pass
+ get
+ LanguageName as string:
+ get
+
MimeType as string:
- get:
- pass
+ get
+
+ MimeTypeExtension as string:
+ get
+
+ References as IList:
+ get
Index: Extras/BooBinding/Gui/ShellTextView.boo
===================================================================
--- Extras/BooBinding/Gui/ShellTextView.boo (revision 2671)
+++ Extras/BooBinding/Gui/ShellTextView.boo (working copy)
@@ -31,11 +31,13 @@
import GtkSourceView
import MonoDevelop.Gui.Widgets
+import MonoDevelop.Gui.Completion
import MonoDevelop.Core.Services
import MonoDevelop.Services
import MonoDevelop.Core.Properties
import MonoDevelop.Internal.Project
+import MonoDevelop.SourceEditor.CodeCompletion
/*
* TODO
@@ -44,9 +46,10 @@
* 2) Don't record lines with errors in the _scriptLines buffer
*/
-class ShellTextView (SourceView):
+class ShellTextView (SourceView, ICompletionWidget):
private static _promptRegular = ">>> "
private static _promptMultiline = "... "
+ private static _fakeFileName as string
[Getter(Model)]
model as IShellModel
@@ -68,9 +71,14 @@
private _proj as Project
private _assembliesLoaded as bool
+
+ private _fakeProject as DotNetProject
+ private _parserService as DefaultParserService
+ private _fileInfo as FileStream
def constructor(model as IShellModel):
service = cast(SourceViewService,ServiceManager.GetService(typeof(SourceViewService)))
+ _parserService = cast(IParserService, ServiceManager.GetService (typeof (DefaultParserService)))
buf = SourceBuffer(service.GetLanguageFromMimeType(model.MimeType))
// This freaks out booc for some reason.
@@ -82,6 +90,14 @@
self.WrapMode = Gtk.WrapMode.Word
self.ModifyFont(Model.Properties.Font)
+ _fakeFileName = "/tmp/shell-dummy-file.${Model.MimeTypeExtension}"
+ _fileInfo = System.IO.File.Create (_fakeFileName)
+
+ # FIXME: Put the project file somewhere other than /tmp
+ _fakeProject = DotNetProject(Model.LanguageName, Name: "___ShellProject", FileName: "/tmp/shell-project.mdp")
+
+ _parserService.LoadProjectDatabase(_fakeProject)
+
Model.Properties.InternalProperties.PropertyChanged += OnPropertyChanged
Model.RegisterOutputHandler (HandleOutput)
@@ -155,6 +171,10 @@
for line as string in output:
processOutput (line )
prompt (true)
+ for assembly in Model.References:
+ _fakeProject.AddReference(assembly)
+
+ GLib.Idle.Add( { _parserService.ParseFile (_fakeFileName, _scriptLines) } )
return false
override def Dispose():
@@ -208,6 +228,9 @@
_reset.Show()
override def OnKeyPressEvent (ev as Gdk.EventKey):
+ if CompletionListWindow.ProcessKeyEvent (ev):
+ return true
+
// Short circuit to avoid getting moved back to the input line
// when paging up and down in the shell output
if ev.Key in Gdk.Key.Page_Up, Gdk.Key.Page_Down:
@@ -219,6 +242,9 @@
Buffer.MoveMark (Buffer.SelectionBound, InputLineEnd)
Buffer.MoveMark (Buffer.InsertMark, InputLineEnd)
+ if (ev.State == Gdk.ModifierType.ControlMask) and ev.Key == Gdk.Key.space:
+ TriggerCodeCompletion ()
+
if ev.Key == Gdk.Key.Return:
if _inBlock:
if InputLine == "":
@@ -237,7 +263,7 @@
else:
// Special case for start of new code block
if InputLine.Trim()[-1:] == ":":
- _inBlock = true;
+ _inBlock = true
_blockText = InputLine
prompt (true, true)
if _auto_indent:
@@ -268,7 +294,7 @@
elif ev.Key == Gdk.Key.Up:
if (not _inBlock) and _commandHistoryPast.Count > 0:
if _commandHistoryFuture.Count == 0:
- _commandHistoryFuture.Push(InputLine);
+ _commandHistoryFuture.Push(InputLine)
else:
if _commandHistoryPast.Count == 1:
return true
@@ -297,6 +323,12 @@
Buffer.MoveMark (Buffer.SelectionBound, InputLineBegin)
return true
+ elif ev.Key == Gdk.Key.period:
+ ret = super.OnKeyPressEvent(ev)
+ prepareCompletionDetails (Buffer.GetIterAtMark (Buffer.InsertMark))
+ CompletionListWindow.ShowWindow(char('.'), CodeCompletionDataProvider (true), self, _fakeProject, _fakeFileName)
+ return ret
+
// Short circuit to avoid getting moved back to the input line
// when paging up and down in the shell output
elif ev.Key in Gdk.Key.Page_Up, Gdk.Key.Page_Down:
@@ -304,8 +336,41 @@
return super (ev)
+ protected override def OnFocusOutEvent (e as EventFocus):
+ CompletionListWindow.HideWindow ()
+ return super.OnFocusOutEvent(e)
+
#endregion
+ private def TriggerCodeCompletion():
+ iter = Cursor
+ triggerChar = char('\0')
+ triggerIter = TextIter.Zero
+ if (iter.Char != null and iter.Char.Length > 0):
+ if iter.Char[0] in (char(' '), char('\t'), char('.'), char('('), char('[')):
+ triggerIter = iter
+ triggerChar = iter.Char[0]
+
+ while iter.LineOffset > 0 and triggerIter.Equals (TextIter.Zero):
+ if (iter.Char == null or iter.Char.Length == 0):
+ iter.BackwardChar ()
+ continue
+
+ if iter.Char[0] in (char(' '), char('\t'), char('.'), char('('), char('[')):
+ triggerIter = iter
+ triggerChar = iter.Char[0]
+ break
+
+ iter.BackwardChar ()
+
+ if (triggerIter.Equals (TextIter.Zero)):
+ return
+
+ triggerIter.ForwardChar ()
+
+ prepareCompletionDetails (triggerIter)
+ CompletionListWindow.ShowWindow (triggerChar, CodeCompletionDataProvider (true), self, _fakeProject, _fakeFileName)
+
// Mark to find the beginning of our next input line
private _endOfLastProcessing as TextMark
@@ -403,3 +468,76 @@
return
#endregion
+
+ private def prepareCompletionDetails (triggerIter as TextIter):
+ rect = GetIterLocation (Buffer.GetIterAtMark (Buffer.InsertMark))
+
+ wx as int
+ wy as int
+ BufferToWindowCoords (Gtk.TextWindowType.Widget, rect.X, rect.Y + rect.Height, wx, wy)
+
+ tx as int
+ ty as int
+ GdkWindow.GetOrigin (tx, ty)
+
+ self.completionX = tx + wx
+ self.completionY = ty + wy
+ self.textHeight = rect.Height
+ self.triggerMark = Buffer.CreateMark (null, triggerIter, true)
+
+ #region ICompletionWidget
+
+ [Getter(ICompletionWidget.TriggerXCoord)]
+ private completionX
+
+ [Getter(ICompletionWidget.TriggerYCoord)]
+ private completionY
+
+ [Getter(ICompletionWidget.TriggerTextHeight)]
+ private textHeight as int
+
+ ICompletionWidget.Text:
+ get:
+ return Buffer.Text
+
+ ICompletionWidget.TextLength:
+ get:
+ return Buffer.EndIter.Offset
+
+ def ICompletionWidget.GetChar (offset as int) as System.Char:
+ return Buffer.GetIterAtLine (offset).Char[0]
+
+ def ICompletionWidget.GetText (startOffset as int, endOffset as int) as string:
+ return Buffer.GetText(Buffer.GetIterAtOffset (startOffset), Buffer.GetIterAtOffset(endOffset), true)
+
+ ICompletionWidget.CompletionText:
+ get:
+ return Buffer.GetText (Buffer.GetIterAtMark (triggerMark), Buffer.GetIterAtMark (Buffer.InsertMark), false)
+
+ def ICompletionWidget.SetCompletionText (partial_word as string, complete_word as string):
+ offsetIter = Buffer.GetIterAtMark(triggerMark)
+ endIter = Buffer.GetIterAtOffset (offsetIter.Offset + partial_word.Length)
+ Buffer.MoveMark (Buffer.InsertMark, offsetIter)
+ Buffer.Delete (offsetIter, endIter)
+ Buffer.InsertAtCursor (complete_word)
+
+ def ICompletionWidget.InsertAtCursor (text as string):
+ Buffer.InsertAtCursor (text)
+
+ private triggerMark as TextMark
+ ICompletionWidget.TriggerOffset:
+ get:
+ return Buffer.GetIterAtMark (triggerMark).Offset
+
+ ICompletionWidget.TriggerLine:
+ get:
+ return Buffer.GetIterAtMark (triggerMark).Line
+
+ ICompletionWidget.TriggerLineOffset:
+ get:
+ return Buffer.GetIterAtMark (triggerMark).LineOffset
+
+ ICompletionWidget.GtkStyle:
+ get:
+ return self.Style.Copy();
+ #endregion
Index: Extras/BooBinding/Gui/BooShellModel.boo
===================================================================
--- Extras/BooBinding/Gui/BooShellModel.boo (revision 2671)
+++ Extras/BooBinding/Gui/BooShellModel.boo (working copy)
@@ -49,24 +49,32 @@
get:
return "text/x-boo"
+ LanguageName as string:
+ get:
+ return "Boo"
+
+ MimeTypeExtension as string:
+ get:
+ return "boo"
+
Properties as ShellProperties:
get:
return _props
- def constructor ():
- pass
-
- def constructor (program_path as string, socket_path as string):
- GetRemoteShellObject ()
+ References as IList:
+ get:
+ return _booShell.References
+
+ def constructor():
+ getRemoteShellObject()
_booShell.Run ()
- def GetRemoteShellObject ():
+ private def getRemoteShellObject ():
_procService as ProcessService = ServiceManager.GetService (typeof (ProcessService))
_booShell = _procService.CreateExternalProcessObject ("../AddIns/BackendBindings/BooShell.dll", "BooBinding.BooShell.BooShell", false)
if _booShell is null:
raise Exception ("Unable to instantiate remote BooShell object")
-
-
+
def Reset () as bool:
_booShell.Reset()
return true
Index: Extras/BooBinding/Gui/OptionPanels/CodeCompilationPanel.boo
===================================================================
--- Extras/BooBinding/Gui/OptionPanels/CodeCompilationPanel.boo (revision 2671)
+++ Extras/BooBinding/Gui/OptionPanels/CodeCompilationPanel.boo (working copy)
@@ -105,9 +105,7 @@
labelCompileTarget.Markup = String.Format ("{0} :", GettextCatalog.GetString ("Output Assembly"))
- typeArray = array(System.Type, 1)
- typeArray[0] = typeof(string)
- store = ListStore (typeArray)
+ store = ListStore ((typeof(string),))
stringArray = array(System.String, 1)
stringArray[0] = GettextCatalog.GetString ("Executable")
Index: Extras/BooBinding/Properties/ShellProperties.boo
===================================================================
--- Extras/BooBinding/Properties/ShellProperties.boo (revision 2671)
+++ Extras/BooBinding/Properties/ShellProperties.boo (working copy)
@@ -17,7 +17,7 @@
private propertyService = cast (PropertyService, ServiceManager.GetService (typeof(PropertyService)))
private properties = cast (IProperties, propertyService.GetProperty (PropertyName, DefaultProperties()))
- public virtual PropertyName as string:
+ public abstract PropertyName as string:
get:
pass
Index: Extras/BooBinding/Parser/BooParser.boo
===================================================================
--- Extras/BooBinding/Parser/BooParser.boo (revision 2671)
+++ Extras/BooBinding/Parser/BooParser.boo (working copy)
@@ -67,8 +67,8 @@
def Parse(fileName as string, fileContent as string) as ICompilationUnitBase:
//print "Parse ${fileName} with content"
- cr = '\r'[0]
- ln = '\n'[0]
+ cr = char('\r')
+ ln = char('\n')
linecount = 1
for c as Char in fileContent:
linecount += 1 if c == ln
@@ -87,15 +87,20 @@
compiler = BooCompiler()
compiler.Parameters.Input.Add(StringInput(fileName, fileContent))
project as Project
- for entry as Project in MonoDevelop.Services.Runtime.ProjectService.CurrentOpenCombine.GetAllProjects():
- if entry.IsFileInProject(fileName):
- project = entry
-
- return Parse(fileName, lineLength, compiler, project)
+ if MonoDevelop.Services.Runtime.ProjectService.CurrentOpenCombine is not null:
+ for entry as Project in MonoDevelop.Services.Runtime.ProjectService.CurrentOpenCombine.GetAllProjects():
+ if entry.IsFileInProject(fileName):
+ project = entry
+
+ if project is not null and project.ProjectReferences is not null:
+ for projectRef as ProjectReference in project.ProjectReferences:
+ compiler.Parameters.References.Add(System.Reflection.Assembly.LoadFile(projectRef.GetReferencedFileName()))
+
+ return Parse(fileName, lineLength, compiler)
- private def Parse(fileName as string, lineLength as (int), compiler as BooCompiler, project as Project):
+ private def Parse(fileName as string, lineLength as (int), compiler as BooCompiler):
compiler.Parameters.OutputWriter = StringWriter()
- compiler.Parameters.TraceSwitch.Level = TraceLevel.Warning;
+ compiler.Parameters.TraceSwitch.Level = TraceLevel.Warning
compilePipe = Compile()
parsingStep as Boo.Lang.Parser.BooParsingStep = compilePipe[0]
@@ -117,8 +122,6 @@
compilePipe.BreakOnErrors = false
compiler.Parameters.Pipeline = compilePipe
- for projectRef as ProjectReference in project.ProjectReferences:
- compiler.Parameters.References.Add(System.Reflection.Assembly.LoadFile(projectRef.GetReferencedFileName()))
try:
compiler.Run()
Index: Extras/BooBinding/BooShellPadContent.boo
===================================================================
--- Extras/BooBinding/BooShellPadContent.boo (revision 2671)
+++ Extras/BooBinding/BooShellPadContent.boo (working copy)
@@ -35,23 +35,23 @@
override Control:
get:
+ if _scroller is null:
+ CreateBooShell()
return _scroller
def constructor():
super( "Boo Shell", "md-boo-binding-base" )
- CreateBooShell()
def CreateBooShell():
_scroller = Gtk.ScrolledWindow()
- _user = System.Environment.GetEnvironmentVariable("USER")
- _model = BooShellModel ("../AddIns/BackendBindings/BooShellServer.exe", "/tmp/md-booshell-${_user}")
+ _model = BooShellModel ()
_shellView = ShellTextView (_model)
_scroller.Add(_shellView)
_scroller.ShowAll()
override def RedrawContent():
- OnTitleChanged(null);
- OnIconChanged(null);
+ OnTitleChanged(null)
+ OnIconChanged(null)
override def Dispose():
_shellView.Dispose()
Index: Extras/BooBinding/BooShell/BooShell.boo
===================================================================
--- Extras/BooBinding/BooShell/BooShell.boo (revision 2671)
+++ Extras/BooBinding/BooShell/BooShell.boo (working copy)
@@ -52,6 +52,19 @@
EnqueueCommand (ShellCommand (ShellCommandType.Load, assemblyPath))
return true
+ References as IList:
+ get:
+ list = []
+ Monitor.Enter (_interpreter)
+ for assembly as System.Reflection.Assembly in _interpreter.References.List:
+ try:
+ loc = assembly.Location
+ list.Add (loc)
+ except x:
+ continue
+ Monitor.Exit (_interpreter)
+ return list
+
def GetOutput() as (string):
ret as (string)
try:
@@ -78,7 +91,7 @@
GLib.Idle.Add(ProcessCommands)
Application.Run()
- def ProcessCommands() as bool:
+ private def ProcessCommands() as bool:
com as ShellCommand
try:
Monitor.Enter (_commandQueue)
@@ -89,6 +102,7 @@
com = _commandQueue.Dequeue()
+ Monitor.Enter(_interpreter)
if com.Type == ShellCommandType.Eval:
if com.Data is not null:
_interpreter.LoopEval(com.Data)
@@ -97,7 +111,9 @@
elif com.Type == ShellCommandType.Load:
if com.Data is not null:
_interpreter.load(com.Data)
-
+
+ Monitor.Exit(_interpreter)
+
com.Type = ShellCommandType.NoOp
if _commandQueue.Count == 0:
@@ -115,15 +131,16 @@
private def kickOffGuiThread():
- _thread = System.Threading.Thread(ThreadRun)
- _thread.Start()
+ _start as ThreadStart = ThreadRun
+ _thread = System.Threading.Thread (_start)
+ _thread.Start ()
- def print(obj):
+ private def print(obj):
Monitor.Enter (_outputQueue)
_outputQueue.Enqueue(obj)
Monitor.Exit (_outputQueue)
- def EnqueueCommand (command as ShellCommand):
+ private def EnqueueCommand (command as ShellCommand):
if not _thread.IsAlive:
kickOffGuiThread()
More information about the Monodevelop-list
mailing list