Fenceposts
Environment: VisualStudio 6.0
The EPM text editor under OS/2 provided a macro facility not unlike that in DevStudio, which meant that before it had been around for long, a number of really useful macros started popping up on internet sites that catered to OS/2 users. One particular set of macros that I have really been missing since moving off of that platform is called "Fenceposts" (though I am not entirely sure that was the original name). The family of DevStudio macros presented here, duplicates this feature.
So what's a fencepost?
A fencepost contains a filename and cursor position (row and column coordinates) within the active document of your current DevStudio project. That is, it completely describes a location within your sourcecode. Fenceposts can be planted, and they can be pulled. Planting a fencepost saves this location information within the fencepost stack. Pulling a fencepost then returns the editor to the most recently planted fencepost, activating and opening documents as necessary, and removes that information from the stack.
I find this kind of sourcecode navigation very useful, especially in a deeply nested class hierarchy.
'------------------------------------------------------------------------------
'FILE DESCRIPTION: Provide a stack for storing edit locations
'
'NOTES:
'* Access to the postfile is very rudimentary -- the file is
' read completely, modified and rewritten when posts are
' added or removed. There is probably a better way, but that
' was the first method I found.
'* I would like to add a 'Beep' when PullFencepost has nothing
' to do, but DevStudio provides no way to do this that I know
' of.
'------------------------------------------------------------------------------
Sub SetDefaultFencepostKeyBindings()
'DESCRIPTION: Setup default key mappings for fencepost macros.
'This is simply an installation routine
AddKeyBinding "Ctrl+Shift+NumPad Clear", "ClearFencepostStack", "Text"
AddKeyBinding "Ctrl+Shift+Down Arrow", "PlantFencepost", "Text"
AddKeyBinding "Ctrl+Shift+Up Arrow", "PullFencepost", "Text"
End Sub
Function postfilePathname()
'DESCRIPTION: File where fenceposts are stored.
'The postfile lives in the ActiveProject directory, so the
'pathname is built from that.
str = Application.ActiveProject.FullName
pos = InStrRev(str, "\")
str = Left(str, pos)
postfilePathname = str + "_postfile.dat"
End Function
Sub PlantFencepost()
'DESCRIPTION: Save current location on an in-file stack for later.
'Access the filesystem
Set fso = CreateObject("Scripting.FileSystemObject")
fencepostfile = postfilePathname()
'If postfile exists, read into block
If (fso.fileexists(fencepostfile)) Then
Set f = fso.GetFile(fencepostfile)
Set a = f.OpenAsTextStream(1)
If f.Size > 0 Then
block = a.readall
End If
a.Close
End If
'Build Fencepost
fencepost = ActiveDocument.FullName _
+ "(" + CStr(ActiveDocument.Selection.CurrentLine) _
+ ":" + CStr(ActiveDocument.Selection.CurrentColumn) _
+ ")"
'Prepend fencepost to fencepost block
block = fencepost + vbNewLine + block
'Write the block to file
Set a = fso.CreateTextFile(fencepostfile, True)
a.write (block)
a.Close
End Sub
Sub PullFencepost()
'DESCRIPTION: Retrieve a previous location from the in-file stack.
'Access the filesystem
Set fso = CreateObject("Scripting.FileSystemObject")
fencepostfile = postfilePathname()
'If the file exists...
If (fso.fileexists(fencepostfile)) Then
Set f = fso.GetFile(fencepostfile)
Set a = f.OpenAsTextStream(1)
'...and if there are records to read
If f.Size > 0 Then
'Read the file
block = a.readall
pos = InStr(block, vbNewLine)
Line = Left(block, pos)
block = Mid(block, pos + 2)
a.Close
'Write the modified fencepost block
Set a = fso.CreateTextFile(fencepostfile, True)
a.write (block)
a.Close
'If there is anything in the line
If Len(Line) > 0 Then
'Parse the line into something like:
'fname(lineNum,ColNum)
pos = InStr(Line, "(")
fname = Left(Line, pos - 1)
Line = Mid(Line, pos + 1)
pos = InStr(Line, ":")
lineNum = CInt(Left(Line, pos - 1))
Line = Mid(Line, pos + 1)
pos = InStr(Line, ")")
colNum = CInt(Left(Line, pos - 1))
'Open or surface the given document
Set doc = Documents.open(fname)
'Move to the proper location
doc.Selection.moveTo lineNum,colNum
'moving the cursor around gives us some
'context around our post location
doc.Selection.lineDown dsMove,3
doc.Selection.lineUp dsMove,6
'Move to the proper location again
doc.Selection.moveTo lineNum,colNum
End If
End If
End If
End Sub
Sub ClearFencepostStack()
'DESCRIPTION: Remove all entries from the fencepost stack
Set fso = CreateObject("Scripting.FileSystemObject")
fencepostfile = postfilePathname()
Set a = fso.CreateTextFile(fencepostfile, True)
a.Close
MsgBox "Fenceposts cleared"
End Sub

Comments
There are no comments yet. Be the first to comment!