Page 1 of 1

An improved script to use space as modifier

Posted: 28 Apr 2017, 10:36
by cy18
I have written an improved script to use space as modifier. The problem in https://autohotkey.com/board/topic/8414 ... ifier-key/ is solved.

Space becomes a modifier when it is pressed more than 0.1 second (100 ms). Of course, this delay could be modified. If no other keys are pressed during space is pressed, a space is output when space is released. Fewest hand move are necessary when typing. You can type arrow keys, BS, DEL, HOME, END and any other keys you like without moving your hand.

I made several tunes so that it works well when typing fast. You should feel just like normal when typing in fast speed.

Since, this is my first AHK script, there should be some problems such as misusing some functions. Any suggestions are welcome.

Code: Select all

;
; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT
; Author:         cy18 <thecy18@gmail.com>
;
; An improved script to use space as modifier
; In normal cases, if space is pressed for more than 0.1 second, it becomes a modifier, this time could be modified in the script
; If no other keys are pressed during space is pressed, a space is output when space is released
; Severial tunes are made so that the script works well when typing in fast speed
; Note that repeating space no longer works

#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.

AnyKeyPressedOtherThanSpace(mode = "P") {
    keys = 1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./
    Loop, Parse, keys
    {        
        isDown :=  GetKeyState(A_LoopField, mode)
        if(isDown)
            return True
    }   
    return False
}
 
Space Up::
    space_up := true
    Send, {F18}
    return
Space::
    if AnyKeyPressedOtherThanSpace(){
        SendInput, {Blind}{Space}
        Return
    }
    space_up := False
    inputed := False
    input, UserInput, L1 T0.1, {F18}
    if (space_up) {
        Send, {Blind}{Space}
        return
    }else if (StrLen(UserInput) == 1){
        Send, {Space}%UserInput%
        return
    }
    while true{
        input, UserInput, L1, {F18}
        if (space_up) {
            if (!inputed){
                Send, {Blind}{Space}
            }
            break
        }else if (StrLen(UserInput) == 1) {
            inputed := True
            StringLower, UserInput, UserInput
            if (UserInput == "e")
                Send, {Blind}{Up}
            else if (UserInput == "d")
                Send, {Blind}{Down}
            else if (UserInput == "s")
                Send, {Blind}{Left}
            else if (UserInput == "f")
                Send, {Blind}{Right}
            else if (UserInput == "w")
                Send, {Blind}{Home}
            else if (UserInput == "r")
                Send, {Blind}{End}
            else if (UserInput == "c")
                Send, {Blind}{BS}
            else if (UserInput == "v")
                Send, {Blind}{DEL}
            else
                Send, {Blind}%UserInput%
        }
    }
    return



Re: An improved script to use space as modifier

Posted: 28 Apr 2017, 23:58
by stealzy
Look strange for me. How about this:

Code: Select all

Space::
^Space::
+Space::
!Space::
+^Space::
+!Space::
^!Space::
	Return
*Space Up::Send % (A_PriorKey = "Space") ? "{Blind}{Space}" : ""

#If GetKeyState("Space", "P")
	Left::WinMinimize A
	Up::WinMaximize A
	*vk45:: ; e
	*vk44:: ; d
	*vk53:: ; s
	*vk46:: ; f
		SendRemap()
		Return
#If

SendRemap() {
	Static RemapArr:={e: "{Up}", d: "{Down}", s: "{Left}", f: "{Right}"}
	Send % "{Blind}" RemapArr[GetKeyName(SubStr(A_ThisHotkey, 2))]
}
Esc::ExitApp
With delay:

Code: Select all

#MaxHotkeysPerInterval 200
ModActivateDelay := 100

*Space::
	If SpacePressed ; AutoRepeat defense
		Return
	SpacePressed:=true
	SetTimer ModActivate, % "-" ModActivateDelay
	Return
*Space Up::
	SpacePressed:=false
	SetTimer ModActivate, Off
	If ((A_PriorKey = "Space") OR !ModActive)
		Send {Blind}{Space}
	ModActive := false
	Return
ModActivate:
	ModActive := true
	Return

#If (GetKeyState("Space", "P") && ModActive)
	Left::WinMinimize A
	Up::WinMaximize A
	*vk45::SendRemap() ; e
	*vk44::SendRemap() ; d
	*vk53::SendRemap() ; s
	*vk46::SendRemap() ; f
#If

SendRemap() {
	Static SendRemapArr:={e: "{Up}", d: "{Down}", s: "{Left}", f: "{Right}"}
	Send % "{Blind}" SendRemapArr[GetKeyName(SubStr(A_ThisHotkey, 2))]
}
Esc::ExitApp

Re: An improved script to use space as modifier

Posted: 29 Apr 2017, 01:26
by cy18
For example, if A is pressed, then press Space, then release A, then release Space. With my script, the output is "a ".
Another case is press Space, then press A, release Space, release A. With my script, the output is " a".
These two situation are common when typing fast.

Re: An improved script to use space as modifier

Posted: 29 Apr 2017, 06:38
by stealzy
In my examples your first case work as you want.
Your second case disputable: in my opinion, if there is a hotkey Space+A, then hotkey must be unconditional.
Just imagine that the Ctrl+C action effect depends on the speed of execution. If you press it slow — copy; if you press it fast — something else :| .

Re: An improved script to use space as modifier

Posted: 29 Apr 2017, 08:17
by cy18
I have to say, behavior depending on the speed is all what I improved in the script.

After all, space is so commonly used. If not this way, the script would be annoying rather than convenient because of the mistakes made when typing fast.

Re: An improved script to use space as modifier

Posted: 11 Feb 2023, 01:27
by nithinpm09
stealzy wrote:
28 Apr 2017, 23:58
Look strange for me. How about this:

Code: Select all

Space::
^Space::
+Space::
!Space::
+^Space::
+!Space::
^!Space::
	Return
*Space Up::Send % (A_PriorKey = "Space") ? "{Blind}{Space}" : ""

#If GetKeyState("Space", "P")
	Left::WinMinimize A
	Up::WinMaximize A
	*vk45:: ; e
	*vk44:: ; d
	*vk53:: ; s
	*vk46:: ; f
		SendRemap()
		Return
#If

SendRemap() {
	Static RemapArr:={e: "{Up}", d: "{Down}", s: "{Left}", f: "{Right}"}
	Send % "{Blind}" RemapArr[GetKeyName(SubStr(A_ThisHotkey, 2))]
}
Esc::ExitApp
With delay:

Code: Select all

#MaxHotkeysPerInterval 200
ModActivateDelay := 100

*Space::
	If SpacePressed ; AutoRepeat defense
		Return
	SpacePressed:=true
	SetTimer ModActivate, % "-" ModActivateDelay
	Return
*Space Up::
	SpacePressed:=false
	SetTimer ModActivate, Off
	If ((A_PriorKey = "Space") OR !ModActive)
		Send {Blind}{Space}
	ModActive := false
	Return
ModActivate:
	ModActive := true
	Return

#If (GetKeyState("Space", "P") && ModActive)
	Left::WinMinimize A
	Up::WinMaximize A
	*vk45::SendRemap() ; e
	*vk44::SendRemap() ; d
	*vk53::SendRemap() ; s
	*vk46::SendRemap() ; f
#If

SendRemap() {
	Static SendRemapArr:={e: "{Up}", d: "{Down}", s: "{Left}", f: "{Right}"}
	Send % "{Blind}" SendRemapArr[GetKeyName(SubStr(A_ThisHotkey, 2))]
}
Esc::ExitApp
This works great. I am wondering if there is a way to make it generic. That is any key pressed with space should send a modifier (eg: alt) + the at key.


*:: send !* ?