Author |
Topic |
|
KirillMueller
Ketchup Master
72 Posts |
Posted - May 13 2006 : 2:32:00 PM
|
Often, I find myself editing files that contain definitions for resource identifiers, like
#define FIRST_RESOURCE 10001
#define SECOND_RESOURCE 10002
#define THIRD_RESOURCE 10003
To create new identifiers, I copy existing ones and paste them, then change the names and numbers. The number change consists of incrementing the old number by one in the vast majority of cases. It would be really cool if VAX could do the increment itself if it finds that this could be my intention. This operation can be put to the "undo" stack, one could easily undo this if it's not appropriate.
VAX could check if - the code copied comes from the same file - the clipboard and the environment where it is to be pasted looks like a sequence of definitions or empty lines (please find a regex for this below) - the user has checked the corresponding option in the config dialog
Hexadecimal or octal numbers might be treated accordingly.
Do you think this feature could make it into VAX one day?
Kind regards, Kirill
Regular expression for #define sequences:((\\#define( |\\t)+[A-Za-z_][A-Za-z_0-9]*( |\\t)+[0-9]+( |\\t)*\\n)|(( |\\t)*\\n))+
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - May 15 2006 : 5:38:33 PM
|
*considers*
i am tempted to agree with you. have you ever used the VIM editor? it has a built in feature to increase or decrease a number, which supports decimal, hex and octal. personally this is one of the features that i really miss from vim.
the flip side is that on its own this is an "odd" feature. it is incredibly useful when used in the middle of macro's, but not so obviously useful on its own.
due to the way macro's work in the IDE they do not tend to play nicely with VA.
a specific feature for this exact scenario is not really sensible for VA, it is to particular to one users needs.
have you considered using Excel? use two columns, one for the #define string and one for the numbers. you can then get Excel to auto fill the numbers, and to duplicate the #define string. then it is simply a case of copying the text back into the IDE and searching for the #define string, replacing it as you find it. F3 which selects it on find is ideal for this. |
zen is the art of being at one with the two'ness |
|
|
KirillMueller
Ketchup Master
72 Posts |
Posted - May 17 2006 : 09:17:45 AM
|
Thank you for your reply.
Of course I could use Excel if I had many symbols to redefine. The issue is that most often I need only one or two new symbols, and it's worth the effort to start Excel. Assigning different values manually is a matter of seconds, and I just wondered if I could save those seconds with VAX :-)
It should be easy to write a macro that looks for a number around the caret position and replaces it with its increment. This would solve at least half of the cases. Thank you for your suggestion! -- What do yo mean exactly by "not playing nicely with VA"?
Another option would be a "paste handler" -- a macro called by VAX (or by the IDE?) just before the paste operation is to be performed. By this, users could easily do whatever they want with the clipboard, without any extra effort. (The "Format after paste" feature would be a special "paste handler", then.)
Kind regards,
Kirill |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - May 17 2006 : 2:32:39 PM
|
i have seen various bug reports go by, over time, that report problems with VA when recording or playing back macros, mainly the simple "record and repeat this" type.
remember the same keystrokes can do different things based on context when VA is enabled, which adds another element to consider when using such macros.
format after paste is something the IDE its self does, so you would be digging fairly deeply into the IDE to try and catch all paste events in the manor you describe.
i myself have wondered about a macro to find and change numbers in the code, but so far i have not looked into it. certainly i would be interested in any such macro if you find or write one |
zen is the art of being at one with the two'ness |
|
|
KirillMueller
Ketchup Master
72 Posts |
Posted - Sep 05 2006 : 05:25:37 AM
|
I wrote a simple macro that basically does the job. No error handling is done, it even does not check if it's actually a number. However, you can place the caret in the beginning or the middle of a decimal number. Works in VS 2005, but should work in VS .NET 2003, too.
Public Sub IncrementSelection()
Dim pSel As TextSelection = DTE.ActiveDocument.Selection
pSel.Collapse()
pSel.WordRight(False)
pSel.WordLeft(True)
pSel.Text = CLng(pSel.Text) + 1
pSel.Collapse()
pSel.WordLeft()
End Sub
|
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Sep 05 2006 : 3:37:16 PM
|
outstanding! this just works in VS2005. many thanks.
this just goes to show that getting around to learning something about macro programming would be useful. this is very short, which seems reasuring. |
zen is the art of being at one with the two'ness |
|
|
bugfix
Tomato Guru
Germany
324 Posts |
|
KirillMueller
Ketchup Master
72 Posts |
Posted - Sep 06 2006 : 05:14:59 AM
|
Yes, and it will cripple octal numbers, too. And it works only for numbers that are on "word boundaries", not for incrementing, say, "N13" to "N14". And it will fail if positioned at the end of a number. Not to mention that it never managed to make coffee or clean the kitchen . But you wouldn't expect that from such a simple macro, would you? |
|
|
bugfix
Tomato Guru
Germany
324 Posts |
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Sep 06 2006 : 6:06:25 PM
|
i suspect the official answer is that this is being left as an exercise for the reader
personally i can live without octal and hex for now, but the word boundaries case will be a slight issue. i have a couple of other improvements in mind that this could do with as well.
step 1, find some spare time step 2, find some documentation on writing IDE macro's step 3, enhance the macro
i am currently hard at work on step 1 |
zen is the art of being at one with the two'ness |
|
|
KirillMueller
Ketchup Master
72 Posts |
Posted - Sep 06 2006 : 6:25:54 PM
|
For step 3, you don't really need step 2 -- virtually anything needed for this task can be done with the TextSelection object, which is documented in the on-line help. Also, the macro recording feature does a good job for finding out which function calls correspond to which actions. For the "intelligence" (like decoding hex, ...), you need to know VB .NET.
I'll try the exercise myself when I'm through with step 1: "Discover that I really need an enhanced version of this macro". For now, I'm quite happy with the hack |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Sep 09 2006 : 09:30:19 AM
|
the VIM version of this command says "i will start at the caret, and then scan along the current line until i find a number. once i find that number i will increment it by one".
having got used to this, i am far to "lazy" to move the caret to the number unless i have to |
zen is the art of being at one with the two'ness |
|
|
KirillMueller
Ketchup Master
72 Posts |
Posted - Sep 12 2006 : 8:03:07 PM
|
I think you will like this version better. The "Public Sub" methods at the bottom can be run as macros from the IDE. Highlights are:
- Increment all numbers in the current line or in a selection - Restrict to stand-alone numbers, leaving out ID_2_A (*crementWord* macros) - Specify an offset (Increment*By macros)
Still, no hex or octal. Is there anyone familiar to VB.NET who can propose an elegant solution with delegates?
Restricting the macro to incrementing the first occurence of a number only should be easy to do, too.
Private Function AlterNumbers(ByVal sText As String, _
ByVal sPattern As String, _
ByVal iDiff As Long) As String
Dim pRegExp As New System.Text.RegularExpressions.Regex(sPattern)
Dim pMatch As System.Text.RegularExpressions.Match
Dim lStartIndex As Integer = 0
pMatch = pRegExp.Match(sText)
Do While pMatch.Success
With pMatch
Dim sOldValue As String = CLng(.Value)
Dim sValue As String = sOldValue + iDiff
sText = sText.Substring(0, .Index) & sValue _
& sText.Substring(.Index + .Length)
' New value may be shorter or longer than old value
lStartIndex = .Index + .Length + Len(sValue) - Len(sOldValue)
End With
pMatch = pRegExp.Match(sText, lStartIndex)
Loop
AlterNumbers = sText
End Function
Private Sub AddToSelection(ByVal sPattern As String, ByVal lCount As Long)
Dim pSel As TextSelection = DTE.ActiveDocument.Selection
Dim lColumn As Long = -1
If lCount = 0 Then
Dim sCount As String = InputBox("By what?", "Increment selection", "1")
If Len(sCount) = 0 Then Exit Sub
lCount = CLng(sCount)
End If
If pSel.IsEmpty Then
lColumn = pSel.AnchorPoint.LineCharOffset
pSel.Insert("")
pSel.StartOfLine()
pSel.EndOfLine(True)
End If
Dim sNewText As String = AlterNumbers(pSel.Text, sPattern, lCount)
pSel.Insert(sNewText, vsInsertFlags.vsInsertFlagsContainNewText)
If lColumn >= 0 Then
pSel.StartOfLine()
pSel.CharRight(, lColumn - 1)
End If
End Sub
Public Sub IncrementSelection()
AddToSelection("[0-9]+", +1)
End Sub
Public Sub DecrementSelection()
AddToSelection("[0-9]+", -1)
End Sub
Public Sub IncrementSelectionWord()
AddToSelection("\\b[0-9]+\\b", +1)
End Sub
Public Sub DecrementSelectionWord()
AddToSelection("\\b[0-9]+\\b", -1)
End Sub
Public Sub IncrementSelectionBy()
AddToSelection("[0-9]+", 0)
End Sub
Public Sub IncrementSelectionWordBy()
AddToSelection("\\b[0-9]+\\b", 0)
End Sub
|
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Sep 16 2006 : 3:35:54 PM
|
most interesting
this is definitely going onto my "things to check out" pile |
zen is the art of being at one with the two'ness |
|
|
|
Topic |
|