Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: docs/windows_visual_studio_macros.md

Issue 1309473002: WIP: Migrate Wiki content over to src/docs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Random Visual Studio macros
2
3
4
5 The following macros can aid your workflow under the full (non-Express, i.e. pai d) versions of Visual Studio 2010 and earlier. Unfortunately, Visual Studio 2012 and later <a href='http://social.msdn.microsoft.com/Forums/vstudio/en-US/d84108 38-085b-4647-8c42-e31b669c9f11/macros-in-visual-studio-11-developer-preview?foru m=vsx'>do not support macros</a>. You should try <a href='http://chromium.github .io/vs-chromium/'>the <b>vs-chromium</b> Visual Studio Extension which provides similar functionality</a>.
Bons 2015/08/20 20:16:51 delete since all builds are with ninja, now.
6
7 Note: Syntax highlighting is wrong, there's nothing to do about it.
8
9 ## How to install one
10 * Verify that you have the non-Express version of Visual Studio 2010 or earlie r
11 * Menu: Tools, Macros, Macro Explorer
12 * Double click on `MyMacros`
13 * Double click on `Module1`, that will open the Macros editor
14 * Paste whatever code you want there inside the `Module` section. You may want to create one module per macro to keep it sane.
15
16
17 ## How to bind
18 Once you've added a macro, you can double click it in the Macro Explorer to exec ute it, but it's often convenient to bind it.
19 * Keyboard
20 * Menu Tools, Options
21 * Navigate to Environment, Keyboard
22 * Type `MyMacros` or your macro name, select the one you want.
23 * Press the key to bind in the bottom, press Assign.
24 * Toolbar
25 * Menu Tools, Customize
26 * Tab Commands
27 * Select `Macros` on the left
28 * Drag the macro name on the right to a toolbar
29 * The text will be awfully long, right click on the new button and edit the Name property
30
31
32 ## Automatically grab chromium child processes
33
34 Hint: Bind `AttachChromium()` to a toolbar button and enable the "Debug Location " toolbar to navigate between processes.
35 ```
36 Public Sub AttachToProcesses(ByVal process_name As String, ByVal AttachIfCmdLine Contains As String)
37 ' Attaches to a process by its name. If a command line argument is neede d, looks for it.'
38 Dim pids As New System.Collections.Generic.List(Of Integer)
39 Dim pids_debugged As New System.Collections.Generic.List(Of Integer)
40 For Each debugged As EnvDTE.Process In DTE.Debugger.DebuggedProcesses
41 pids_debugged.Add(debugged.ProcessID)
42 Next
43 Dim processes As System.Diagnostics.Process() = System.Diagnostics.Proce ss.GetProcessesByName(process_name)
44 For Each proc As System.Diagnostics.Process In processes
45 If proc.MainModule.FileName().ToLower().Contains(AttachIfCmdLine Contains.ToLower()) Then
46 pids.Add(proc.Id)
47 End If
48 Next
49 For Each proc As EnvDTE.Process In DTE.Debugger.LocalProcesses
50 If Not pids_debugged.Contains(proc.ProcessID) And pids.Contains( proc.ProcessID) Then
51 proc.Attach()
52 End If
53 Next
54 End Sub
55
56 Sub AttachChromium()
57 ' Attaches to the chrome.exe processes that has \code\ in their command line'
58 ' argument or binary path.'
59 AttachToProcesses("chrome", System.IO.Path.GetDirectoryName(System.IO.Pa th.GetDirectoryName(DTE.Solution.FullName)) & "\build\")
60 End Sub
61 ```
62
63 Note that Visual Studio 2012 and later <a href='http://social.msdn.microsoft.com /Forums/vstudio/en-US/d8410838-085b-4647-8c42-e31b669c9f11/macros-in-visual-stud io-11-developer-preview?forum=vsx'>do not support macros</a>. The functionality of this macro is <a href='http://chromium.github.io/vs-chromium/#attach-to-chrom e'>included in the vs-chromium plug-in</a>.
64
65 ## Format comments to 80 cols
66
67 Hint: Bind `FormatComment()` to Alt-F.
68 ```
69 Sub FormatComment()
70 ' Make comments fit 80 cols.'
71 Dim sel As TextSelection = CType(DTE.ActiveDocument.Selection, TextSelec tion)
72 Dim text As String = sel.Text
73 Dim CommentMarker As String = "//"
74
75 ' InStr() is one-based'
76 Dim commentColumn As Integer = InStr(text, CommentMarker)
77 ' Substring() is zero-based'
78 Dim prefix As String = text.Substring(0, commentColumn - 1) + CommentMar ker + " "
79 ' Take in account the length of the comment marker and the space. The ma ximum is 81'
80 ' and not 80; column starts at 1 and not 0. InStr() is 1 based too.'
81 Dim maxline As Integer = 81 - commentColumn - CommentMarker.Length
82
83 ' Remove comment marker'
84 text = System.Text.RegularExpressions.Regex.Replace(text, "^ *// *", "", System.Text.RegularExpressions.RegexOptions.Multiline)
85 ' Remove \r\n to put all the text on one line'
86 text = System.Text.RegularExpressions.Regex.Replace(text, " *[" + vbLf + "]+ *", " ")
87 text = text.Trim()
88
89 Dim newtext As String = ""
90
91 While text <> ""
92 ' InStrRev() is one-based'
93 Dim pos As Integer = InStrRev(text, " ", maxline)
94 If pos = 0 Then
95 pos = text.Length
96 End If
97
98 ' Substring() is zero-based'
99 Dim line As String = text.Substring(0, pos).Trim()
100 newtext += prefix + line + vbLf
101 text = text.Substring(pos)
102 End While
103
104 sel.Insert(newtext, vsInsertFlags.vsInsertFlagsContainNewText)
105 End Sub
106 ```
107
108 Note that [clang-format can auto-format code (including comments) with excellent adherence to the Chromium style guide](ClangFormat.md). It is probably a better bet than the above macro.
109
110 ## Remove trailing white spaces
111 Add this sub to your EnvironmentEvents. When your .cc/.cpp/.c/.h is saved, trai ling white spaces are removed automatically. No longer need to worry about pres ubmit giving nits.
112
113 ```
114 Private Sub DocumentEvents_DocumentSaved(ByVal document As EnvDTE.Document) _
115 Handles DocumentEvents.DocumentSaved
116 Dim fileName As String
117 Dim result As vsFindResult
118
119 Try
120 fileName = document.Name.ToLower()
121
122 If fileName.EndsWith(".cc") _
123 Or fileName.EndsWith(".cpp") _
124 Or fileName.EndsWith(".c") _
125 Or fileName.EndsWith(".h") Then
126 ' Remove trailing whitespace'
127 result = DTE.Find.FindReplace( _
128 vsFindAction.vsFindActionReplaceAll, _
129 "{:b}+$", _
130 vsFindOptions.vsFindOptionsRegularExpression, _
131 String.Empty, _
132 vsFindTarget.vsFindTargetFiles, _
133 document.FullName, _
134 "", _
135 vsFindResultsLocation.vsFindResultsNone)
136
137 If result = vsFindResult.vsFindResultReplaced Then
138 ' Triggers DocumentEvents_DocumentSaved event again'
139 document.Save()
140 End If
141 End If
142 Catch ex As Exception
143 MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Trim White Space exception")
144 End Try
145 End Sub
146 ```
147
148 Note that [clang-format can auto-format code (including comments) with excellent adherence to the Chromium style guide](ClangFormat.md). It is probably a better bet than the above macro.
149
150 ## Alternate between source and header file
151
152 Hint: Bind `SwitchOfSourceFile()` to Alt-O.
153 ```
154 Function TryOpenProjectItem(ByVal project_items As ProjectItems, ByVal item As S tring) As Boolean
155 TryOpenProjectItem = False
156 If project_items Is Nothing Then
157 Exit Function
158 End If
159 For Each project_item As EnvDTE.ProjectItem In project_items
160 If Strings.StrComp(project_item.Name, item, CompareMethod.Text) = 0 Then
161 ' Found!'
162 project_item.Open().Activate()
163 TryOpenProjectItem = True
164 End If
165 If project_item.SubProject Is Nothing Then
166 TryOpenProjectItem = TryOpenProjectItem(project_item.Pro jectItems, item)
167 Else
168 TryOpenProjectItem = TryOpenProjectItem(project_item.Sub Project.ProjectItems, item)
169 End If
170 If TryOpenProjectItem = True Then
171 Exit Function
172 End If
173 Next
174 End Function
175
176 ' Will find the file if it is:'
177 ' - beside in the same directory,'
178 ' - in "opened documents",'
179 ' - in the same project'
180 ' - TODO(maruel): Try in includes?'
181 Public Function TryOpen(ByVal FileName As String, ByVal Path As String, ByVal pr oject As EnvDTE.Project) As Boolean
182 TryOpen = False
183 ' Try to open the file in same folder.'
184 Try
185 DTE.Documents.Open(Path + FileName, "Text")
186 TryOpen = True
187 Exit Function
188 Catch
189 End Try
190
191 ' Search document in the same project.'
192 If Not project Is Nothing Then
193 TryOpen = TryOpenProjectItem(project.ProjectItems, FileName)
194 End If
195
196 ' Search opened documents.'
197 For Each myDocument As EnvDTE.Document In DTE.Documents
198 If Strings.StrComp(myDocument.Name, FileName, CompareMethod.Text ) = 0 Then
199 Try
200 myDocument.Activate()
201 TryOpen = True
202 Exit Function
203 Catch
204 End Try
205 End If
206 Next
207 End Function
208
209 ' Shortcut.'
210 Public Function TryOpen(ByVal FilePathName As String) As Boolean
211 TryOpen = TryOpen(System.IO.Path.GetFileName(FilePathName), System.IO.Pa th.GetFullPath(FilePathName), Nothing)
212 End Function
213
214 ' Will cycle thru .cc, .cpp, .h and .inl file extensions'
215 Public Sub SwitchOfSourceFile()
216 ' For source looping. It\'s not extension in the true meaning.'
217 Dim supportedExts As String() = {"-inl.h", ".cc", ".cpp", ".h", ".hpp", ".inl"}
218
219 Dim origFile As String
220 Dim origFilePath As String
221 Dim project As EnvDTE.Project
222 Try
223 origFile = DTE.ActiveDocument.Name
224 origFilePath = DTE.ActiveDocument.Path
225 project = DTE.ActiveDocument.ProjectItem.ContainingProject
226 Catch
227 Exit Sub
228 End Try
229
230 ' This is touchy here because we want to support both ".h" and "-inl.h" so we have to find the right extension first.'
231 For indexExt As Integer = 0 To supportedExts.Length - 1
232 Dim ext As String = supportedExts(indexExt)
233 If origFile.Length > ext.Length Then
234 If origFile.Substring(origFile.Length - ext.Length) = ex t Then
235 Dim FileToOpen As String = origFile.Substring(0, origFile.Length - ext.Length)
236 ' Try the rest'
237 For indexTry As Integer = 0 To supportedExts.Len gth - 2
238 Dim trueIndex As Integer = (indexExt + i ndexTry + 1) Mod supportedExts.Length
239 If TryOpen(FileToOpen + supportedExts(tr ueIndex), origFilePath, project) Then
240 ' We succeeded'
241 Exit Sub
242 End If
243 Next
244 ' We failed.'
245 Exit For
246 End If
247 End If
248 Next
249 ' We failed.'
250 End Sub
251 ```
252
253
254 ## Run the currently selected google test
255 See the function's description.
256 ```
257 Sub RunCurrentGTest()
258 ' From the active source file, find the test that the user wants to run'
259 ' based on the current cursor position. Set the project containing this'
260 ' source file as the startup project, changes the command line to run'
261 ' only this test, compile the project and starts it under the debugger.'
262 ' Doesn\'t change any breakpoint.'
263 Dim ActiveDoc As Document = DTE.ActiveDocument
264
265 ' Try to guess the test to run.'
266 Dim TestGroup As String = ""
267 Dim TestName As String = ""
268 Dim selection As TextSelection = CType(ActiveDoc.Selection(), TextSelect ion)
269 Dim toppoint As EditPoint = selection.TopPoint.CreateEditPoint()
270 Dim bottompoint As EditPoint = selection.BottomPoint.CreateEditPoint()
271 Dim ranges As TextRanges = selection.TextRanges
272 Dim line As Integer = selection.TopPoint.Line
273 ' selection.FindPattern() is crummy.'
274 While line <> 0
275 selection.GotoLine(line)
276 selection.SelectLine()
277 Dim match As System.Text.RegularExpressions.Match = System.Text. RegularExpressions.Regex.Match(selection.Text, "TEST[_F]*\((.*),(.*)\)")
278 If Not match Is System.Text.RegularExpressions.Match.Empty Then
279 TestGroup = match.Groups.Item(1).Value.Trim()
280 TestName = match.Groups.Item(2).Value.Trim()
281 Exit While
282 End If
283 line = line - 1
284 End While
285 ' Cheap way to try to restore the old selection. Isn\'t 100% correct.'
286 selection.MoveToLineAndOffset(toppoint.Line, toppoint.LineCharOffset)
287 selection.MoveToLineAndOffset(bottompoint.Line, bottompoint.LineCharOffs et, True)
288
289 ' From the current active document, find the project and the active conf iguration.'
290 Dim Proj As Project = ActiveDoc.ProjectItem.ContainingProject
291 Dim config As Configuration = Proj.ConfigurationManager.ActiveConfigurat ion
292
293 ' Fix the command line argument.'
294 Dim CmdLine As EnvDTE.Property = config.Properties.Item("CommandArgument s")
295 If TestGroup <> "" Then
296 CmdLine.Value = "--gtest_filter=" & TestGroup & "." & TestName
297 Else
298 ' Run all'
299 CmdLine.Value = ""
300 End If
301
302 ' Set it as startup project.'
303 Dim SoluBuild As SolutionBuild = DTE.Solution.SolutionBuild
304 Dim StartupProject As String
305 StartupProject = Proj.UniqueName
306 SoluBuild.StartupProjects = StartupProject
307
308 ' Build it.'
309 SoluBuild.BuildProject(config.ConfigurationName, Proj.UniqueName, True)
310
311 ' Start it.'
312 DTE.Debugger.Go()
313 End Sub
314 ```
315
316 ## Add a definition in a .cc file for the currently selected method/variable dec larations.
317 Select a class method or member variable declaration, then run this macro to add empty definitions in the corresponding .cc file.
318 Hint: Bind AddDefinitionForSelectedDeclaration() to Alt-D
319 ```
320 Public Sub AddDefinitionForSelectedDeclaration()
321 ' Get the function declaration text.'
322 Dim sel As TextSelection = DTE.ActiveDocument.Selection
323 Dim text = sel.Text.Trim()
324
325 Dim className = ClassNameFinder()
326
327 Dim funcDef = text
328 ' Remove comments first, since they mess up the rest of the regexes.'
329 funcDef = Regex.Replace(funcDef, "//.*$", "", RegexOptions.Multiline)
330 ' Try to put declarations all on the same line.'
331 funcDef = Regex.Replace(funcDef, "([^;]) *\n *", "$1 ", RegexOptions.Singlel ine)
332 ' Replace the identifier with ClassName::identifier.'
333 funcDef = Regex.Replace(funcDef, "^(.*) ([^ ()]+;|[^ ()]+ *\()", _
334 "$1 " + className + "::$2", RegexOptions.Multili ne)
335 ' Convert ; to {} for functions.'
336 funcDef = Regex.Replace(funcDef, "\) *;", ") {" + vbLf + "}" + vbLf)
337 ' Remove leading whitespace, static/virtual.'
338 funcDef = Regex.Replace(funcDef, "^ *", "", RegexOptions.Multiline)
339 funcDef = Regex.Replace(funcDef, "static *", "// static" + vbLf)
340 funcDef = Regex.Replace(funcDef, "virtual *", "")
341 ' Collapse empty lines.'
342 funcDef = Regex.Replace(funcDef, vbLf + vbLf + "+", vbLf + vbLf)
343
344 ' Switch to source file and append defs at the end.'
345 GoToCCFile()
346 sel = DTE.ActiveDocument.Selection
347 sel.EndOfDocument()
348 sel.Insert(funcDef)
349 End Sub
350
351 ' If the current document is an .h file, try to switch to the .cc file of the sa me name.'
352 Sub GoToCCFile()
353 Dim origFile = DTE.ActiveDocument.FullName()
354 If Regex.IsMatch(origFile, "\.h$") Then
355 Dim altFile = Regex.Replace(origFile, "\.h$", ".cpp")
356 If Not My.Computer.FileSystem.FileExists(altFile) Then
357 altFile = Regex.Replace(origFile, "\.h$", ".cc")
358 End If
359 DTE.Documents.Open(altFile, "Text")
360 End If
361 End Sub
362
363 ' Finds which class the cursor is inside of, and returns the class name.'
364 ' Note: This is indent based. Your class bodies must be indented, and the closi ng'
365 ' "};" must line up with the initial "class".'
366 ' ex: class Foo {\nclass Bar {\n <cursor>...'
367 ' returns: "Foo::Bar"''
368 Private Function ClassNameFinder() As String
369 Dim sel As TextSelection = DTE.ActiveDocument.Selection
370 Dim origPos = sel.ActivePoint.AbsoluteCharOffset
371 Dim endLine = sel.CurrentLine
372
373 sel.MoveToAbsoluteOffset(1, True)
374 Dim pos = 0
375 Dim text = sel.Text
376 Dim className = ClassNameFinderInternal(text)
377 sel.MoveToAbsoluteOffset(origPos)
378
379 If className.Length > 0 Then
380 className = className.Substring(2)
381 End If
382 Return className
383 End Function
384
385 ' Helper function for ClassNameFinder. Returns the full class name that doesn\' t'
386 ' have matching close braces in the given text string.'
387 Private Function ClassNameFinderInternal(ByRef text As String) As String
388 Dim className = ""
389 While text.Length > 0
390 Dim match = Regex.Match(text, "^( *)class ([^ \n\r{:;]+)[^\n\r;]*$", Reg exOptions.Multiline)
391 If match.Success Then
392 Dim indentString = match.Groups.Item(1).Value
393 Dim newClass = "::" + match.Groups.Item(2).Value
394 text = text.Substring(match.Index + match.Length)
395
396 match = Regex.Match(text, "^" + indentString + "};", RegexOptions.Mu ltiline)
397 If match.Success Then
398 text = text.Substring(match.Index + match.Length)
399 Else
400 className += newClass + ClassNameFinderInternal(text)
401 End If
402 Else
403 text = ""
404 Exit While
405 End If
406 End While
407
408 Return className
409 End Function
410
411
412 ```
413
414 ## Open all the files of a given change list.
415 Specify which change list you want to open all files of, and this macro will fin d it if it lies in the same svn repository as the currently opened solution. If it can't find it there, it will prompt you to specify the path of the root of yo ur client view.
416
417 ```
418 Sub OpenChangeListFiles()
419 ' Open all the files of a given change list.'
420 Dim change_list_name As String = InputBox("Enter the change list name." + vb NewLine + "(with an optional repo folder path prefix)")
421 If String.IsNullOrEmpty(change_list_name) Then
422 Exit Sub
423 End If
424 Dim solution As Solution = DTE.Solution
425 ' Try to get the source root path starting from the solution path and search upward in the folder hierarchy.'
426 Dim source_root_path As String
427 If Not solution Is Nothing And Not String.IsNullOrEmpty(solution.FullName) T hen
428 source_root_path = GetRepositoryRootFolder(solution.FullName)
429 End If
430 If source_root_path Is Nothing Or String.IsNullOrEmpty(source_root_path) The n
431 ' We couldn\'t find the root ourselves, ask the user.'
432 source_root_path = InputBox("Can't find a solution file path." + vbNewLi ne + "Please specify the root of your source tree.")
433 If String.IsNullOrEmpty(source_root_path) Then
434 Exit Sub
435 End If
436 End If
437    ' If we provided one or more \ in change_list_name, we want to check a subdi rectory of the root path.'
438    ' This is useful if we have another repository in our solution.'
439    Dim change_list_path() As String = Split(change_list_name, "\")
440    If change_list_path.Length > 1 Then
441        source_root_path += "\" + String.Join("\", change_list_path, 0, change_l ist_path.Length - 1)
442        change_list_name = change_list_path(change_list_path.Length - 1)
443    End If
444 ' Look for the CL file in the appropriate folder.'
445 Dim change_list_file As String = source_root_path + "\.svn\gcl_info\changes\ " + change_list_name
446 If Not IO.File.Exists(change_list_file) Then
447 ' OK, give one last chance to the user to specify the appropriate path f or the CL.'
448 source_root_path = InputBox("Can't find CL: '" + change_list_name + "', under " + source_root_path + vbNewLine + "Specify the proper root folder one las t time:")
449 If String.IsNullOrEmpty(source_root_path) Then
450 Exit Sub
451 End If
452 change_list_file = source_root_path + "\.svn\gcl_info\changes\" + change _list_name
453 If Not IO.File.Exists(change_list_file) Then
454 MsgBox("Can't find CL: '" + change_list_name + "', under " + source_ root_path)
455 Exit Sub
456 End If
457 End If
458 ' Now load its content.'
459 Dim change_list_content As String
460 Try
461 change_list_content = IO.File.ReadAllText(change_list_file, Text.Encodin g.GetEncoding(1252))
462 Catch e As Exception
463 MsgBox("Exception: " + e.Message())
464 Exit Sub
465 End Try
466 ' Match the lines where the paths of the opened files can be found.'
467 Dim pattern As String = "M\s*(.*)$"
468 Dim regex As New Text.RegularExpressions.Regex(pattern, Text.RegularExpressi ons.RegexOptions.Multiline)
469 Dim matches As Text.RegularExpressions.MatchCollection = regex.Matches(chang e_list_content)
470 Dim match
471 For Each match In matches
472 ' And now we can open each and everyone of them.'
473 Dim file_path As String = match.Groups(1).ToString()
474 Dim full_path As String = source_root_path + "\" + Left(file_path, file_ path.Length() - 1)
475 If IO.File.Exists(full_path) Then
476 DTE.ItemOperations.OpenFile(full_path)
477 End If
478 Next
479 End Sub
480
481 Private Function GetRepositoryRootFolder(ByVal solution_path As String) As Strin g
482 Try
483 ' We look for a change in the svn: root path in the .svn/entries file.'
484 ' This means we have reached view root or changed repo.'
485 Dim solution_folder As String = IO.Directory.GetParent(solution_path).To String()
486 Dim svn_root_path As String = GetSvnRootPath(solution_folder)
487 If String.IsNullOrEmpty(svn_root_path) Then
488 ' We don'\t seem to be within a repo if we can\'t get the SVN root p ath.'
489 Return ""
490 End If
491 ' We need to keep the previous path, since we need to stop once we found a bad parent.'
492 Dim previous_path As String = solution_folder
493 While True
494 Dim next_path As String = IO.Directory.GetParent(previous_path).ToSt ring()
495 Dim current_svn_root_path As String = GetSvnRootPath(next_path)
496 ' As long as we have the same svn root path, we are in the same repo , continue.'
497 If current_svn_root_path = svn_root_path Then
498 previous_path = next_path
499 Else
500 Exit While
501 End If
502 End While
503 Return previous_path
504 Catch e As Exception
505 MsgBox("Exception: " + e.Message())
506 End Try
507 Return Nothing
508 End Function
509
510 Private Function GetSvnRootPath(ByVal client_path As String) As String
511 ' First make sure we are within a repo.'
512 Dim svn_folder As String = client_path + "\.svn"
513 If Not IO.Directory.Exists(svn_folder) Then
514 Return ""
515 End If
516 ' Then there MUST be an entries file in there.'
517 Dim entries_file As String = svn_folder + "\entries"
518 If Not IO.File.Exists(entries_file) Then
519 Return ""
520 End If
521 ' Read the content of the file and find the svn root, and return it.'
522 Dim entries_content As String = IO.File.ReadAllText(entries_file, Text.Encod ing.GetEncoding(1252))
523 Dim pattern As String = "svn:(.*)$"
524 Dim regex As New Text.RegularExpressions.Regex(pattern, Text.RegularExpressi ons.RegexOptions.Multiline)
525 Dim matches As Text.RegularExpressions.MatchCollection = regex.Matches(entri es_content)
526 Return matches.Item(1).ToString()
527 End Function
528
529
530 ```
531
532
533 ## Only build startup project
534
535 Stolen from Boris, thanks!
536 ```
537 Sub BuildStartupProject()
538 Dim sb As SolutionBuild = DTE.Solution.SolutionBuild
539 Dim projName As String = sb.StartupProjects(0)
540 DTE.ExecuteCommand("View.Output")
541 sb.BuildProject(sb.ActiveConfiguration.Name, projName, False)
542 End Sub
543 ```
544
545
546 ## Use WinDbg as your debugger
547 I fully regret writing this macro as it didn't pass the "time wasted to write it "/"utility" ratio. But I'm really too proud.
548
549 ```
550 Sub WinbgStartupProject()
551 ' Use the right one:
552 Dim windbg As String = "C:\program files\Debugging Tools for Windows (x86)\w indbg.exe"
553 'Dim windbg As String = "C:\program files\Debugging Tools for Windows (x64)\ windbg.exe"
554
555 Dim project_name As String = CType(DTE.Solution.SolutionBuild.StartupProject s(0), String)
556 Dim project As EnvDTE.Project = FindProjects(DTE.Solution.Projects, project_ name)
557 Dim config As Configuration = project.ConfigurationManager.ActiveConfigurati on
558 ' Hack to remove file:///
559 Dim target_path As String = config.OutputGroups.Item(1).FileURLs(0).ToString ().Remove(0, 8)
560 Dim arguments As String = config.Properties.Item("CommandArguments").Value
561 'MsgBox(windbg & " -o " & target_path & " " & arguments)
562 System.Diagnostics.Process.Start(windbg, "-o " & target_path & " " & argumen ts)
563 End Sub
564
565 Function FindProjectItems(ByVal project_items As EnvDTE.ProjectItems, ByVal proj ect_name As String) As EnvDTE.Project
566 FindProjectItems = Nothing
567 For Each project_item As EnvDTE.ProjectItem In project_items
568 If Not project_item.SubProject Is Nothing Then
569 FindProjectItems = FindProject(project_item.SubProject, project_name )
570 If Not FindProjectItems Is Nothing Then Exit Function
571 End If
572 Next
573 End Function
574
575 Function FindProject(ByVal project As EnvDTE.Project, ByVal project_name As Stri ng) As EnvDTE.Project
576 If project.UniqueName = project_name Then
577 FindProject = project
578 Exit Function
579 End If
580 If Not project.ProjectItems Is Nothing Then
581 FindProject = FindProjectItems(project.ProjectItems, project_name)
582 If Not FindProject Is Nothing Then Exit Function
583 End If
584 End Function
585
586 Function FindProjects(ByVal projects As EnvDTE.Projects, ByVal project_name As S tring) As EnvDTE.Project
587 ' You never thought it'd be so complex to find a project. The VS extensibili ty team
588 ' stole me an hour of my life I will never get back.
589 FindProjects = Nothing
590 For Each project As EnvDTE.Project In projects
591 FindProjects = FindProject(project, project_name)
592 If Not FindProjects Is Nothing Then Exit Function
593 Next
594 End Function
595 ```
596
597
598 ## Indent to open-paren on line-wrap
599
600 This macro is slightly different than the rest. You'll need to put it in your En vironmentEvents project rather than Module, since it runs on every keypress.
601
602 What it does is indent your cursor up to the level of the open-paren on the prev ious line when you hit Enter.
603
604 ```
605 Public Sub keypress(ByVal key As String, ByVal sel As TextSelection, ByVal c ompletion As Boolean, ByRef cancel As Boolean) _
606 Handles TextDocumentKeyPressEvents.BeforeKeyPress
607 If (Not completion And key = vbCr) Then
608 Dim textDocument As TextDocument = DTE.ActiveDocument.Object("TextDo cument")
609 Dim startPoint As EditPoint = textDocument.StartPoint.CreateEditPoin t()
610 startPoint.MoveToLineAndOffset(sel.ActivePoint.Line, 1)
611 Dim text = startPoint.GetText(sel.ActivePoint.LineCharOffset - 1)
612 Dim pos = findUnclosedParenIndent(text)
613
614 If pos <> -1 Then
615 Dim commentPos = text.IndexOf("//")
616 If commentPos = -1 Or commentPos > pos Then
617 sel.Insert(vbLf)
618 sel.DeleteWhitespace()
619 sel.PadToColumn(pos + 2)
620 cancel = True
621 End If
622 End If
623 End If
624 End Sub
625
626 Public Function findUnclosedParenIndent(ByRef text As String) As Integer
627 findUnclosedParenIndent = -1
628
629 Dim parens As Char() = "()".ToCharArray()
630 Dim lastPos = text.Length
631 Dim numClosed = 0
632
633 While True
634 Dim pos = text.LastIndexOfAny(parens, lastPos - 1)
635
636 If pos = -1 Then
637 Exit While
638 End If
639
640 If text(pos) = ")" Then
641 numClosed += 1
642 Else
643 If numClosed = 0 Then
644 findUnclosedParenIndent = pos
645 Exit While
646 End If
647 numClosed -= 1
648 End If
649
650 lastPos = pos
651 End While
652 End Function
653 ```
654
655 ## Add other useful macros here
656 Feel free to edit this page to add other useful macros.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698