Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to be able to map the Caps Lock Key to Escape if it is not pressed with any other key and Control if it is. How can I do that on Windows 7?

share|improve this question
1  
possible duplicate of How can I disable and reassign the Caps Lock key? –  techie007 Jan 23 '12 at 3:46
2  
Well, conditional reassigning is not covered there –  wizzard0 Jan 23 '12 at 3:55
add comment

4 Answers

You can remap it to Escape with SharpKeys

However, I don't know of a realistic way to perform conditional remapping, other than writing a keyboard driver.

share|improve this answer
    
I already have my Caps Lock key mapped to Escape with SharpKeys. –  Zameer Manji Jan 23 '12 at 14:24
add comment

This is not exactly what you want but very close if you can live with some flaws. Here's an AutoHotKey script:

$CapsLock::LControl
$CapsLock Up::Send {Escape}
return

It remaps Caps Lock to Ctrl and sends Escape when you release the key. It took me a while to get used to the Escape key being pressed every time I let go the Caps Lock key. However it's pretty much useless on website textareas because pressing Escape loses the focus on the textarea.

I'm looking for a solution to this though. I might go as far as write some sort of driver/keyboard hook in C if needed, haha.

Vim-specific annoyances: It makes digraphs impossible to type using the Ctrl-K combination and is generally plain annoying before you get used to it. It works well for me though because I'd do anything to avoid Esc and Ctrl keys as much as possible.

share|improve this answer
add comment

The remapkey.exe program included in the Windows Server 2003 Resource Kit Tools mentioned in this article works nicely in Windows 7.

share|improve this answer
1  
please avoid using links as answers. instead, try explaining to your best the contents of the links and only then use them as reference. if the link ever gets broken, so does your whole answer. –  Lorenzo Von Matterhorn Apr 8 '13 at 16:08
add comment

I use the following AutoHotkey script for this, adapted from one I found on the Vim Tips Wiki. The implementation is a bit hacky, but it "works for me." (And unlike the other answers on the page, it fully solves the issue without caveats.)

The original coder noted:

The script also tries to detect and avoid "false positives" where you press Control and another key and release both too quickly, i.e. before the timeout period.

Be sure to tweak the 250ms value depending on how good or bad your keyboard is, and your own reaction time. This is probably something to tweak experimentally to your own liking.

CapsLockCtrlEscape.ahk gist:

g_LastCtrlKeyDownTime := 0
g_AbortSendEsc := false
g_ControlRepeatDetected := false

*CapsLock::
    if (g_ControlRepeatDetected)
    {
        return
    }

    send,{Ctrl down}
    g_LastCtrlKeyDownTime := A_TickCount
    g_AbortSendEsc := false
    g_ControlRepeatDetected := true

    return

*CapsLock Up::
    send,{Ctrl up}
    g_ControlRepeatDetected := false
    if (g_AbortSendEsc)
    {
        return
    }
    current_time := A_TickCount
    time_elapsed := current_time - g_LastCtrlKeyDownTime
    if (time_elapsed <= 250)
    {
        SendInput {Esc}
    }
    return

~*^a::
    g_AbortSendEsc := true
    return
~*^b::
    g_AbortSendEsc := true
    return
~*^c::
    g_AbortSendEsc := true
    return
~*^d::
    g_AbortSendEsc := true
    return
~*^e::
    g_AbortSendEsc := true
    return
~*^f::
    g_AbortSendEsc := true
    return
~*^g::
    g_AbortSendEsc := true
    return
~*^h::
    g_AbortSendEsc := true
    return
~*^i::
    g_AbortSendEsc := true
    return
~*^j::
    g_AbortSendEsc := true
    return
~*^k::
    g_AbortSendEsc := true
    return
~*^l::
    g_AbortSendEsc := true
    return
~*^m::
    g_AbortSendEsc := true
    return
~*^n::
    g_AbortSendEsc := true
    return
~*^o::
    g_AbortSendEsc := true
    return
~*^p::
    g_AbortSendEsc := true
    return
~*^q::
    g_AbortSendEsc := true
    return
~*^r::
    g_AbortSendEsc := true
    return
~*^s::
    g_AbortSendEsc := true
    return
~*^t::
    g_AbortSendEsc := true
    return
~*^u::
    g_AbortSendEsc := true
    return
~*^v::
    g_AbortSendEsc := true
    return
~*^w::
    g_AbortSendEsc := true
    return
~*^x::
    g_AbortSendEsc := true
    return
~*^y::
    g_AbortSendEsc := true
    return
~*^z::
    g_AbortSendEsc := true
    return
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.