Intermittent failure: wrap symbols around selected text

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
alancantor
Posts: 76
Joined: 11 Jun 2019, 11:28

Intermittent failure: wrap symbols around selected text

Post by alancantor » 02 Aug 2021, 22:44

I use scripts to "wrap" symbols around selected text. For example:

"text"
[text]
(text)
%text%

When text is not selected, the scripts insert the two symbols. For example:

""
[]
()
%%

With unselected text, the script moves the cursor between the two symbols.

The scripts are close to 100% reliable when text is not selected. But the scripts fail about 20% of the time when I act on selected text. The failure: the two symbols are inserted, but without the selected text.

I've toyed with logic tweaks and timing changes in an effort to increase reliability. But I haven't been able to discover a "magic bullet" that will cure this problem. Any ideas?

Code: Select all

; -------------------
; All of my hotkey-activated text wrapping macros are in this section. 

!Q::				; Alt + Q 
Opener := Chr(34)	; Quotation marks
Closer := Chr(34)
Gosub, TextWrapMain
return

; -------------------

![::				; Alt + [
Opener := Chr(91) 	; [ ]
Closer := Chr(93)
Gosub, TextWrapMain
return

; -------------------

!9::				; Alt + (
Opener := Chr(40)	; ( )
Closer := Chr(41)
Gosub, TextWrapMain
return

; etc.

; -------------------
; This subroutine is the "engine" for the scripts in the above section. 

TextWrapMain:
ClipSaved := ClipboardAll   ; Store the current clipboard 
clipboard := ""

SendInput ^c
; Try increasing Clipwait delay to prevent clipboard from getting inserted rather than the selection!
; ClipWait, 0.2		; Occasionally fails with 0.3, 0.4, 0.5, and 0.8 But maybe failure is inevitable?
ClipWait, 0.6		
; Sleep 200			; This pause was a desperate measure, but it does not seem to matter now!

if ErrorLevel		; ErrorLevel is TRUE implies the clipboard did NOT become populated, which means nothing was selected.
	{
 	SendInput {Text}%Opener%%Closer%		; "{Text}" is needed to handle unescaped curly braces { and }
	SendInput {Left}
	}
Else
	{
	clipboard := Trim(clipboard, " `t`r`n")	; Trim spaces, tabs, CRs, and NLs
	clipboard := Opener clipboard Closer
	SendInput {Del}^v					; Sometimes the selection is not overwritten. Deleting it helps.
 	}
 	
; Delay needed for reliability. Without, the original clipboard (or nothing) is inserted instead of the selection!
; Sleep 200
Sleep 800

clipboard := ClipSaved		; Restore the original clipboard.
ClipSaved := ""  		; Free memory in case the original clipboard was very large.
Return
User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Intermittent failure: wrap symbols around selected text

Post by mikeyww » 03 Aug 2021, 06:06

Code: Select all

char := {q: """""", "[": "[]", 9: "()"}
!q::
![::
!9::
Clipboard := "", bound := char[SubStr(A_ThisHotkey, 2)]
Send ^c
Sleep, 100
c := Clipboard
Send +{Left}^c
Sleep, 100
Send % Clipboard = c ? "" : "+{Right}"
SendInput % "{Text}" Chr(Asc(bound)) Trim(Clipboard = c ? c : SubStr(Clipboard, 2), " `t`r`n")
            . SubStr(bound, 2)
Return
alancantor
Posts: 76
Joined: 11 Jun 2019, 11:28

Re: Intermittent failure: wrap symbols around selected text

Post by alancantor » 03 Aug 2021, 11:05

Mikey, This is a very impressive example. I'm still trying to understand how you've managed to make it work!

Any thoughts on what might be causing my code to be slightly erratic? I suspect clipwait may be flaky. But maybe the true source of the problem can be traced back to the software between my ears...
User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Intermittent failure: wrap symbols around selected text

Post by mikeyww » 03 Aug 2021, 11:07

Thank you.

One possible issue is that your Else block has two sequential clipboard assignments, with no intervening delay or wait. As you know from your use of ClipWait, that can cause problems, because the clipboard tends to work somewhat slowly. Confirming whether this is a problem would be easy, because you can display the clipboard contents at various points in the script.
alancantor
Posts: 76
Joined: 11 Jun 2019, 11:28

Re: Intermittent failure: wrap symbols around selected text

Post by alancantor » 04 Aug 2021, 12:13

My sense is that clipboard operations either take longer, or are slightly less reliable, under Windows 10. The same AHK scripts worked flawlessly before I "upgraded" from Windows 7.

To reduce the number of discrete clipboard operations, I combined the two clipboard instructions into a single line of code, followed by a delay.

Before:

Code: Select all

clipboard := Trim(clipboard, " `t`r`n")
clipboard := Opener clipboard Closer
Current version:

Code: Select all

clipboard := Opener Trim(clipboard, " `t`r`n") Closer
Sleep, 100
So far it's working. But time will tell...

Postscript... I just stumbled upon an application in which these commands almost always fail... Sigh!
Post Reply

Return to “Ask for Help (v1)”