Product Feedback woes and yet another macro
A while back, we received a suggestion via our product feedback website. The site lets anyone log bugs and/or suggestions for our product, which feed directly into our internal bug tracking mechanism. In other words, the site is not simply a façade but a direct input into our development, supplementing our internal testing (it’s hard to find every bug in a piece of code as large as Visual Studio) and helping us prioritize issues.
The upside of this website is that we have received valuable feedback, fixed real customer bugs (many of these fixes will be in our upcoming service pack) and identified certain features that are lacking and others that are slowly becoming superfluous. For example, many users voted on the fact that we lack support for code snippets in C++, a feature I would love to have and we are investigating providing this support in Orcas (our next release). When so many customers show their desire for the feature, it helps us allocate resources, something which is always in scarce supply
The downside of the product feedback is the simple fact that we can’t handle the quantity of bugs and suggestions that people submit (my personal opinion) and we’ve had to make some tough decisions with prioritization. While we fight to keep our product bug-free, we also understand the inescapable need to implement our customers’ suggestions. It’s one of the most simultaneously loathsome and attractive aspects of being a program manager at Microsoft. After all, few people in the industry can say they decide whether some feature will make it into a product used by millions
All this rambling has me straying from this post’s purpose. Yet another piece of (macro) code. Today’s macro was inspired by a suggestion we received via product feedback, which I deemed unworthy due to how easy it is to add using our extensibility model. Without further ado, here is a macro to preprocess the current file and bring it up in the editor.
Sub RunPreprocessor()
Dim doc As Document = DTE.ActiveDocument
Dim docname As String = doc.Name.ToLower
Dim project As Project = doc.ProjectItem.ContainingProject
If doc.Language = "C/C++" Then
' not the most accurate way of identifying a cpp file
If docname.EndsWith(".cpp") Then
Dim vcproj As VCProject = project.Object
Dim projfiles As IVCCollection = vcproj.Files
Dim vcfile As VCFile = Nothing
' find the file in current project
For Each f As VCFile In projfiles
If f.Name = doc.Name Then
vcfile = f
Exit For
End If
Next
Dim activeconfigname As String = DTE.Solution.SolutionBuild.ActiveConfiguration.Name
Dim fileconfig As VCFileConfiguration = vcfile.FileConfigurations(activeconfigname)
Dim filecompiler As VCCLCompilerTool = fileconfig.Tool
' toggle preprocessing on, compile, toggle preprocessing
filecompiler.GeneratePreprocessedFile = preprocessOption.preprocessNoLineNumbers
fileconfig.Compile(True, True)
filecompiler.GeneratePreprocessedFile = preprocessOption.preprocessNo
Dim preprocessedpath = doc.Path + docname.Replace(".cpp", ".i")
ClearEmptyLines(preprocessedpath)
DTE.ItemOperations.OpenFile(preprocessedpath + ".cpp")
End If
End If
End Sub
And the required helper function:
Sub ClearEmptyLines(ByVal filepath As String)
Dim line As String
' iterate through a file and write out non-empty lines into a new file
Using sr As New IO.StreamReader(filepath)
' out file name is <filename>.i.cpp (for highlighting)
Using sw As New IO.StreamWriter(New IO.FileStream(filepath + ".cpp", IO.FileMode.Create))
While Not sr.EndOfStream
line = sr.ReadLine()
If line.Length > 0 Then
sw.WriteLine(line)
End If
End While
End Using
End Using
End Sub
The implementation has two issues in its current form. The first is that changing the compiler property on the file causes the project file to change, which in turn requires checking out the project file and probably re-linking the project. The second is that the macro always rebuilds the preprocessed file even when there is no need to. I will post a follow-up, solving both of these issues.
Comments
- Anonymous
January 12, 2007
I can't seem to get this to work for me. When I run RunPreprocessor(), I get an error that filecompiler "is not set to an instance of an object."Things that I can think of that might be relevant are that the file has no file-specific customization, and that inherited project sheets are in use.I verified that activeconfigname was indeed the name of the active project, vcfile.Name was the name of the file, and that the file is compiled in that configuration (and all other configurations).Any ideas? This macro implements one of the features that I really miss from when emacs was my IDE.Thank you,Todd