AHK: Copying non-adjacent words & joining them together - autohotkey

As the title already says, I would like to copy and join any number of (mostly) non-adjacent words in any app (Web browser, E-Mail, MS Word, Editor, Evernote etc.). That is, any words that I (mouse-)select and copy hitting the 5-key while I simultaneously hold down the F4 key (but actually any hotkeys and modifiers that don't interfere with their normal functioning and which are also both easily and simultaneously reachable with the left hand would do).
This is what I came up with with my limited AHK-skills. The clipboard-part works, but for all I know not the global-variable (and therefore not the word-joining) nor the F4 Down & 5-hotkey-combo (without Down or without & 5 it technically would, though):
global MyString := "" ; make string global to keep contents between {5}-key presses
~F4 Down & 5:: ; copy any (non-adjacent) words with {5}-key as long as I hold down {F4}-key
clipboard := ""
Sleep 100
Send ^c
ClipWait, 1
MyString := MyString Trim(clipboard) ; append lastly copied word to any words copied before (while holding down {F4})
~F4 Up::
MsgBox, %MyString% ; show final string consisting of ALL copied words separated by a space
MyString := "" ; reset string
Return
Ultimately, I would like to copy %MyString% to the clipboard as one single long string rather than show it in a message box. I think I'm already near to the solution.
Can you solve it?

You're never ending the first hotkey's execution block, so its execution bleeds into the hotkey below and your MyString gets reset every time.
Also if you have an down/up hotkey pair, you don't specify the first down, only the up.
Also, there's no need to make your variable super-global.
Fixed script:
~F4 & 5::
Clipboard := ""
Sleep, 100
Send, ^c
ClipWait, 1
MyString := MyString " " Trim(Clipboard)
return
~F4 Up::
MsgBox, % MyString
MyString := ""
return
Pretty cool idea for a script btw. I might use something like this myself.

Related

AutoHotKey String substitution

I am writing a small AHK script that defines a few simple HotStrings.
The concept is that when I type "Build QA1", the appropriate text associated with that HotString appears.
No problem there ...quite simple ...the issue is that I wish to have the string associated with the HotString appear as part of the substitute text ...in the example below, the results should be
Build QA1
Now is the time for all good men
The script below accomplishes this and works fine ...it does exactly what I ask, HOWEVER, when I enter the HotString text and hit Enter or Tab or whatever initiates the HotString, that first line of text ( Build QA1 ) will "flash" on the screen as it is being substituted ...it makes it obvious that a HotString substitution is in operation ...
I would ideally like the HotString ( Build QA1 ) to remain as a part of the
substitute text without being replaced ...is this possible or is there a way to avoid the "flash" as that string is substituted ?
::Build QA1::
send, Build QA1
send, {enter}
send, Now is the time for all good men
return
Try it this way:
::b0::Build QA1:: ; automatic backspacing is not done to erase the abbreviation you type.
ClipSaved := ClipboardAll ; save the entire clipboard to the variable ClipSaved
clipboard := "" ; empty the clipboard (start off empty to allow ClipWait to detect when the new text has arrived
clipboard = ; copy this text:
(
Now is the time for all good men
)
ClipWait, 1 ; wait for the clipboard to contain data.
if (!ErrorLevel) ; if NOT ErrorLevel ClipWait found data on the clipboard
Send ^v ; paste the text
Sleep, 300 ; don't change clipboard while pasting! (Sleep > 0)
clipboard := ClipSaved ; restore original clipboard
VarSetCapacity(ClipSaved, 0) ; free the memory of the variable ClipSaved
return
See Hotstrings Options, Clipboard and ClipboardAll in the documentation.

Creating text macro system on AHK

I am quite new on AutoHotKey, and I'm trying to make my macro system. Currently I have a system that looks like this:
I have text variables
hi =
(
Hello,
Some more text
)
a Hotstring
::\hi::
Macro(hi)
return
And a function Macro:
Macro(text)
{
ClipSaved := ClipboardAll ; save clipboard
clipboard := text
ClipWait
Sleep, 150
Send, ^v
clipboard := ClipSaved ; restore original clipboard
return
}
The reason for using a function with clipboard is because long text blocks tend to have a delay until they are printed out, an issue that does not occur with the function.
I've found a concept called dynamic hotstrings, and I think I can somehow implement it so that I wouldn't have to write the second displayed block for every text field, but instead have a one hotstring that would understand that if it's my input starts with \ and there is a variable in the script under the name x that follows it, it should execute Macro(x), but I have never found any similar examples.
Could you provide me with a code sample or give any leads to what I should check out?
There are several dynamic Hotstring AutoHotkey functions, but this is probably the one you want to use Hotstring by menixator
So you need to download the hotstring.ahk and #include it as in the examples.
#SingleInstance, force
#include Hotstring.ahk
hi=
(
Hello,
Some more text
)
bye=
(
So long,
Some more text
)
Hotstring("/hi", "Paste")
Hotstring("/bye", "Paste")
return
Paste:
text:=Trim($,"/") ; we need to get rid of the leading /
text:=% %text% ; and need to dereference it
Macro(text)
Return
Macro(text)
{
ClipSaved := ClipboardAll ; save clipboard
Clipboard := text
ClipWait
Sleep, 150
Send, ^v
clipboard := ClipSaved ; restore original clipboard
return
}
There are some more elegant ways to do it, especially with the variables, you could store them in a global object (associative array) for example, but this should get you going.

How does AutoHotKey determine if a copied string is a number?

The following AutoHotKey snippet is supposed to:
Verify if copied string is a number
If so, search for that number in a website and in Windows Search.
Nothing happens. The If's expression is not seeing integers and bypasses code.
Any ideas?
Send ^c
sss = ClipBoard
if sss is integer
{
Run, https://sd.borschow.com:8443/SREdit.jsp?id=%sss%
Run, search-ms:query=%sss%
}
A text copy usually isn't as fast as AHK executes the subsequent code. That is, you need to wait for the clipboard to be updated:
F9::
oldClip := ClipboardAll
Clipboard := ""
Send, ^c
ClipWait
clip := Clipboard
if clip is integer
{
msgbox, integer
}
else
{
msgbox, not an integer
}
Clipboard := oldClip
; we better make that empty, since it could contain sensitive data
oldClip := ""
return
Best practice is to store the clipboard, empty it, trigger the copy, and wait for the clipboard to contain something. And finally, restore the old clipboard if you don't need the contents anymore.

Replicate ++ operator via AutoHotKey script?

Let's say I'm programming in a text editor and want to iterate a variable:
i++
Now, let's say for whatever reason, this language doesn't ++ but rather:
i = i + 1
this is annoying when you are used to the first syntax. I want a script which when receiving ++ translates this to a series of commands I send (control shift left arrow, etc, this is not the part I'm having trouble with).
However I cannot seem to get this method to execute:
+ & +::
Msgbox test
return
For whatever reason though, this is not fully being called - I do not see the keystroke for + when typing so I know it is somehow getting to that method, but, not registering the second +.
How can I call a method using the keystrokes ++ as a trigger?
There's a really great library called RegEx Powered Dynamic Hotstrings. And replacing someVar++ with someVar = someVar + 1 reeks of RegEx!
This one line will do what you want:
hotstrings("(\w+)\+\+", "%$1% = %$1% {+} 1")
This will work for every variable name that's alphanumeric (plus underscore): [a-zA-Z0-9_]
Of course, this won't work for every language since it strongly depends on the syntax. For example, some languages use := to assign expressions, other languages need a semicolon to complete a statement and so on...
Hotstrings WILL work for this occasion, however, you might need the "?" modifier for it to grab even within a "word" try it like this:
:*?:++::
ClipboardOld := ClipboardAll,Clipboard := ""
Send, +^{Left}^c
Clipwait
Send, ^{Right} = %Clipboard% {+} 1
Clipboard := ClipboardOld,ClipboardOld := ""
return
This also preserves the clipboard.

Selecting the last N characters before caret with AutoHotkey

Is there a way to select last N symbols with autohotkey?
I'm making a function which replicates Sublime Text's duplicate function (Ctrl+Shift+D). I want text to be selected before it is duplicated via SendInput ^C{right}^V
Technically, I could make something like:
selectBefore(n){
Loop, %n% {
SendInput +{Left}
}
}
But that has shown poor performance.
Another method would be to play with Shift+Home. For example, Send +{Home}, then count the number of symbols selected, then Send {Left} and Send +{Home} again, and so on until reaching the length of the duplicated string.
I don't see any better alternatives.
Is there a good, basic way to select N symbols before caret?
From what I read about ST2 (thank you for making me aware) is that ^+d either copies the selected text or if nothing is selected, copies the whole line.
Would this work?
TempCB = %ClipBoard% ; Park clipboard (text) content, Other content (format, images, etc.) will be lost.
ClipBoard = ; Clear clipboard
Send, ^c ; Grab selected text
Sleep, 100 ; Wait 0.1 seconds for clipboard (clipboard will not get filled if nothing is selected)
if (Clipboard = "") ; Nothing selected, thus copy whole line
{
Send, {Home}+{End}^c ; Select line and copy to clipbard
}
MoveBack := StrLen(ClipBoard)
MoveFwd := MoveBack
MoveBack++ ; Move one step back further back due to earlier step {right}
Send, {Right}{Left}^v{Right}{left %Moveback%}+{Right %MoveFwd%} ; Go to end of selected text (in MS notepad this is will jump over the first next char., thus a jump back as well), add a space and paste.
ClipBoard = %TempCB% ; Restore (text part) of previous clipboard content.
Return
I tested this in MS Notepad, other editors might behave differently (especially around jumping towards the end of the selected text).
The script now copies and pastes the selected text and highlights the newly pasted text.