I am trying to make shortcut using autohotkey where typing "println" produces "System.out.println();" but typing ".println" produces ".println();".
The purpose of this is to help me with something I commonly type when I'm writing code for my java course. I want use the regular keyboard dot to be not the numpad dot for this shortcut but I do not care about which dot is used in the output.
I have tried the following:
;for Java println
::println::
SendInput System.out.println();{Left}{Left}
return
;block change if '.println'
::.println::
SendInput {NumpadDot}println();{Left}{Left}
return
However, this only does the first shortcut and not the second.
Can you help me get this script to work?
Declare ::.println:: before ::println:: and your idea will work.
::. println:: ; you might wan't to add this in case you add a space after a ,
SendInput {NumpadDot}println();{Left}{Left}
return
::.println::
SendInput {NumpadDot}println();{Left}{Left}
return
::println::
SendInput System.out.println();{Left}{Left}
return
Related
My goal is mapping WASD to the 4 arrow buttons on the keyboard and make 1 'Suspend' the script while z exits it. That was easy enough. Now I'd like a and d only apply conditionally. I look at the docs and I have no idea what's wrong here. I think I'm either using the if statement wrong or Left/Right doesn't work in if statements in which case I have no idea what to do.
#SingleInstance
a::if(UseAD) Left
d::if(UseAD) Right
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp
Try this:
#SingleInstance
$a::Send % UseAD ? "{Left}" : "a"
$d::Send % UseAD ? "{Right}" : "d"
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp
Okay now a break down.
Your If statement wasn't being evaluated correctly. The following line of code after the condition is met is what is run. Like so:
If (true)
do this
Your Hotkey is also wrong for a Multi lined statement. Essentially a single lined Hotkey is a basically a Send command for whatever key or keys specified on that line (unless you specify an assignment/function/command etc...) it will act as a Send Command does. To have an If evaluation requires multiple lines. When you specify a hotkey and you want an evaluation that will require multiple lines you, and must return from a Multi-Lined Hotkey same a Sub Routine:
a::
Code goes here
more code
etc..
Return
b::AnotherHotkey
etc..
Okay so lets plug this Logic in with your code:
#SingleInstance
a::
if(UseAD)
Left
return
d::
if(UseAD)
Right
return
1::Suspend
2::UseAD:=!UseAD
w::Up
s::Down
z::ExitApp
If you run this you'll get an Error about the Text Left... that is because instead of our Hotkey acting as Send command it's acting as a Sub Routine so we have to specify Send command with Left:
a::
if(UseAD)
Send, Left
return
But this isn't correct either, now it's sending the word Left instead of the Key left.. so again we have add Brackets around our named key like so:
a::
if(UseAD)
Send, {Left}
return
Okay, now a and b are not being sent when UseAD is False, so we must Send them by specifying with Else like so:
a::
if(UseAD)
Send, {Left}
else
Send, a
return
Now we run this code and press a or b get an Max Hotkeys reached message because our code is triggering the Hotkey in an Infinate loop. We need to specify our code in such a way that it will not trigger itself, like so:
$a::
if(UseAD)
Send, {Left}
else
Send, a
return
If you notice we have added a $ symbol in front of our hotkey, this adds a keyboard Hook to that Hotkey and will prevent the the script from triggering that hotkey itself. This is now a complete working script but looks entirely different from the first code I posted. That is because I like typing less lines, if I can.
In the first code sample I'm using a Forced Expression % on the Send command and Ternary ? : to evaluate UseAD and if true send Left key if false send the letter, exactly the same as above code, just more concise.
I have a Autohotkey script that puts "D89dl" at the end of a sentence everytime I press Enter, but using it with a AutoCorrect script it doesn't work as it should. Let's say you type "dont", it then would look like this "don't" instead of "don't.". Something is blocking it but I'm not sure what it is, I've been trying for months now.
Here are the scripts:
enter::
send,D89dl{Enter}
Return
#Hotstring EndChars -()[]{}:;'"/\,.?!`n `t
::dont::don't
I would be VERY thankful if anyone of you helps me with this.
Overall, do you know any other way instead of Autohotkey that puts "D89dl" at the end of a sentence?
The easiest solution seems to be to use the :*: mode, which will trigger everytime the misspelled word is typed, without the need for Hotstring EndChars:
:*:dont::don't
Instead of using Enter, I suggest you use a special combination of keys that enter the string D89dl and then press Enter. Use a modifier like ctrl or alt and another key. The reasoning is that the key Enter has very important functionality and should not be changed. Pressing that special combination is appropriate, given the very special function it does.
It's a bit hacky, but it should do the job (given that by "end of sentence" you actually meant pressing "Enter"):
~enter::
Sleep, 100
SendInput, {BS}D89dl{Enter}
Return
#Hotstring EndChars -()[]{}:;'"/\,.?!`n `t
::dont::don't
I found this working autohotkey (ahk) code from the website https://jacksautohotkeyblog.wordpress.com/2015/10/22/how-to-turn-autohotkey-hotstring-autocorrect-pop-up-menus-into-a-function-part-5-beginning-hotstrings/ .
::agin::
TextMenu("again,a gin,aging")
Return
::duh::
TextMenu("what,huh,you're joking")
Return
TextMenu(TextOptions)
{
StringSplit, MenuItems, TextOptions , `,
Loop %MenuItems0%
{
Item := MenuItems%A_Index%
Menu, MyMenu, add, %Item%, MenuAction
}
Menu, MyMenu, Show
Menu, MyMenu, DeleteAll ;Moved from MenuAction:
}
MenuAction:
SendInput %A_ThisMenuItem%{Raw}%A_EndChar%
Return
This is a hotstring script with menu. For example when I type agin I get a many with three options (again,a gin,aging) to choose. Now I want to write it something like this:
agin=again,a gin,aging
duh=what,huh,you're joking
qwe=qwe,qww,ere
Because I have a lot of hotstrings.
As time has passed, in the most recent version of AHK it became possible to do!
Use option x to allow expressions in the oneliner.
Either as :x:...:: OR as a group option above all lines: #Hotstring x
:x:agin::TextMenu("again,a gin,aging")
As nice as it would be, unlike AutoHotkey Hotkeys, I don't believe you can put anything other than replacement text on the same line of an AutoHotkey Hotstring. In other words,
::agin::TextMenu("again,a gin,aging")
would not work while,
::agin::
TextMenu("again,a gin,aging")
Return
does. It is a few more characters long, but not overwhelming.
I'm trying to make something for our employees to use so that they dont have to alter the script itself to define hotkeys. This may only work for hotkeys which can be defined by a single character, but that's fine, as there are so many combinations that can be made with them, and they can be very easy to remember. The script would look only at 2 character AHK files (or 6 if you must include the extension) in the working directory. And the variables it would search for could be defined with RegEx so for the first hotkey, it would look like ^. and then second would look like .(?=.) Once a match is found, it would simply launch that matched file. Has something like this been done before? It seems so simple but I can't seem to find anything on it.
Edit: Elliot brought this to my attention: http://autohotkey.com/board/topic/60630-easy-editmanage-hotkeyshotstrings-plugin-ahk-l/
It's a neat script manager, and very useful, but it's not what I'm looking for.
I dont not want an additional interface. I want to be able to change the hotkeys by using the filename.
Based on the answer of Forvin. Added the execution of the corresponding ahk script.
#Persistent
SetTimer, FindNewHotkeys, 2000
FindNewHotkeys:
Loop, %A_ScriptDir%\*
{
RegExMatch(A_LoopFileName, "^(.)(.).ahk$", hk)
If (hk)
{
Hotkey, ~%hk1% & ~%hk2%, HotkeyLabel
}
}
Return
HotkeyLabel:
RegExMatch(A_ThisHotkey, "~(.) & ~(.)", hk)
run, %hk1%%hk2%.ahk
Return
#Persistent
SetTimer, FindNewHotkeys, 2000
FindNewHotkeys:
Loop, %A_ScriptDir%\*
{
RegExMatch(A_LoopFileName, "^(.)(.).ahk$", hk)
If (hk)
Hotkey, ~%hk1% & ~%hk2%, HotkeyLabel
}
Return
HotkeyLabel:
MsgBox, A hotkey has been pressed!
Return
SendInput %userInput% causes my computer to do very weird stuff. Sometimes it logs off, sometimes my arrows of the keyboard get disabled, sometimes it runs cmd in windows an infinite times...
UPDATE:
this is the thing that gets inputed in the command line and runs:
runas /user:administrator cmd
UPDATE:
I think I almost got the problem, as such I edited the question to leave out what I deem to be irrelevant now.
When SendInput is happening, and the user is still inputting data in the keyboard, such as pressing the win-key, then this can cause the system to log off because win-key + l is a shortcut for that. Likewise must be for all the other things that are happening. Another observation is that SendInput skips certain characters, like {enter} etc. It only processes them at the end, when all the regular characters are put into place. I notice that at the end, SendInput is still busy doing stuff, perhaps some exotic characters it delayed till the end. Because the user think the output is complete, he ends up pressing the shortcut key again which in combination with the current sendInput is causing the system to crash.
UPDATE:
It also goes bezerk if there is a "!" to be send with SendInput.
This is one string I pasted to the copyboard:
dsjkfhjdsfsjdh!!!!!!!!!!!####################$$$$$$$$$$$%%%%%%%%%^^^^^^^^^^^^^&&&&&&&&&&&&&*****(((((((((())))))))))))____++++++++++++++++=======------------000000000000000099999988888.
But the output is WITHOUT the exclamation marks. Like this:
dsjkfhjdsfsjdh#######$$$$$$$$$$%%%%%%%%%&&&&&&&&&&&&*****(((((((((())))))))))))____+======------------000000000000000099999988888.
Why is that? Are there any other characters? Exclamation marks are important I feel, and I don't want to remove them. Are there any workarounds?
UPDATE:
It is more complicated than that. When I copy paste the above characters WITHOUT the exclamation marks, it still does weird stuff.
Here is some of the code that eventually userInput combines and sends away with SendInput:
StringReplace, contents, save_selection, ``, ````, All ; Do this replacement first to avoid interfering with the others below.
StringReplace, contents, contents, `r`n, %A_SPACE%, All ; Using `r works better than `n in MS Word, etc.
StringReplace, contents, contents, `;, ```;, All
;* loc_title origanally contains browser specification. Remove it.
StringGetPos, pos_delim, loc_title, - , R
length := StrLen(loc_title)
count := length - pos_delim
StringTrimRight, loc_title, loc_title, count
You could use sendraw instead of sendinput.
Here is what the docs say:
Raw mode: The SendRaw command interprets all characters literally
rather than translating {Enter} to an ENTER keystroke, ^c to
Control-C, etc. However, the normal rules for escape sequences,
variable references and expressions still apply since these are
processed before the command executes. To use raw mode with SendInput,
SendPlay, or SendEvent, write {Raw} as the first item in the string;
for example: SendInput {Raw}abc.
Then you don't have to worry about the ! or other control modifiers.
The reason that the exclamation mark character is an issue is because SendInput treats it as a code to press the Alt key.
There are several similar codes:
^ = Ctrl
+ = Shift
# = Windows key
You can find the others listed in the documentation for SendInput.
It seems like you want to send the raw text and not have SendInput look for these codes. You should be able to put {Raw} at the beginning of the userinput variable and it will ignore any codes in the rest of the characters.
If it is typing too slowly, you could put SetKeyDelay,-1 in your script to remove the key sending delay.
A good workaround that I found was to avoid SendInput altogether. Rather use the clipboard to copy the string inside, to then paste it on your screen. It works flawlessly, and is a billion times faster. Why would a person utilize SendInput in the first place? However, the actual question still is standing, why does SendInput behave so strangely? What is inside that string: %userInput% that causes my system to crash? How can I find out?