Remap arrow keys onto JKLI whenever holding down a certain modifier key
Asked Answered
O

8

8

I'm just wondering if there's a way that I can hold down the control key or something and use my jkli keys as arrow keys. I think it will be easier to program. Is that possible? Thanks.

Otiliaotina answered 1/6, 2015 at 14:41 Comment(2)
You could do this with an autohotkey script. Such a question is best suited to SuperUser thoughScyphate
Thanks for your reply, I saw that but I don't really know how to "script" in autohotkey. Is there an easier way? ThanksOtiliaotina
S
12

Here's the .ahk script I use.

It remaps arrow keys to ALT + I / J / K / L.

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.

; AHK Command       ; key   = Effect        (Description)   

; ALT Keypress Implied for all below

!i::Send {UP}       ; i UP          (Cursor up line)
!k::Send {DOWN}     ; k DOWN            (Cursor down line)

!j::Send {LEFT}     ; j LEFT        (Cursor left one character)
!l::Send {RIGHT}    ; l RIGHT       (Cursor right one character)

!h::Send {HOME}     ; h     ALT + RIGHT (Cursor to beginning of line)
!;::Send {END}      ; ; ALT + LEFT  (Cursor to end of line)

!u::Send ^{HOME}    ; h     SHIFT + HOME    (Cursor to beginning of document)
!o::Send ^{END}     ; o SHIFT + END (Cursor to end of document)

; CTRL + ALT Keypress Implied for all below

!^j::Send ^{LEFT}   ; j     CTRL + LEFT (Cursor left per word)
!^l::Send ^{RIGHT}  ; l CTRL + RIGHT    (Cursor right per word)

; SHIFT + ALT Keypress Implied for all below

!+i::Send +{UP}     ; i SHIFT + UP  (Highlight per line)
!+k::Send +{DOWN}   ; k SHIFT + DOWN    (Highlight per line)

!+j::Send +{LEFT}   ; j SHIFT + LEFT    (Highlight per character)
!+l::Send +{RIGHT}  ; l SHIFT + RIGHT   (Highlight per character)

!+h::Send +{HOME}   ; h SHIFT + ALT + LEFT  (Highlight to beginning of line)
!+;::Send +{END}    ; ; SHIFT + ALT + RIGHT (Hightlight to end of line) 

!+u::Send ^+{HOME}  ; u SHIFT + CTRL + HOME (Highlight to beggininng of document)
!+o::Send ^+{END}   ; o SHIFT + CTRL + END  (Hightlight to end of document) 

; SHIFT + CTRL + ALT Keypress Implied for all below

!+^j::Send +^{LEFT}     ; j SHIFT + CTRL + LEFT (Highlight per word)
!+^l::Send +^{RIGHT}    ; l SHIFT + CTRL + RIGHT    (Hightlight per word)

!+^i::Send +!{UP}   ; i SHIFT + ALT + UP    (Multiply cursor up)
!+^k::Send +!{DOWN} ; k SHIFT + ALT + DOWN  (Multiply cursor down) 

; CTRL + SHIFT Keypress Implied for all below

+^i::Send +^{UP}
+^k::Send +^{DOWN}

Everything after a ; is a comment.

To decipher, use: https://autohotkey.com/docs/Hotkeys.htm

Spherule answered 6/8, 2016 at 14:25 Comment(1)
thank you very much. would be nice to add a delete button on alt + p so we don't have to move to that place on our keyboard e.g. !p::Send {Delete} !+p::Send {Delete}Faust
A
5

Also using AutoHotKey, I really wanted to have key navigation for CAPSLOCK, which is trickier than the special modifier keys (Ctrl, Alt, etc). The trick ended up being using the built-in function GetKeyState(...).

I am sharing my results below. The autohotkey script below is based off of nafzal's answer here, but I made it a bit cleaner :)

; Main Navigation
CAPSLOCK & j::MoveCursor("{LEFT}")
CAPSLOCK & l::MoveCursor("{RIGHT}")
CAPSLOCK & i::MoveCursor("{UP}")
CAPSLOCK & k::MoveCursor("{DOWN}")
CAPSLOCK & h::MoveCursor("{HOME}")
CAPSLOCK & `;::MoveCursor("{END}")
CAPSLOCK & BACKSPACE::Send {DELETE}

; Navigation Combos
MoveCursor(key) {
    shift := GetKeyState("SHIFT","P")
    control := GetKeyState("CONTROL","P")
    controlShift := control && shift

    if controlShift {
        Send, ^+%key%
    }
    else if shift {
        Send, +%key%
    }
    else if control {
        Send, ^%key%
    }
    else {
        Send, %key%
    }
}

; Alternatively, using Alt...
ALT & j::MoveCursor("{LEFT}")
ALT & l::MoveCursor("{RIGHT}")
ALT & i::MoveCursor("{UP}")
ALT & k::MoveCursor("{DOWN}")
ALT & h::MoveCursor("{HOME}")
ALT & `;::MoveCursor("{END}")
ALT & BACKSPACE::Send {DELETE}
Anxious answered 22/7, 2018 at 11:11 Comment(1)
FYI, you have to use the &. >! (what I was using) doesn't work with combining modifiersLadner
O
3

After a bit of trial and error, I was able to make this. I'm putting it on here so anyone who has the same question can use this code.

!j::Send {Left}
!k::Send {Down}
!l::Send {Right}
!i::Send {Up}
Otiliaotina answered 2/6, 2015 at 1:11 Comment(0)
H
1

I tried numerous AutoHotKey scripts from the internet to solve this issue, including all versions mentioned in previous answers to this question. Unfortunately, none of them worked properly. Some of them appear to work at first, but have subtle issues.

After spending quite some time on this issue, I finally managed to create a version that seems to work (kind of).

Posting the code here for those who will find this page by googling.

With this script, ijkl will work as the arrow keys as long as right alt is pressed. It seems to work well in combination with shift and control.

However, the downside is that right alt loses its original function. It is not a problem for me because I only use left alt. If you don't want to sacrifice right alt, you can replace "RAlt" with "CapsLock" and it will work as well.

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

; Arrows & navigation

Hotkey, *i, Off
Hotkey, *j, Off
Hotkey, *k, Off
Hotkey, *l, Off

*RAlt::
    Hotkey, *i, on
    Hotkey, *j, on
    Hotkey, *k, on
    Hotkey, *l, on
return

*RAlt up::
    Hotkey, *i, off
    Hotkey, *j, off
    Hotkey, *k, off
    Hotkey, *l, off
return

*i::send {blind}{up}
*j::send {blind}{left}
*k::send {blind}{down}
*l::send {blind}{right}

Hans Winterhalter's version almost works. However, at least on my pc, if I press and hold alt+shift+j, then it starts selecting text (as expected), but if I hold it long enough, at some point, the shortcut doesn't work and it just prints letter J, destroying the selected text, which is definitely not desirable.

Heavyhearted answered 20/11, 2020 at 17:12 Comment(2)
Usage: Copy the code to a .txt file. rename the extension to '.ahk' and run the file, assuming you have autohotkey installed and active. | Worked perfectly. Thank you very much.Fowkes
to simulate the effect of some keyboards with shortcuts FN+RIGHT=end and FN+LEFT =home, I set RALT+o=home and RALT+p=end. Code: RAlt & p::send {blind}{End}\nRAlt & o::send {blind}{Home}Fowkes
S
0

Simple autohotkey script.

Ctrl+T to turn on toggle, then IJKL behave as arrow keys until Ctrl+T is pressed again.

#SingleInstance ignore
Hotkey, I, Off
Hotkey, J, Off
Hotkey, K, Off
Hotkey, L, Off

^t::
    Hotkey, I, Toggle
    Hotkey, J, Toggle
    Hotkey, K, Toggle
    Hotkey, L, Toggle
return

I::
    Send {Up}
return

J::
    Send {Left}
return

K::
    Send {Down}    
return

L::
    Send {Right} 
return

(Although I'd recommend learning vim HJKL approach instead!)

Scyphate answered 1/6, 2015 at 14:51 Comment(13)
Wow, thanks so much!! That works really well! Is there a way to do it by just holding down the control key instead though? ThanksOtiliaotina
Your profile lists "interested in programming". I'm sure you can make such tweaks :). autohotkey.com/docs (Remove the toggle code, change hotkeys to have the Ctrl modifier prefix ^K, ^L)Scyphate
Real quick, can you please tell me what is wrong with this?Otiliaotina
#SingleInstance ignore #InstallMouseHook #UseHook Hotkey, I, Off Hotkey, J, Off Hotkey, K, Off Hotkey, L, Off !f:: while GetKeyState("I") { Send {Up} } while GetKeyState("J") { Send {Left} } while GetKeyState("K") { Send {Down} } while GetKeyState("L") { Send {Right} } returnOtiliaotina
The Hotkey lines are redundant in your script, you can remove those. The !f while-loops isn't the easiest way of doing things; I think you probably want to think of each press as Alt+F+I, then have 4 separate hotkeys.Scyphate
Sorry, I don't really know what you mean by your last sentence. Thanks again for your time.Otiliaotina
Your script in the comment has 1 hotkey definition for Alt+F then is using while-loops to try to work out what "sub-key" is pressed. My gut feeling is that this won't work; you will press Alt+F, and be just about to press I, then the hotkey code will reach the bottom of the Alt+F definition and return, then I won't do anything. Instead, make the definition for Alt+F+IScyphate
Oooohhhhh, I see what you mean. Thanks for the advice.Otiliaotina
okay, so i'm trying to make it turn it into an arrow key when I hold down the alt key. Is there another way to do this other than the toggle option?Otiliaotina
Ah, I thought you could do !fi:: but it seems that's not supported. You have a few options; you can make Alt+F trigger a toggle that will effect subsequent presses of I, or you can use a hotkey that only uses 1 keyboard letter, or you can possibly do something clever with GetKeyState as you were trying.Scyphate
(Can a mod move this to Chat please?)Scyphate
@RJFalconer: We can't actually, not until there is more of a conversation.Searching
@MartijnPieters ah, thanks anyway. How many comments are required?Scyphate
L
0

This autohotkey script mostly based on nafzal and Hans Winterhalter answers (great appreciation). Crucial difference is in "modifier key". If you map "modifier key" to Alt or Ctrl, sometimes it cause misuse functionality in apps that rely on this keys, so you will encounter unexpected behaviour. Remmaping "modifier key" to "unreal key", key that does not physically exists on current keyboard, makes it work like "Fn key" (1). Pressing this key will not modify, nor interrupt any other keys (like Win, Alt, Ctrl, Shift, etc) and you will be able to use any combination of keys. To remap "modifier key" you need SharpKeys or manual edit Windows Registry (2).

Here is example of "unreal key" (AHK special key (3) ), the one - that not exists on my keyboard, remapped to Right Alt.

It is conviniet to put arrow keys similar to vim "hjkl", but with shift to right - "jkl;" so fingers are always on typing position, plus additional keys.

With autostartup (4) - it work like a charm and reduce overhead of configuring different text editors, browsers, terminals, etc.

There is exception - it will not work in some administrative apps (5).

Remarks:

  1. There are no possible ways to remap real Fn key, at least without modifing keyboard driver or PCB. https://superuser.com/questions/65/remap-fn-to-another-key

  2. Detailed guide for editing Windows Registry manually. https://isenselabs.com/posts/keyboard-key-kills-and-remaps-for-windows-users

  3. Detailed guide for using AHK special keys. https://www.autohotkey.com/docs/KeyList.htm#SpecialKeys

  4. Make script to autostartup. https://www.autohotkey.com/docs/FAQ.htm#Startup

  5. Task Manger, Regedit Editor, Admin PowerShell, etc are administrative apps. Run ahk with admin right to work. Run as Administrator

     MoveCursor(key) {
       control := GetKeyState("CONTROL","P")
       shift := GetKeyState("SHIFT","P")
       alt := GetKeyState("ALT","P")
       win := GetKeyState("LWIN","P")
       ctrlShift := control && shift
       ctrlAlt := control && alt 
       altShift := alt && shift
       ctrlAltShift := control && alt && shift    
    if ctrlAltShift {
       Send, ^!+%key%
    } else if altShift {
       Send, !+%key%
    } else if ctrlShift {
       Send, ^+%key%
    } else if ctrlAlt {
       Send, ^!%key%
    } else if control {
       Send, ^%key%
    } else if shift {
       Send, +%key%
    } else if alt {
       Send, !%key%
    } else if win {
       Send, #%key%
    } else {
       Send, %key%
    }}
    SC163 & j::MoveCursor("{LEFT}")
    SC163 & k::MoveCursor("{DOWN}")
    SC163 & l::MoveCursor("{UP}")
    SC163 & `;::MoveCursor("{RIGHT}")
    SC163 & m::MoveCursor("{HOME}")
    SC163 & ,::MoveCursor("{PGDN}")
    SC163 & .::MoveCursor("{PGUP}")
    SC163 & /::MoveCursor("{END}")
    SC163 & BS::MoveCursor("{DEL}")
    ;SC163 & u::BS.SetBrightness(-10)
    ;SC163 & i::BS.SetBrightness(10)
    ;SC163 & o::Volume_Down
    ;SC163 & p::Volume_Up
    
  • List item
Lamontlamontagne answered 7/12, 2020 at 20:47 Comment(0)
Y
0

I re-mapped my arrow keys (on Mac) using Hammerspoon and documented in a GitHub repo https://github.com/RobotCharlie/key-remapping-hammerspoon

Yugoslavia answered 3/10, 2021 at 18:16 Comment(0)
A
0

My best way of doing this in Windows OS is by installing Microsoft PowerToys. In the keyboard section, remap shortcut: Left ALT + "I J K L" as Up, Left, Down, Right

This way, whenever Left ALT is Held, IJKL will function as arrow keys

Further customization, I also liked to use: Left ALT + ", . /" as Home, End, and Apps/Menu

Apsis answered 8/5, 2022 at 16:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.