
{"id":1055,"date":"2012-08-21T14:19:55","date_gmt":"2012-08-21T18:19:55","guid":{"rendered":"http:\/\/www.ikriv.com\/blog\/?p=1055"},"modified":"2012-08-21T14:19:55","modified_gmt":"2012-08-21T18:19:55","slug":"visual-studio-extensibility","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=1055","title":{"rendered":"Visual Studio Extensibility"},"content":{"rendered":"<p>Just write a quick macro for Visual Studio that would replace < with &lt; and > with &gt;, etc. I am probably the 1000th person to do that. Yet, it proved to be surprisingly hard.<\/p>\n<ul>\n<li>\n<code>DTE.ActiveDocument.Selection<\/code> is an <code>Object<\/code>. No methods, no nothing. Need to cast to <code>TextSelection<\/code> to do anything useful with it.<\/li>\n<li><code>TextSelection.ReplacePattern()<\/code> happily replaces one pattern, then loses selection. Attempts to artificially restore selection failed, as <code>TopPoint<\/code> and <code>BottomPoint<\/code> properties are read only. <code>MoveToPoint()<\/code> did not do the trick either. I am still not sure how to tell the IDE to select the text from here to there.<\/li>\n<li>If you attempt to do something like <code>Selection.Text = Selection.Text.Replace((...)<\/code> it works fine for one line, but for multiline selection it inserts lots of spaces and generally looks very weird. It also takes a lot of time and occasionally throws exceptions. A non starter.<\/li>\n<li>Tried to use <code>DTE.Find<\/code> object, could not find a way to close programmatically the damn Find window. Fortunately  <code>DTE.Find.FindReplace()<\/code> works without opening the window.<\/li>\n<\/ul>\n<p>Oh yeah, if you try Googling for it &#8211; forget about it. You are drowning in crap. Bing is slightly better, but still no help there.<\/p>\n<p>Final solution:<\/p>\n<pre><code>\n    Sub EscapeXmlChars()\n        Replace(\"&\", \"&amp;amp;\")\n        Replace(\"<\", \"&amp;lt;\")\n        Replace(\">\", \"&amp;gt;\")\n    End Sub\n\n    Sub UnescapeXmlChars()\n        Replace(\"&amp;lt;\", \"<\")\n        Replace(\"&amp;gt;\", \">\")\n        Replace(\"&amp;amp;\", \"&\")\n    End Sub\n\n    Private Sub Replace(ByVal find As String, ByVal replace As String)\n        DTE.ActiveDocument.Activate()\n        DTE.Find.FindReplace( _\n        vsFindAction.vsFindActionReplaceAll, _\n        find, _\n        vsFindOptions.vsFindOptionsMatchInHiddenText, _\n        replace, _\n        vsFindTarget.vsFindTargetCurrentDocumentSelection)\n    End Sub<\/code><\/pre>\n<p><a style=\"display:none\" href=\"http:\/\/www.codeproject.com\/script\/Articles\/BlogFeedList.aspx?amid=1181663\" rel=\"tag\">CodeProject<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just write a quick macro for Visual Studio that would replace < with &lt; and > with &gt;, etc. I am probably the 1000th person to do that. Yet, it <a href=\"https:\/\/ikriv.com\/blog\/?p=1055\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[16,4],"tags":[],"class_list":["entry","author-ikriv","post-1055","post","type-post","status-publish","format-standard","category-demos","category-hack"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1055","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1055"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1055\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}