/// <summary> /// Is the given key a completion trigger key? /// </summary> private bool IsTriggerKey(char key) { var xls = XmlEditorServiceProvider.GetEditorService(serviceProvider, Dot42Package.DteVersion).GetLanguageService(); var quoteChar = xls.AutoInsertAttributeQuotes ? '=' : '"'; return(!key.Equals(char.MinValue) && (char.IsLetterOrDigit(key) || char.IsPunctuation(key) || char.IsWhiteSpace(key) || key.Equals(quoteChar))); }
/// <summary> /// Gets a single instance of the Xml language service. /// </summary> private IXmlLanguageService GetXmlLanguageService() { if (xmlLanguageService == null) { xmlLanguageService = XmlEditorServiceProvider.GetEditorService(serviceProvider, Dot42Package.DteVersion).GetLanguageService(); } return(xmlLanguageService); }
/// <summary> /// Determines which <see cref="T:Microsoft.VisualStudio.Language.Intellisense.CompletionSet"/>s should be part of the specified <see cref="T:Microsoft.VisualStudio.Language.Intellisense.ICompletionSession"/>. /// </summary> /// <param name="session">The session for which completions are to be computed.</param><param name="completionSets">The set of the completionSets to be added to the session.</param> /// <remarks> /// Each applicable <see cref="M:Microsoft.VisualStudio.Language.Intellisense.ICompletionSource.AugmentCompletionSession(Microsoft.VisualStudio.Language.Intellisense.ICompletionSession,System.Collections.Generic.IList{Microsoft.VisualStudio.Language.Intellisense.CompletionSet})"/> instance will be called in-order to /// (re)calculate a <see cref="T:Microsoft.VisualStudio.Language.Intellisense.ICompletionSession"/>. <see cref="T:Microsoft.VisualStudio.Language.Intellisense.CompletionSet"/>s can be added to the session by adding /// them to the completionSets collection passed-in as a parameter. In addition, by removing items from the collection, a /// source may filter <see cref="T:Microsoft.VisualStudio.Language.Intellisense.CompletionSet"/>s provided by <see cref="T:Microsoft.VisualStudio.Language.Intellisense.ICompletionSource"/>s earlier in the calculation /// chain. /// </remarks> public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets) { //var context = session.TextView.Properties[typeof(XmlResourceCompletionContext)] as XmlResourceCompletionContext; //if (context == null) //return; var editorService = XmlEditorServiceProvider.GetEditorService(serviceProvider, Dot42Package.DteVersion); var xls = editorService.GetLanguageService(); var vsTextView = vsEditorAdaptersFactoryService.GetViewAdapter(session.TextView); int line; int column; vsTextView.GetCaretPos(out line, out column); IVsTextLines buffer; ErrorHandler.ThrowOnFailure(vsTextView.GetBuffer(out buffer)); var source = xls.GetSource(buffer); var tokenInfo = source.GetTokenInfo(line, column); if ((!tokenInfo.IsStartOfTag) && (!tokenInfo.IsWhitespace) && (!tokenInfo.IsStringLiteral) && (!tokenInfo.IsStartStringLiteral)) { return; } var doc = xls.GetParseTree(source, vsTextView, line, column); var nf = doc.SearchForNodeAtPosition(line, column); var attachCommitted = false; if (nf.IsXmlStartTag) { if (tokenInfo.IsStartOfTag) { // New element var descriptors = GetElementDescriptors(nf.GetParentPath(), true); completionSets.Clear(); completionSets.Add(CreateCompletionSet(CreateElementCompletions(descriptors), session, null)); attachCommitted = true; } else if (tokenInfo.IsWhitespace) { // New attribute var descriptor = GetElementDescriptors(nf.GetPath(), false).FirstOrDefault(); if (descriptor != null) { completionSets.Clear(); completionSets.Add(CreateCompletionSet(CreateAttributeCompletions(descriptor), session, null)); attachCommitted = true; } } } else if (nf.IsElement) { //var element = (XmlElement) nf.Scope; } else if (nf.IsAttribute) { // Attribute value var descriptor = GetAttributeDescriptor(nf.GetParentPath(), nf.GetLocalName()); if ((descriptor != null) && (descriptor.HasStandardValues)) { completionSets.Clear(); completionSets.Add(CreateCompletionSet(CreateAttributeValueCompletions(descriptor), session, tokenInfo)); attachCommitted = true; } } if (attachCommitted) { session.Committed += OnSessionCommitted; } }
/// <summary> /// Called after the WindowPane has been sited with an IServiceProvider from the environment /// </summary> protected override void Initialize() { base.Initialize(); // Create and initialize the editor #region Register with IOleComponentManager var componentManager = (IOleComponentManager)GetService(typeof(SOleComponentManager)); if (this.componentId == 0 && componentManager != null) { var crinfo = new OLECRINFO[1]; crinfo[0].cbSize = (uint)Marshal.SizeOf(typeof(OLECRINFO)); crinfo[0].grfcrf = (uint)_OLECRF.olecrfNeedIdleTime | (uint)_OLECRF.olecrfNeedPeriodicIdleTime; crinfo[0].grfcadvf = (uint)_OLECADVF.olecadvfModal | (uint)_OLECADVF.olecadvfRedrawOff | (uint)_OLECADVF.olecadvfWarningsOff; crinfo[0].uIdleTimeInterval = 100; int hr = componentManager.FRegisterComponent(this, crinfo, out this.componentId); ErrorHandler.Succeeded(hr); } #endregion var resources = new ComponentResourceManager(typeof(XmlEditorPane)); #region Hook Undo Manager // Attach an IOleUndoManager to our WindowFrame. Merely calling QueryService // for the IOleUndoManager on the site of our IVsWindowPane causes an IOleUndoManager // to be created and attached to the IVsWindowFrame. The WindowFrame automaticall // manages to route the undo related commands to the IOleUndoManager object. // Thus, our only responsibilty after this point is to add IOleUndoUnits to the // IOleUndoManager (aka undo stack). undoManager = (IOleUndoManager)GetService(typeof(SOleUndoManager)); // In order to use the IVsLinkedUndoTransactionManager, it is required that you // advise for IVsLinkedUndoClient notifications. This gives you a callback at // a point when there are intervening undos that are blocking a linked undo. // You are expected to activate your document window that has the intervening undos. if (undoManager != null) { IVsLinkCapableUndoManager linkCapableUndoMgr = (IVsLinkCapableUndoManager)undoManager; if (linkCapableUndoMgr != null) { linkCapableUndoMgr.AdviseLinkedUndoClient(this); } } #endregion // hook up our var dteVersion = Dot42Package.DteVersion; var xmlEditorService = XmlEditorServiceProvider.GetEditorService(this, dteVersion); if (xmlEditorService == null) { throw new InvalidOperationException("XmlEditorService required"); } store = xmlEditorService.CreateXmlStore(); store.UndoManager = undoManager; model = store.OpenXmlModel(new Uri(_fileName)); // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable, // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on // the object returned by the Content property. //designerControl = new VsDesignerControl(new ViewModel(store, model, this, textBuffer)); designerControl = context.CreateDesigner(thisPackage.Ide, store, model, this, textBuffer); base.Content = designerControl; RegisterIndependentView(true); var mcs = GetService(typeof(IMenuCommandService)) as IMenuCommandService; if (null != mcs) { // Now create one object derived from MenuCommnad for each command defined in // the CTC file and add it to the command service. // For each command we have to define its id that is a unique Guid/integer pair, then // create the OleMenuCommand object for this command. The EventHandler object is the // function that will be called when the user will select the command. Then we add the // OleMenuCommand to the menu service. The addCommand helper function does all this for us. AddCommand(mcs, VSConstants.GUID_VSStandardCommandSet97, (int)VSConstants.VSStd97CmdID.NewWindow, OnNewWindow, OnQueryNewWindow); AddCommand(mcs, VSConstants.GUID_VSStandardCommandSet97, (int)VSConstants.VSStd97CmdID.ViewCode, OnViewCode, OnQueryViewCode); } }