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

  • Sounds real useful, but could we...

    Posted by Legacy on 07/09/1999 12:00am

    Originally posted by: James White

    The idea sounds good and I while I'm not familiar with Bookmarks, I don't think they persist like fenceposts do. One thing I would like to see though is a navigation command that doesn't remove a fencepost, so I can move along the fence one way or another but leave it intact.

    Reply
  • It Don'T work fo me...

    Posted by Legacy on 07/08/1999 12:00am

    Originally posted by: d_wzrdv_z


    THIS macro file contained the following error and will be unloaded:

    Line 15: ActiveX component can't create object: 'Scripting.FileSystemObject'

    Would you like to edit the file?

    OZ-2000
    O O O
    O O

    \_|_|_|_/
    oOOOOOo
    (*^@ @^*)
    | O |
    \&_&/
    __-__
    /?;|;?\

    D_WZRDV_Z

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds