1

I have a block of text containing multiple lines and want to send it to a chap app line-by-line. I want to have a procedure like this:

  1. I type in a hotstring trigger (say, hotstringtrigger), and AutoHotKey will send the first line (the text should stay in the input box of chat app)
  2. I edit it to suit my need
  3. I press Enter. The chat app will send the text, and AutoHotKey will send the next line
  4. Return to 2 until no more line is left
  5. Enter will act normal after that, until hotstringtrigger is typed again

So far, my attempt is to split it into multiple hotstrings:

:*:hotstringtrigger::first line
:*:hotstringtrigger2::second line
:*:hotstringtrigger3::third line
...

But this has some disadvantages:

  • Use many hotstrings
  • Have extra key presses

This page doesn't seem to cover this: Hotstrings - Definition & Usage | AutoHotkey

Ooker
  • 1,969
  • 4
  • 28
  • 58

2 Answers2

1

I guess very simple and straight forward example could be something like this

TextToSend := "
(
first line
second line 
)"
 
lines := StrSplit(TextToSend, "`n", "`r")
 
 
:*T:hotstringtrigger::
    SendInput,
    (
    Hello ____________________. Welcome to the World^{Home}{right 6}
    )
    
    i := 1
return
 
~Enter::
    if (!i || i > lines.length())
        return
    
    SendInput, % "{Text}" lines[i]
    i++
return

The input text is here simply typed into a continuation section and loaded from there to an array when the script starts. When your desired hotstring is ran, the index i gets reset.

Then upon pressing Enter, text is sent from the array until our index, i, is greater than the length of lines in the input string.

If your input text has very long lines, you should load the lines to your clipboard first, and then just send Ctrl + v.

Ooker
  • 1,969
  • 4
  • 28
  • 58
0x464e
  • 5,948
  • 1
  • 12
  • 17
  • I add a hotstring line at the top of your code and it works fine. But if I have a separate block of code containing `#If WinActive("ahk_class Notepad++")`, then it only works in Notepad++, even when there is a `return` to close that directive. Do you know why is that? Here is my [pastebin](https://pastebin.com/5btYHTSP). – Ooker Dec 05 '21 at 16:16
  • Not sure what you mean. `#If` starts a context sensitive hotkey block, and the block wont end until another relevant #directive is encountered. Maybe you have misunderstood how context sensitive hotkeys work? [Here's](https://www.autohotkey.com/docs/commands/_IfWinActive.htm#ExBasic) an example that might help. Also, you shouldn't use `#If, WinActive()`, you should use `#IfWinActive`. – 0x464e Dec 05 '21 at 16:32
  • hmm, so the `return` doesn't play like a closing bracket like in other languages? That explains. Today I learn that in order to close an `#If` directive, you need to add another `#If`. – Ooker Dec 05 '21 at 17:01
  • 1
    It's maybe easy to think of `return` as just something that stops the code execution from going further. #IfDirectives don't care about `return`s, or anything else related to code execution, because they have nothing to do with code execution. They are kind of just markers that enclose different parts of code within them. – 0x464e Dec 05 '21 at 17:21
  • I see. A different question: I put this code into a hotstring. Every time the script starts or reloads, when I first use `Enter` it shows a warning that the variables `lines` and `i` aren't assigned a value, even though I don't call the hotstring. But then it works fine. Do you know why is that? – Ooker Dec 11 '21 at 13:52
  • Show your full script (use e.g. Pastebin), I'm guessing they aren't in the [auto-execute section](https://www.autohotkey.com/docs/Scripts.htm#auto). – 0x464e Dec 11 '21 at 13:53
  • I hope this is the MRE: https://pastebin.com/AQXpSq0u – Ooker Dec 11 '21 at 14:01
  • When the script stats, code execution ends on this line `:*T:thamgia::`. Therefore, `lines` and `i` are indeed undefined, until you run your `:*T:thamgia::` hotstring. Btw, is it intended that that hotstring runs code until the line `~Enter::`? Maybe you're missing a `return` somewhere there to indicate that the hotstring ends? [Here's](https://pastebin.com/gGQxHcdK) my guess on what you might want. Or maybe you intended for `lines` and `i` to reset upon running that hotstring, I'm not sure. – 0x464e Dec 11 '21 at 14:11
  • no, actually the `:*T:thamgia::` hotstring is to activate the code, and the text in the `SendInput` is actually the first line of the block. I have to split it out in order to use the `^{Home}{right 9}`. I've tried putting them into a function, but hotstrings aren't allowed in functions – Ooker Dec 12 '21 at 08:02
  • Hello. May I ask if you still have interest in this topic? – Ooker Dec 14 '21 at 09:09
  • I'm not really sure what the problem is still. – 0x464e Dec 14 '21 at 09:34
  • hmm, so first if I only want `Enter` to send text after I type in `hotstringtrigger`, and act as normal when there is not, then how should I do this? I guess we can use a function, but hotstring is not allowed in function – Ooker Dec 14 '21 at 09:44
  • 1
    Maybe you mean [this](https://pastebin.com/CJpvjiBk)? Now the `Enter` key acts normally until the hotstring gets ran. And running the hotstrings always resets the situation. – 0x464e Dec 14 '21 at 09:56
  • this is a nice hack. Thanks. Do you want to update your answer? Also, I ask another question here, hope to see you there: [What exactly does `return` do in AutoHotKey?](https://stackoverflow.com/q/70377117/3416774) – Ooker Dec 16 '21 at 10:04
  • Yeah I'll update my answer. You should update your question to include your previous full code as well, so my answer makes sense. And I can answer your new question. Maybe not straight away, but once I have time. – 0x464e Dec 16 '21 at 11:29
1

Try to use an Array:

; Create the array, initially empty:
Array := [] ; or Array := Array()

text =
(
first line
second line
third line
)
; Write to the array:
Loop, parse, text,`n
    Array.Push(A_LoopField) ; Append this line to the array.
return


F1::
Index++ ; checks the number in the variable "Index" and increases it by 1 every time you press F1
if (Index <= Array.MaxIndex())
    SendInput, % Array[Index]
else
    MsgBox, No more lines.
return
user3419297
  • 9,537
  • 2
  • 15
  • 24