autohotkey looping tooltip and confirm selection with enter - autohotkey

I want to accomplish an apparently easy task with autohotkey: when certain hotstring is detected, then show a tooltip (in this case, with the current date). While the tooltip is displayed I want to react to UP and DOWN key-presses showing the next and previous item on an array respectively. Then when the Enter key is pressed I want to confirm the "selection" and paste that tooltip text. Here is the current code, which looks too big for a task that is so simple.
; ------------------------ Date tooltip
::#curdate::
EnteringDate := True
DateSeparator := [".","/","-"]
SelectedSep := 1
GoSub, ShowToolTip
return
ShowToolTip:
Sep := DateSeparator[SelectedSep]
FormatTime, Time,, dd%Sep%MM%Sep%yyyy ; dd MM yyyy is day month year
ToolTip, %Time%
return
#If EnteringDate
Up::
SelectedSep := cycle(SelectedSep,DateSeparator.MaxIndex(),1)
GoSub, ShowToolTip
return
Down::
SelectedSep := cycle(SelectedSep,DateSeparator.MaxIndex(),-1)
GoSub, ShowToolTip
return
Enter::
EnteringDate := False
SendInput, %Time%
ToolTip ; Clear the tool tip
return
#If ; end entering date
cycle(value,maxValue,increment:=1){
value += increment
if value not between 1 and %maxValue%
value := increment<0 ? maxValue : 1
return value
}

::#curdate::
i:=0,DateSep:= [".","/","-"],EnteringDate:=1
return
#If EnteringDate
Up::
ToolTip
,% DateSep[i:=i<DateSep.MaxIndex()?++i:1]
return
Down::
ToolTip
,% DateSep[i:=i>1?--i:DateSep.MaxIndex()]
return
Enter::
EnteringDate:=0,Sep := DateSep[i]
FormatTime, Time,, dd%Sep%MM%Sep%yyyy
SendInput, %Time%
ToolTip
return
#If
Esc::ExitApp

::#curdate::
i:=0,DateSep:= [".","/","-"],EnteringDate:=1
SendLevel,1
Send,{up}
return
#If EnteringDate
Up::
DateSep[i:=i<DateSep.MaxIndex()?++i:1]
Sep:=DateSep[i]
FormatTime, Time,, dd%Sep%MM%Sep%yyyy
ToolTip,% Time
return
Down::
DateSep[i:=i>1?--i:DateSep.MaxIndex()]
Sep:=DateSep[i]
FormatTime, Time,,dd%Sep%MM%Sep%yyyy
ToolTip,% Time
return
Enter::
EnteringDate:=0
SendInput, % Time
ToolTip
return
#If

Related

Press in random time range?

I am currently having this code which will press Z every 1.5 seconds after activated by pressing B
toggle := 0
return
b::
toggle := !toggle
if (toggle = 1)
SetTimer, Pressz, 1500
else
SetTimer, Pressz, Off
return
Pressz:
SendInput, z
v::SetTimer, Pressz, 1500
But then I am not sure how to change the SetTimer into random time between 0 to 1500
Please help thanks.
Utilizing the 'Random' function that 0x464e mentioned, and single fire SetTimer routines, I created this
toggle := 0
return
b::
toggle := !toggle
;MsgBox %toggle%
if (toggle){
gosub Routine
}
return
Routine:
if(toggle){
Random, var, -1500, 0
gosub Pressz
SetTimer, Routine, %var%
}
return
Pressz:
SendInput, z
return
v::
toggle=1
gosub Routine
return

MATLAB auto completing start and end statements of code body?

Is it possible in MATLAB to automatically insert start and end of a code body ?
For example: classdef and end; function and end; methods and end.
classdef Circle
properties
radius
end
methods
function dia = FindDia(obj)
dia = [obj.radius]*2;
end
function %no automatic insertion of 'end'
end
end
Since I work regularly in so many different editors, I don't rely on any one editor's features. It's a pain to learn them all and keep the configuration for all these editors in sync, on all my machines. Often, it's useful to have the same feature set I'm used to, in editors not even meant for code (like MS Word, or here on Stack Overflow).
Therefore, I use AutoHotkey for this kind of thing (and Autokey on Linux).
For functions and classes, I use a paste function to paste a specific template file, depending on whether I'm at work or at home, and which project I'm working on. A small GUI then asks me for the function or class name, which it then populates the template with. I can share that too if you want.
Below are a few AutoHotkey functions and hotstrings I use for including the end keyword. Note that this might all seem overly complex just to put an end there, and in this case, it probably is. But the clipCopy, clipPaste and getIndent functions have proven their usefulness in the rest of my programming snippets, and I hope they might be for you too.
I've thrown in the error functions as well, just because.
; Copy selected text
; More robust than C-c/C-x/C-v; see
; https://autohotkey.com/board/topic/111817-robust-copy-and-paste-routine-function/
clipCopy(dontRestoreClipboard := 0)
{
prevClipboard := Clipboard
Clipboard := ""
copyKey := "vk43sc02E" ; Copy
SendInput, {Shift Down}{Shift Up}{Ctrl Down}{%copyKey% Down}
ClipWait, 0.25, 1
SendInput, {%copyKey% Up}{Ctrl Up}
str := Clipboard
if (dontRestoreClipboard == 0)
Clipboard := prevClipboard
return str
}
clipPaste(ByRef txt, dontBackupClipboard := 0)
{
if (txt != "")
{
prevClipboard := ""
pasteKey := "vk56sc02F" ; Paste
if (dontBackupClipboard == 0) {
prevClipboard := Clipboard
Clipboard := ""
}
Clipboard := txt
ClipWait, 1.00, 1
; Start pressing paste key
SendInput, {Shift Down}{Shift Up}{Ctrl Down}{%pasteKey% Down}
; Wait until clipboard is ready
startTime := A_TickCount
while (DllCall("GetOpenClipboardWindow") && (A_TickCount - startTime < 1000)) {
Sleep, 50
}
; Release paste key
SendInput, {%pasteKey% Up}{Ctrl Up}
; TODO: a manual delay still seems necessary...this vlaue needs to be this large, to also have
; correct behavior in superslow apps like MS Office, Outlook, etc. Sadly, the SetTimer approach
; does not seem to work (doesn't correctly restore the clipboard); to be investigated.
Sleep 333
; Put previous clipboard content back onto the clipboard
Clipboard := prevClipboard
}
}
; Get current indentation level in an editor-independent way
getIndent(dontRestoreClipboard := 0)
{
; Select text from cursor to start of line
SendInput, +{Home}
indent := clipCopy(dontRestoreClipboard)
numsp := 0
if (indent != "")
indent := RegExReplace(indent, ".", " ", numsp)
; Undo selection (this is tricky; different editors often have
; different behavior for Home/End keys while text is selected
SendInput, {Right}{Left}{Home}
; NOTE: don't use {End}, because we might be in the middle of a sentence
; Use the "right" key, repeatedly
Loop, %numsp% {
SendInput, {Right}
}
return indent
}
mBasic(str)
{
current_indent := getIndent()
SendInput, %str% (){Enter}+{Home}%current_indent%{Space 4}{Enter}+{Home}%current_indent%end{Up 2}{End}{Left}
}
mErrfcn(str)
{
current_indent := getIndent()
spaces := RegExReplace(str, ".", " ")
clipPaste(str . "([mfilename ':default_errorID'],...`r`n" . current_indent . spaces . " 'Default error string.');")
return current_indent
}
; MATLAB Hotstrings for basic control structures
:o:mfor::
mBasic("for")
return
:o:mpar::
mBasic("parfor")
return
:o:mwhile::
mBasic("while")
return
:o:spmd::
mBasic("spmd")
return
:o:mif::
mBasic("if")
return
; ...etc.
; error, warning, assert
:o:merr::
:o:merror::
mErrfcn("error")
SendInput, {Up}{End}{Left 21}
return
:o:mwarn::
:o:mwarning::
mErrfcn("warning")
SendInput, {Up}{End}{Left 21}
return
_mlAssert()
{
current_indent := mErrfcn("assert")
SendInput, {Up}{End}{Left 34}true,...{Enter}+{Home}%current_indent%{Space 7}{Up}{End}{Left 8}
}
:o:massert::
_mlAssert()
return

AutoHotKey: Merge scripts that monitor selection in Firefox and other programs

I am struggling with a script that monitors selections by mouse in FireFox, Adobe Acrobat and one more program and then copies this selection to clipboard and changes it according to a regex. For each program another regex is needed. Each script works as a separate program, but when I merge them, the copied text is not changed according to my regex.
Script for Adobe Acrobat:
#ifWinActive ahk_class AcrobatSDIWindow
~LButton::
now := A_TickCount
while GetKeyState("LButton", "P")
continue
if (A_TickCount-now > 600 )
{
Send ^c
copied := true
}
return
OnClipboardChange:
if !copied
return
copied := false
ToolTip % Clipboard := RegExReplace(Clipboard, "\r\n", " ")
SetTimer, ToolTipOff, -1000
return
ToolTipOff:
ToolTip
return
And stript for Firefox:
#ifWinActive ahk_class MozillaWindowClass
~LButton::
now := A_TickCount
while GetKeyState("LButton", "P")
continue
if (A_TickCount-now > 600 )
{
Send ^c
copied := true
}
return
OnClipboardChange2:
if !copied
return
copied := false
ToolTip % Clipboard := RegExReplace(Clipboard, "[0-9]\.\s*|\s?\([^)]*\)|\.")
SetTimer, ToolTipOff1, -1000
return
ToolTipOff1:
ToolTip
return
The #If does only work on hotkeys, not on labels. Using OnClipboardChange seems unnecessary. When you press ctrl+c you already know that the clipboard changed.
I also really recommend setting indentations for hotkeys and also #If statements.
Here is how I would do it:
#If WinActive("ahk_class AcrobatSDIWindow") || WinActive("ahk_class MozillaWindowClass")
~LButton::
now := A_TickCount
while GetKeyState("LButton", "P")
continue
if (A_TickCount-now > 600 )
{
Send ^c
if WinActive("ahk_class AcrobatSDIWindow")
{
regex := "\r\n"
replace := " "
}
else if WinActive("ahk_class MozillaWindowClass")
{
regex := "[0-9]\.\s*|\s?\([^)]*\)|\."
replace := ""
}
ToolTip % Clipboard := RegExReplace(Clipboard, regex, replace)
SetTimer, ToolTipOff, -1000
}
return
#If
ToolTipOff:
ToolTip
return
(untested)
edit:
.....
~Left::
~Right::
~Up::
~Down::
now := A_TickCount
while GetKeyState("Shift", "P")
continue
if (A_TickCount-now > 600 )
{
oldShiftState := GetKeyState("Shift", "P")
Send, {Shift Up}
Send ^c
If (oldShiftState)
Send, {Shift Down}
.....
(untested)

Autohotkey. How to make work both `a hotkey` and `a hotkey+key`?

I want to have two hotkeys in my script. Namely LWin Up and LWin+LAlt Up. I've tried to do it like that:
LAlt & LWin Up:: ;I've also tried commenting out the first
LWin & LAlt Up:: ;or the second line
LWin Up::
msgbox, % A_ThisHotkey
return
But the output depends on the order in which keys were pressed and released. The time between releasing the first and the second key also affects the result. Sometimes I get two MessageBoxes, sometimes just one and sometimes even none at all (the first line is commented out, press alt, press win, release win, release alt). How do I make it work? To be clear: I want to get only one MessageBox.
In the answer it would be great to see a script that provides full information about the hotkey pressed and the order in which the keys it consist of were pressed and released. *Only one hotkey should be triggered after releasing a hotkey+key combo.
You can not put them altogether.
you should use something like this:
altPressed := false
LAlt & LWin Up::
msgbox, % A_ThisHotkey
return
LWin & LAlt Up::
msgbox, % A_ThisHotkey
altPressed := true
return
LWin Up::
if !altPressed {
msgbox, % A_ThisHotkey
}
altPressed := false
return
If what you want to do instead of msgbox is too spreaded in my code you can use the below one:
SetTimer, toDo, 10
toDo:
if doWhatEver {
;; HERE DESCRIBE WHAT TO DO
doWhatEver := false
}
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
altPressed := false
doWhatEver := false
LAlt & LWin Up::
doWhatEver := true
return
LWin & LAlt Up::
doWhatEver := true
altPressed := true
return
LWin Up::
if !altPressed {
doWhatEver := true
}
altPressed := false
return
TechJS's answer wasn't working exactly as I wish so here is my script. It detects the order in which the keys were pressed and released, and doesn't depend on time between keys pressed/released.
global firstPressed := ""
LAlt::
altDown := true
if (winDown)
return
firstPressed := "!"
return
LWin::
winDown := true
if (altDown)
return
firstPressed := "#"
return
LAlt Up::
altDown := false
if (!winDown) {
if (comboJustUp) {
comboJustUp := false
return
}
msgbox !
}
if (winDown) {
comboJustUp := true
if (firstPressed = "#")
msgbox #!!.
if (firstPressed = "!")
msgbox !#!.
}
return
LWin Up::
winDown := false
if (!altDown) {
if (comboJustUp) {
comboJustUp := false
return
}
msgbox #
}
if (altDown) {
comboJustUp := true
if (firstPressed = "!") ; \here is one bug though. If you switch theese
msgbox !##. ; /two lines
if (firstPressed = "#") ; \with theese
msgbox #!#. ; /two. It won't work correctly for some reason
}
return

Tooltip on control focus ahk

In Autohotkey, is there a way to detect what gui control has focus so that I display a text box with basically a tooltip.
I want to hover my mouse or use the keyboard to navigate and display what would be stored in the tooltip in a multiline textbox.
I dont want to have a tooltip.
OnMessage(0x0200, "WM_MOUSEMOVE") ; WM_MOUSEMOVE 0x0200
Return
WM_MOUSEMOVE(wParam, lParam)
{
global Control_Name
X := lParam & 0xFFFF
Y := lParam >> 16
MouseGetPos, , , , Control_Name
Tooltip, %Control_Name%, (x+150), (y+150)
}
Esc::ExitApp
ControlGetFocus is used to get the name. See sample code below
a::
ControlGetFocus, OutputVar, A
if ErrorLevel
MsgBox, The target window doesn't exist or none of its controls has input focus.
else
MsgBox, Control with focus = %OutputVar%
Got it! ;-)
I watch if the mouse moves, or a control has focus and display in a text box some stored values
#Persistent
SetTimer, WatchCursor, 100
return
WatchCursor:
MouseGetPos, mx, my, id, mouseControl
ControlGetFocus, currentFocus, A
if (SubStr(mouseControl,1,6)= "Button" OR SubStr(currentFocus,1,6)= "Button")
butIDkey := SubStr(currentFocus,7,2)
butIDmouse := SubStr(mouseControl,7,2)
if (SubStr(mouseControl,1,6)= "Button" && lastmx <> mx && lastmy <> my)
butID := butIDmouse
if (butIDkey <> lastControl)
butID := butIDkey
lastControl := butIDkey
lastmx := mx
lastmy := my
GuiControl,TemplateEngine:, MyTooltip, % Value%butID%
}
return