Autohotkey Script that edits selected text without using the clipboard - autohotkey

I want to write an Autohotkey text to edit the text that the user selects and append four spaces at the beginning of every line.
If I would simply have a string with multiple lines the task would be easy.
I googled and found one solution at the official Autohotkey forum. That solution copies the text into the clipboard potentially deleting the clipboard content.
Is there a way to do this in autohotkey that doesn't use the clipboard where I can directly operate on the selected text?

Here are some basic Clipboard techniques:
ClipSaved := ClipboardAll ; Save the entire clipboard to a variable of your choice (in this case, ClipSaved).
; Here is where you put your code
Clipboard := ClipSaved ; Restore the original clipboard.
ClipSaved = ; Free the memory in case the clipboard was very large.
More here: https://autohotkey.com/docs/misc/Clipboard.htm

Well, this one requires your mouse cursor to hover over the window with the selected text:
MouseGetPos,,,thiswindow,thiscontrol
ControlGet,VarX,selected,,%thiscontrol%,ahk_id %thiswindow%
;Do something with "VarX" here.

Related

AHK: convert ClipboardAll to string (without calling Clipboard instead)

In an AHK script, I want to convert data I read from the clipboard earlier via ClipboardAll into a string I can manipulate, but StrGet() very oddly cannot do that.
!2:: clipget()
clipget()
{
clip := ClipboardAll
MsgBox % clip
MsgBox % NumGet(clip)
MsgBox % StrGet(clip)
Return
}
Firts MsgBox returns empty, because clip is not a string, as expected.
Second returns a numerical representation of the bit data, as expected.
The third returns nothing, not as expected.
I know I could just use clipstr = Clipboard in the first place to have it converted in the first place, but then I would have to read the clipboard twice as in:
clip := ClipboardAll
clipstr := Clipboard
to get both string data and bit data, but that looks uncool and takes longer if the data on the cliboard is large.
A dumb but functional way way could also be
Clipboard := clip
Sleep 500
clipstr := Clipboard
needless to say is not what I am looking for.
So, is there any way to get a string from ClipboardAll bit data with something like
clip := ClipboardAll
clipstr := MagicalFunction(clip)
?
Im not sure if this will help. But the clipboard is not the piece of string that is currently copied. The clipboard is a place where your computer holds your copied stuff, its a place where you can find your previous copied stuff.
A code I found in ahk's Clipboard doc is this
Loop, parse, clipboard, `n, `r
{
MsgBox, %A_LoopField% is your current copied first line..
}
I'm not very familiar with ahk's variable system but I think this should give a string output from %A_LoopField%
in AHK script: Save ClipBoardAll to File.
in external text editor: Write to the BEGINING of File some text eg. "rrr" (or you can do it by "copy +" in command line bat file)
in AHK script: Read File to variable.

Appending a .txt document with contents of clipboard using autohotkey

!w::
Sendinput ^c ; copy selection
Sleep 1000 ; gives time for the copy to work
FileAppend, `n`n%clipboard%, C:\Users\John Salter\ToAnki.txt; Add clipboard content to the end of a text file. Insert 2 new lines before inserting the clipboard with `n`n
Return
This is the script I've been trying to use. I was concerned about the space in between "John" and "Salter" so tried it in other locations but it still doesn't work.
I get no error messages.
The content of the the clipboard is altered, so the problem lies beneath the second line.
The use of FileAppend would seem to work looking at the help documentation.
Can anybody figure out what's going wrong?
Thanks!
A comment flag that appears on the same line as a command is
not considered to mark a comment unless it has at least one space or
tab to its left.
FileAppend, `n`n%clipboard%, C:\Users\John Salter\ToAnki.txt ; Add clipboard content to the end of a text file. Insert 2 new lines before inserting the clipboard with `n`n

Creating text macro system on AHK

I am quite new on AutoHotKey, and I'm trying to make my macro system. Currently I have a system that looks like this:
I have text variables
hi =
(
Hello,
Some more text
)
a Hotstring
::\hi::
Macro(hi)
return
And a function Macro:
Macro(text)
{
ClipSaved := ClipboardAll ; save clipboard
clipboard := text
ClipWait
Sleep, 150
Send, ^v
clipboard := ClipSaved ; restore original clipboard
return
}
The reason for using a function with clipboard is because long text blocks tend to have a delay until they are printed out, an issue that does not occur with the function.
I've found a concept called dynamic hotstrings, and I think I can somehow implement it so that I wouldn't have to write the second displayed block for every text field, but instead have a one hotstring that would understand that if it's my input starts with \ and there is a variable in the script under the name x that follows it, it should execute Macro(x), but I have never found any similar examples.
Could you provide me with a code sample or give any leads to what I should check out?
There are several dynamic Hotstring AutoHotkey functions, but this is probably the one you want to use Hotstring by menixator
So you need to download the hotstring.ahk and #include it as in the examples.
#SingleInstance, force
#include Hotstring.ahk
hi=
(
Hello,
Some more text
)
bye=
(
So long,
Some more text
)
Hotstring("/hi", "Paste")
Hotstring("/bye", "Paste")
return
Paste:
text:=Trim($,"/") ; we need to get rid of the leading /
text:=% %text% ; and need to dereference it
Macro(text)
Return
Macro(text)
{
ClipSaved := ClipboardAll ; save clipboard
Clipboard := text
ClipWait
Sleep, 150
Send, ^v
clipboard := ClipSaved ; restore original clipboard
return
}
There are some more elegant ways to do it, especially with the variables, you could store them in a global object (associative array) for example, but this should get you going.

How to wrap currently selected text in ``

How can write a hotkey (which works in any editor) to wrap currently selected text in ``
e.g double click "text", it becomes selected, then by pressing key for single `` it
is converted to text
Here is mix of pseudo code and actual code. Text within <> is what I'm not sure of
^<COMMAND FOR PRESSING ` KEY>::
KeyWait Control
<STORE CURRENTLY SELECTED TEXT IN MEMORY>
SendInput `<STORED SELECTED TEXT>'
return
Your approach is pretty good already. Try this:
$`::
clp_tmp := ClipboardAll
send ^c
currently_selected := Clipboard
stringReplace, currently_selected, currently_selected, `r,, All
Clipboard := clp_tmp
sendraw ``%A_Space%
sendraw %currently_selected%
sendraw ``%A_Space%
return
$ is needed because otherwise, sendraw `` would re-trigger this hotkey. The built-in variable clipboard / clipboardAll contains windows' clipboard. Also, you don't need any keywaits. ahk manages concurring modifiers from hotkey triggers by itself. I also suggest using sendraw which will not treat # as the win-button, + as Shift and so on.
script inserts new lines between each line if multiple lines are selected
Weird. When using msgBox, %currently_selected% instead of any send command, the line breaks are displayed correctly... there is obviously some strange formatting going on, I fixed it by simply removing all Carriage Returns (CR) (`r) from the string which does not change the selected text at all.
The given solution works for my keyboard which is German. This might be different for other keyboard layouts. For me, the %A_Space% in sendraw ``%A_Space% (at least in the second one) is needed, because if you state sendraw `` (a literal space character in the end), AHK will ignore it. You could also put all three sends in one line like
sendraw `` %currently_selected%``%A_Space%
Another solution might be
sendInput ````{BS}%currently_selected%````{BS}
or just simply
sendRaw `%currently_selected%`
Finally: If you wanted to make everything easier, make use of the #EscapeChar command and change the delimiter from ` to \ or sth. similar.

Selecting the last N characters before caret with AutoHotkey

Is there a way to select last N symbols with autohotkey?
I'm making a function which replicates Sublime Text's duplicate function (Ctrl+Shift+D). I want text to be selected before it is duplicated via SendInput ^C{right}^V
Technically, I could make something like:
selectBefore(n){
Loop, %n% {
SendInput +{Left}
}
}
But that has shown poor performance.
Another method would be to play with Shift+Home. For example, Send +{Home}, then count the number of symbols selected, then Send {Left} and Send +{Home} again, and so on until reaching the length of the duplicated string.
I don't see any better alternatives.
Is there a good, basic way to select N symbols before caret?
From what I read about ST2 (thank you for making me aware) is that ^+d either copies the selected text or if nothing is selected, copies the whole line.
Would this work?
TempCB = %ClipBoard% ; Park clipboard (text) content, Other content (format, images, etc.) will be lost.
ClipBoard = ; Clear clipboard
Send, ^c ; Grab selected text
Sleep, 100 ; Wait 0.1 seconds for clipboard (clipboard will not get filled if nothing is selected)
if (Clipboard = "") ; Nothing selected, thus copy whole line
{
Send, {Home}+{End}^c ; Select line and copy to clipbard
}
MoveBack := StrLen(ClipBoard)
MoveFwd := MoveBack
MoveBack++ ; Move one step back further back due to earlier step {right}
Send, {Right}{Left}^v{Right}{left %Moveback%}+{Right %MoveFwd%} ; Go to end of selected text (in MS notepad this is will jump over the first next char., thus a jump back as well), add a space and paste.
ClipBoard = %TempCB% ; Restore (text part) of previous clipboard content.
Return
I tested this in MS Notepad, other editors might behave differently (especially around jumping towards the end of the selected text).
The script now copies and pastes the selected text and highlights the newly pasted text.