Welcome to Foxite.COM Community Weblog Sign in | Join | Help
<November 2006>
SuMoTuWeThFrSa
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

Post Categories

Navigation

Syndication




cute little tool making you productive

I use this tool for quite a while now. VariSense it is called. So what it does is simple but increases your productivity a lot.

When starting VFP it does start the prg as a typical "on key label" thing.
I personally use ctrl+SPACE for this.

So, here is a sample.

I am in a codesnippet and I declared two variables, as in:

Local lcString as string, lcString2 as string

Any further in the code I type "lc" and then press ctrl+SPACE. VariSense then immediately fills the string up to lcString (common denominator for both variables), pressing CTRL+SPACE again brings up a small popup that has both variables in it. navigating to either one and pressing enter does bring up the right name (even in the case you declared it.)

Another sample:
In the code I have a #DEFINE somevar Value

I also have #INCLUDE MyHeaderFile.h, in that file I have another #DEFINE like

DEFINE somevar2 AnotherValue

In the codesnippet I type "some" and press CTRL+SPACE.

varisense fills that up to somevar, typing ctrl+space again brings up a list of DEFINE'd variables from which you can take a pick;

Here's the code:

********************************************************************************

* Title: VariSense 1.2

* Author: Derek J. Kalweit(dkalweit@sensiblesoftware.com)

* Description: This program belongs under an "ON KEY LABEL" in your development

* environment. When triggered, it will automatically consult your declared

* variables and determine what it can do to complete it for you if possible.

* This can lead to a huge savings in typing, particularly if you routinely use

* long, clear variables with very unique names. This is the functionality

* available with a CTRL+SPACEBAR key combination in VC++, though VC++ is smart

* enough to do this with member variables and functions as well(which this is

* not).

* Terms of use: Freeware. Feel free to use and modify for your needs. Send me

* any useful/interesting enhancements so that I may include them in the main

* version, if appropriate.

********************************************************************************

* Version History:

* 1.2(Released 2003-2-28):

* o Adds support for "DIMENSION" arrays

* o Adds support for function parameters defined in parenthesis versus LPARAMETERS statement

* 1.1(Released 2002-10-18):

* o Added drop-down menu to pick ambigious variables

* 1.0(Released 2002-10-8):

* o Original release

********************************************************************************

* Special Thanks to:

* Ed leafe(ed@leafe.com):

* Contributed code to add drop-down menu for ambiguous variables

* Bo Durban(wdurban@datascantech.com):

* Contributed EditPos() function to get cursor position for drop-down menu

********************************************************************************

SET ECHO OFF

#DEFINE VARIABLE_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTYUVWXYZ0123456789_"

SET LIBRARY TO (SYS(2004) + "FoxTools.fll") && foxtools is always in the foxpro dir, right?

DECLARE INTEGER Beep IN KERNEL32 AS Beep INTEGER nFrequecy, INTEGER nDuration

LOCAL hwndCode, laEnv[25]

LOCAL cVariables

LOCAL cProgText, iLastLine, aProgText[1], iLine, cLine

LOCAL liStartParen, liEndParen

LOCAL iOffset

LOCAL aVars[1], y

LOCAL cDeclaredVar

LOCAL cNewVar

LOCAL cChoice, nRow, nCol, iMatch, cOnSelect

hwndCode = _WonTop()

IF 1 == _EdGetEnv(hwndCode, @laEnv) Then

IF 0 == laEnv[12] && AND INLIST(laEnv[25], 0, 1, 8, 10, 12) Then

LOCAL iPos, cVar, aMatches[1], iMatches

iMatches = 0

iPos = laEnv[17]

cVar = GetVariable(@hwndCode, @iPos)

IF NOT EMPTY(cVar) then

*-- get all code from the beginning to our current cursor position, as we care about nothing more.

cProgText = _EdGetStr(hwndCode, 0, iPos)

iLastLine = ALINES(aProgText, cProgText)

FOR iLine = iLastLine TO 1 STEP -1

cVariables = ""

cLine = WSTRIM(aProgText[iLine])

DO CASE

CASE "LOCAL " == UPPER(LEFT(cLine, 6)) AND "ARRAY " == SUBSTR( UPPER(cLine),7,6)

cVariables = WSTRIM(SUBSTR(cLine, 13))

CASE "LOCAL " == UPPER(LEFT(cLine, 6))

cVariables = WSTRIM(SUBSTR(cLine, 7))

CASE "PROC" == UPPER(LEFT(cLine, 4))

EXIT

CASE "FUNCTION " == UPPER(LEFT(cLine, 9))

liStartParen = AT("(", cLine)

liEndParen = AT(")", cLine)

IF liStartParen > 0 AND liEndParen > liStartParen Then

cVariables = WSTRIM(SUBSTR(cLine, liStartParen+1, liEndParen-liStartParen-1))

iLine = 0 && This forces the loop to exit after it does the dirty work...

ELSE

EXIT

ENDIF

CASE "LPARAMETERS " == UPPER(LEFT(cLine, 12))

cVariables = WSTRIM(SUBSTR(cLine, 13))

CASE "PARAMETERS " == UPPER(LEFT(cLine, 11))

cVariables = WSTRIM(SUBSTR(cLine, 12))

CASE "PRIVATE " == UPPER(LEFT(cLine, 8))

cVariables = WSTRIM(SUBSTR(cLine, 9))

CASE "PUBLIC " == UPPER(LEFT(cLine, 7)) AND UPPER(GETWORDNUM(cLine,2)) <> "ARRAY"

cVariables = WSTRIM(GETWORDNUM(cLine, 2))

CASE "PUBLIC " == UPPER(LEFT(cLine, 7)) AND UPPER(GETWORDNUM(cLine,2)) == "ARRAY"

cVariables = WSTRIM(GETWORDNUM(cLine, 3))

CASE "DIMENSION " == UPPER(LEFT(cLine, 10))

cVariables = WSTRIM(SUBSTR(cLine, 11))

CASE "#DEFINE " == UPPER(LEFT(cLine, 8))

cVariables = ReadDefines(cLine)

CASE "DECLARE " == UPPER(LEFT(cLine, 8))

IF INLIST( UPPER(GETWORDNUM(cLine,2)), "SHORT", "INTEGER", "SINGLE", "LONG", "STRING", "OBJECT")

cVariables = WSTRIM(GETWORDNUM(cLine, 3))

ELSE

cVariables = WSTRIM(GETWORDNUM(cLine, 2))

ENDIF

CASE "#INCLUDE " == UPPER(LEFT(cLine, 9))

 

**** Code for ReadInclude taken away here

lcFile2open = GETWORDNUM(cLine,2)

IF FILE( (lcFile2Open) )

ALINES( laINCL, FILETOSTR( lcFile2Open),.T.,CHR(13)+CHR(10))

FOR lnItemsInArray = 1 TO ALEN( laINCL,1)

cVariables = WSTRIM( GETWORDNUM( laINCL[lnItemsInArray], 2))

IF UPPER(cVar) == SUBSTR(UPPER(cVariables), 1, LEN(cVar)) Then

* Add Match to list

iMatches = iMatches + 1

DIMENSION aMatches[iMatches]

aMatches[iMatches] = cVariables

ENDIF

ENDFOR

ENDIF

ENDCASE

 

* addToArray(@cVariables, @aMatches, @avars, cVar)

* Let's handle multi-line definitions...

iOffset = 0

DO WHILE ";" == RIGHT(cVariables, 1)

iOffset = iOffset + 1

cVariables = LEFT(cVariables, LEN(cVariables)-1) + WSTRIM(aProgText[iLine+iOffset])

ENDDO

 

FOR y = 1 TO ASPLIT(@aVars, cVariables, ",")

cDeclaredVar = WSTRIM(aVarsYes [Y])

IF " " $ cDeclaredVar Then && Don't include anything beyond the space; Strong-typing comes to mind

cDeclaredVar = LEFT(cDeclaredVar, AT(" ", cDeclaredVar)-1)

ENDIF

IF CHR(9) $ cDeclaredVar Then && Don't include anything beyond the tab

cDeclaredVar = LEFT(cDeclaredVar, AT(CHR(9), cDeclaredVar)-1)

ENDIF

IF "[" $ cDeclaredVar Then && Don't include anything beyond the array subscript; We could set this up to include the array subscript, as it will be used most places...

cDeclaredVar = LEFT(cDeclaredVar, AT("[", cDeclaredVar)-1)

ENDIF

IF "(" $ cDeclaredVar Then && Don't include anything beyond the array subscript(some people use these parentheses for arrays!!!)

cDeclaredVar = LEFT(cDeclaredVar, AT("(", cDeclaredVar)-1)

ENDIF

IF UPPER(cVar) == SUBSTR(UPPER(cDeclaredVar), 1, LEN(cVar)) Then

* Add Match to list

iMatches = iMatches + 1

DIMENSION aMatches[iMatches]

aMatches[iMatches] = cDeclaredVar

ENDIF

NEXT

NEXT

* Now we go to the head of the prg to look at the #defined vars in the file and in the #includes

* cProgText = _EdGetStr(hwndCode, 0, iPos)

* iLastLine = ALINES(aProgText, cProgText)

* Need to solve this problem

* BL * FOR lnI = 1 TO ALEN( aProgText,1)

* BL * lcLine = aProgText[ lnI ]

* BL *

* BL * DO CASE

* BL * CASE "#DEFINE " == UPPER(LEFT(lcLine, 8))

* BL * cVariables = ReadDefines(lcLine)

* BL * CASE "#INCLUDE " == UPPER(LEFT(lcLine, 9))

* BL * ReadInclude( lcLine, cVar, @cVariables )

* BL * CASE ("FUNC" $ UPPER(lcLine) OR "PROC" $ UPPER(lcLine)) AND ;

* BL * LEFT( lcLine, 1) <> "*"

* BL * EXIT

* BL * ENDCASE

* BL * ENDFOR

* BL * addToArray(@cVariables, @aMatches, @avars, cVar)

iMatches = ACleanUp( @amatches )

IF iMatches > 0 AND VARTYPE( aMatches[1]) <> "L" Then && we have at least one match!

cNewVar = GetBestMatch(@aMatches, cVar)

IF UPPER(cVar) == UPPER(cNewVar) THEN

IF iMatches > 1 Then

cChoice = ""

nRow = 0

nCol = 0

EditPos(@nRow, @nCol, @laEnv)

DEFINE POPUP shortcut shortcut && RELATIVE FROM MROW(),MCOL()

FOR iMatch = 1 TO iMatches

DEFINE BAR iMatch OF shortcut PROMPT aMatches[iMatch]

cOnSelect = [ON SELECTION BAR iMatch OF shortcut cChoice = "] + aMatches[iMatch] + ["]

&cOnSelect

ENDFOR

ACTIVATE POPUP shortcut AT nRow, nCol

cNewVar = cChoice

ENDIF

ENDIF

ChangeText(@hwndCode, laEnv[17], cVar, cNewVar)

ELSE

* If there's no match, BEEP!!!

??CHR(7)

ENDIF

ENDIF

ENDIF

ENDIF

RETURN .T.

 

FUNCTION GetBestMatch

LPARAMETERS taMatches, cVar

LOCAL cMatch, iMatches, i

cMatch = ""

iMatches = ALEN(taMatches)

ASORT(taMatches)

FOR i = 1 TO LEN(taMatches[1]) && size of shortest var

LOCAL cChar, cOldChar, j

cOldChar = ""

FOR j = 1 TO iMatches

cChar = SUBSTR(taMatches[j], i, 1)

IF NOT EMPTY(cOldChar)

IF UPPER(cChar) != UPPER(cOldChar) Then

RETURN cMatch

ENDIF

ENDIF

cOldChar = cChar

NEXT

cMatch = cMatch + cChar

NEXT

RETURN cMatch

 

FUNCTION WSTRIM

LPARAMETERS tcText

LOCAL lcText

lcText = ALLTRIM(CHRTRAN(tcText, CHR(13) + CHR(10), ""))

DO WHILE CHR(9) == LEFT(lcText, 1) OR " " == LEFT(lcText, 1)

lcText = SUBSTR(lcText, 2)

ENDDO

DO WHILE CHR(9) == RIGHT(lcText, 1) OR " " == RIGHT(lcText, 1)

lcText = LEFT(lcText, LEN(lcText)-1)

ENDDO

RETURN lcText

FUNCTION ASPLIT

LPARAMETERS taArray, tcText, tcSplitChar

LOCAL iElements, x, iOld, iNext

iElements = OCCURS(tcSplitChar, tcText)+1

DIMENSION taArray[iElements]

iOld = 1

FOR x = 1 TO iElements

iNext = AT(tcSplitChar, tcText, x)

IF iNext = 0 THEN

taArray[x] = SUBSTR(tcText, iOld)

ELSE

taArray[x] = SUBSTR(tcText, iOld, iNext-iOld)

ENDIF

iOld = iNext+1

NEXT

RETURN iElements

 

FUNCTION ChangeText

LPARAMETERS thWnd, tiPos, tcOldVar, tcNewVar

_EdSelect(thWnd, tiPos-LEN(tcOldVar), tiPos)

_EdDelete(thWnd)

_EdInsert(thWnd, tcNewVar, LEN(tcNewVar))

RETURN .T.

 

FUNCTION GetVariable

LPARAMETERS thWnd, tiPos

LOCAL cVar, cChar, iCnt

cVar = ""

iCnt = tiPos - 1

cChar = _EdGetChar(thWnd, iCnt)

DO WHILE cChar $ VARIABLE_CHARS

cVar = cChar + cVar

iCnt = iCnt - 1

cChar = _EdGetChar(thWnd, iCnt)

ENDDO

RETURN cVar

 

 

FUNCTION EditPos (nRow, nCol, taEnv)

LOCAL cPoint, cLeft, cTop, nLeft, nTop

#DEFINE EDENV_KIND 25

#DEFINE EDSNIP 10

nRow = 0

nCol = 0

DECLARE Long GetCaretPos in Win32API String@

DECLARE memcpy IN msvcrt AS memcpy_s2l Long@, String@, Long

** Get the caret point

cPoint = REPLICATE(CHR(0), 8)

GetCaretPos(@cPoint)

** Convert the point to top and left

cLeft = SUBSTR(cPoint, 1, 4)

cTop = SUBSTR(cPoint, 5, 4)

nLeft = 0

nTop = 0

memcpy_s2l(@nLeft, @cLeft, 4)

memcpy_s2l(@nTop, @cTop, 4)

** Add window border dimensions

nTop = nTop + SYSMETRIC(4)+SYSMETRIC(9)

nLeft = nLeft + SYSMETRIC(3)

** If this is a snippet screen add more space for the combos

IF INLIST(taEnv[EDENV_KIND], EDSNIP)

nTop = nTop + 38

ENDIF

** Get edit window corner

nRow = WLROW(WONTOP())

nCol = WLCOL(WONTOP())

** Add caret position

** (add 1 to the height for the height of the caret)

*! ToDo: 1 is close, but we need to calculate the caret height

*! based on the current font dimensions

nRow = nRow + (nTop/FONTMETRIC(1)) + 1

nCol = nCol + (nLeft/FONTMETRIC(6))

RETURN .T.

FUNCTION ACleanUp( taArray )

EXTERNAL ARRAY taArray

LOCAL i

FOR i = ALEN( taArray,1) TO 1 STEP -1

IF i > 1

IF VARTYPE( taArrayIdea [I] ) == VARTYPE( taArray[i-1] )

IF taArrayIdea [I] == taArray[i-1]

ADEL( taArray,i)

DIMENSION taArray[ ALEN(taArray,1)-1]

ENDIF

ENDIF

ENDIF

ENDFOR

RETURN ALEN( taArray,1)

FUNCTION ReadDefines( tcLine )

RETURN WSTRIM( GETWORDNUM( tcLine, 2) )

ENDFUNC

FUNCTION ReadInclude( tcLine, tcVar, tcVariables )

LOCAL lcFileToOpen

lcFile2open = GETWORDNUM(tcLine,2)

IF FILE( (lcFile2open) )

ALINES( laINCL, FILETOSTR( lcFile2open), .T., CHR(13)+CHR(10))

FOR lnItemsInArray = 1 TO ALEN( laINCL,1)

tcVariables = WSTRIM( GETWORDNUM( laINCL[lnItemsInArray], 2))

IF UPPER(tcVar) == SUBSTR(UPPER(tcVariables), 1, LEN(tcVar)) THEN

* Add Match to list

iMatches = ALEN(aMatches,1) + 1

DIMENSION aMatches[iMatches]

aMatches[iMatches] = tcVariables

ENDIF

ENDFOR

ENDIF

ENDFUNC

PROCEDURE addtoarray( tcVariables, taMatches, taVars, tcVar )

EXTERNAL ARRAY taVars

EXTERNAL ARRAY taMatches

* Let's handle multi-line definitions...

iOffset = 0

DO WHILE ";" == RIGHT(tcVariables, 1)

iOffset = iOffset + 1

tcVariables = LEFT(tcVariables, LEN(tcVariables)-1) + WSTRIM(aProgText[iLine+iOffset])

ENDDO

 

FOR y = 1 TO ASPLIT(@taVars, tcVariables, ",")

cDeclaredVar = WSTRIM(taVarsYes [Y])

IF " " $ cDeclaredVar Then && Don't include anything beyond the space; Strong-typing comes to mind

cDeclaredVar = LEFT(cDeclaredVar, AT(" ", cDeclaredVar)-1)

ENDIF

IF CHR(9) $ cDeclaredVar Then && Don't include anything beyond the tab

cDeclaredVar = LEFT(cDeclaredVar, AT(CHR(9), cDeclaredVar)-1)

ENDIF

IF "[" $ cDeclaredVar Then && Don't include anything beyond the array subscript; We could set this up to include the array subscript, as it will be used most places...

cDeclaredVar = LEFT(cDeclaredVar, AT("[", cDeclaredVar)-1)

ENDIF

IF "(" $ cDeclaredVar Then && Don't include anything beyond the array subscript(some people use these parentheses for arrays!!!)

cDeclaredVar = LEFT(cDeclaredVar, AT("(", cDeclaredVar)-1)

ENDIF

IF UPPER(tcVar) == SUBSTR(UPPER(cDeclaredVar), 1, LEN(tcVar)) Then

* Add Match to list

iMatches = ALEN(taMatches,1) + 1

DIMENSION taMatches[iMatches]

taMatches[iMatches] = cDeclaredVar

ENDIF

NEXT

ENDPROC

I hope it will be of good use for you.

Published Friday, November 10, 2006 3:30 PM by Boudewijn
Filed Under: ,

Comments

# Nice... but ISX does this, too. @ Sunday, November 12, 2006 11:08 PM

Hello,
I use a similar tool from Christof Wollenhaupt for years now. It does actually the same but instead of need of defining a key label it uses 'm.' to show a list of declared variables, and Alt+RightArrow for variables and constants.

Maybe this could be interesting for you.

Kind regards, JoKi

jochenk

# re: cute little tool making you productive @ Tuesday, November 14, 2006 3:14 PM

Tried to use this in VFP7 but it doesnt work it thinks 'aVarsYes' is a program. Also how do you get it to load this in automatically when VFP is opened?

Shame this looks very good tool :o)

MikeyS

Anonymous comments are disabled
Powered by Community Server, by Telligent Systems