Example #1
0
        void IWpfTextViewCreationListener.TextViewCreated(IWpfTextView textView)
        {
            // Create the IVimBuffer after loading the VimRc so that it gets the appropriate
            // settings
            var opt = _vim.GetOrCreateVimBufferForHost(textView);

            if (opt.IsNone())
            {
                return;
            }

            var vimBuffer = opt.Value;

            // Visual Studio really puts us in a bind with respect to setting synchronization.  It doesn't
            // have a prescribed time to apply it's own customized settings and in fact differs between
            // versions (2010 after TextViewCreated and 2012 is before).  If we start synchronizing
            // before Visual Studio settings take affect then they will just overwrite the Vim settings.
            //
            // We need to pick a point where VS is done with settings.  Then we can start synchronization
            // and change the settings to what we want them to be.
            //
            // In most cases we can just wait until IVsTextViewCreationListener.VsTextViewCreated fires
            // because that happens after language preferences have taken affect.  Unfortunately this won't
            // fire for ever IWpfTextView.  If the IWpfTextView doesn't have any shims it won't fire.  So
            // we post a simple action as a backup mechanism to catch this case.
            _toSyncSet.Add(vimBuffer);
            _protectedOperations.BeginInvoke(() => BeginSettingSynchronization(vimBuffer), DispatcherPriority.Loaded);
        }
Example #2
0
        public void BeginInvoke_Priority_Standard()
        {
            var didRun = false;

            _protectedOperations.BeginInvoke(delegate { didRun = true; }, DispatcherPriority.Normal);
            Dispatcher.CurrentDispatcher.DoEvents();
            Assert.True(didRun);
        }
Example #3
0
        void IVimBufferCreationListener.VimBufferCreated(IVimBuffer vimBuffer)
        {
            Action doCheck = () =>
            {
                if (vimBuffer.IsClosed)
                {
                    return;
                }

                if (ConflictingKeyBindingState == ConflictingKeyBindingState.HasNotChecked)
                {
                    if (_vimApplicationSettings.IgnoredConflictingKeyBinding)
                    {
                        IgnoreAnyConflicts();
                    }
                    else
                    {
                        RunConflictingKeyBindingStateCheck(vimBuffer);
                    }
                }
            };

            // Don't block startup by immediately running a key binding check.  Schedule it
            // for the future
            _protectedOperations.BeginInvoke(doCheck);
        }
Example #4
0
        /// <summary>
        /// Queue up a check for the specified type here.  If there is already check queued 
        /// this wont' have any effect other than to ensure the specified check is included
        /// in the existing queue
        /// </summary>
        private void QueueCheck(CheckKind kind)
        {
            if (_queuedCheckKind.HasValue)
            {
                _queuedCheckKind |= kind;
                return;
            }

            Action doCheck =
                () =>
                {
                    var saved = _queuedCheckKind ?? kind;
                    _queuedCheckKind = null;

                    // The ITextView can close in between the time of dispatch and the actual 
                    // execution of the call.  
                    //
                    // In addition to being the right thing to do by bailing out early, there are parts 
                    // of the SHIM layer which can't handle being called after the ITextView is 
                    // called.  EnumMarkers for example will throw a NullReferenceException.
                    if (_textView.IsClosed)
                    {
                        return;
                    }
                    PerformCheck(saved);
                };

            _protectedOperations.BeginInvoke(doCheck, DispatcherPriority.Loaded);
        }
Example #5
0
 void IVimBufferCreationListener.VimBufferCreated(IVimBuffer vimBuffer)
 {
     // Let the command margin get into a known state before we disable it.
     _vimProtectedOperations.BeginInvoke(
         () => _commandMarginUtil.SetMarginVisibility(vimBuffer, _vimApplicationSettings.UseEditorCommandMargin),
         DispatcherPriority.ApplicationIdle);
 }
Example #6
0
        /// <summary>
        /// Hookup the output window to the vim trace data when it's requested by the developer
        /// </summary>
        private void InitOutputPane()
        {
            // The output window is not guaraneed to be accessible on startup. On certain configurations of VS2015
            // it can throw an exception. Delaying the creation of the Window until after startup has likely
            // completed. Additionally using IProtectedOperations to guard against exeptions
            // https://github.com/VsVim/VsVim/issues/2249

            _protectedOperations.BeginInvoke(initOutputPaneCore, DispatcherPriority.ApplicationIdle);

            void initOutputPaneCore()
            {
                if (!(_dte is DTE2 dte2))
                {
                    return;
                }

                var outputWindow = dte2.ToolWindows.OutputWindow;
                var outputPane   = outputWindow.OutputWindowPanes.Add("VsVim");

                VimTrace.Trace += (_, e) =>
                {
                    if (_vimApplicationSettings.EnableOutputWindow)
                    {
                        outputPane.OutputString(e.Message + Environment.NewLine);
                    }
                };
            }
        }
Example #7
0
        /// <summary>
        /// Perform the specified action when the specified text view is ready
        /// </summary>
        /// <param name="textView"></param>
        /// <param name="action"></param>
        public virtual void DoActionWhenTextViewReady(FSharpFunc <Unit, Unit> action, ITextView textView)
        {
            // Local functions to do the action.
            void doAction()
            {
                // Perform action if the text view is still open.
                if (!textView.IsClosed && !textView.InLayout)
                {
                    action.Invoke(null);
                }
            }

            void doActionHandler(object sender, RoutedEventArgs e)
            {
                // Unsubscribe.
                if (sender is FrameworkElement element)
                {
                    element.Loaded -= doActionHandler;
                }

                // Then schedule the action.
                _protectedOperations.BeginInvoke(doAction, DispatcherPriority.Loaded);
            }

            if (textView is IWpfTextView wpfTextView && !wpfTextView.VisualElement.IsLoaded)
            {
                // FrameworkElement.Loaded Event:
                //
                // Occurs when a FrameworkElement has been constructed and
                // added to the object tree, and is ready for interaction.
                wpfTextView.VisualElement.Loaded += doActionHandler;
            }
Example #8
0
        private void ConnectToOleCommandTarget(IVimBuffer vimBuffer, ITextView textView, IVsTextView vsTextView)
        {
            var broker = _displayWindowBrokerFactoryServcie.GetDisplayWindowBroker(textView);
            var vimBufferCoordinator = _bufferCoordinatorFactory.GetVimBufferCoordinator(vimBuffer);
            var result = VsCommandTarget.Create(vimBufferCoordinator, vsTextView, _textManager, _adapter, broker, _keyUtil, _vimApplicationSettings, _commandTargetFactoryList);

            if (result.IsSuccess)
            {
                // Store the value for debugging
                _vimBufferToCommandTargetMap[vimBuffer] = result.Value;
            }

            // Try and install the IVsFilterKeys adapter.  This cannot be done synchronously here
            // because Venus projects are not fully initialized at this state.  Merely querying
            // for properties cause them to corrupt internal state and prevents rendering of the
            // view.  Occurs for aspx and .js pages
            void install() => VsFilterKeysAdapter.TryInstallFilterKeysAdapter(_adapter, vimBuffer);

            _protectedOperations.BeginInvoke(install);
        }
Example #9
0
        void IVimBufferCreationListener.VimBufferCreated(IVimBuffer vimBuffer)
        {
            vimBuffer.WindowSettings.SettingChanged += (_, args) => OnSettingChanged(vimBuffer, args);

            // On startup enforce the vim cursor line setting over any Visual Studio default.  This is important
            // because the default changes between Dev10 (off) and Dev11 (on).  Need to be consistent here and
            // choose the Vim setting
            Action action = () => SyncVimToEditor(vimBuffer);

            _protectedOperations.BeginInvoke(action, DispatcherPriority.Loaded);
        }
Example #10
0
        void IVimBufferCreationListener.VimBufferCreated(IVimBuffer vimBuffer)
        {
            // This work only needs to be done once and consumes noticeable cycles while
            // operating.  Skip this if settings are already migrated
            if (!NeedsMigration)
            {
                return;
            }

            _protectedOperations.BeginInvoke(() => DoMigration(vimBuffer), DispatcherPriority.ApplicationIdle);
        }
Example #11
0
        void IWpfTextViewCreationListener.TextViewCreated(IWpfTextView textView)
        {
            // Load the VimRC file if we haven't tried yet
            MaybeLoadVimRc();

            // Create the IVimBuffer after loading the VimRc so that it gets the appropriate
            // settings
            var buffer = _vim.GetOrCreateVimBuffer(textView);

            // Save the tab size and expand tab in case we need to reset them later
            var bufferData = new BufferData
            {
                TabStop   = buffer.LocalSettings.TabStop,
                ExpandTab = buffer.LocalSettings.ExpandTab,
                Number    = buffer.LocalSettings.Number
            };

            _bufferMap[buffer] = bufferData;

            Action doCheck = () =>
            {
                // Run the key binding check now
                if (_keyBindingService.ConflictingKeyBindingState == ConflictingKeyBindingState.HasNotChecked)
                {
                    if (Settings.Settings.Default.IgnoredConflictingKeyBinding)
                    {
                        _keyBindingService.IgnoreAnyConflicts();
                    }
                    else
                    {
                        _keyBindingService.RunConflictingKeyBindingStateCheck(buffer, (x, y) => { });
                    }
                }
            };

            _protectedOperations.BeginInvoke(doCheck);
        }
Example #12
0
 void IProtectedOperations.BeginInvoke(Action action, DispatcherPriority dispatcherPriority)
 {
     _protectedOperations.BeginInvoke(action, dispatcherPriority);
 }
Example #13
0
        /// <summary>
        /// Raised when an IVsTextView is created.  When this occurs it means a previously created
        /// ITextView was associated with an IVsTextView shim.  This means the ITextView will be
        /// hooked into the Visual Studio command system and a host of other items.  Setup all of
        /// our plumbing here
        /// </summary>
        void IVsTextViewCreationListener.VsTextViewCreated(IVsTextView vsView)
        {
            // Get the ITextView created.  Shouldn't ever be null unless a non-standard Visual Studio
            // component is calling this function
            var textView = _adaptersFactory.GetWpfTextView(vsView);

            if (textView == null)
            {
                return;
            }

            // Sanity check. No reason for this to be null
            var opt = _vim.GetVimBuffer(textView);

            if (!opt.IsSome())
            {
                return;
            }

            var        buffer = opt.Value;
            BufferData bufferData;

            if (_bufferMap.TryGetValue(buffer, out bufferData))
            {
                // During the lifetime of an IVimBuffer the local and editor settings are kept
                // in sync for tab values.  At startup though a decision has to be made about which
                // settings should "win" and this is controlled by 'UseEditorSettings'.
                //
                // Visual Studio of course makes this difficult.  It will create an ITextView and
                // then later force all of it's language preference settings down on the ITextView
                // if it does indeed have an IVsTextView.  This setting will inherently overwrite
                // the custom settings with the stored Visual Studio settings.
                //
                // To work around this we store the original values and reset them here.  This event
                // is raised after this propagation occurs so we can put them back
                if (!_vim.GlobalSettings.UseEditorSettings)
                {
                    buffer.LocalSettings.TabStop   = bufferData.TabStop;
                    buffer.LocalSettings.ExpandTab = bufferData.ExpandTab;
                    buffer.LocalSettings.Number    = bufferData.Number;
                }
            }
            else
            {
                bufferData         = new BufferData();
                _bufferMap[buffer] = bufferData;
            }

            var broker            = _displayWindowBrokerFactoryServcie.CreateDisplayWindowBroker(textView);
            var bufferCoordinator = _bufferCoordinatorFactory.GetVimBufferCoordinator(buffer);
            var result            = VsCommandTarget.Create(bufferCoordinator, vsView, _adapter, broker, _resharperUtil, _keyUtil);

            if (result.IsSuccess)
            {
                // Store the value for debugging
                bufferData.VsCommandTarget = result.Value;
            }

            // Try and install the IVsFilterKeys adapter.  This cannot be done synchronously here
            // because Venus projects are not fully initialized at this state.  Merely querying
            // for properties cause them to corrupt internal state and prevents rendering of the
            // view.  Occurs for aspx and .js pages
            Action install = () => VsFilterKeysAdapter.TryInstallFilterKeysAdapter(_adapter, _editorOptionsFactoryService, buffer);

            _protectedOperations.BeginInvoke(install);
        }