Clip() - Send and Retrieve Text using the Clipboard
-
- Posts: 78
- Joined: 06 May 2017, 11:07
Re: Clip() - Send and Retrieve Text using the Clipboard
Hi! Another grateful, longtime user of Clip() here.
I'm now trying to port it to AHK v2 so I can keep enjoying the goodness. But I'm stuck at the part where it uses a label and then retrieves the value of A_ThisLabel, which doesn't exist anymore in v2. SetTimer also requires functions and not labels now.
Do you know how I could adapt that part of the function so that I can make it work in v2?
I'm now trying to port it to AHK v2 so I can keep enjoying the goodness. But I'm stuck at the part where it uses a label and then retrieves the value of A_ThisLabel, which doesn't exist anymore in v2. SetTimer also requires functions and not labels now.
Do you know how I could adapt that part of the function so that I can make it work in v2?
-
- Posts: 78
- Joined: 06 May 2017, 11:07
Re: Clip() - Send and Retrieve Text using the Clipboard
I ended up doing this, which "works", but I'm not sure I haven't introduced bugs:
Code: Select all
Clip(Text := "", Reselect := "", Restore := "")
{
Static BackUpClip := "", Stored := False, LastClip := "", Restored := ""
If (Restore) {
If (A_Clipboard == LastClip)
A_Clipboard := BackUpClip
BackUpClip := LastClip := Stored := ""
return Clip()
} Else {
If !Stored {
Stored := True
BackUpClip := ClipboardAll() ; ClipboardAll must be on its own line
} Else {
SetTimer ClipRestore, 0
}
LongCopy := A_TickCount, A_Clipboard := "", LongCopy -= A_TickCount
; LongCopy gauges the amount of time it takes to empty the clipboard
; which can predict how long the subsequent clipwait will need
If (Text = "") {
SendInput("^c")
ClipWait (LongCopy ? 0.6 : 0.2), True
} Else {
A_Clipboard := LastClip := Text
ClipWait 10
SendInput("^v")
}
SetTimer ClipRestore, -700
Sleep 20
; Short sleep in case Clip() is followed by more keystrokes such as {Enter}
If (Text = "")
Return LastClip := StrReplace( A_Clipboard, "`r" )
Else If (ReSelect = True) or (Reselect and (StrLen(Text) < 3000)) {
Text := StrReplace(Text, "`r")
SendInput("{Shift Down}{Left " StrLen(Text) "}{Shift Up}")
}
}
Return
ClipRestore() {
Clip( , , "RESTORE" )
}
Clip:
Return Clip()
}
Re: Clip() - Send and Retrieve Text using the Clipboard
I recently found this and love the idea. In practice, I'm encountering an issue with the function restoring BackupClip after successfully copying the highlighted text. Absolutely nothing special about the use case and the issue will generally crop up after the script has been active for some time. Anyone else had issues with the function not working in v1?
-
- Posts: 4
- Joined: 05 Jun 2023, 10:58
Re: Clip() - Send and Retrieve Text using the Clipboard
@elbitjusticiero I know you said you got it figured out but when I was trying your code out I ran into some issues with Clip() continuously recalling itself. I think this stems from the call to Clip() after the return in line 12.
I may be way off base, but after doing some msgbox debugging, I found that removing that mention of Clip() in line 12 (Since any output by that point was already returned anyway) and adding an additional (maybe unnecessary) did the trick. The code below works for me. I hope others find it useful.
If you want, you could post it to the V2 forums and link here so others can see and contribute if interested.
I may be way off base, but after doing some msgbox debugging, I found that removing that mention of Clip() in line 12 (Since any output by that point was already returned anyway) and adding an additional (maybe unnecessary)
Code: Select all
SetTimer , 0
If you want, you could post it to the V2 forums and link here so others can see and contribute if interested.
Code: Select all
#Warn ; Enable warnings to assist with detecting common errors.
SetWorkingDir(A_ScriptDir) ; Ensures a consistent starting directory.
Clip(Text := "", Reselect := "", Restore := "")
{
Static BackUpClip := "", Stored := False, LastClip := "", Restored := ""
If (Restore) {
If (A_Clipboard == LastClip){
A_Clipboard := BackUpClip
}
BackUpClip := LastClip := Stored := ""
SetTimer , 0
return
} Else {
If !Stored {
Stored := True
BackUpClip := ClipboardAll() ; ClipboardAll must be on its own line
} Else {
SetTimer ClipRestore, 0
}
LongCopy := A_TickCount, A_Clipboard := "", LongCopy -= A_TickCount
; LongCopy gauges the amount of time it takes to empty the clipboard
; which can predict how long the subsequent clipwait will need
If (Text = "") {
SendInput("^c")
ClipWait (LongCopy ? 0.6 : 0.2), True
} Else {
A_Clipboard := LastClip := Text
ClipWait 10
SendInput("^v")
}
SetTimer ClipRestore, -700
Sleep 20
; Short sleep in case Clip() is followed by more keystrokes such as {Enter}
If (Text = ""){
Return LastClip := StrReplace( A_Clipboard, "`r" )
} Else If (ReSelect = True) or (Reselect and (StrLen(Text) < 3000)) {
Text := StrReplace(Text, "`r")
SendInput("{Shift Down}{Left " StrLen(Text) "}{Shift Up}")
}
}
Return
ClipRestore() {
Clip( , , "RESTORE" )
}
}
-
- Posts: 78
- Joined: 06 May 2017, 11:07
Re: Clip() - Send and Retrieve Text using the Clipboard
Thank you, @MoltenKeyboards! It looks like I had introduced a bug after all.
-
- Posts: 78
- Joined: 06 May 2017, 11:07
Re: Clip() - Send and Retrieve Text using the Clipboard
BTW @berban, if you could look at it and ensure it's all correct, it would be helpful for those who made the jump to v2!
Re: Clip() - Send and Retrieve Text using the Clipboard
Hi @elbitjusticiero,
Thanks for bringing this to my attention! I put it on the V2 forums here: viewtopic.php?f=83&t=118764
Let me know if you see any issues with it. I altered what you had slightly according to my understanding of the differences with V2!
Berban
Thanks for bringing this to my attention! I put it on the V2 forums here: viewtopic.php?f=83&t=118764
Let me know if you see any issues with it. I altered what you had slightly according to my understanding of the differences with V2!
Berban
Re: Clip() - Send and Retrieve Text using the Clipboard
@berban
Nice function! Thanks for that.
But why do you wait 700 ms to call the function again to restore clipboard? In my test 10 ms was sufficient but, knowing AHK, I left it on 50 ms. But why 700? On what machine, under what load and with how large pasted text would it be required to wait this much to restore clipboard?
Nice function! Thanks for that.
But why do you wait 700 ms to call the function again to restore clipboard? In my test 10 ms was sufficient but, knowing AHK, I left it on 50 ms. But why 700? On what machine, under what load and with how large pasted text would it be required to wait this much to restore clipboard?
Re: Clip() - Send and Retrieve Text using the Clipboard
I think it was not the absolute required time to ensure the operation worked correctly; rather it was an extra amount of time to give the user time to perform any other work with the clipboard before restoring it. For instance, a common usage (in some of my scripts at least) is to copy selected text, transform the copied text somehow, and then paste it back. Ideally in this situation you’d do backup > copy > paste > restore, not backup > copy > restore > backup > paste > restore. So in principle the extra lag there gives you time to finish working with the clipboard, before restoring it. Another situation this might apply to is if you wanted to spam a bunch of text using ctrl+v, if you did it with under 700ms between pastes it would reduce the number of backups and restores here too.Chrysalis wrote: ↑25 May 2024, 20:01But why do you wait 700 ms to call the function again to restore clipboard? In my test 10 ms was sufficient but, knowing AHK, I left it on 50 ms. But why 700? On what machine, under what load and with how large pasted text would it be required to wait this much to restore clipboard?
Because it’s a timer, it doesn’t interrupt future code at all so I figured the delay doesn’t matter. The only issue is if your script ends after the paste, which can be a problem.
Still, in my experience windows does require a decent amount of time to finish a clipboard action before you can safely restore the value. Otherwise sometimes the original value gets pasted instead of the new value. From testing I recall this being in the neighborhood of 50-100ms but that was some years ago and I wouldn’t be surprised if performance has improved a lot since then.
Re: Clip() - Send and Retrieve Text using the Clipboard
OK, I understand now.
So in the process of backup > copy > transform > paste > restore, if paste occurs less than 700 ms away from copy, does the second call to SetTimer reset the previously running one?
So in the process of backup > copy > transform > paste > restore, if paste occurs less than 700 ms away from copy, does the second call to SetTimer reset the previously running one?
Re: Clip() - Send and Retrieve Text using the Clipboard
That's correct. It would cancel the restore and set a new timer for 700ms in the future.
Re: Clip() - Send and Retrieve Text using the Clipboard
OK, thanks for clarifying.