Creating text macro system on AHK - macros

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.

Related

AHK: Copying non-adjacent words & joining them together

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.

AHK: convert ClipboardAll to string (without calling Clipboard instead)

In an AHK script, I want to convert data I read from the clipboard earlier via ClipboardAll into a string I can manipulate, but StrGet() very oddly cannot do that.
!2:: clipget()
clipget()
{
clip := ClipboardAll
MsgBox % clip
MsgBox % NumGet(clip)
MsgBox % StrGet(clip)
Return
}
Firts MsgBox returns empty, because clip is not a string, as expected.
Second returns a numerical representation of the bit data, as expected.
The third returns nothing, not as expected.
I know I could just use clipstr = Clipboard in the first place to have it converted in the first place, but then I would have to read the clipboard twice as in:
clip := ClipboardAll
clipstr := Clipboard
to get both string data and bit data, but that looks uncool and takes longer if the data on the cliboard is large.
A dumb but functional way way could also be
Clipboard := clip
Sleep 500
clipstr := Clipboard
needless to say is not what I am looking for.
So, is there any way to get a string from ClipboardAll bit data with something like
clip := ClipboardAll
clipstr := MagicalFunction(clip)
?
Im not sure if this will help. But the clipboard is not the piece of string that is currently copied. The clipboard is a place where your computer holds your copied stuff, its a place where you can find your previous copied stuff.
A code I found in ahk's Clipboard doc is this
Loop, parse, clipboard, `n, `r
{
MsgBox, %A_LoopField% is your current copied first line..
}
I'm not very familiar with ahk's variable system but I think this should give a string output from %A_LoopField%
in AHK script: Save ClipBoardAll to File.
in external text editor: Write to the BEGINING of File some text eg. "rrr" (or you can do it by "copy +" in command line bat file)
in AHK script: Read File to variable.

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.

Autohotkey Script that edits selected text without using the clipboard

I want to write an Autohotkey text to edit the text that the user selects and append four spaces at the beginning of every line.
If I would simply have a string with multiple lines the task would be easy.
I googled and found one solution at the official Autohotkey forum. That solution copies the text into the clipboard potentially deleting the clipboard content.
Is there a way to do this in autohotkey that doesn't use the clipboard where I can directly operate on the selected text?
Here are some basic Clipboard techniques:
ClipSaved := ClipboardAll ; Save the entire clipboard to a variable of your choice (in this case, ClipSaved).
; Here is where you put your code
Clipboard := ClipSaved ; Restore the original clipboard.
ClipSaved = ; Free the memory in case the clipboard was very large.
More here: https://autohotkey.com/docs/misc/Clipboard.htm
Well, this one requires your mouse cursor to hover over the window with the selected text:
MouseGetPos,,,thiswindow,thiscontrol
ControlGet,VarX,selected,,%thiscontrol%,ahk_id %thiswindow%
;Do something with "VarX" here.

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.