Autohotkey foreign language accents - autohotkey

I'm trying to create an easy ahk script for sending letters with accent marks when typing in different languages.
I know I can use !a::Send {U+00E0} to send à, but is there an easy way to say "If I enter a capital a, send À? I thought I'd be able to use !+a::Send {U+00C0} but that doesn't seem to work (and also seems a bit more complicated than it should be)

Eabryt,
The way I addressed this in AutoHotKey is like this:
;===== SPECIAL CHARACTERS FOR US KEYBOARD DRIVER (NOT US INTERNATIONAL) =======
:?C*:`` :: ; Turn `{Space} into a neutral `, else ` will be used in next vowel.
Send, ``{Space}{BackSpace}
Return
:?C*:``a::à
:?C*:``i::ì
:?C*:``e::è
:?C*:``o::ò
:?C*:``u::ù
:?C*:``A::À
:?C*:``I::Ì
:?C*:``E::È
:?C*:``O::Ò
:?C*:``U::Ù
:?C*:^ :: ; Turn ^{Space} into neutral ^, else ^ will be used in next vowel.
Send, {^}{Space}{BackSpace}
Return
:?C*:^a::â
:?C*:^i::î
:?C*:^e::ê
:?C*:^o::ô
:?C*:^u::û
:?C*:^A::Â
:?C*:^I::Î
:?C*:^E::Ê
:?C*:^O::Ô
:?C*:^U::Û
:?C*:`" :: ; Turn "{Space} into neutral ", else " will be used in next vowel.
Send, +{'}{Space}{BackSpace}
Return
:?C*:`'a::ä ; I used 'because I use the Umlaut's much more often than the accent aigu
:?C*:`;a::ä
:?C*:`'i::ï
:?C*:`;i::ï
:?C*:`'e::ë
:?C*:`;e::ë
:?C*:`'o::ö
:?C*:`;o::ö
:?C*:`'u::ü
:?C*:`;u::ü
:?C*:`'A::Ä
:?C*:`'I::Ï
:?C*:`'E::Ë
:?C*:`'O::Ö
:?C*:`'U::Ü
:?C*:' :: ; Turn '{Space} into neutral ', else ' will be used in next vowel.
Send, {'}{Space}{BackSpace}
Return
:?C*:`"a::á
:?C*:`"i::í
:?C*:`"e::é
:?C*:`"o::ó
:?C*:`"u::ú
:?C*:`"A::Á
:?C*:`"I::Í
:?C*:`"E::É
:?C*:`"O::Ó
:?C*:`"U::Ú
:?C*:`'c::ç
:?C*:`'C::Ç
:?C*:ss]::ß
:?C*:sss::ß
:?C*:ae]::æ
:?C*:AE]::Æ
:?C*:oe]::œ
:?C*:OE]::Œ
I use the Umlauts far more often than the accent aigu, therefore I (personally) swapped the use of the "and ' on my US International Keyboard. If this is too confusing, then just swap:
:?C*:`'a::ä with :?C*:`"a::ä
and
:?C*:`"a::á with :?C*:`'a::á
At the end are some special characters. I use the ] as the end sign for these special characters as it is close to the [Enter] key.

Related

Autohotkey: replace key combination (but with timeout)

When I type, I want my script to replace:
"ab" to "x"
"ac" to "y"
"a[more than 300ms]b" - don't replace, just leave "ab"
So, it should replace only if time between "a" and "b"/"c" is less than 300ms
tried doing this:
a & b :: Send x
a & c :: Send y
But it obviously doesn't 'forgive' me any delay
Would be great to get any hints, thanks!
A hotstring is usually good for replacements. To add that delay, here's a simple thing I could come up with:
~*a::APressTime := A_TickCount
:*B0:ab::
if(A_TickCount - APressTime <= 300)
SendInput, % "{BS 2}x"
return
First a simple hotkey for A that just saves the current system time with A_TickCount.
Then a hotstring to which I set some options you're likely going to want to use:
* so you don't need to type an ending character.
B0 so it doesn't backspace the letters ab automatically.
You might also want to use the ? option so the hotstring also works while "inside of a word". Add it in if you want.
Then we compare the current system time to the time when a was last pressed. If it's 300ms or less, send backspace twice followed up by x.
({BS 2} is same as {Backspace 2} or {Backspace}{Backspace})
To do the same with ac, just copy paste the hotstring again and switch b with c, and x with y.
Alternatively, here's something a bit more fancy to put them in the same hotstring label with a ternary:
:*B0:ab::
:*B0:ac::
if(A_TickCount - APressTime <= 300)
SendInput, % "{BS 2}" (SubStr(A_ThisHotkey, 0) = "b" ? "x" : "y")
return

Autohotkey - how to store unicode and use it?

Here's my code below. AHK file is saved as UTF-8 with BOM and I can see the unicode characters just fine whenever I paste it into the script. But everytime I save the script and re-open it, the unicode characters become question marks and random gibberish characters. When "sendinput" is run, the output also comes out as question marks and gibberish, instead of the actual unicode emoticons.
MyVarEmoticon =
(Ltrim
What is your choice? (Enter #):
1. (╯°□°)╯︵ ┻━┻
2. (┛ಠ_ಠ)┛彡┻━┻
3. (╯°Д°)╯︵/(.□ . \)
4. ┏━┓┏━┓┏━┓ ︵ /(^.^/)
)
InputBox, MyVarEmoticonChoices, Emoticon Choices, %MyVarEmoticon%, , 400, % HEmoticon(MyVarEmoticon),,,,,1
HEmoticon(MyVarEmoticon)
{
StringReplace, MyVarEmoticon,myvaremoticon,`n,`n,UseErrorLevel
Lines:=ErrorLevel+1
height:=lines * 30 ; play with this value !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;MsgBox % height
If (Height < 40) ; too low
Height+=80
Return height
}
if ErrorLevel {
;MsgBox, CANCEL was pressed.
} else {
if (MyVarEmoticonChoices = "1"){
MyVarEmoticonChoices = (╯°□°)╯︵ ┻━┻
}
if (MyVarEmoticonChoices = "2"){
MyVarEmoticonChoices = (┛ಠ_ಠ)┛彡┻━┻
}
if (MyVarEmoticonChoices = "3"){
MyVarEmoticonChoices = (╯°Д°)╯︵/(.□ . \)
}
if (MyVarEmoticonChoices = "4"){
MyVarEmoticonChoices = ┏━┓┏━┓┏━┓ ︵ /(^.^/)
}
WinGetPos, X, Y, Width, Height, ahk_exe ToW.exe, , ,
XVar = %X%
YVar = %Y%
WVar = %Width%
HVar = %Height%
XWVar = % XVar+39
YHVar = % YVar+682
Sleep,200
sendinput, {raw}%MyVarEmoticonChoices%
Although there are some quite weird things in this code, it seems to work as expected if saved with the correct encoding.
I can't really know what goes wrong when you're trying to save it, maybe try to explain the steps you take to save it in the editor you're using.
If you don't want to worry about file encoding, you could store the characters as code points for example.
You can find a quick little converter with a Google search, here is the one I landed on with a Google search:
http://unicode.scarfboy.com/?s=%28%E2%95%AF%C2%B0%E2%96%A1%C2%B0%29%E2%95%AF%EF%B8%B5+%E2%94%BB%E2%94%81%E2%94%BB
And then you can convert to the code points to characters with Chr().
For example:
emote := "0028 256F 00B0 25A1 00B0 0029 256F FE35 0020 253B 2501 253B"
for each, codepoint in StrSplit(emote, " ")
output .= Chr("0x" codepoint)
Clipboard := output
SendInput, ^v
And here I'm also utilizing the clipboard and sending Ctrl+v, which is a good trick if you can use it. Especially for long text, which this really isn't I guess, but I figured I'd show it.
Or if you want to Send the string, you can use the Unicode notation:
emote := "0028 256F 00B0 25A1 00B0 0029 256F FE35 0020 253B 2501 253B"
for each, codepoint in StrSplit(emote, " ")
output .= "{U+" codepoint "}"
SendInput, % output
;SendInput, % "{U+0028}{U+256F}{U+00B0}{U+25A1}{U+00B0}{U+0029}{U+256F}{U+FE35}{U+0020}{U+253B}{U+2501}{U+253B}"
In ahk script files you must choose UTF-16 LE BOM Encoding to support Unicode characters. That's a Microsoft Windows default behaviour which indicates all other encodings as ASCII.

Get First Character of A_LoopFileName?

I'm trying to parse a filename and get the first character from it as a string to compare it to a previously inputted variable. My code looks like:
FileSelectFolder, WhichFolder ; Ask the user to pick a folder.
; Ask what letter you want to start the loop from
InputBox, UserInput, Start At What Letter?, Please enter a letter to start at within the folder (CAPITALIZE IT!)., , 450, 150
if ErrorLevel {
MsgBox, CANCEL was pressed.
ExitApp
} else {
inputted_letter = %UserInput%
tooltip %inputted_letter% ; Show the inputted letter
sleep, 2000
tooltip
}
Loop, %WhichFolder%\*.*
{
current_filename_full = %A_LoopFileName%
files_first_letter := SubStr(current_filename_full, 1, 1)
tooltip %files_first_letter% ; Show the file's first letter
sleep, 2000
tooltip
if files_first_letter != inputted_letter
continue
...
Right now, it clearly shows in the tooltips the user-entered capital letter, and then the first letter of each file name from within the selected folder, but for some reason when the two look alike, it doesn't recognize them as a match. I'm thinking maybe because technically A_LoopFileName is not of a string type? Or maybe the inputted letter doesn't match the type of the first filename's letter?
I want it to continue if the inputted letter and the first letter of the filename don't match, but if they do, to carry on with the rest of the script. Any ideas on how I can get these two to successfully match? Thanks!
Firstly, AHK doesn't really have types. At least not how you've experienced types in other languages.
So your assumption about "not being correct type" will pretty much always be wrong.
So the actual cause is because in a legacy if statement, the syntax is
if <name of variable> <operator> <legacy way of representing a value>
So you'd do it like this:
if files_first_letter != %inputted_letter%
You we're comparing if the variable files_first_letter is equal to the literal text inputted_letter.
However, I highly recommend you stop using legacy syntax. It's really just that old.
It'll differ horribly much from any other programming language and you run into confusing behavior like this. Expression syntax is what you want to use in AHK nowadays.
Here's your code snippet converted over to expression syntax in case you're interested:
FileSelectFolder, WhichFolder
;Forcing an expression like this with % in every parameter
;is really not needed of course, and could be considered
;excessive, but I'm doing it for demonstrational
;purposes here. Putting everything in expression syntax.
;also, not gonna lie, I always do it myself haha
InputBox, UserInput, % "Start At What Letter?", % "Please enter a letter to start at within the folder (CAPITALIZE IT!).", , 450, 150
if (ErrorLevel)
;braces indicate an expression and the non-legacy if statement
;more about this, as an expression, ErrorLevel here holds the value
;1, which gets evaluated to true, so we're doing
;if (true), which is true
{
MsgBox, % "CANCEL was pressed."
ExitApp
}
else
inputted_letter := UserInput ; = is never used, always :=
Loop, Files, % WhichFolder "\*.*"
;non-legacy file loop
;note that here forcing the expression statement
;with % is actually very much needed
{
current_filename_full := A_LoopFileName
files_first_letter := SubStr(current_filename_full, 1, 1)
if (files_first_letter != inputted_letter)
continue
}
Also you don't have to be concerned about case with !=, it'll always compare case insensitively.

How to keep original keybind aswell as well as a new one in AHK?

So i have an ahk script to write letters with macrons for Latin words. When you press tilde and a vowel; it types that vowel with a macron. My only problem is removes the function of the tilde key, except typing macrons. adding a ~ to keep the original keybind makes it so when i hit tilde and a vowel, it types tilde and a long vowel. How do i fix this? (this is supposed to replicate the Maori keyboard, but that was too tedious)
` & a::
send, ā
return
` & e::
send, ē
return
` & i::
send, ī
return
` & o::
send, ō
return
` & u::
send, ū
return
Add `::` to your script and backtick (`) will fire when you release the key and tilde (~) will fire on press.
https://www.autohotkey.com/docs/Hotkeys.htm#combo
Alternatively, you can use
Hotstrings
aa := Chr(257)
:?O:`a::
Send, %aa%
Return
Typing `athen pressing an ending character (like Space) creates ā.
• The "O" is an Option which omits the ending character (such as an unwanted Space).
• The "?" is an Option which allows the hotstring to be triggered inside of words, so you can type pra` then a Space and it will become prā.
• Using Hotstrings instead of Hotkeys will keep the functionality of the Tilde key unchanged.
• By default, the backtick (`) is used as the AHK escape character. For this Hotstring to work properly, the escape character should be changed. Example:
#EscapeChar \
My version of your script:
#EscapeChar \
; lower case graphemes
aa := Chr(257)
ee := Chr(275)
ii := Chr(299)
oo := Chr(333)
uu := Chr(363)
yy := Chr(563)
ae := Chr(230)
; upper case graphemes
upper_aa := Chr(256)
upper_ee := Chr(274)
upper_ii := Chr(298)
upper_oo := Chr(332)
upper_uu := Chr(362)
upper_yy := Chr(562)
upper_ae := Chr(198)
; Hotstrings
:?O:`a::
Send, %aa%
Return
:?O:`a`::
Send, %upper_aa%
Return
:?O:`e::
Send, %ee%
Return
:?O:`e`::
Send, %upper_ee%
Return
:?O:`i::
Send, %ii%
Return
:?O:`i`::
Send, %upper_ii%
Return
:?O:`o::
Send, %oo%
Return
:?O:`o`::
Send, %upper_oo%
Return
:?O:`u::
Send, %uu%
Return
:?O:`u`::
Send, %upper_uu%
Return
:?O:`y::
Send, %yy%
Return
:?O:`y`::
Send, %upper_yy%
Return
:?O:`ae::
Send, %ae%
Return
:?O:`ae`::
Send, %upper_ae%
Return
>
The above snippet saves the true ASCII values of the characters to variables (as to avoid compatibility issues), rather than trying to print the characters directly through "Send".
Other Options (and more information on Hotstrings) can be found in the Hotstrings AutoHotkey documentation.

Can I list several keys to perform the same action? [AHK]

AHK allows to bind keys, that is us a::z t fire 'z' whenever 'a' is pressed.
What if I want to fire 'z' whenever 'a', 'b', or 'c' is pressed?
I can obviously repeat my code:
a::z
b::z
c::z
I can probably use a Gosub like
a::Gosub, abc
b::Gosub, abc
c::Gosub, abc
abc:
send z
return
Is there a better way to say "if a,b, or c are pressed - fire z"?
You can just use
a::
b::
c::z
i am not sure what is the exact synthax, but this works.
We're at codegolf.stackexchange.com, right?
JFF, here's assigning A-Y to Z with just 61 characters, using the Hotkey command:
loop,25
hotkey,% chr(a_index+64),z
return
z(){
send z
}
Another solution using Hotkey to define hotkeys on the fly, and parse so that the user can directly specify a list of keys:
; Thanks engunneer: autohotkey.com/board/topic/45636-script-to-prevent-double-typing/?p=284048
; Thanks throwaway_ye: https://www.reddit.com/r/AutoHotkey/comments/54g40q/how_can_i_bind_several_keys_to_the_same_command/d81j0we
; The following part must be located in the auto-execute section,
; i.e. the top part of the AHK script.
keylist = 1234567890qwertzuiopasdfghjklyxcvbnm
Loop, parse, keylist
{
Hotkey, $%A_LoopField%, SendGivenKey
}
Return
; This can be located anywhere in the AHK file
SendGivenKey:
StringReplace, key, A_ThisHotkey, $, , All
send %key%
Return