예제 #1
0
        public static void PostProcessKeyEvent(CompletionTextEditorExtension ext, ICompletionWidget widget, Gdk.Key key, Gdk.ModifierType modifier)
        {
            // Called after the key has been processed by the editor

            if (methods.Count == 0)
            {
                return;
            }

            for (int n = 0; n < methods.Count; n++)
            {
                // If the cursor is outside of any of the methods parameter list, discard the
                // information window for that method.

                MethodData md  = methods [n];
                int        pos = ext.GetCurrentParameterIndex(md.MethodProvider.StartOffset);
                if (pos == -1)
                {
                    methods.RemoveAt(n);
                    n--;
                }
            }
            // If the user enters more parameters than the current overload has,
            // look for another overload with more parameters.
            UpdateOverload(ext, widget);

            // Refresh.
            UpdateWindow(ext, widget);
        }
        /// <summary>
        /// Get the index of the parameter where the cursor is currently positioned.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="CodeCompletionContext"/>
        /// </param>
        /// <returns>
        /// A <see cref="System.Int32"/>: The index of the parameter,
        /// 0 for no parameter entered,
        /// -1 for outside the list
        /// </returns>
        public int GetCurrentParameterIndex(ICompletionWidget widget, CodeCompletionContext ctx)
        {
            int cursor = document.Editor.Caret.Offset;
            int i      = ctx.TriggerOffset;

            if (i > cursor)
            {
                return(-1);
            }
            else if (i == cursor)
            {
                return(1);
            }

            int parameterIndex = 1;

            while (i++ < cursor)
            {
                char ch = document.Editor.GetCharAt(i - 1);
                if (ch == ',')
                {
                    parameterIndex++;
                }
                else if (ch == ')')
                {
                    return(-1);
                }
            }

            return(parameterIndex);
        }
        bool ShowListWindow(char firstChar, ICompletionDataProvider provider, ICompletionWidget completionWidget, ICodeCompletionContext completionContext, CompletionDelegate closedDelegate)
        {
            if (mutableProvider != null)
            {
                mutableProvider.CompletionDataChanging -= OnCompletionDataChanging;
                mutableProvider.CompletionDataChanged  -= OnCompletionDataChanged;
            }

            this.provider          = provider;
            this.completionContext = completionContext;
            this.closedDelegate    = closedDelegate;
            mutableProvider        = provider as IMutableCompletionDataProvider;

            if (mutableProvider != null)
            {
                mutableProvider.CompletionDataChanging += OnCompletionDataChanging;
                mutableProvider.CompletionDataChanged  += OnCompletionDataChanged;

                if (mutableProvider.IsChanging)
                {
                    OnCompletionDataChanging(null, null);
                }
            }

            this.completionWidget = completionWidget;
            this.firstChar        = firstChar;

            return(FillList());
        }
예제 #4
0
 public void HideParameterInfo()
 {
     ChangeOverload();
     Hide();
     Ext    = null;
     Widget = null;
 }
		// Called when a key is pressed in the editor.
		// Returns false if the key press has to continue normal processing.
		internal static bool ProcessKeyEvent (CompletionTextEditorExtension ext, ICompletionWidget widget, KeyDescriptor descriptor)
		{
			if (methods.Count == 0)
				return false;

			MethodData cmd = methods [methods.Count - 1];

			if (descriptor.SpecialKey == SpecialKey.Down) {
				if (cmd.MethodProvider.Count <= 1)
					return false;
				if (cmd.CurrentOverload < cmd.MethodProvider.Count - 1)
					cmd.CurrentOverload ++;
				else
					cmd.CurrentOverload = 0;
				window.ChangeOverload ();
				UpdateWindow (ext, widget);
				return true;
			} else if (descriptor.SpecialKey == SpecialKey.Up) {
				if (cmd.MethodProvider.Count <= 1)
					return false;
				if (cmd.CurrentOverload > 0)
					cmd.CurrentOverload --;
				else
					cmd.CurrentOverload = cmd.MethodProvider.Count - 1;
				window.ChangeOverload ();
				UpdateWindow (ext, widget);
				return true;
			}
			else if (descriptor.SpecialKey == SpecialKey.Escape) {
				HideWindow (ext, widget);
				return true;
			}
			return false;
		}
		public static bool ShowWindow (char firstChar, ICompletionDataList list, ICompletionWidget completionWidget, CodeCompletionContext completionContext, System.Action closedDelegate)
		{
			try {
				if (wnd == null) {
					wnd = new CompletionListWindow ();
					wnd.WordCompleted += HandleWndWordCompleted;
				}
				try {
					if (!wnd.ShowListWindow (firstChar, list, completionWidget, completionContext, closedDelegate)) {
						if (list is IDisposable)
							((IDisposable)list).Dispose ();
						DestroyWindow ();
						return false;
					}
					
					if (ForceSuggestionMode)
						wnd.AutoSelect = false;
					
					OnWindowShown (EventArgs.Empty);
					return true;
				} catch (Exception ex) {
					LoggingService.LogError (ex.ToString ());
					return false;
				}
			} finally {
				ParameterInformationWindowManager.UpdateWindow (completionWidget);
			}
		}
		// ext may be null, but then parameter completion don't work
		public static bool ShowWindow (CompletionTextEditorExtension ext, char firstChar, ICompletionDataList list, ICompletionWidget completionWidget, CodeCompletionContext completionContext)
		{
			try {
				if (ext != null) {
					int inserted = ext.document.Editor.EnsureCaretIsNotVirtual ();
					if (inserted > 0)
						completionContext.TriggerOffset = ext.document.Editor.Caret.Offset;
				}
				if (wnd == null) {
					wnd = new CompletionListWindow ();
					wnd.WordCompleted += HandleWndWordCompleted;
				}
				wnd.Extension = ext;
				try {
					if (!wnd.ShowListWindow (firstChar, list, completionWidget, completionContext)) {
						if (list is IDisposable)
							((IDisposable)list).Dispose ();
						HideWindow ();
						return false;
					}
					
					if (ForceSuggestionMode)
						wnd.AutoSelect = false;
					wnd.Show ();
					DesktopService.RemoveWindowShadow (wnd);
					OnWindowShown (EventArgs.Empty);
					return true;
				} catch (Exception ex) {
					LoggingService.LogError (ex.ToString ());
					return false;
				}
			} finally {
				ParameterInformationWindowManager.UpdateWindow (ext, completionWidget);
			}
		}
예제 #8
0
        static void UpdateOverload(ICompletionWidget widget)
        {
            if (methods.Count == 0)
            {
                return;
            }

            // If the user enters more parameters than the current overload has,
            // look for another overload with more parameters.

            MethodData md     = methods [methods.Count - 1];
            int        cparam = md.MethodProvider.GetCurrentParameterIndex(widget, md.CompletionContext);

            if (cparam > md.MethodProvider.GetParameterCount(md.CurrentOverload))
            {
                // Look for an overload which has more parameters
                int bestOverload   = -1;
                int bestParamCount = int.MaxValue;
                for (int n = 0; n < md.MethodProvider.OverloadCount; n++)
                {
                    int pc = md.MethodProvider.GetParameterCount(n);
                    if (pc < bestParamCount && pc >= cparam)
                    {
                        bestOverload   = n;
                        bestParamCount = pc;
                    }
                }
                if (bestOverload != -1)
                {
                    md.CurrentOverload = bestOverload;
                }
            }
        }
예제 #9
0
		public static void ShowWindow (char firstChar, ICompletionDataProvider provider, ICompletionWidget completionWidget, ICodeCompletionContext completionContext, CompletionDelegate closedDelegate)
		{
			try {
				if (!wnd.ShowListWindow (firstChar, provider,  completionWidget, completionContext, closedDelegate)) {
					provider.Dispose ();
					return;
				}
				
				// makes control-space in midle of words to work
				string text = wnd.completionWidget.GetCompletionText (completionContext);
				if (text.Length == 0) {
					text = provider.DefaultCompletionString;
					if (text != null && text.Length > 0)
						wnd.SelectEntry (text);
					return;
				}
				
				wnd.PartialWord = text; 
				//if there is only one matching result we take it by default
				if (wnd.IsUniqueMatch && !wnd.IsChanging)
				{	
					wnd.UpdateWord ();
					wnd.Hide ();
				}
				
			} catch (Exception ex) {
				Console.WriteLine (ex);
			}
		}
		public static void PostProcessKeyEvent (ICompletionWidget widget, Gdk.Key key, Gdk.ModifierType modifier)
		{
			// Called after the key has been processed by the editor
		
			if (methods.Count == 0)
				return;
				
			for (int n=0; n<methods.Count; n++) {
				// If the cursor is outside of any of the methods parameter list, discard the
				// information window for that method.
				
				MethodData md = methods [n];
				int pos = md.MethodProvider.GetCurrentParameterIndex (widget, md.CompletionContext);
				if (pos == -1) {
					methods.RemoveAt (n);
					n--;
				}
			}
			// If the user enters more parameters than the current overload has,
			// look for another overload with more parameters.
			UpdateOverload (widget);
			
			// Refresh.
			UpdateWindow (widget);
		}
예제 #11
0
        public static bool ShowWindow(char firstChar, ICompletionDataList list, ICompletionWidget completionWidget, CodeCompletionContext completionContext, System.Action closedDelegate)
        {
            try {
                if (wnd == null)
                {
                    wnd = new CompletionListWindow();
                    wnd.WordCompleted += HandleWndWordCompleted;
                }
                try {
                    if (!wnd.ShowListWindow(firstChar, list, completionWidget, completionContext, closedDelegate))
                    {
                        if (list is IDisposable)
                        {
                            ((IDisposable)list).Dispose();
                        }
                        DestroyWindow();
                        return(false);
                    }

                    if (ForceSuggestionMode)
                    {
                        wnd.AutoSelect = false;
                    }

                    OnWindowShown(EventArgs.Empty);
                    return(true);
                } catch (Exception ex) {
                    LoggingService.LogError(ex.ToString());
                    return(false);
                }
            } finally {
                ParameterInformationWindowManager.UpdateWindow(completionWidget);
            }
        }
		// Called when a key is pressed in the editor.
		// Returns false if the key press has to continue normal processing.
		public static bool ProcessKeyEvent (ICompletionWidget widget, Gdk.Key key, Gdk.ModifierType modifier)
		{
			if (methods.Count == 0)
				return false;

			MethodData cmd = methods [methods.Count - 1];
			
			if (key == Gdk.Key.Down) {
				if (cmd.MethodProvider.OverloadCount <= 1)
					return false;
				if (cmd.CurrentOverload < cmd.MethodProvider.OverloadCount - 1)
					cmd.CurrentOverload ++;
				else
					cmd.CurrentOverload = 0;
				UpdateWindow (widget);
				return true;
			}
			else if (key == Gdk.Key.Up) {
				if (cmd.MethodProvider.OverloadCount <= 1)
					return false;
				if (cmd.CurrentOverload > 0)
					cmd.CurrentOverload --;
				else
					cmd.CurrentOverload = cmd.MethodProvider.OverloadCount - 1;
				UpdateWindow (widget);
				return true;
			}
			else if (key == Gdk.Key.Escape) {
				HideWindow (widget);
				return true;
			}
			return false;
		}
예제 #13
0
		// Returns the index of the parameter where the cursor is currently positioned.
		// -1 means the cursor is outside the method parameter list
		// 0 means no parameter entered
		// > 0 is the index of the parameter (1-based)
		public int GetCurrentParameterIndex (ICompletionWidget widget, CodeCompletionContext ctx)
		{
			int cursor = widget.CurrentCodeCompletionContext.TriggerOffset;
			int i = ctx.TriggerOffset;
			if (i < 0 || i >= editor.Length || editor.GetCharAt (i) == ')')
				return -1;
			
			if (i > cursor)
				return -1;
			else if (i == cursor)
				return 0;
			
			int parameterIndex = 1;
			
			while (i++ < cursor) {
				if (i >= widget.TextLength)
					break;
				char ch = widget.GetChar (i);
				if (ch == ',')
					parameterIndex++;
				else if (ch == ')')
					return -1;
			}
			
			return parameterIndex;
		}
        public void InsertCompletionText(ICompletionWidget widget, CodeCompletionContext context)
        {
            // insert add/remove event handler code after +=/-=
            editor.Replace (initialOffset, editor.Caret.Offset - initialOffset, this.DisplayText + ";");

            // Search opening bracket of member
            int pos = editor.Document.LocationToOffset (callingMember.BodyRegion.Start.Line - 1, callingMember.BodyRegion.Start.Column - 1);
            while (pos < editor.Document.Length && editor.Document.GetCharAt (pos) != '{') {
                pos++;
            }

            // Search closing bracket of member
            pos = editor.Document.GetMatchingBracketOffset (pos) + 1;

            pos = Math.Max (0, Math.Min (pos, editor.Document.Length - 1));

            // Insert new event handler after closing bracket
            string indent = editor.Document.GetLine (callingMember.Location.Line).GetIndentation (editor.Document);

            StringBuilder sb = new StringBuilder ();
            sb.AppendLine ();
            sb.AppendLine ();
            sb.Append (indent);
            if (callingMember.IsStatic)
                sb.Append ("static ");
            sb.Append ("void ");sb.Append (this.DisplayText);sb.Append (' ');sb.Append (this.parameterList);sb.AppendLine ();
            sb.Append (indent);sb.Append ("{");sb.AppendLine ();
            sb.Append (indent);sb.Append (TextEditorProperties.IndentString);
            int cursorPos = pos + sb.Length;
            sb.AppendLine ();
            sb.Append (indent);sb.Append ("}");
            editor.Insert (pos, sb.ToString ());
            editor.Caret.Offset = cursorPos;
        }
예제 #15
0
        internal void InitializeListWindow(ICompletionWidget completionWidget, CodeCompletionContext completionContext)
        {
            if (completionWidget == null)
            {
                throw new ArgumentNullException("completionWidget");
            }
            if (completionContext == null)
            {
                throw new ArgumentNullException("completionContext");
            }
            if (mutableList != null)
            {
                mutableList.Changing -= OnCompletionDataChanging;
                mutableList.Changed  -= OnCompletionDataChanged;
                HideFooter();
            }
            ResetState();
            CompletionWidget      = completionWidget;
            CodeCompletionContext = completionContext;

            string text = CompletionWidget.GetCompletionText(CodeCompletionContext);

            initialWordLength = CompletionWidget.SelectedLength > 0 ? 0 : text.Length;
            StartOffset       = CompletionWidget.CaretOffset - initialWordLength;
        }
        public int GetCurrentParameterIndex(ICompletionWidget widget, CodeCompletionContext ctx)
        {
            if (showCompletion)
            {
                return 0;
            }

            return -1;
        }
 internal static void HideWindow(CompletionTextEditorExtension ext, ICompletionWidget widget)
 {
     currentMethodGroup = null;
     if (window != null)
     {
         window.ChangeOverload();
     }
     UpdateWindow(ext, widget);
 }
 protected override void Initialize()
 {
     base.Initialize();
     defaultCompletionWidget       = CompletionWidget;
     defaultDocumentContext        = DocumentContext;
     defaultEditor                 = Editor;
     defaultDocumentContext.Saved += AsyncUpdateDesignerFile;
     OnParsedDocumentUpdated();
 }
예제 #19
0
//		AspProjectDomWrapper domWrapper;
        public override void Initialize()
        {
            base.Initialize();
            defaultCompletionWidget = CompletionWidget;
            defaultDocument         = document;
            defaultDocument.Editor.Caret.PositionChanged += delegate {
                OnCompletionContextChanged(CompletionWidget, EventArgs.Empty);
            };
        }
 public static void HideWindow(CompletionTextEditorExtension ext, ICompletionWidget widget)
 {
     methods.Clear();
     if (window != null)
     {
         window.ChangeOverload();
     }
     UpdateWindow(ext, widget);
 }
        public override void Initialize()
        {
            base.Initialize();

            CompletionWidget = Document.GetContent <ICompletionWidget> ();
            if (CompletionWidget != null)
            {
                CompletionWidget.CompletionContextChanged += OnCompletionContextChanged;
            }
        }
 public override void Initialize()
 {
     base.Initialize();
     defaultCompletionWidget = CompletionWidget;
     defaultDocument         = document;
     defaultDocument.Editor.Caret.PositionChanged += delegate {
         OnCompletionContextChanged(CompletionWidget, EventArgs.Empty);
     };
     defaultDocument.Saved += AsyncUpdateDesignerFile;
     OnParsedDocumentUpdated();
 }
예제 #23
0
        protected override void Run(RefactoringOptions options)
        {
            Gtk.Menu menu = new Gtk.Menu();

            bool          resolveDirect;
            List <string> namespaces = GetResolveableNamespaces(options, out resolveDirect);

            foreach (string ns in namespaces)
            {
                // remove used namespaces for conflict resolving.
                if (options.Document.CompilationUnit.IsNamespaceUsedAt(ns, options.ResolveResult.ResolvedExpression.Region.Start))
                {
                    continue;
                }
                Gtk.MenuItem menuItem = new Gtk.MenuItem(string.Format(GettextCatalog.GetString("Add using '{0}'"), ns));
                CurrentRefactoryOperationsHandler.ResolveNameOperation resolveNameOperation = new CurrentRefactoryOperationsHandler.ResolveNameOperation(options.Dom, options.Document, options.ResolveResult, ns);
                menuItem.Activated += delegate
                {
                    resolveNameOperation.AddImport();
                };
                menu.Add(menuItem);
            }
            if (resolveDirect)
            {
                foreach (string ns in namespaces)
                {
                    Gtk.MenuItem menuItem = new Gtk.MenuItem(string.Format(GettextCatalog.GetString("Add '{0}'"), ns));
                    CurrentRefactoryOperationsHandler.ResolveNameOperation resolveNameOperation = new CurrentRefactoryOperationsHandler.ResolveNameOperation(options.Dom, options.Document, options.ResolveResult, ns);
                    menuItem.Activated += delegate
                    {
                        resolveNameOperation.ResolveName();
                    };
                    menu.Add(menuItem);
                }
            }

            if (menu.Children != null && menu.Children.Length > 0)
            {
                menu.ShowAll();

                ICompletionWidget     widget = options.Document.GetContent <ICompletionWidget> ();
                CodeCompletionContext codeCompletionContext = widget.CreateCodeCompletionContext(options.GetTextEditorData().Caret.Offset);

                menu.Popup(null, null, delegate(Gtk.Menu menu2, out int x, out int y, out bool pushIn)
                {
                    x      = codeCompletionContext.TriggerXCoord;
                    y      = codeCompletionContext.TriggerYCoord;
                    pushIn = false;
                }, 0, Gtk.Global.CurrentEventTime);
                menu.SelectFirst(true);
            }
        }
예제 #24
0
        // Called when a key is pressed in the editor.
        // Returns false if the key press has to continue normal processing.
        public static bool ProcessKeyEvent(CompletionTextEditorExtension ext, ICompletionWidget widget, Gdk.Key key, Gdk.ModifierType modifier)
        {
            if (methods.Count == 0)
            {
                return(false);
            }

            MethodData cmd = methods [methods.Count - 1];

            if (key == Gdk.Key.Down)
            {
                if (cmd.MethodProvider.Count <= 1)
                {
                    return(false);
                }
                if (cmd.CurrentOverload < cmd.MethodProvider.Count - 1)
                {
                    cmd.CurrentOverload++;
                }
                else
                {
                    cmd.CurrentOverload = 0;
                }
                window.ChangeOverload();
                UpdateWindow(ext, widget);
                return(true);
            }
            else if (key == Gdk.Key.Up)
            {
                if (cmd.MethodProvider.Count <= 1)
                {
                    return(false);
                }
                if (cmd.CurrentOverload > 0)
                {
                    cmd.CurrentOverload--;
                }
                else
                {
                    cmd.CurrentOverload = cmd.MethodProvider.Count - 1;
                }
                window.ChangeOverload();
                UpdateWindow(ext, widget);
                return(true);
            }
            else if (key == Gdk.Key.Escape)
            {
                HideWindow(ext, widget);
                return(true);
            }
            return(false);
        }
        // Called when a key is pressed in the editor.
        // Returns false if the key press has to continue normal processing.
        internal static bool ProcessKeyEvent(CompletionTextEditorExtension ext, ICompletionWidget widget, KeyDescriptor descriptor)
        {
            if (methods.Count == 0)
            {
                return(false);
            }

            MethodData cmd = methods [methods.Count - 1];

            if (descriptor.SpecialKey == SpecialKey.Down)
            {
                if (cmd.MethodProvider.Count <= 1)
                {
                    return(false);
                }
                if (cmd.CurrentOverload < cmd.MethodProvider.Count - 1)
                {
                    cmd.CurrentOverload++;
                }
                else
                {
                    cmd.CurrentOverload = 0;
                }
                window.ChangeOverload();
                UpdateWindow(ext, widget);
                return(true);
            }
            else if (descriptor.SpecialKey == SpecialKey.Up)
            {
                if (cmd.MethodProvider.Count <= 1)
                {
                    return(false);
                }
                if (cmd.CurrentOverload > 0)
                {
                    cmd.CurrentOverload--;
                }
                else
                {
                    cmd.CurrentOverload = cmd.MethodProvider.Count - 1;
                }
                window.ChangeOverload();
                UpdateWindow(ext, widget);
                return(true);
            }
            else if (descriptor.SpecialKey == SpecialKey.Escape)
            {
                HideWindow(ext, widget);
                return(true);
            }
            return(false);
        }
        public ICompletionData[] GenerateCompletionData(ICompletionWidget widget, 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));
        }
예제 #27
0
 public ProjectedCompletionWidget(ICompletionWidget completionWidget, Projection projection)
 {
     if (completionWidget == null)
     {
         throw new ArgumentNullException("completionWidget");
     }
     if (projection == null)
     {
         throw new ArgumentNullException("projection");
     }
     this.projection       = projection;
     this.completionWidget = completionWidget;
 }
        public override void Initialize()
        {
            base.Initialize();

            enableCodeCompletion   = (bool)PropertyService.Get("EnableCodeCompletion", true);
            enableParameterInsight = (bool)PropertyService.Get("EnableParameterInsight", true);

            PropertyService.PropertyChanged += OnPropertyUpdated;
            CompletionWidget = Document.GetContent <ICompletionWidget> ();
            if (CompletionWidget != null)
            {
                CompletionWidget.CompletionContextChanged += OnCompletionContextChanged;
            }
        }
		internal static bool OverloadDown (CompletionTextEditorExtension ext, ICompletionWidget widget)
		{
			if (currentMethodGroup == null)
				return false;
			if (currentMethodGroup.MethodProvider.Count <= 1)
				return false;
			if (currentMethodGroup.CurrentOverload < currentMethodGroup.MethodProvider.Count - 1)
				currentMethodGroup.CurrentOverload ++;
			else
				currentMethodGroup.CurrentOverload = 0;
			window.ChangeOverload ();
			UpdateWindow (ext, widget);
			return true;
		}
		public override void Initialize ()
		{
			base.Initialize ();

			defaultCompletionWidget = CompletionWidget;
			defaultDocument = Document;
			completionBuilder = RazorCompletionBuilderService.GetBuilder ("C#");

			defaultDocument.Editor.Document.TextReplacing += UnderlyingDocument_TextReplacing;
			defaultDocument.Editor.Caret.PositionChanged += delegate
			{
				OnCompletionContextChanged (CompletionWidget, EventArgs.Empty);
			};
		}
        public override void Initialize()
        {
            base.Initialize();

            defaultCompletionWidget = CompletionWidget;
            defaultDocument         = Document;
            completionBuilder       = RazorCompletionBuilderService.GetBuilder("C#");

            defaultDocument.Editor.Document.TextReplacing += UnderlyingDocument_TextReplacing;
            defaultDocument.Editor.Caret.PositionChanged  += delegate
            {
                OnCompletionContextChanged(CompletionWidget, EventArgs.Empty);
            };
        }
		public void ShowCompletion (ICompletionDataList completionList)
		{
			completionWidget = Document.GetContent <ICompletionWidget> ();
			currentCompletionContext = completionWidget.CreateCodeCompletionContext (Document.TextEditorData.Caret.Offset);
			int cpos, wlen;
			if (!GetCompletionCommandOffset (out cpos, out wlen)) {
				cpos = Document.TextEditorData.Caret.Offset;
				wlen = 0;
			}
			currentCompletionContext.TriggerOffset = cpos;
			currentCompletionContext.TriggerWordLength = wlen;
			
			CompletionWindowManager.ShowWindow ('\0', completionList, completionWidget, currentCompletionContext, OnCompletionWindowClosed);
		}
        protected override void Initialize()
        {
            base.Initialize();

            defaultCompletionWidget = CompletionWidget;
            defaultDocumentContext  = DocumentContext;
            defaultEditor           = Editor;
            completionBuilder       = RazorCompletionBuilderService.GetBuilder("C#");

            // defaultEditor.TextChanging += UnderlyingDocument_TextReplacing;
            //syntaxMode = new RazorSyntaxMode (Editor, DocumentContext);
            //var textEditorData = DocumentContext.GetContent<TextEditorData> ();
            //if (textEditorData != null)
            //	textEditorData.Document.SyntaxMode = syntaxMode;
        }
		internal static bool OverloadDown (CompletionTextEditorExtension ext, ICompletionWidget widget)
		{
			if (methods.Count == 0)
				return false;
			MethodData cmd = methods [methods.Count - 1];
			if (cmd.MethodProvider.Count <= 1)
				return false;
			if (cmd.CurrentOverload < cmd.MethodProvider.Count - 1)
				cmd.CurrentOverload ++;
			else
				cmd.CurrentOverload = 0;
			window.ChangeOverload ();
			UpdateWindow (ext, widget);
			return true;
		}
        public void ShowCompletion(ICompletionDataList completionList)
        {
            completionWidget         = Document.GetContent <ICompletionWidget> ();
            currentCompletionContext = completionWidget.CreateCodeCompletionContext(Document.TextEditorData.Caret.Offset);
            int cpos, wlen;

            if (!GetCompletionCommandOffset(out cpos, out wlen))
            {
                cpos = Document.TextEditorData.Caret.Offset;
                wlen = 0;
            }
            currentCompletionContext.TriggerOffset     = cpos;
            currentCompletionContext.TriggerWordLength = wlen;

            CompletionWindowManager.ShowWindow('\0', completionList, completionWidget, currentCompletionContext, OnCompletionWindowClosed);
        }
		// Called when a key is pressed in the editor.
		// Returns false if the key press has to continue normal processing.
		internal static bool ProcessKeyEvent (CompletionTextEditorExtension ext, ICompletionWidget widget, KeyDescriptor descriptor)
		{
			if (currentMethodGroup == null)
				return false;

			if (descriptor.SpecialKey == SpecialKey.Down) {
				return OverloadDown (ext, widget);
			} else if (descriptor.SpecialKey == SpecialKey.Up) {
				return OverloadUp (ext, widget);
			}
			else if (descriptor.SpecialKey == SpecialKey.Escape) {
				HideWindow (ext, widget);
				return true;
			}
			return false;
		}
 public override void Initialize()
 {
     base.Initialize();
     CompletionWindowManager.WindowClosed += HandleWindowClosed;
     CompletionWidget = Document.GetContent <ICompletionWidget> ();
     if (CompletionWidget != null)
     {
         CompletionWidget.CompletionContextChanged += OnCompletionContextChanged;
     }
     document.Editor.Caret.PositionChanged += HandlePositionChanged;
     document.Editor.Paste += HandlePaste;
     if (document.Editor.Parent != null)
     {
         document.Editor.Parent.TextArea.FocusOutEvent += HandleFocusOutEvent;
     }
 }
        /*		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 ICompletionData[] GenerateCompletionData(ICompletionWidget widget, 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));
        }
예제 #39
0
 public int GetCurrentParameterIndex(ICompletionWidget widget, CodeCompletionContext ctx)
 {
     /*
      * int cursor = widget.CurrentCodeCompletionContext.TriggerOffset;
      * var loc=new CodeLocation(ctx.TriggerLineOffset,ctx.TriggerLine);
      *
      * if (args.IsTemplateInstanceArguments)
      * {
      *
      * }
      * else
      * {
      *      var firstArgLocation = CodeLocation.Empty;
      *
      *      if (args.ParsedExpression is PostfixExpression_MethodCall)
      *              firstArgLocation = (args.ParsedExpression as PostfixExpression_MethodCall).Arguments[0].Location;
      *      else if (args.ParsedExpression is NewExpression)
      *              firstArgLocation = (args.ParsedExpression as NewExpression).Arguments[0].Location;
      *      else
      *              return -1;
      *
      *      if (loc < firstArgLocation)
      *              loc = firstArgLocation;
      *
      *      var code = doc.Editor.Document.GetTextBetween(firstArgLocation.Line,firstArgLocation.Column, scopeMethod.EndLocation.Line, scopeMethod.EndLocation.Column);
      *
      *      var tr = new StringReader(code);
      *      var parser = new DParser(new Lexer(tr));
      *      parser.Lexer.SetInitialLocation(firstArgLocation);
      *      parser.Step();
      *
      *      var updatedArguments = parser.ArgumentList();
      *      tr.Close();
      *
      *      var lastArg = updatedArguments[updatedArguments.Count - 1];
      *
      *      for (int i = 0; i < updatedArguments.Count; i++)
      *              if ((loc >= updatedArguments[i].Location && loc <= updatedArguments[i].EndLocation) ||
      *                      (i==updatedArguments.Count-1 && loc <= updatedArguments[i].EndLocation))
      *                      return i + 1;
      * }
      */
     return(1);
 }
예제 #40
0
        static void UpdateOverload(CompletionTextEditorExtension ext, ICompletionWidget widget)
        {
            if (methods.Count == 0)
            {
                return;
            }

            // If the user enters more parameters than the current overload has,
            // look for another overload with more parameters.

            MethodData md     = methods [methods.Count - 1];
            int        cparam = ext.GetCurrentParameterIndex(md.MethodProvider.StartOffset);

            if (cparam > md.MethodProvider.GetParameterCount(md.CurrentOverload) && !md.MethodProvider.AllowParameterList(md.CurrentOverload))
            {
                // Look for an overload which has more parameters
                int bestOverload   = -1;
                int bestParamCount = int.MaxValue;
                for (int n = 0; n < md.MethodProvider.Count; n++)
                {
                    int pc = md.MethodProvider.GetParameterCount(n);
                    if (pc < bestParamCount && pc >= cparam)
                    {
                        bestOverload   = n;
                        bestParamCount = pc;
                    }
                }
                if (bestOverload == -1)
                {
                    for (int n = 0; n < md.MethodProvider.Count; n++)
                    {
                        if (md.MethodProvider.AllowParameterList(n))
                        {
                            bestOverload = n;
                            break;
                        }
                    }
                }
                if (bestOverload != -1)
                {
                    md.CurrentOverload = bestOverload;
                }
            }
        }
        static async void UpdateOverload(CompletionTextEditorExtension ext, ICompletionWidget widget, CancellationToken token)
        {
            if (currentMethodGroup == null || window == null)
            {
                return;
            }

            // If the user enters more parameters than the current overload has,
            // look for another overload with more parameters.

            int bestOverload = await ext.GuessBestMethodOverload(currentMethodGroup.MethodProvider, currentMethodGroup.CurrentOverload, token);

            if (bestOverload != -1)
            {
                currentMethodGroup.CurrentOverload = bestOverload;
                window.ChangeOverload();
                UpdateWindow(ext, widget);
            }
        }
예제 #42
0
        public static void ShowWindow(ICompletionWidget widget, CodeCompletionContext ctx, IParameterDataProvider provider)
        {
            if (provider.OverloadCount == 0)
            {
                return;
            }

            // There can be several method parameter lists open at the same time, so
            // they have to be queued. The last one of queue is the one being shown
            // in the information window.

            MethodData md = new MethodData();

            md.MethodProvider    = provider;
            md.CurrentOverload   = 0;
            md.CompletionContext = ctx;
            methods.Add(md);
            UpdateWindow(widget);
        }
        static void UpdateOverload(CompletionTextEditorExtension ext, ICompletionWidget widget)
        {
            if (methods.Count == 0 || window == null)
            {
                return;
            }

            // If the user enters more parameters than the current overload has,
            // look for another overload with more parameters.
            MethodData md = methods [methods.Count - 1];

            int bestOverload = ext.GuessBestMethodOverload(md.MethodProvider, md.CurrentOverload);

            if (bestOverload != -1)
            {
                md.CurrentOverload = bestOverload;
                window.ChangeOverload();
                UpdateWindow(ext, widget);
            }
        }
        internal static void ShowWindow(CompletionTextEditorExtension ext, ICompletionWidget widget, CodeCompletionContext ctx, ParameterHintingResult provider)
        {
            if (provider.Count == 0)
            {
                return;
            }

            // There can be several method parameter lists open at the same time, so
            // they have to be queued. The last one of queue is the one being shown
            // in the information window.

            MethodData md = new MethodData();

            md.MethodProvider    = provider;
            md.CurrentOverload   = 0;
            md.CompletionContext = ctx;
            currentMethodGroup   = md;
            UpdateOverload(ext, widget, default(CancellationToken));
            UpdateWindow(ext, widget);
        }
 /// <summary>
 /// Shows the completion window. The ShowListWindow method is internal
 /// so use reflection to call it. There are no public methods that can
 /// be used.
 /// </summary>
 public static bool ShowListWindow(
     this CompletionListWindow window,
     char firstChar,
     ICompletionDataList list,
     ICompletionWidget completionWidget,
     CodeCompletionContext completionContext)
 {
     MethodInfo[] methods = window.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
     foreach (MethodInfo method in methods)
     {
         if (method.Name == "ShowListWindow")
         {
             if (method.GetParameters().Length == 4)
             {
                 return((bool)method.Invoke(window, new object[] { firstChar, list, completionWidget, completionContext }));
             }
         }
     }
     throw new NotImplementedException("CompletListWindow.ShowListWindow not found");
 }
        // Returns the index of the parameter where the cursor is currently positioned.
        // -1 means the cursor is outside the method parameter list
        // 0 means no parameter entered
        // > 0 is the index of the parameter (1-based)
        internal int GetCurrentParameterIndex(ICompletionWidget widget, CodeCompletionContext ctx)
        {
            int cursor = widget.CurrentCodeCompletionContext.TriggerOffset;
            int i      = ctx.TriggerOffset;

            if (i < 0 || i >= editor.Length || editor.GetCharAt(i) == ')')
            {
                return(-1);
            }

            if (i > cursor)
            {
                return(-1);
            }
            else if (i == cursor)
            {
                return(0);
            }

            int parameterIndex = 1;

            while (i++ < cursor)
            {
                if (i >= widget.TextLength)
                {
                    break;
                }
                char ch = widget.GetChar(i);
                if (ch == ',')
                {
                    parameterIndex++;
                }
                else if (ch == ')')
                {
                    return(-1);
                }
            }

            return(parameterIndex);
        }
        public ICompletionData[] GenerateCompletionData(ICompletionWidget widget, char charTyped)
        {
            completionData = new ArrayList();

            // the parser works with 1 based coordinates
            caretLineNumber      = widget.TriggerLine + 1;
            caretColumn          = widget.TriggerLineOffset + 1;
            //string expression    = TextUtilities.GetExpressionBeforeOffset (textArea, insertIter.Offset);
            ResolveResult results;

            IExpressionFinder expressionFinder = parserContext.GetExpressionFinder(fileName);
            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 f*****g *HACK*
            if (expression == "is" || expression == "as") {
                string expr = expressionFinder == null ? TextUtilities.GetExpressionBeforeOffset (widget, widget.TriggerOffset - 3) : expressionFinder.FindExpression (widget.GetText (0, widget.TriggerOffset), widget.TriggerOffset - 5);
                AddResolveResults (parserContext.IsAsResolve (expr, caretLineNumber, caretColumn, fileName, widget.GetText (0, widget.TextLength)));
                return (ICompletionData[])completionData.ToArray (typeof (ICompletionData));
            }
            if (ctrlspace && charTyped != '.') {
                AddResolveResults (parserContext.CtrlSpace (caretLineNumber, caretColumn, fileName));
                return (ICompletionData[])completionData.ToArray (typeof (ICompletionData));
            }
            if (charTyped == ' ') {
                if (expression == "using" || expression.EndsWith(" using") || expression.EndsWith("\tusing")|| expression.EndsWith("\nusing")|| expression.EndsWith("\rusing")) {
                    string[] namespaces = parserContext.GetNamespaceList ("", true, true);
                    AddResolveResults(new ResolveResult(namespaces));
                }
            } else {
                //FIXME: I added the null check, #D doesnt need it, why do we?
                if (fileName != null) {
                    results = parserContext.Resolve (expression, caretLineNumber, caretColumn, fileName, widget.GetText (0, widget.TextLength));
                    AddResolveResults(results);
                }
            }
            return (ICompletionData[]) completionData.ToArray (typeof (ICompletionData));
        }
		// ext may be null, but then parameter completion don't work
		internal static void PrepareShowWindow (CompletionTextEditorExtension ext, char firstChar, ICompletionWidget completionWidget, CodeCompletionContext completionContext)
		{
			isShowing = true;

			if (wnd == null) {
				wnd = new CompletionListWindow ();
				wnd.WordCompleted += HandleWndWordCompleted;
			}
			if (ext != null) {
				var widget = ext.Editor.GetNativeWidget<Gtk.Widget> ();
				wnd.TransientFor = widget?.Parent?.Toplevel as Gtk.Window;
			} else {
				var widget = completionWidget as Gtk.Widget;
				if (widget != null) {
					var window = widget.Toplevel as Gtk.Window;
					if (window != null)
						wnd.TransientFor = window;
				}
			}
			wnd.Extension = ext;

			wnd.InitializeListWindow (completionWidget, completionContext);
		}
		internal static int GetCurrentParameterIndex (ICompletionWidget widget, int offset, int memberStart)
		{
			int cursor = widget.CurrentCodeCompletionContext.TriggerOffset;
			int i = offset;
			
			if (i > cursor)
				return -1;
			if (i == cursor)
				return 1;
			
			int index = memberStart + 1;
			int depth = 0;
			do {
				char c = widget.GetChar (i - 1);
				
				if (c == ',' && depth == 1)
					index++;
				if (c == '<')
					depth++;
				if (c == '>')
					depth--;
				i++;
			} while (i <= cursor && depth > 0);
			
			return depth == 0 ? -1 : index;
		}
		public int GetCurrentParameterIndex (ICompletionWidget widget, CodeCompletionContext ctx)
		{
			return GetCurrentParameterIndex (widget, ctx.TriggerOffset, 0);
		}
 public override void Initialize()
 {
     base.Initialize ();
     CompletionWindowManager.WindowClosed += HandleWindowClosed;
     CompletionWidget = Document.GetContent <ICompletionWidget> ();
     if (CompletionWidget != null)
         CompletionWidget.CompletionContextChanged += OnCompletionContextChanged;
     document.Editor.Caret.PositionChanged += HandlePositionChanged;
     document.Editor.Paste += HandlePaste;
     if (document.Editor.Parent != null)
         document.Editor.Parent.TextArea.FocusOutEvent += HandleFocusOutEvent;
 }
		public static void ShowWindow (ICompletionWidget widget, CodeCompletionContext ctx, IParameterDataProvider provider)
		{
			if (provider.OverloadCount == 0)
				return;
			
			// There can be several method parameter lists open at the same time, so
			// they have to be queued. The last one of queue is the one being shown
			// in the information window.
			
			MethodData md = new MethodData ();
			md.MethodProvider = provider;
			md.CurrentOverload = 0;
			md.CompletionContext = ctx;
			methods.Add (md);
			UpdateWindow (widget);
		}
예제 #53
0
		// ext may be null, but then parameter completion don't work
		internal static bool ShowWindow (CompletionTextEditorExtension ext, char firstChar, ICompletionDataList list, ICompletionWidget completionWidget, CodeCompletionContext completionContext)
		{
			PrepareShowWindow (ext, firstChar, completionWidget, completionContext);
			return ShowWindow (list, completionContext);
		}
		internal static void UpdateWindow (ICompletionWidget widget)
		{
			// Updates the parameter information window from the information
			// of the current method overload
			if (window == null && methods.Count > 0) {
				window = new ParameterInformationWindow ();
				wasAbove = false;
			}
			
			if (methods.Count == 0) {
				if (window != null) {
					window.Hide ();
					wasAbove = false;
				}
				return;
			}
			var ctx = widget.CurrentCodeCompletionContext;
			MethodData md = methods[methods.Count - 1];
			int cparam = md.MethodProvider.GetCurrentParameterIndex (widget, md.CompletionContext);
			Gtk.Requisition reqSize = window.ShowParameterInfo (md.MethodProvider, md.CurrentOverload, cparam - 1);
			X = md.CompletionContext.TriggerXCoord;
			if (CompletionWindowManager.IsVisible) {
				// place above
				Y = ctx.TriggerYCoord - ctx.TriggerTextHeight - reqSize.Height - 10;
			} else {
				// place below
				Y = ctx.TriggerYCoord;
			}
			
			Gdk.Rectangle geometry = DesktopService.GetUsableMonitorGeometry (window.Screen, window.Screen.GetMonitorAtPoint (X + reqSize.Width, Y));
		
			if (X + reqSize.Width > geometry.Right)
				X = geometry.Right - reqSize.Width;
			
			if (Y < geometry.Top)
				Y = ctx.TriggerYCoord;
			
			if (wasAbove || Y + reqSize.Height > geometry.Bottom) {
				Y = Y - ctx.TriggerTextHeight - reqSize.Height - 4;
				wasAbove = true;
			}
			
			if (CompletionWindowManager.IsVisible) {
				Rectangle completionWindow = new Rectangle (CompletionWindowManager.X, CompletionWindowManager.Y,
				                                            CompletionWindowManager.Wnd.Allocation.Width, CompletionWindowManager.Wnd.Allocation.Height);
				if (completionWindow.IntersectsWith (new Rectangle (X, Y, reqSize.Width, reqSize.Height))) {
					X = completionWindow.X;
					Y = completionWindow.Y - reqSize.Height - 6;
					if (Y < 0)
						Y = completionWindow.Bottom + 6;
				}
			}
			
			window.Move (X, Y);
			window.Show ();
			
		}
		static void UpdateOverload (ICompletionWidget widget)
		{
			if (methods.Count == 0)
				return;
			
			// If the user enters more parameters than the current overload has,
			// look for another overload with more parameters.
			
			MethodData md = methods [methods.Count - 1];
			int cparam = md.MethodProvider.GetCurrentParameterIndex (widget, md.CompletionContext);
			
			if (cparam > md.MethodProvider.GetParameterCount (md.CurrentOverload)) {
				// Look for an overload which has more parameters
				int bestOverload = -1;
				int bestParamCount = int.MaxValue;
				for (int n=0; n<md.MethodProvider.OverloadCount; n++) {
					int pc = md.MethodProvider.GetParameterCount (n);
					if (pc < bestParamCount && pc >= cparam) {
						bestOverload = n;
						bestParamCount = pc;
					}
				}
				if (bestOverload != -1)
					md.CurrentOverload = bestOverload;
			}
		}
		public static void HideWindow (ICompletionWidget widget)
		{
			methods.Clear ();
			UpdateWindow (widget);
		}
		public CodeCompletionContextEventArgs (ICompletionWidget widget, CodeCompletionContext codeCompletionContext, string completedWord)
		{
			this.Widget = widget;
			this.CodeCompletionContext = codeCompletionContext;
			this.CompletedWord = completedWord;
		}
		public override void Initialize ()
		{
			base.Initialize ();

			enableCodeCompletion = (bool)PropertyService.Get ("EnableCodeCompletion", true);
			enableParameterInsight = (bool)PropertyService.Get ("EnableParameterInsight", true);
			
			PropertyService.PropertyChanged += OnPropertyUpdated;
			CompletionWidget = Document.GetContent <ICompletionWidget> ();
			if (CompletionWidget != null)
				CompletionWidget.CompletionContextChanged += OnCompletionContextChanged;
		}
예제 #59
0
        public int GetCurrentParameterIndex(ICompletionWidget widget, CodeCompletionContext ctx)
        {
            /*
            int cursor = widget.CurrentCodeCompletionContext.TriggerOffset;
            var loc=new CodeLocation(ctx.TriggerLineOffset,ctx.TriggerLine);

            if (args.IsTemplateInstanceArguments)
            {

            }
            else
            {
                var firstArgLocation = CodeLocation.Empty;

                if (args.ParsedExpression is PostfixExpression_MethodCall)
                    firstArgLocation = (args.ParsedExpression as PostfixExpression_MethodCall).Arguments[0].Location;
                else if (args.ParsedExpression is NewExpression)
                    firstArgLocation = (args.ParsedExpression as NewExpression).Arguments[0].Location;
                else
                    return -1;

                if (loc < firstArgLocation)
                    loc = firstArgLocation;

                var code = doc.Editor.Document.GetTextBetween(firstArgLocation.Line,firstArgLocation.Column, scopeMethod.EndLocation.Line, scopeMethod.EndLocation.Column);

                var tr = new StringReader(code);
                var parser = new DParser(new Lexer(tr));
                parser.Lexer.SetInitialLocation(firstArgLocation);
                parser.Step();

                var updatedArguments = parser.ArgumentList();
                tr.Close();

                var lastArg = updatedArguments[updatedArguments.Count - 1];

                for (int i = 0; i < updatedArguments.Count; i++)
                    if ((loc >= updatedArguments[i].Location && loc <= updatedArguments[i].EndLocation) ||
                        (i==updatedArguments.Count-1 && loc <= updatedArguments[i].EndLocation))
                        return i + 1;
            }
            */
            return args.CurrentlyTypedArgumentIndex;
        }
		internal static int GetCurrentParameterIndex (ICompletionWidget widget, int offset, int memberStart)
		{
			int cursor = widget.CurrentCodeCompletionContext.TriggerOffset;
			int i = offset;
			
			if (i > cursor)
				return -1;
			if (i == cursor) 
				return 1; // parameters are 1 based
			IEnumerable<string> types = MonoDevelop.Ide.DesktopService.GetMimeTypeInheritanceChain (CSharpFormatter.MimeType);
			CSharpIndentEngine engine = new CSharpIndentEngine (MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<CSharpFormattingPolicy> (types));
			int index = memberStart + 1;
			int parentheses = 0;
			int bracket = 0;
			do {
				char c = widget.GetChar (i - 1);
				engine.Push (c);
				switch (c) {
				case '{':
					if (!engine.IsInsideOrdinaryCommentOrString)
						bracket++;
					break;
				case '}':
					if (!engine.IsInsideOrdinaryCommentOrString)
						bracket--;
					break;
				case '(':
					if (!engine.IsInsideOrdinaryCommentOrString)
						parentheses++;
					break;
				case ')':
					if (!engine.IsInsideOrdinaryCommentOrString)
						parentheses--;
					break;
				case ',':
					if (!engine.IsInsideOrdinaryCommentOrString && parentheses == 1 && bracket == 0)
						index++;
					break;
				}
				i++;
			} while (i <= cursor && parentheses >= 0);
			
			return parentheses != 1 || bracket > 0 ? -1 : index;
		}