Friday, March 27, 2009

Add new line at end of file.

Working on a cross platform c++ project I find it annoying that Linux requires a new line at the end of each file. I constantly forget to do this.

I wrote this simple macro which will add the new line each time you save a file.

You don't need the whole thing. Most of this is generated in EnvironmentEvents but saved here for posterity.



Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module EnvironmentEvents

#Region "Automatically generated code, do not modify"
'Automatically generated code, do not modify
'Event Sources Begin
Public WithEvents DTEEvents As EnvDTE.DTEEvents
Public WithEvents DocumentEvents As EnvDTE.DocumentEvents
Public WithEvents WindowEvents As EnvDTE.WindowEvents
Public WithEvents TaskListEvents As EnvDTE.TaskListEvents
Public WithEvents FindEvents As EnvDTE.FindEvents
Public WithEvents OutputWindowEvents As EnvDTE.OutputWindowEvents
Public WithEvents SelectionEvents As EnvDTE.SelectionEvents
Public WithEvents BuildEvents As EnvDTE.BuildEvents
Public WithEvents SolutionEvents As EnvDTE.SolutionEvents
Public WithEvents SolutionItemsEvents As EnvDTE.ProjectItemsEvents
Public WithEvents MiscFilesEvents As EnvDTE.ProjectItemsEvents
Public WithEvents DebuggerEvents As EnvDTE.DebuggerEvents
Public WithEvents ProjectsEvents As EnvDTE.ProjectsEvents
Public WithEvents TextDocumentKeyPressEvents As EnvDTE80.TextDocumentKeyPressEvents
Public WithEvents CodeModelEvents As EnvDTE80.CodeModelEvents
Public WithEvents DebuggerProcessEvents As EnvDTE80.DebuggerProcessEvents
Public WithEvents DebuggerExpressionEvaluationEvents As EnvDTE80.DebuggerExpressionEvaluationEvents
'Event Sources End
'End of automatically generated code
#End Region




Private Sub DocumentEvents_DocumentOpened(ByVal Document As EnvDTE.Document) Handles DocumentEvents.DocumentOpened

End Sub

Private Sub DocumentEvents_DocumentSaved(ByVal Document As EnvDTE.Document) Handles DocumentEvents.DocumentSaved

Dim textSelection As EnvDTE.TextSelection

textSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
textSelection.EndOfDocument(True)
textSelection.EndOfLine()
If textSelection.Text <> vbCrLf Then
textSelection.Text = textSelection.Text & vbCrLf
End If



End Sub
End Module

Visual Studio Macros for source control.

Visual Studio allows for users to customize the environment by writing macros. With Visual Studio 2008 the macros can be written in VB.Net. VB.Net is a very powerful language as it can use any of the standard .NET object, and in addition it has access to Visual Studios ENVDTE object.

The following set of macros replace the buggy Perforce source control plugin.


Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module MiscCommands
Sub P4Add()
Dim filename As String = DTE.ActiveWindow.Document.FullName
ChDir("c:\p4")
ExecuteCommand("p4.exe", "add " + filename)
End Sub

Sub P4Edit()
Dim filename As String = DTE.ActiveWindow.Document.FullName
ChDir("c:\p4")
ExecuteCommand("p4.exe", "edit " + filename)
End Sub

Sub P4Diff()
Dim filename As String = DTE.ActiveWindow.Document.FullName
ChDir("c:\p4")
ExecuteCommand("p4.exe", "diff " + filename)
End Sub

Sub P4Revert()
Dim filename As String = DTE.ActiveWindow.Document.FullName
ChDir("c:\p4")
ExecuteCommand("p4.exe", "revert " + filename)
End Sub

Sub P4Opened()
ChDir("c:\p4")
ExecuteCommand("p4.exe", "opened")
End Sub

Sub P4History()
Dim filename As String = DTE.ActiveWindow.Document.FullName
ChDir("c:\p4")
ExecuteCommand("p4.exe", "filelog " + filename)
End Sub

Public Sub ExecuteCommand(ByVal filename As String, ByVal arguments As String)

Dim p As New System.Diagnostics.Process
p.StartInfo.UseShellExecute = False
p.StartInfo.FileName = filename
p.StartInfo.Arguments = arguments
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.Start()
p.WaitForExit()


WriteToMyNewPane(filename + " " + arguments, p.StandardOutput.ReadToEnd + p.StandardError.ReadToEnd)


End Sub

Public Sub WriteToMyNewPane(ByVal command As String, ByVal results As String)
Dim win As Window = _
DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
Dim ow As OutputWindow = win.Object
Dim owPane As OutputWindowPane
Dim cnt As Integer = ow.OutputWindowPanes.Count
owPane = ow.OutputWindowPanes.Item(1)
owPane.OutputString(command & vbCrLf)
owPane.OutputString(results & vbCrLf)
owPane.Activate()
End Sub


Sub OpenFile()
Dim fileName As String = InputBox("Open file:")
If String.IsNullOrEmpty(fileName) Then
Return
End If
Dim item As EnvDTE.ProjectItem = DTE.Solution.FindProjectItem(fileName)
If item Is Nothing Then
MsgBox("File not found", MsgBoxStyle.Exclamation)
Return
End If
item.Open()
item.Document.Activate()
End Sub

End Module