Exemplo n.º 1
0
 protected void OnCompletionContextChanged(object o, EventArgs a)
 {
     if (autoHideCompletionWindow)
     {
         CompletionWindowManager.HideWindow();
     }
     if (autoHideParameterWindow)
     {
         ParameterInformationWindowManager.HideWindow(this, CompletionWidget);
     }
     ParameterInformationWindowManager.UpdateCursorPosition(this, CompletionWidget);
 }
Exemplo n.º 2
0
 internal protected virtual void OnCompletionContextChanged(object o, EventArgs a)
 {
     if (!IsActiveExtension())
     {
         return;
     }
     if (autoHideCompletionWindow)
     {
         CompletionWindowManager.HideWindow();
     }
     if (autoHideParameterWindow)
     {
         ParameterInformationWindowManager.HideWindow(this, CompletionWidget);
     }
     ParameterInformationWindowManager.UpdateCursorPosition(this, CompletionWidget);
 }
        // When a key is pressed, and before the key is processed by the editor, this method will be invoked.
        // Return true if the key press should be processed by the editor.
        public override bool KeyPress(KeyDescriptor descriptor)
        {
            if (!IsActiveExtension())
            {
                return(base.KeyPress(descriptor));
            }
            bool res;

            if (CurrentCompletionContext != null)
            {
                if (CompletionWindowManager.PreProcessKeyEvent(descriptor))
                {
                    CompletionWindowManager.PostProcessKeyEvent(descriptor);
                    autoHideCompletionWindow = true;
                    // in named parameter case leave the parameter window open.
                    autoHideParameterWindow = descriptor.KeyChar != ':';
                    if (!autoHideParameterWindow && ParameterInformationWindowManager.IsWindowVisible)
                    {
                        ParameterInformationWindowManager.PostProcessKeyEvent(this, CompletionWidget, descriptor);
                    }

                    return(false);
                }
                autoHideCompletionWindow = autoHideParameterWindow = false;
            }

            if (ParameterInformationWindowManager.IsWindowVisible)
            {
                if (ParameterInformationWindowManager.ProcessKeyEvent(this, CompletionWidget, descriptor))
                {
                    return(false);
                }
                autoHideCompletionWindow = autoHideParameterWindow = false;
            }

            //			int oldPos = Editor.CursorPosition;
            //			int oldLen = Editor.TextLength;
            char deleteOrBackspaceTriggerChar = '\0';

            if (descriptor.SpecialKey == SpecialKey.Delete && Editor.CaretOffset < Editor.Length)
            {
                deleteOrBackspaceTriggerChar = Editor.GetCharAt(Editor.CaretOffset);
            }
            if (descriptor.SpecialKey == SpecialKey.BackSpace && Editor.CaretOffset > 0)
            {
                deleteOrBackspaceTriggerChar = Editor.GetCharAt(Editor.CaretOffset - 1);
            }

            res = base.KeyPress(descriptor);
            if (Editor.EditMode == EditMode.TextLink && Editor.TextLinkPurpose == TextLinkPurpose.Rename)
            {
                return(res);
            }
            if (descriptor.KeyChar == (char)16 || descriptor.KeyChar == (char)17)
            {
                return(res);
            }

            CompletionWindowManager.PostProcessKeyEvent(descriptor);

            var ignoreMods = ModifierKeys.Control | ModifierKeys.Alt
                             | ModifierKeys.Command;

            // Handle parameter completion
            if (ParameterInformationWindowManager.IsWindowVisible)
            {
                ParameterInformationWindowManager.PostProcessKeyEvent(this, CompletionWidget, descriptor);
            }

            if ((descriptor.ModifierKeys & ignoreMods) != 0)
            {
                return(res);
            }

            // don't complete on block selection
            if (/*!EnableCodeCompletion ||*/ Editor.SelectionMode == MonoDevelop.Ide.Editor.SelectionMode.Block)
            {
                return(res);
            }
            // Handle code completion
            if (descriptor.KeyChar != '\0' && CompletionWidget != null && !CompletionWindowManager.IsVisible)
            {
                completionTokenSrc.Cancel();
                CurrentCompletionContext = CompletionWidget.CurrentCodeCompletionContext;
                completionTokenSrc       = new CancellationTokenSource();
                var caretOffset = Editor.CaretOffset;
                var token       = completionTokenSrc.Token;
                try {
                    var task = HandleCodeCompletionAsync(CurrentCompletionContext, new CompletionTriggerInfo(CompletionTriggerReason.CharTyped, descriptor.KeyChar), token);
                    if (task != null)
                    {
                        // Show the completion window in two steps. The call to PrepareShowWindow creates the window but
                        // it doesn't show it. It is used only to process the keys while the completion data is being retrieved.
                        CompletionWindowManager.PrepareShowWindow(this, descriptor.KeyChar, CompletionWidget, CurrentCompletionContext);
                        EventHandler windowClosed = delegate(object o, EventArgs a) {
                            completionTokenSrc.Cancel();
                        };
                        CompletionWindowManager.WindowClosed += windowClosed;
                        task.ContinueWith(t => {
                            CompletionWindowManager.WindowClosed -= windowClosed;
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }
                            var result = t.Result;
                            if (result != null)
                            {
                                int triggerWordLength = result.TriggerWordLength + (Editor.CaretOffset - caretOffset);
                                if (triggerWordLength > 0 && (triggerWordLength < Editor.CaretOffset ||
                                                              (triggerWordLength == 1 && Editor.CaretOffset == 1)))
                                {
                                    CurrentCompletionContext = CompletionWidget.CreateCodeCompletionContext(Editor.CaretOffset - triggerWordLength);
                                    if (result.TriggerWordStart >= 0)
                                    {
                                        CurrentCompletionContext.TriggerOffset = result.TriggerWordStart;
                                    }
                                    CurrentCompletionContext.TriggerWordLength = triggerWordLength;
                                }
                                // Now show the window for real.
                                if (!CompletionWindowManager.ShowWindow(result, CurrentCompletionContext))
                                {
                                    CurrentCompletionContext = null;
                                }
                            }
                            else
                            {
                                CompletionWindowManager.HideWindow();
                                CurrentCompletionContext = null;
                            }
                        }, Runtime.MainTaskScheduler);
                    }
                    else
                    {
                        CurrentCompletionContext = null;
                    }
                } catch (TaskCanceledException) {
                } catch (AggregateException) {
                }
            }

            if ((descriptor.SpecialKey == SpecialKey.Delete || descriptor.SpecialKey == SpecialKey.BackSpace) && CompletionWidget != null && !CompletionWindowManager.IsVisible)
            {
                if (!char.IsLetterOrDigit(deleteOrBackspaceTriggerChar) && deleteOrBackspaceTriggerChar != '_')
                {
                    return(res);
                }
                CurrentCompletionContext = CompletionWidget.CurrentCodeCompletionContext;

                int cpos, wlen;
                if (!GetCompletionCommandOffset(out cpos, out wlen))
                {
                    cpos = Editor.CaretOffset;
                    wlen = 0;
                }

                CurrentCompletionContext.TriggerOffset     = cpos;
                CurrentCompletionContext.TriggerWordLength = wlen;

                completionTokenSrc.Cancel();
                completionTokenSrc = new CancellationTokenSource();
                var caretOffset = Editor.CaretOffset;
                var token       = completionTokenSrc.Token;
                try {
                    var task = HandleCodeCompletionAsync(CurrentCompletionContext, new CompletionTriggerInfo(CompletionTriggerReason.BackspaceOrDeleteCommand, deleteOrBackspaceTriggerChar), token);
                    if (task != null)
                    {
                        // Show the completion window in two steps. The call to PrepareShowWindow creates the window but
                        // it doesn't show it. It is used only to process the keys while the completion data is being retrieved.
                        CompletionWindowManager.PrepareShowWindow(this, descriptor.KeyChar, CompletionWidget, CurrentCompletionContext);
                        EventHandler windowClosed = delegate(object o, EventArgs a) {
                            completionTokenSrc.Cancel();
                        };
                        CompletionWindowManager.WindowClosed += windowClosed;

                        task.ContinueWith(t => {
                            CompletionWindowManager.WindowClosed -= windowClosed;
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }
                            var result = t.Result;
                            if (result != null)
                            {
                                int triggerWordLength = result.TriggerWordLength + (Editor.CaretOffset - caretOffset);

                                if (triggerWordLength > 0 && (triggerWordLength < Editor.CaretOffset ||
                                                              (triggerWordLength == 1 && Editor.CaretOffset == 1)))
                                {
                                    CurrentCompletionContext = CompletionWidget.CreateCodeCompletionContext(Editor.CaretOffset - triggerWordLength);
                                    if (result.TriggerWordStart >= 0)
                                    {
                                        CurrentCompletionContext.TriggerOffset = result.TriggerWordStart;
                                    }
                                    CurrentCompletionContext.TriggerWordLength = triggerWordLength;
                                }
                                // Now show the window for real.
                                if (!CompletionWindowManager.ShowWindow(result, CurrentCompletionContext))
                                {
                                    CurrentCompletionContext = null;
                                }
                                else
                                {
                                    CompletionWindowManager.Wnd.StartOffset = CurrentCompletionContext.TriggerOffset;
                                }
                            }
                            else
                            {
                                CompletionWindowManager.HideWindow();
                                CurrentCompletionContext = null;
                            }
                        }, Runtime.MainTaskScheduler);
                    }
                    else
                    {
                        CurrentCompletionContext = null;
                    }
                } catch (TaskCanceledException) {
                    CurrentCompletionContext = null;
                } catch (AggregateException) {
                    CurrentCompletionContext = null;
                }
            }

            if (CompletionWidget != null)
            {
                CodeCompletionContext ctx  = CompletionWidget.CurrentCodeCompletionContext;
                var newparameterHintingSrc = new CancellationTokenSource();
                var token = newparameterHintingSrc.Token;
                try {
                    var task = HandleParameterCompletionAsync(ctx, descriptor.KeyChar, token);
                    if (task != null)
                    {
                        parameterHintingSrc.Cancel();
                        parameterHintingSrc = newparameterHintingSrc;
                        parameterHingtingCursorPositionChanged = false;
                        task.ContinueWith(t => {
                            if (!token.IsCancellationRequested && t.Result != null)
                            {
                                ParameterInformationWindowManager.ShowWindow(this, CompletionWidget, ctx, t.Result);
                                if (parameterHingtingCursorPositionChanged)
                                {
                                    ParameterInformationWindowManager.UpdateCursorPosition(this, CompletionWidget);
                                }
                            }
                        }, token, TaskContinuationOptions.None, Runtime.MainTaskScheduler);
                    }
                    else
                    {
                        //Key was typed that was filtered out, no heavy processing will be performed(task==null)
                        //but we still want to update ParameterInfo window to avoid displaying it outside method call
                        parameterHingtingCursorPositionChanged = true;
                    }
                } catch (TaskCanceledException) {
                } catch (AggregateException) {
                }
            }
            return(res);
        }