AutoHotKey SetKeyDelay option does not appear to work - autohotkey

I have a very simple AutoHotKey script which I wish to introduce a visible delay between the characters typed ...I have read the documentation on SetKeyDelay but the example below does not seem to provide any key delay ...any thoughts ? I would expect that when I type rpa and the hit enter key, the characters would type slowly ...more like a human typing.
SetKeyDelay ,3000,200
::rpa::
Send {Text}
(
while ( iterator?.hasNext() ) {
def comp = iterator.next()
if (comp.sku != null ) {
def row = [
"sku" : comp.sku,
"ProductGroup": comp.attribute1,
"BusinessUnit": comp.attribute2
]
}
}
)
return

When a new script is created the SendMode Input; line is automatically inserted.
Remove the SendMode Input; fixed the issue.

Related

GTK EntryCompletion by insertion instead of replacement

I've built a GTK application with autocompletion in an Entry, but I'd like the selected "completion" string to be replace the only word that the cursor touches, whereas it currently replaces all text in the Entry.
I can use set_match_func on the EntryCompletion to deliver matches based on only the word that is adjacent to the cursor, but I don't see how to override the text-insertion behaviour. Is there a way for me to do this?
I'm working in Ruby with gtk3. (I linked the doc for gtk2 because for the life of me, I can't find a complete doc for gtk3 in Ruby.)
Edit Here's my implementation (in Ruby), which lacks the desired "insert" behaviour:
module MyAutocomplete
# Add autocomplete to a Gtk::Entry object
def self.add entry, &block
model = Gtk::ListStore.new String
model.append.set_value 0, 'sd'
model.append.set_value 0, 'foo'
model.append.set_value 0, 'six'
completion = Gtk::EntryCompletion.new
completion.set_minimum_key_length 0
completion.set_text_column 0
completion.set_inline_completion true
completion.set_model model
completion.set_match_func do |*args|
self.match_func *args
end
yield(model, completion) if block_given?
entry.set_completion completion
end
def self.match_func(entry_completion, entry_value, list_obj)
len = 0 # Counts characters into the entry text
cursor = entry_completion.entry.position
entry_text = entry_completion.entry.text
entry_tokens = entry_text.scan(/[\w+#]+|[^\w#]+/)
current_token = entry_tokens.find { |tok|
(len += tok.length) >= cursor && tok =~ /\w/
}
obj_text = list_obj.get_value(0)
return current_token && obj_text.start_with?(current_token)
end
end

AutoHotKey - Functions cannot contain functions error

I'm new to AutoHotKey and I wanted to create a script macro for a flash game but when I run it, it creates an error.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
condChecker := false
state := true
Mine()
{
Sleep, rand(10,80)
Send, {Space}
while(state = true)
{
PixelGetColor, gemColor, 982, 433
if(gemColor = B93557)
{
state := true
{
else(gemColor = 96885A)
{
state := false
}
Sleep, rand(90,120)
}
}
^-::
loop 10000
{
getState()
if(state = true)
{Mine()}
else
{Sleep, rand(70,150)}
}
When I press Run Script on the ahk file, a menu pops up saying
Error at line 20.
Line Text else(gemColor = 96885A)
Error: Functions cannot contain functions.
The program will now exit.
I don't know where to start with this error and I read up on other forums saying that my formatting was incorrect.
A couple of various things:
The curly brace after state := true should be the other way (}, not {)
There is no default rand function in AHK, you are probably either looking for Random, or you have a custom function called rand that you is not shown in your question. In any case, I'll write a function rand(a,b) that will return an integer value between a and b
rand(a, b)
{
Random, rand, a, b
return rand
}
Additionally, there is another function getState() that is being invoked inside the loop 10000. I'm not sure what it is supposed to do (or if you meant something like GetKeyState instead), but I'll assume that you have that covered on your end.
As #Pranav Hosangadi mentioned, you likely wanted an else if statement instead of just an else statement on this line: else(gemColor = 96885A)
Are you sure you want SendMode Input? Although it does have superior speed than standard Send, its use is normally limited to typing text in a text box. It seems that you are trying to send a keystroke to a flash game, so you might want to check whether that functioning as you intend it to.
When writing a end curly brace (}) to conclude an if() or else() clause, you need to put it on its own line. (i.e. change
if(state = true)
{Mine()}
else
{Sleep, rand(70,150)}
to something like
if(state = true)
{
Mine()
}
else
{
Sleep, rand(70,150)
}
or even (since the if and else statements here only trigger one line of code each)
if(state = true)
Mine()
else
Sleep, rand(70,150)
So, that was a bit long, but here is the final code:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
; ---> Double check this! ---> SendMode Input
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
condChecker := false
state := true
Mine()
{
Sleep, rand(10,80)
Send, {Space}
while(state = true)
{
PixelGetColor, gemColor, 982, 433
if(gemColor = B93557)
{
state := true
}
else if(gemColor = 96885A)
{
state := false
}
Sleep, rand(90,120)
}
}
rand(a, b)
{
Random, rand, a, b
return rand
}
^-::
loop 10000
{
;getState()
if(state = true)
Mine()
else
Sleep, rand(70,150)
}
lmk if something doesn't work properly, and I'll try to update this response

Mirc script to find exact match in customer list

I am using this to find customer name in text file. Names are each on a separate line. I need to find exact name. If searching for Nick specifically it should find Nick only but my code will say found even if only Nickolson is in te list.
On*:text:*!Customer*:#: {
if ($read(system\Customer.txt,$2)) {
.msg $chan $2 Customer found in list! | halt }
else { .msg $chan 4 $2 Customer not found in list. | halt }
}
You have to loop through every matching line and see if the line is an exact match
Something like this
On*:text:*!Custodsddmer*:#: {
var %nick
; loop over all lines that contains nick
while ($read(customer.txt, nw, *nick*, $calc($readn + 1))) {
; check if the line is an exact match
if ($v1 == nick) {
%nick = $v1
; stop the loop because a result is found
break;
}
}
if (%nick == $null) {
.msg $chan 4 $2 Customer not found in list.
}
else{
.msg $chan $2 Customer found in list!
}
You can find more here: https://en.wikichip.org/wiki/mirc/text_files#Iterating_Over_Matches
If you're looking for exact match in a new line separate list, then you can use the 'w' switch without using wildcard '*' character.
From mIRC documentation
$read(filename, [ntswrp], [matchtext], [N])
Scans the file info.txt for a line beginning with the word mirc and
returns the text following the match value. //echo $read(help.txt, w,
*help*)
Because we don't want the wildcard matching, but a exact match, we would use:
$read(customers.txt, w, Nick)
Complete Code:
ON *:TEXT:!Customer *:#: {
var %foundInTheList = $read(system\Customer.txt, w, $2)
if (%foundInTheList) {
.msg # $2 Customer found in list!
}
else {
.msg 4 # $2 Customer not found in list.
}
}
Few remarks on Original code
Halting
halt should only use when you forcibly want to stop any future processing to take place. In most cases, you can avoid it, by writing you code flow in a way it will behave like that without explicitly using halting.
It will also resolve new problems that may arise, in case you will want to add new code, but you will wonder why it isn't executing.. because of the darn now forgotten halt command.
This will also improve you debugging, in the case it will not make you wonder on another flow exit, without you knowing.
Readability
if (..) {
.... }
else { .. }
When considering many lines of codes inside the first { } it will make it hard to notice the else (or elseif) because mIRC remote parser will put on the same identification as the else line also the line above it, which contains the closing } code. You should almost always few extra code in case of readability, especially which it costs new nothing!, as i remember new lines are free of charge.
So be sure the to have the rule of thump of every command in a new line. (that includes the closing bracket)
Matching Text
On*:text:*!Customer*:#: {
The above code has critical problem, and bug.
Critical: Will not work, because on*:text contains no space between on and *:text
Bug: !Customer will match EVERYTHING-BEFORE!customerANDAFTER <NICK>, which is clearly not desired behavior. What you want is :!Customer *: will only match if the first word was !customer and you must enter at least another text, because I've used [SPACE]*.

Expect Interact and special characters

trying to create a macro program with expect to help me manage my cisco devices>
I want to keep all native cisco functions like tab complete ETC.
initially I wanted to type "!...!" where my macro is inside the bangs, my code looked like this:
interact {
-re "!(.+)!" { #find correct macro }
}
but with this method, there is no feedback to the user. what happens if they misspell? etc then they can't see their corrections with backspace.
then I started thinking about just capturing each character press and building a string
interact {
#book says backspace character
"\b" {
set command [lreplace $command end end]
}
#detect return, sending command
-re "\r" {
set command [join $command ""]
if [regexp "^!" $command] {
#send ctrl+u to erase line sent
send "\025"
findMacro $command
}
set command ""
send "\r"
}
#send tab for tab completion
"\t" { send "\t" }
-re "(.)" {
send $interact_out(1,string)
lappend command $interact_out(1,string)
}
}
but I can't "expect" the backspace. I've tried 0x08.. etc nothing is working. in the end I'm not even sure this is the way to go simply because there are to many other buttons a user could push and mess up my string I'm building.
the real solution, I think, is to wait until "\r" is pressed, and then run a regex on that line. but I'm not sure how to do that.

Combination of specific key and any other key

I would like to turn F15 into a macro key. Pressing another key while F15 is held should call a function that will read a .ini file for instructions.
I know that I can it this like this, but I'd rather not have the giant list:
DoMacro(key) { ... }
F15 & a::DoMacro('a')
F15 & b::DoMacro('b')
F15 & c::DoMacro('c')
.
.
.
I tried fiddling around with Input, but I couldn't figure out any way to capture (or even pass through) non-character keys. Is there any alternative to the long list?
Unfortunately there is no 100% nice way to do this in AHK (unless you know a way to do it through API calls which I don't).
I think the best you could make out of this situation is this:
GetAnyKey(timeout) {
Input, PressedKey, T%timeout% L1, {F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{F14}{F15}{F16}{F17}{F18}{F19}{F20}{F21}{F22}{F23}{F24}{PrintScreen}{Del}{Home}{End}{PgUp}{PgDn}{ScrollLock}{Pause}{Ins}{BS}{Space}{Left}{Right}{Up}{Down}{Left}{Right}{NumLock}{NumPad1}{NumPad2}{NumPad3}{NumPad4}{NumPad5}{NumPad6}{NumPad7}{NumPad8}{NumPad9}{NumPad0}{NumPadAdd}{NumPadSub}{NumPadMult}{NumPadDiv}{NumPadEnter}{NumPadDot}{NumPadEnd}{NumPadHome}{NumPadPgDn}{NumPadPgUp}{NumpadClear}{NumpadDown}{NumpadIns}{NumpadLeft}{NumpadRight}{AppsKey}{LShift}{RShift}{LCtrl}{RCtrl}{LAlt}{RAlt}{LWin}{RWin}
If (ErrorLevel = "Timeout")
Return
If PressedKey
Key := PressedKey
Else
Key := SubStr(ErrorLevel,8)
Return Key
}
F13::
Key := GetAnyKey(1)
If (Key && GetKeyState("F13", "P")) {
DoMacro(Key)
}
Return
DoMacro(Key) {
MsgBox, F13 and %Key% have been pressed!
}
I removed the hotkey (F13) from the Input key list, so that it doesn't trigger the Input when you wait too long.
So, if you change the hotkey you have to change the input list accordingly.