public void OnTextInput(int position)
        {
            if (m_view == null)
            {
                return;
            }
            if (!m_view.Properties.TryGetProperty(nameof(UIViewItem), out UIViewItem info))
            {
                return;
            }
            if (info == null)
            {
                return;
            }

            if (m_sh_broker.IsSignatureHelpActive(m_view))
            {
                return;
            }

            if (m_view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageSignatureHelpSource), out ALanguageSignatureHelpSource source))
            {
                source.RefreshSignatureHelp(null, 0, 0, null);
            }

            if (m_view.Properties.TryGetProperty(nameof(ALanguageServer), out ALanguageServer server))
            {
                server.AddTask(() => server.QuerySignatureHelp(info.GetFullPath(), position));
            }
        }
예제 #2
0
        /// <summary>
        /// This handler is necessary to intercept keyboard input which maps to Vim
        /// commands but doesn't map to text input.  Any combination which can be
        /// translated into actual text input will be done so much more accurately by
        /// WPF and will end up in the TextInput event.
        ///
        /// An example of why this handler is needed is for key combinations like
        /// Shift+Escape.  This combination won't translate to an actual character in most
        /// (possibly all) keyboard layouts.  This means it won't ever make it to the
        /// TextInput event.  But it can translate to a Vim command or mapped keyboard
        /// combination that we do want to handle.  Hence we override here specifically
        /// to capture those circumstances
        /// </summary>
        public override void KeyDown(KeyEventArgs e)
        {
            VimTrace.TraceInfo("VimKeyProcessor::KeyDown {0} {1}", e.Characters, e.CharactersIgnoringModifiers);

            bool handled;

            if (KeyEventIsDeadChar(e))
            {
                // When a dead key combination is pressed we will get the key down events in
                // sequence after the combination is complete.  The dead keys will come first
                // and be followed the final key which produces the char.  That final key
                // is marked as DeadCharProcessed.
                //
                // All of these should be ignored.  They will produce a TextInput value which
                // we can process in the TextInput event
                handled = false;
            }
            else if (_completionBroker.IsCompletionActive(TextView) && !IsEscapeKey(e))
            {
                handled = false;
            }
            else if (_signatureHelpBroker.IsSignatureHelpActive(TextView))
            {
                handled = false;
            }
            else if (_inlineRenameListenerFactory.InRename)
            {
                handled = false;
            }
            else
            {
                var oldMode = VimBuffer.Mode.ModeKind;

                VimTrace.TraceDebug(oldMode.ToString());
                // Attempt to map the key information into a KeyInput value which can be processed
                // by Vim.  If this works and the key is processed then the input is considered
                // to be handled
                if (_keyUtil.TryConvertSpecialToKeyInput(e.Event, out KeyInput keyInput))
                {
                    handled = TryProcess(keyInput);
                }
                else
                {
                    handled = false;
                }
            }

            VimTrace.TraceInfo("VimKeyProcessor::KeyDown Handled = {0}", handled);

            var status = Mac.StatusBar.GetStatus(VimBuffer);
            var text   = status.Text;

            if (VimBuffer.ModeKind == ModeKind.Command)
            {
                // Add a fake 'caret'
                text = text.Insert(status.CaretPosition, "|");
            }
            IdeApp.Workbench.StatusBar.ShowMessage(text);
            e.Handled = handled;
        }
예제 #3
0
        private bool TryProcess(KeyEventArgs e, KeyInput keyInput)
        {
            if (KeyEventIsDeadChar(e))
            {
                // When a dead key combination is pressed we will get the key down events in
                // sequence after the combination is complete.  The dead keys will come first
                // and be followed the final key which produces the char.  That final key
                // is marked as DeadCharProcessed.
                //
                // All of these should be ignored.  They will produce a TextInput value which
                // we can process in the TextInput event
                return(false);
            }

            if ((_vimBuffer.ModeKind.IsAnyInsert() || _vimBuffer.ModeKind.IsAnySelect()) &&
                !_vimBuffer.CanProcessAsCommand(keyInput) &&
                keyInput.Char > 0x1f &&
                _vimBuffer.BufferedKeyInputs.IsEmpty &&
                !_vimBuffer.Vim.MacroRecorder.IsRecording)
            {
                return(false);
            }

            if (_completionBroker.IsCompletionActive(_textView) && !IsEscapeKey(e))
            {
                return(false);
            }

            if (_signatureHelpBroker.IsSignatureHelpActive(_textView) && !IsEscapeKey(e))
            {
                return(false);
            }

            if (_inlineRenameListenerFactory.InRename)
            {
                return(false);
            }

            if (_vimBuffer.ModeKind.IsAnyInsert() && e.Characters == "\t")
            {
                // Allow tab key to work for snippet completion
                //
                // TODO: We should only really do this when the characters
                // to the left of the caret form a valid snippet
                return(false);
            }

            return(_vimBuffer.CanProcess(keyInput) && _vimBuffer.Process(keyInput).IsAnyHandled);
        }
        void IDisplayWindowBroker.DismissDisplayWindows()
        {
            if (_completionBroker.IsCompletionActive(_textView))
            {
                _completionBroker.DismissAllSessions(_textView);
            }

            if (_signatureHelpBroker.IsSignatureHelpActive(_textView))
            {
                _signatureHelpBroker.DismissAllSessions(_textView);
            }

            if (_quickInfoBroker.IsQuickInfoActive(_textView))
            {
                _quickInfoBroker.GetSession(_textView).DismissAsync();
            }
        }
예제 #5
0
        private void OnViewMouseHover(object sender, MouseHoverEventArgs e)
        {
            //find the mouse position by mapping down to the subject buffer
            var point = _textView.BufferGraph.MapDownToFirstMatch
                            (new SnapshotPoint(_textView.TextSnapshot, e.Position),
                            PointTrackingMode.Positive,
                            snapshot => _subjectBuffers.Contains(snapshot.TextBuffer),
                            PositionAffinity.Predecessor);

            if (point != null)
            {
                var triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, PointTrackingMode.Positive);
                if (!_quickInfoBroker.IsQuickInfoActive(_textView) && !_signatureHelpBroker.IsSignatureHelpActive(_textView))
                {
                    _quickInfoBroker.TriggerQuickInfo(_textView, triggerPoint, true);
                }
            }
        }
예제 #6
0
        void IDisplayWindowBroker.DismissDisplayWindows()
        {
            if (_completionBroker.IsCompletionActive(_textView))
            {
                _completionBroker.DismissAllSessions(_textView);
            }

            if (_signatureHelpBroker.IsSignatureHelpActive(_textView))
            {
                _signatureHelpBroker.DismissAllSessions(_textView);
            }

            if (_quickInfoBroker.IsQuickInfoActive(_textView))
            {
                foreach (var session in _quickInfoBroker.GetSessions(_textView))
                {
                    session.Dismiss();
                }
            }
        }
예제 #7
0
        private bool ShouldBeProcessedByVim(KeyEventArgs e)
        {
            if (KeyEventIsDeadChar(e))
            {
                // When a dead key combination is pressed we will get the key down events in
                // sequence after the combination is complete.  The dead keys will come first
                // and be followed the final key which produces the char.  That final key
                // is marked as DeadCharProcessed.
                //
                // All of these should be ignored.  They will produce a TextInput value which
                // we can process in the TextInput event
                return(false);
            }

            if (_completionBroker.IsCompletionActive(TextView) && !IsEscapeKey(e))
            {
                return(false);
            }

            if (_signatureHelpBroker.IsSignatureHelpActive(TextView) && !IsEscapeKey(e))
            {
                return(false);
            }

            if (_inlineRenameListenerFactory.InRename)
            {
                return(false);
            }

            if (VimBuffer.Mode.ModeKind == ModeKind.Insert && e.Characters == "\t")
            {
                // Allow tab key to work for snippet completion
                return(false);
            }

            return(true);
        }
        private void StartSignatureSession()
        {
            if (_currentSignatureSession != null)
            {
                return;
            }

            if (_signatureHelpBroker.IsSignatureHelpActive(_textView))
            {
                _currentSignatureSession = _signatureHelpBroker.GetSessions(_textView)[0];
            }
            else
            {
                var point         = _textView.Caret.Position.BufferPosition;
                var snapshot      = point.Snapshot;
                var trackingPoint = snapshot.CreateTrackingPoint(point, PointTrackingMode.Positive);

                _currentSignatureSession = _signatureHelpBroker.CreateSignatureHelpSession(_textView, trackingPoint, true);
                _textView.TextBuffer.Properties.AddProperty(typeof(ISignatureHelpSession), _currentSignatureSession);
            }

            _currentSignatureSession.Dismissed += SignatureSessionDismissed;
            _currentSignatureSession.Start();
        }
예제 #9
0
        /// <summary>
        /// Is there an active signature help session? (is the tooltip showing?)
        /// </summary>
        public static bool HasActiveSignatureSession(ITextView textView, ICoreShell shell)
        {
            ISignatureHelpBroker broker = shell.ExportProvider.GetExportedValue <ISignatureHelpBroker>();

            return(broker.IsSignatureHelpActive(textView));
        }
예제 #10
0
        internal bool StartSignatureSession(bool comma, IXTypeSymbol type = null, string methodName = null, char triggerchar = '\0')
        {
            WriteOutputMessage("StartSignatureSession()");

            if (_signatureSession != null)
            {
                return(false);
            }
            IXMemberSymbol currentElement = null;
            SnapshotPoint  ssp            = this._textView.Caret.Position.BufferPosition;

            if (triggerchar == '(' && ssp.Position < ssp.Snapshot.Length && ssp.GetChar() == ')')
            {
                ssp -= 1;
            }
            var location = _textView.FindLocation(ssp);

            if (location == null || location.Member == null)
            {
                return(false);
            }
            if (location.Member.Range.StartLine == location.LineNumber)
            {
                return(false);
            }

            var props = new XSharpSignatureProperties(location);

            props.triggerChar     = triggerchar;
            props.triggerPosition = this._textView.Caret.Position.BufferPosition.Position;

            if (type != null && methodName != null)
            {
                var findStatic = triggerchar == '.';
                currentElement = XSharpLookup.SearchMethod(location, type, methodName, Modifiers.Private, findStatic).FirstOrDefault();
            }
            else
            {
                currentElement = findElementAt(comma, ssp, props);
            }
            if (currentElement == null)
            {
                return(false);
            }

            SnapshotPoint caret         = _textView.Caret.Position.BufferPosition;
            ITextSnapshot caretsnapshot = caret.Snapshot;

            //
            if (_signatureBroker.IsSignatureHelpActive(_textView))
            {
                _signatureSession = _signatureBroker.GetSessions(_textView)[0];
            }
            else
            {
                _signatureSession = _signatureBroker.CreateSignatureHelpSession(_textView, caretsnapshot.CreateTrackingPoint(caret, PointTrackingMode.Positive), true);
            }
            _signatureSession.Properties[typeof(XSharpSignatureProperties)] = props;

            if (location.Member.Kind.IsGlobalTypeMember())
            {
                props.Visibility = Modifiers.Public;
            }
            else
            {
                props.Visibility = Modifiers.Protected;
            }
            _signatureSession.Dismissed += OnSignatureSessionDismiss;
            props.Element = currentElement;
            if (comma)
            {
                var  tokenList = XSharpTokenTools.GetTokenListBeforeCaret(location, out var state);
                bool done      = false;
                int  nested    = 0;
                for (int i = tokenList.Count - 1; i >= 0 && !done; i--)
                {
                    var token = tokenList[i];
                    switch (token.Type)
                    {
                    case XSharpLexer.LPAREN:
                    case XSharpLexer.LCURLY:
                    case XSharpLexer.LBRKT:
                        done = nested == 0;
                        if (done)
                        {
                            props.Start  = token.Position;
                            props.Length = _textView.Caret.Position.BufferPosition.Position - token.Position;
                        }
                        nested -= 1;
                        break;

                    case XSharpLexer.RPAREN:
                    case XSharpLexer.RCURLY:
                    case XSharpLexer.RBRKT:
                        nested += 1;
                        break;
                    }
                }
            }
            else
            {
                props.Start  = ssp.Position;
                props.Length = _textView.Caret.Position.BufferPosition.Position - ssp.Position;
            }


            try
            {
                _signatureSession.Start();
            }
            catch (Exception e)
            {
                XSettings.LogException(e, "Start Signature session failed:");
            }
            //
            return(true);
        }
예제 #11
0
        /// <summary>
        /// Is there an active signature help session? (is the tooltip showing?)
        /// </summary>
        public static bool HasActiveSignatureSession(ITextView textView)
        {
            ISignatureHelpBroker broker = EditorShell.Current.ExportProvider.GetExportedValue <ISignatureHelpBroker>();

            return(broker.IsSignatureHelpActive(textView));
        }
예제 #12
0
        /// <summary>
        /// Is there an active signature help session? (is the tooltip showing?)
        /// </summary>
        public static bool HasActiveSignatureSession(ITextView textView, ICoreShell shell)
        {
            ISignatureHelpBroker broker = shell.GetService <ISignatureHelpBroker>();

            return(broker.IsSignatureHelpActive(textView));
        }