Autohotkey - Undo entire macro instead of single commands (Windows 7) - autohotkey

I tried searching for an answer beforehand but didn't find what I was looking for. Apologies in advance if this has been answered before.
I do some web work and created a macro in AHK that binds Ctrl+Shift+B to the HTML equivalent of adding bold tags around a text selection.
The flow is:
cut (ctrl+x), type <b>, paste cut text (ctrl+v), type </b>.
The macro runs fine, but sometimes I want to undo it. However, whenever I press Undo (ctrl+z), I'm left pressing the command 4 times, with each press reverting 1 of the commands posted above.
Is there a better way to write my AHK macro so that I'm able to undo the entire macro in 1 keypress? Any tips would be great. For Windows 7 if that makes a difference.
I've added the macro below.
^+b::
{
SendInput ^x
SendInput <b>
SendInput ^v
SendInput </b>
return
}
Edit: & #60; is the hmtl equiv on '<', but I was worried that this post would convert the HTML tags instead of showing the characters. Fixed.
Sorry about that, I tend to use a combination of notepad, notepad++, internet explorer to access a CMS. –
I think adding a delay and rewriting the AHK macro in the following way has solved my issue. Thanks for the help!
^+b::
clipboard =
SendInput ^x
ClipWait,1
if ErrorLevel
{
MsgBox, The attempt to copy text onto the clipboard failed.
return
}
SendInput < b >%clipboard% < /b>
return

Try this instead:
^+b::
{
Clipboard =
SendInput ^c
ClipWait, 1
Clipboard = <b>%Clipboard%</b>
SendInput ^v
return
}
Because the only thing you are doing is a paste, undoing this will undo both of the bold tag. The clipboard edits are not registered as an "undo" action.

Here is some code:
^+b::
Click, 2 ; Highlight current word
Send, ^x
ClipWait, 1 ; ADDED to wait for clipboard
SendInput, <b>^v<`/b>
Return
!b::
Send, ^{z 4}
Return
or
!b::
Send, "command to search backwards" for </b>
Send, {Del}
Send, "command to search backwards" for <b>
Send, {Del}
Return
or
!b::
Send, {Home}+{end} ; [Home] then [Shift][End] to highlight current line
Send, ^h ; Or any other command to start find/replace
Send, <b>^v<`/b>{Tab}^v{Enter} ; or what is required to replace in current section only...
Return

Related

How to make script to paste something in with AutoHotKey

I'm trying to make a script in AutoHotkey where, when I press Numpad 1, it presses the slash button, then pastes in some text, let's say "hello world", and then presses enter, but I can't figure out how. Can someone help?
Welcome to Stack Overflow.
In the future, try to at least show what you tried. All of this should be accomplished pretty easily by e.g. looking at the beginner tutorial combined with a quick Google search.
But well, here it is:
Numpad1::
Clipboard := "/hello word"
SendInput, ^v{Enter}
return
Numpad1:: creates the hotkey label.
Clipboard:= ... puts something into the clipboard.
SendInput sends input.
^v means Ctrl+v.
{Enter} means the enter key (could've possibly appended `n (line feed) into the string as well).
Return stops the hotkey label's code execution (in other words, ends the hotkey's code).
Assuming that you already have some text copied inside your clipboard before pressing the numpad1, the following code will work.
Numpad1::
Send, /^v ; ^ means ctrl key,
Send, {Enter}
return

Automatic translation

im really new to all this and i was trying to make an Autohotkey for translation. i was digging for some time looking for examples that only confused me more, even if the code looked simple, i didn't understand half of it.
So, what I'm trying to do is: select a paragraph and replace it automatically with its translation.
i was hooping it to be somenthing as simple as CTRJ + C, Translate, CTRL + V, but i can't find the command to go to google translate or somenthing similar, it's not on the autohotkey help file so i'm guessing i don't have libraries?
I'm at my wits end, please help.
You came to the right place. Check out AutoHotKey for sure.
First, how to do it by hand? Those are the steps for ahk. So, lets say you have a paragraph of text selected. You will hit the ahk shortcut and that shortcut will:
first ahk figures out what window its in (using WinGetActiveTitle) and then sends the keystrokes Ctrl+c to copy the selection ("send, ^c" and "Clipwait"), then
ahk can access the clipboard containing the text, do a string manipulation or regex to replace all spaces with the html escape sequence %20 (eg, transtext := StrReplace(Clipboard, " ", "%20")) and
construct a URL to do the Google Translate, something like (where sl is source language and tl is translation language, and text is what you want translated): transurl := "https://translate.google.com/#view=home&op=translate&sl=en&tl=es&text=" . transtext
AHK runs that url and opens a browser window showing result (run % transurl).
This part sucks. Now, you need to use a mouse click at a location (or maybe you can find a controlsend or a combination of keystrokes moving the cursor with tabs and such) to land on the "Copy translation" button. Or how bout you do it manually (try sleep, 8000 to wait while you hit the button)
then have ahk close the window (optionally, or you just do it by hand during the sleep time) and
ahk switches back to the application with the original selected paragraph (WinActivate or do it yourself) and
send ctrl+v to paste the translated text over the original (send ^v).
A starter pack of AHK code (edited per user comments):
WinGetActiveTitle, activewin
Clipboard =
SendInput, ^c
ClipWait
transtext := StrReplace(Clipboard, " ", "%20")
transurl := "https://translate.google.com/#view=home&op=translate&sl=en&tl=es&text=" . transtext
Run, % transurl
Sleep, 6000 ; adjust to taste.
SendEvent, {tab 10} ; adjust to taste.
Sleep 1000
SendInput, {enter}
Sleep, 1000
SendInput, ^{F4}
WinActivate, activewin
sleep, 1000
SendInput, ^v
Try it and let us know how else to help.
OKOK, first of all, thank you all, the script works just fine now. I'm able to copy, translate and paste any text now. Only a few questions lingering.
1) i'm not sure i get what the step number 5 is suppose to do. whatever it is, it works so i don't touch it.
2) is there a way to reset google.translate so it dosent open a new window every time? that could save a lot of time.
3) this one doesn't have a chance, but i ask anyway. Is there a way to not open google chrome at all? because i know that u can translate from excel automatically. (i know that if it is possible will be super hard)
This is the code i ended with:
^a::
clipboard := ""
sendinput, ^c
ClipWait [,,Waitforanydata]
transtext := StrReplace(Clipboard, " ", "%20")
transurl := "https://translate.google.com/#view=home&op=translate&sl=en&tl=es&text=" .
transtext
run % transurl
Sleep, 4000
SendEvent, {tab 9}
SendEvent, {enter}
Winactivate, NAME.pdf - PROGRAM
sendinput, ^v

How to send a key repeatedly in Autohotkey

I want to write an AutoHotkey script which loop a key X number of times.
For example, here's is a script which overwrites the function of ENTER key with function of F2 key in File Explorer.
#IfWinActive ahk_class CabinetWClass
Enter::
Send, {F2}
#IfWinActive ahk_class CabinetWClass
Enter::
Send, {ENTER}
#IfWinActive
The goal is to press ENTER to rename a select file, and then press ENTER to confirm the rename. Pressing ENTER on the same file that have just been renamed should send F2 key again (In case there is typo error).
Currently the second block doesn't work as I'm sending the same key, how to fix this?
The KeyWait command is your friend in this case.
There is still room to improve on how you handle the second Enter
#IfWinActive ahk_class CabinetWClass
$Enter::
sleep,100 ; giving time to detect the first Enter
Send, {F2}
Keywait, Enter, T5 D ; wait 5 seconds for the Enter to be pressed down
If (ErrorLevel == 0)
{
Send, {Enter}
sleep 200
Send, {F2}
}
else
{
traytip, , timeout ; Enter was not pressed down in 5 seconds
}
return
Basically, it appears you're trying to assign different tasks to the same hotkey and due to this being done seperately ahk is selecting one of the tasks and running with that task and only that task. If loops can be used within hotkeys, so I would suggest using this to rotate between the two expected outcomes. Please see example below:
temp:= 1
enter::
if(temp==1)
{
Send, {ENTER}
temp:=2
}
else if(temp==2)
{
Send, {F2}
temp:=1
}
return
1::
Temp:=1
return
2::
temp:=2
return
^x::ExitApp
I also added in hotkeys for 1/2 to allow you to manually decide the outcome rather than it being specifically assigned in the case of any issues.
Oh, and ctrl+x to close the macro.
You're trying to rebind the enter key twice.
Rebinding a key is like saying "When I press this key, do this:" - in this case it's under an #IfWinActive so it's more like "When this window is open and I press this key..."
When you break that down you have "When I press enter - press F2" as well as "When I press enter, press enter"
What you're wanting to achieve is make the rebind conditional - i.e. it only sends F2 under certain conditions.
It's hard to know how to help without more context. Is there any reason you can't use a different key combination? Like Ctrl + Shift + Enter?
Something like:
+^Enter::send, {F2}

How do I delete the current line using AutoHotkey?

Using an AutoHotkey script I'd like to set the keyboard command Ctrl+D to delete the current line in any active Windows app.
How?
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del}
Might not work in all edge cases, but passes some very basic testing in Notepad. =~)
HaveSpacesuit's answer works but after using it for a while I realized it deletes the active line and sometimes re-positions the spacing of the line below.
This led me to rethink his solution. Instead of going from the front of the line to the back, I tried going from back to front. This solved the re-positioning issue.
SendInput {End}
SendInput +{Home}
SendInput ^+{Left}
SendInput {Delete}
There is still a small problem though. If the cursor is on an empty line, with more empty lines above, then all empty lines get deleted.
I don't know a key combo to replace ^+{Left} that doesn't have this behavior so I had to write a more comprehensive solution.
^d:: DeleteCurrentLine()
DeleteCurrentLine() {
SendInput {End}
SendInput +{Home}
If get_SelectedText() = "" {
; On an empty line.
SendInput {Delete}
} Else {
SendInput ^+{Left}
SendInput {Delete}
}
}
get_SelectedText() {
; See if selection can be captured without using the clipboard.
WinActive("A")
ControlGetFocus ctrl
ControlGet selectedText, Selected,, %ctrl%
;If not, use the clipboard as a fallback.
If (selectedText = "") {
originalClipboard := ClipboardAll ; Store current clipboard.
Clipboard := ""
SendInput ^c
ClipWait .2
selectedText := ClipBoard
ClipBoard := originalClipboard
}
Return selectedText
}
As far as I can tell this produces no unexpected behaviour.
However, be careful if you're using a clipboard manager as this script uses the clipboard, if necessary, as an intermediary to get the selected text. This will impact clipboard manager history.
In case you run into problems where you need different behaviours for different programs, you can "duplicate" your ^d command for specific programs like this:
SetTitleMatchMode, 2 ; Makes the #IfWinActive name searching flexible
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; Generic response to ^d.
#IfWinActive, Gmail ; Gmail specific response
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; adapt this line for gmail
#IfWinActive ; End of Gmail's specific response to ^d
#IfWinActive, Excel ; Excel specific response.
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; adapt this line for Excel
#IfWinActive ; End of Excel's specific response to ^d
This way your ^d command will work differently in Excel and Gmail.
I have a simple way to solve the repositioning issue. Without using the clipboard.
The repositioning issue is due to the need to handle 2 separate cases.
if there's existing text in a line,
we want to select them all, and delete the text (backspace 1)
and backspace one more time to delete the empty line (backspace 2)
if it's a blank line,
we want to delete the empty line (backspace 1)
To cater for both of above cases, I introduced a dummy character.
This will make sure BOTH cases will act the same way.
So doing backspace 2 times, will result in the same transformation each time.
Simply,
; enable delete line shortcut
^d::
Send {Home}
Send {Shift Down}{End}{Shift Up}
Send d
Send {Backspace 2}
Send {down}
return
Disadvantage with this approach,
the dummy character "d" will appear when you undo. Not a bad tradeoff since I don't undo delete lines very often.

Autohotkey - Copy selected text, paste in Notepad++

I'm new to Autohotkey, tried to make a macro to:
Copy selection
Paste it in Notepad++
Playback Notepad++ macro (for formatting) shortcut: Ctrl+Shift+B
Copy all the edited text
Paste in Firefox text field
I tried starting with the following code, but I couldn't even get AHK to copy paste my selection to Notepad++.
^!x::
Send, ^c
ClipWait
IfWinExist, Notepad++
{
WinActivate
Send ^v
}
Here is working script:
^!x::
Send, ^c
ClipWait
SetTitleMatchMode, 2
IfWinExist, Notepad
{
WinActivate
Send, ^v
}
return
I added command SetTitleMatchMode, 2 as Joe DF mentioned in comments. That command (link) with parameter 2 sets the matching behavior of IfWinExist command so that a window's title can contain WinTitle anywhere inside it to be a match. Also added return in the end.