Increase/decrease last number in selected text Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Stauros-Nicod

Increase/decrease last number in selected text

20 Mar 2017, 07:29

I'm trying to make a useful system to automatically increase numbers in selected text. For example, when I working in Zbrush on the project named "Example_character012" I have a folder with 23 files from "Example_character012_prj_01.zpr" to "Example_character012_prj_23.zpr". When I need to save next iteration I'm pressing "ctrl+s" and then regular saving screen opens in the last working directory with preselected filename text, in this scenario it would be "Example_character012_prj_23.zpr". I need to copy this text, select the last number(23) increase it by one, and past it all the text back to the text-field. In this case it would be "Example_character012_prj_24.zpr".
This kind of script would be really useful in all kinds of scenario, mainly with saving in different programs.
I tried to made it myself and come up with this:

Code: Select all

^!Numpad1::
      Sleep 100
      Send ^c
      Sleep 10
      RegExMatch(clipboard,"(\d+)(?!.*\d)",Number)
      NewNumber:=Number1+1
      OldNumber:=NewNumber-1
      Clipboard:=RegExReplace(clipboard, OldNumber, NewNumber)
      Sleep 10
      Send ^v
      Sleep 10
      Send +{Home}

Return

^!Numpad0::
      Sleep 100
      Send ^c
      Sleep 10
      RegExMatch(clipboard,"(\d+)(?!.*\d)",Number)
      NewNumber:=Number1-1
      OldNumber:=NewNumber+1
      Clipboard:=RegExReplace(clipboard, OldNumber, NewNumber)
      Sleep 10
      Send ^v
      Sleep 10
      Send +{Home}

Return
Ctrl+alt+Num1 for increase and Ctrl+alt+Num0 for decrease.
It's work fine with in the simplest scenario, but have significant problems I can't solve myself:

1. It only works in english keyboard-layout. When I use it in russian layout - it puts "cv" instead of pasting(If I paste manually afterwards it put the correct text)
2. Sometimes it increases not only the last number "Example_character012_prj_01.zpr" changing to "Example_character022_prj_02.zpr" instead of "Example_character012_prj_02.zpr"
3. Zeros working incorrectly "Example_prj_09.zpr" changing to "Example_prj_010.zpr" instead of "Example_prj_10.zpr"
4. After pasting it selects the whole line instead of only what just have been pasted
5. If it's possible, it would be great to make it work without affecting clipboard at all.
6. Sometimes some keys like "ctrl" just get stuck until being clicked manually for some reason.
Guest

Re: Increase/decrease last number in selected text

20 Mar 2017, 08:50

1: look at SplitPath to get the base filename and only "get" the last number, remove that number from the base filename and put back the new number (don't rely on replace as you can run into unexpected problems as you've noticed - of if you do use the position parameter)

So "Name_10.zpr" -> number = 10, add one, = 11 -> "Name_" number

2: for ^c ^v you can use the scan codes of the keys or rely on Alternatives for ^c, ^x, ^v:

Copy:
Control+Insert
^{Ins}

Cut:
Shift+Delete
+{Del}

Paste:
Shift+Insert
+{Ins}

For scan codes, see https://autohotkey.com/docs/commands/GetKey.htm and https://autohotkey.com/docs/commands/Send.htm (scan code)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Increase/decrease last number in selected text

20 Mar 2017, 09:15

Nice idea! This RegEx might come in useful in various places. Some fiddly RegEx to get all the text up to the last underscore!

I think the use of {Ctrl up} will avoid the issue with ctrl being held down.

The script I've written expects the whole file name to be selected before beginning. You could use ctrl+a, or 'home, shift+end'.

When you paste, that normally puts the cursor at the end of the pasted text, if you then press shift+home, that then selects from the end of the pasted text, to the start of the line.

Code: Select all

^!Numpad1::
^!Numpad0::
      Sleep 100
      Send {Ctrl up}^c
      Sleep 10
      RegExMatch(Clipboard, "^(.*)(?=_)_(\d+)(\....)$", Match)
      Len := StrLen(Match2)
      if InStr(A_ThisHotkey, 1)
            Match2++
      else
            Match2--
      if (StrLen(Match2) < Len)
            Match2 := Format("{:0" Len "}", Match2)
      Clipboard := Match1 "_" Match2 Match3
      Sleep 10
      Send ^v
      Sleep 10
      Send +{Home}
Return
If the control is an Edit control, you might be able to do:
ControlGet, vText, Selected, , Edit1, A
and

Code: Select all

JEE_EditGetRange(hCtl, ByRef vPos1, ByRef vPos2)
{
VarSetCapacity(vPos1, 4), VarSetCapacity(vPos2, 4)
SendMessage, 0xB0, &vPos1, &vPos2, , ahk_id %hCtl% ;EM_GETSEL
vPos1 := NumGet(vPos1, 0, "UInt"), vPos2 := NumGet(vPos2, 0, "UInt")
Return
}

JEE_EditSetRange(hCtl, vPos1, vPos2, vDoScroll=0)
{
SendMessage, 0xB1, % vPos1, % vPos2, , ahk_id %hCtl% ;EM_SETSEL (anchor, active)
if vDoScroll
	SendMessage, 0xB7, 0, 0, , ahk_id %hCtl% ;EM_SCROLLCARET
Return
}
[EDIT:]
I checked the AHK key history: and LCtrl is VK A2 and SC 01D.
Both of these worked on my PC:
SendInput {SC01D down}v{SC01D up}
SendInput {VKA2 down}v{VKA2 up}
Last edited by jeeswg on 20 Mar 2017, 13:39, edited 5 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Increase/decrease last number in selected text

20 Mar 2017, 09:16

So when it changes the wrong number, did it select the whole text, or did the regex fail?

You might want to chuck a ClipWait command in there after sending Ctrl+C to make sure it gets everything selected into the clipboard.
Stauros-Nicod

Re: Increase/decrease last number in selected text

20 Mar 2017, 11:20

jeeswg wrote:Nice idea! This RegEx might come in useful in various places. Some fiddly RegEx to get all the text up to the last underscore!

I think the use of {Ctrl up} will avoid the issue with ctrl being held down.

The script I've written expects the whole file name to be selected before beginning. You could use ctrl+a, or 'home, shift+end'.

When you paste, that normally puts the cursor at the end of the pasted text, if you then press shift+home, that then selects from the end of the pasted text, to the start of the line.

Code: Select all

^!Numpad1::
^!Numpad0::
      Sleep 100
      Send {Ctrl up}^c
      Sleep 10
      RegExMatch(Clipboard, "^(.*)(?=_)_(\d+)(\....)$", Match)
      Len := StrLen(Match2)
      if InStr(A_ThisHotkey, 1)
            Match2++
      else
            Match2--
      if (StrLen(Match2) < Len)
            Match2 := Format("{:0" Len "}", Match2)
      Clipboard := Match1 "_" Match2 Match3
      Sleep 10
      Send ^v
      Sleep 10
      Send +{Home}
Return
If the control is an Edit control, you might be able to do:
ControlGet, vText, Selected, , Edit1, A
and

Code: Select all

JEE_EditGetRange(hCtl, ByRef vPos1, ByRef vPos2)
{
VarSetCapacity(vPos1, 4), VarSetCapacity(vPos2, 4)
SendMessage, 0xB0, &vPos1, &vPos2, , ahk_id %hCtl% ;EM_GETSEL
vPos1 := NumGet(vPos1, 0, "UInt"), vPos2 := NumGet(vPos2, 0, "UInt")
Return
}

JEE_EditSetRange(hCtl, vPos1, vPos2, vDoScroll=0)
{
SendMessage, 0xB1, % vPos1, % vPos2, , ahk_id %hCtl% ;EM_SETSEL
if vDoScroll
	SendMessage, 0xB7, 0, 0, , ahk_id %hCtl% ;EM_SCROLLCARET
Return
}
[EDIT:]
I checked the AHK key history: and LCtrl is VK A2 and SC 01D.
Both of these worked on my PC:
SendInput {SC01D down}v{SC01D up}
SendInput {VKA2 down}v{VKA2 up}
Thank you! The first part works perfectly. I changed ^c and ^v to ^{Ins} and +{Ins}, so now it's also works with russian language layout. The second part is too hard for me to comprehend on my level, can't really understand what it should do to be honest or where to put it. This is already working a hundred times better. Only 4 and 5 points left. It would be nice to have in clipboard same stuff that was there before running the script and it would be better if only the pasted part was selected after running the script. The problem is I can't just make this by hotkey like ^+{left} because sometimes it could have parentheses or even spaces.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Increase/decrease last number in selected text

20 Mar 2017, 12:39

5. If it's possible, it would be great to make it work without affecting clipboard at all.
You could save the contents of the clipboard to a variable clipback : =clipboard, then send CTRL+C, do your thang, then send CTRL+V, then clipboard := clipback
Probably would not work if you started off with an image in the clipboard, but it would preserve any text you have in the clipboard.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: Increase/decrease last number in selected text

20 Mar 2017, 12:47

Stauros-Nicod wrote:it would be better if only the pasted part was selected after running the script. The problem is I can't just make this by hotkey like ^+{left} because sometimes it could have parentheses or even spaces.
You mean if you selected "Example_character012_prj_01.zpr" and it changed this to "Example_character012_prj_02.zpr", you only want "02" selected?
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Increase/decrease last number in selected text

20 Mar 2017, 12:58

evilC wrote:
5. If it's possible, it would be great to make it work without affecting clipboard at all.
You could save the contents of the clipboard to a variable clipback : =clipboard, then send CTRL+C, do your thang, then send CTRL+V, then clipboard := clipback
Probably would not work if you started off with an image in the clipboard, but it would preserve any text you have in the clipboard.
See ClipboardAll
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Increase/decrease last number in selected text

20 Mar 2017, 13:14

Who said anything about ctrl+shift+left?

Out of interest, are you using a standard save as prompt?

Is the control an Edit control? Because if it is that makes '4' and '5' quite easy, plus I can do tests more easily.

"^(.*)(?=_)_(\d+)(\....)$"
^(.*)(?=_) [get every character from the start of the string onwards, up to before the last underscore]
(\d+) [1 or more digits]
(\....) [a . followed by 3 characters that could be anything]
(\..{3}) [equivalent to the line above]

Match2 := Format("{:0" Len "}", Match2)
This makes sure that the number has at least 'Len' characters, leading zeros are added if needed.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Increase/decrease last number in selected text

21 Mar 2017, 03:58

Try this on Notepad's Save As prompt for example. The functions are available above.

Code: Select all

#IfWinActive, Save As
q:: ;set text in Edit control, maintain text selection
WinGet, hWnd, ID, A
ControlGetText, vText, Edit1, % "ahk_id " hWnd
ControlGet, hCtl, Hwnd, , Edit1, % "ahk_id " hWnd
JEE_EditGetRange(hCtl, vPos1, vPos2)
vText1 := SubStr(vText, 1, -1)
vText2 := Chr(Asc(SubStr(vText, 1-1))+1)
ControlSetText, Edit1, % vText1 vText2, % "ahk_id " hWnd
JEE_EditSetRange(hCtl, vPos1, vPos2)
Return
#IfWinActive
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Chunjee and 313 guests