Using a hotstring and an hotkey at the same time - autohotkey

This question is related to How to set `underline` followed by a character to send another key.
I would like that _t produces T and t produces s. But using the following _t produces _s. Is there any way to fix it?
t::s
:*:_t::T

The Computer can not see the differency between a [hotstring t presses] and a [hotkey t presses] the only thing what you can do is to do if _ is pressed [disable the hotkey] and then [enable enother t hotkey that send the Shift+t=T if the t is pressed] you can do that with the [#if] commands
try this AHK code.
; [+ = Shift] [! = Alt] [^ = Ctrl] [# = Win]
#SingleInstance force
mode=1
:*:_::
send _
mode=0
modes=1
return
#if mode
t::s
#if
#if modes
t::
send +t
mode=1
modes=0
return
#if
note - If you change the code a little bit, you can then also use a Hotstring in the modes for example: :*:test???:: minus the Hotstring :*:_???::

How about
:*:_t::T
t::SendRaw s
or with hotstrings
:*:_t::T
:*R:t::s
Oleg's comment below makes sense, add ? to the option(s) of the hotstring(s)
adding other keys
:*:_t::T
:*R:t::s
:*:a::a
:*:b::b
:*:c::c
:*:d::d
:*:e::e
:*:f::f
:*:g::g
:*:h::h
:*:i::i
:*:j::j
:*:k::k
:*:l::l
:*:m::m
:*:n::n
:*:o::o
:*:p::p
:*:q::q
:*:r::r
:*:u::u
:*:v::v
:*:w::w
:*:x::x
:*:y::y
:*:z::z

Related

How to exit a REPL from the command line

I'm currently learning Lua and also learning how to work with CMD.
I know how to change a directory path and run my codes and files from that path
but what I don't know and I'm here to ask for is how to get out of a programming language REPL when you start it in CMD
For example to jump into the Lua REPL you should type:
lua53 (--like python3 for the Python language)
then you changed the CMD environment to a Lua compiler and can't access CMD commands such as
dir, cd, cls etc. and everytime when I need to access these commands I have to close the CMD window and open a new one.
Now can you guys tell me am I able to access CMD commands while in the Lua REPL? Or do I have to exit Lua first, and is there any command to exit a REPL?
I'd recommend EOF (Ctrl + D on Unix) rather than SIGKILL (Ctrl + C) because some REPLs (node and python) choose to ignore the latter (perhaps because it's often used for copying text?); python will just print KeyboardInterrupt whereas node will only exit if you press Ctrl + C twice (it will send a message telling you this the first time).
EOF (Ctrl + D) on the other hand immediately exists all REPLs I have used so far.
The Lua REPL stops immediately when it receives either EOF or SIGKILL, so you can use both here.
Edit: As Sowban points out, EOF apparently is entered as Ctrl + Z then Enter in powershell.
You could type ctrl c to exit the process that's running generally.
I suggest to write a REPL by yourself.
But be warned :-)
The main loop with a prompt and the interpreting and executing function/method is mostly the easiest part.
99.99999% is the errorhandling thing.
One of my earliest interpreter language is (A)REXX.
A REPL without any errorhandling is done with...
/* REXX have to start with a comment */
do forever
parse pull input
interpret input
end
Now Lua sandboxed to an _ENV with io and os library and a little bit of errorhandling...
#!/usr/bin/env -S readline-editor /usr/local/bin/lua
-- ^--SHEBANG for Linux --------------------------------------------------------------------------------------
-- interpreter.lua
-- Sandboxed to io and os
-- Lua 5.4 >>-because-> goto label <const> load()
--------------------------------------------------------------------------------------------------------------
local Lua = function(...)
-- Info about OS
io.write(("%s\n"):format(io.popen('uname -a'):read())):flush()
-- Global Setting
debug.setmetatable((1), {__index = math}) -- Add math library to number as methods (like string for strings)
os.setlocale('de_DE.UTF8')
os.setlocale('en_US.UTF8', 'time')
io.write(os.date("[%c]\n" .. ("%s\n"):format(os.setlocale():gsub("%;", "\n")))):flush()
-- io.write(("%s\n"):format(_VERSION)):flush()
-- Label for goto
::lua::
-- Local Setting
local args <const> = args or {...}
local Lua = Lua or true
local cmd = cmd or ""
--------------------------------------------------------------------------------------------------------------
local env <const> = env or setmetatable({os = os, io = io}, -- The _ENV for load()
{__call = function(self, ...)
local self, t = ({...})[1] or self, "" -- First argument becomes self if one
if ({...})[1] == "help" then self = getmetatable(({...})[2]).__index end -- Showing metamethod __index (table)
for k, v in pairs(self) do
t = t .. ("%s => %s\n"):format(k, v)
end
return t
end,
__index = {cg = collectgarbage,
gt = getmetatable,
pairs = pairs,
tn = tonumber,
ts = tostring,
_V = ("%s \27[1;" .. (31):random(36) .. "m(sandboxed)\27[0m"):format(_VERSION)},
__tostring = function(self) return self._V end}) -- end env
--------------------------------------------------------------------------------------------------------------
local prompt = prompt or setmetatable({}, {__tostring = function() return getmetatable(env).__index._V .. "> " end})
local name <const> = name or _VERSION
local result = result or true
--------------------------------------------------------------------------------------------------------------
while Lua do
io.write(tostring(prompt))
cmd = io.read() or 'quit'
if cmd == "quit" then Lua, result = true, true break end
Lua, result = pcall(load("return " .. cmd or false, name, "t", env))
if Lua and result then
io.write(("%s"):format(tostring(result)))
else
goto exception
end
end
--------------------------------------------------------------------------------------------------------------
-- Errorhandler
::exception::
io.write(("%s\n"):format("Exception"))
if not Lua or not result then
io.output(io.stderr)
io.write(("[%s][%s][%s]\n\27[1;31m>>-Exception->\27[0m %s\n"):format(os.date(), _VERSION, cmd, result)):flush()
io.output(io.stdout)
collectgarbage()
goto lua
end
goto lua
end
--------------------------------------------------------------------------------------------------------------
-- EXAMPLE ---------------------------------------------------------------------------------------------------
-- Lua = require("interpreter")
Lua() -- UNCOMMENT-> For direct execution like: /bin/lua interpreter.lua
return Lua -- UNCOMMENT-> For: Lua = require("interpreter")
Ctrl&C quits hardly
Ctrl&D is only an exception
...and os.exit(0) do an clean exit with returncode 0.
Impression

Remap `AltGr & someKey`

How do I remap e.g. AltGr + i?
I know how to remap other combinations like alt + i (!i::Send, test) or shift + i (+i::Send, test). But this doesn't work for AltGr.
I know how to map AltGr isolated: LControl & RAlt::Send, test works. But LControl & RAlt & i::Send, test doesn't work.
So, how do I go about it?
EDIT: SOLVED
This solution worked
From the post that OP linked:
Use a context sensitive #IF statement to check whether AltGr is held down, then create a standard one-button hotkey.
#user3419297's example:
LControl & RAlt:: AltGr := true ; assign the boolean value "true" to the variable 'AltGr''
LControl & RAlt Up:: AltGr := false
; The #If directive creates context-sensitive hotkeys and hotstrings
#If (AltGr) ; If this variable has the value "true"
a:: MsgBox AltGr+a
a & b:: MsgBox AltGr+a+b
b & a:: MsgBox AltGr+b+a
h & l:: Send Hello
i & e:: Run iexplore.exe
n & p:: Run notepad
w & p:: Run wordpad
#If ; turn off context sensitivity
So for OP's specific question:
#If (AltGr)
i::Send, test
#If
More info: Context Sensative #IF statements

How can I bind several keys to the same command in AutoHotKey?

How can I bind several keys to the same command in AutoHotKey?
Example: I have this command:
spamLimit(limitTime)
{
StringReplace, key, A_ThisHotkey, $, , All
send %key%
sleep limitTime
}
I would like to bind several to this command, with the same parameter value:
a::spamLimit(500)
b::spamLimit(500)
c::spamLimit(500)
p::spamLimit(500)
d::spamLimit(500)
e::spamLimit(500)
Simplest solution:
a::
b::
c::
p::
d::
e::
spamLimit(500)
return
You can use Hotkey to define hotkeys on the fly:
; 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%, spamLimitNoParam
}
Return
; This can be located anywhere in the AHK file
spamLimitNoParam:
spamLimit(200)
Return
This is equivalent to the solution Bob pointed to:
$a::
$b::
$c::
$d::
$e::
$f::
$g::
$h::
$i::
$j::
$k::
$l::
$m::
$n::
$o::
$p::
$q::
$r::
$s::
$t::
$u::
$v::
$w::
$x::
$y::
$z::
$0::
$1::
$2::
$3::
$4::
$5::
$6::
$7::
$8::
$9::
spamLimit(200)

SendEvent ^{ins} isn't copying content to the clipboard

!c::
file_name = footnote.ini
restore_original_clipBoard := clipboard
clipboard =
KeyWait, Alt
KeyWait, c ;small c
BlockInput, on
SendEvent, ^{ins} ;^c doesn't work
ClipWait, 2 ; Wait for the clipboard to contain text.
if ErrorLevel
{
MsgBox Failed to save the selection: %clipboard%
exit
}
BlockInput, off
save_selection := clipboard
Problem: Despite a selection being made, Sendevent ^{ins} does not save it to the clipboard. Sometimes I have to repeat my hotkey, alt + c several times before the selection is being copied to the clipboard. The KeyWait should ensure me that only ^{ins} is being processed without any additional keys. What am I doing wrong here?
UPDATE
One of the ways I tried to force copy a selection to the clipboard was by using a while loop. I got it to work through the post: Looping clipboard and errorlevel evaluation not working as expected
PROBLEM
When I make a selection and press alt + c it sometimes gets stuck in the infinite loop that I implemented. But as you can see from that code:
clipboard := ""
while( StrLen(clipboard) < 1 )
{
Send, ^{ins}
Sleep, 50
}
MsgBox % ClipBoard
The infinite loop incorporates within itself a continues resending of ^{ins}. For some reason, my selection is not being recognized as a selection. Whilst it is in that infinite loop, I try to reselect the text. It then recognizes it instantly and copies my selection to the clipboard. But alas! The selection is incomplete because it goes so quick.
This problem is not always like that. Sometimes it recognizes the selection first spot on! So sometimes it copies my selection to my clipboard sometimes not. When it does not, then a resending of a ^{ins} does not seem to work. I do not want to the user to reselect his selection. Is that possible to do?
Send {Ctrl Down}{c}{Ctrl Up}
That presses Ctrl+C, you must do it instantly as one command apposed to pressing Ctrl waiting then pressing C.
Never seen Insert key used for copying text.
Also found this sends Ctrl+C as well.
Send, ^c
To send insert key use
{Insert}
This way works for me:
!vk43:: ; alt+c
clipContent:=ClipboardAll
Clipboard:=""
SendEvent, ^{Ins}
ClipWait, .75
MsgBox, % 262 . (ErrorLevel ? 160:208)
, % ErrorLevel ? "Period expired:":"Result:"
, % ErrorLevel ? "Failed to save the selection.":Clipboard
, % (ErrorLevel ? 0:2) . .5
Clipboard:=clipContent
KeyWait, vk43
Return
!vk43:: ; alt+c
clipContent:=ClipboardAll ; backup clipboard content (if needed)
Clipboard:="" ; no comment :)
Loop
{
SendEvent, ^{Ins}
ClipWait, .75 ; means 750ms, same if write 0.75
; assign value of "ErrorLevel" an variable for further usage
errLvl:=ErrorLevel
; monitoring current action (for debugging purpose only)
TrayTip, % "attempt: #"A_Index
, % """ErrorLevel"" of ""ClipWait"" command is: "errLvl
}
; here you can set the condition of ending the cycle: either...
; ...variable errLvl has not a true value,...
; ...or the number of attempts is equal 5
Until, Not errLvl Or A_Index=5
; value of each field of the command "MsgBox"...
; ...are set depending on the value of errLvl variable...
; ...using a ternary expression
; means if errLvl is a true, "options" field is 262160
MsgBox, % 262 . (errLvl ? 160:208)
; means that "title" has a couple variants
, % errLvl ? "Period expired:":"Result:"
; means that "text" has a couple variants
, % errLvl ? "Failed to save the selection.":Clipboard
; means if errLvl is a true, "timeout" field is 0.5 (500ms)
, % (errLvl ? 0:2) . .5
/* same that and above:
IfEqual, errLvl, % True, MsgBox, 262160
, % "Period expired:"
, % "Failed to save the selection."
, 0.5
Else MsgBox, 262208, % "Result:", % Clipboard, 2.5
*/
TrayTip ; remove "TrayTip" (for debugging purpose only)
; save an positive result (if needed)
IfEqual, errLvl, 0, Sleep, -1, someVar:=Clipboard
; return a temporarily saved data into clipboard (if needed)
Clipboard:=clipContent
KeyWait, % "vk43"
Return
From my experience whenever keystrokes are not recognized reliably it's due to either the system or the targeted program not keeping up with the speed at which those keys are sent.
For SendEvent you could try something like SetKeyDelay, 1000, 1000 and see if this improves things. The other option would be to send explicit down and up keys with intermittent sleep calls as outlined in this answer.

Autohotkey - Replace different words or sentences

in this script that I use i can replace only one word teams--> milan, juventus, inter..
But i want replace many words (not only one word) for example:
[simply word replacement jack-->beta]
alfa-->beta
[sentence replacement jack-->jack,john,alfa]
jack
jack
john
alfa
This is actually code that i use
loop {
While !RegexMatch(strCapture, "teams$") {
Input, strUserInput, V L1, {BackSpace} ; V: visible, L1: Character length 1
If ErrorLevel = Endkey:BackSpace
strCapture := SubStr(strCapture, 1, StrLen(strUserInput) - 1)
else
strCapture .= strUserInput
; tooltip % ErrorLevel "`n" strUserInput "`n" strCapture "`n" ; enable this to see what actually happens
}
SendInput,
(Ltrim
{Backspace 5}
milan
juventus
inter
roma
lazio
napoli
mantova
)
strCapture := ""
}
How can I modify the code?
It is also possible to run the script integrating copy-paste?
You could use a For loop to replace the contents, but this would become increasingly tedious to maintain at scale, so YMMV.
The following will use the clipboard contents as the to/from variables, but you can swap it out with a variable as desired (replace "clipboard" with your string variable).
F3::
{
replace := {"alfa":"beta", "gamma":"delta"}
For start, end in replace {
StringReplace, clipboard, clipboard, %start%, %end%, All
}}
Return