In X11 (on console I don't know) you can do it by redefining the behaviour of the Escape key. I looked at the "shift(break_caps)" definition to see how it works, and adapted it.
Look at this answer on xkb for more details on how/where to put the locally modified files and load them.
And for doing what you want, you need in the local symbols file (eg: ~/.xkb/symbols/mysymbols) a section like this:
partial modifier_keys xkb_symbols "esc_breaks_caps" { key <ESC> { type = "ALPHABETIC", actions [Group1] = [ SetMods(modifiers=none), SetMods(modifiers=Lock,clearLocks) ] }; };
and in the local keymap file (eg: ~/.xkb/keymap/mykbd; you can create it with setxkbmap -print > ~/.xkb/keymap/mykbd ) change the xkb_symbols line to add +mysymbols(esc_breaks_caps).
You can now load it with: xkbcomp -I$HOME/.xkb ~/.xkb/keymap/mykbd $DISPLAY and pressing Esc will remove the CapsLock state (actually, the effect happens on the release of Esc; I think that only modifiers keys have immediate effect; others the effect is after their release.)
Oh, if you want to also swap Escape and CapsLock keys; then use this instead (and you put "+mysymbols(esc_swap_and_breaks_caps)" in your mykbd file):
partial modifier_keys xkb_symbols "esc_swap_and_breaks_caps" { replace key <CAPS> { type = "ALPHABETIC", symbols = [ Escape, Escape ], actions [Group1] = [ SetMods(modifiers=none), SetMods(modifiers=Lock,clearLocks) ] }; replace key <ESC> { [ CapsLock, CapsLock ] }; };
note the physical keys are <CAPS> and <ESC>; <CAPS> (key engraved CapsLock in your keyboard) send Escape and <ESC> (key engraved Esc) sends CapsLock, whith <CAPS> (sending Escape) also unsetting capslock state
vim, or the complete desktop?