Today I found this very nice article by Steven Losh in which he presents a couple of productivity boosting keyboard mappings. Among them is a dynamic mapping of the left and right shift keys.

The Idea

When Shift_L or Shift_R are pressed without an additional key they are mapped to '(' and ')' respectively, otherwise they function as usual.

The Problem

He does all of this under OSX. I am trying to achieve the same under Linux. There is no straightforward way for this since as I understand you can't use xmodmap to configure one key for Shift_L alone, and another for Shift when used as a modifier key.

I have googled around a bit and found people trying to do the same under Windows which is apparently possible using AutoHotKey, but I could not find anything for Linux.

Is there a way to solve this under Linux?


Wow! User teika kazura's comment on the original question is quite correct — not only is this effectively a duplicate of that other question, but the answer provided there ("use xcape") solves this problem!

After cloning the xcape repo and compiling (I had to install libXtst-devel on my Fedora box, first), I was able to obtain the exact behavior requested with the following command:

xcape -e "Shift_L=parenleft;Shift_R=parenright"

After admittedly-cursory testing, it seems to work extremely well. Nice!

Other Options

If you use the Shift key as a mouse modifier (i.e. if you ever shift-click anything), you'll probably want to include xcape's timeout option and find a comfortable timeout value, so that solo Shift keypresses used in combination with the mouse don't generate spurious parentheses. From the xcape README:

-t <timeout ms>

If you hold a key longer than this timeout, xcape will not generate a key event. Default is 500 ms.

So, by including the -t flag with a timeout value that works for you, you'll still be able to shift-click with the mouse as long as you hold down Shift for at least timeout ms milliseconds.

(Credit, again, to teika kazura for pointing out the other question, and also to don_crissti for the original answer there.)

  • One problem with this method is I quite often press [Shift] + [LMouse] to select some text in editors. Interestingly Sublime Text also uses [Ctrl] + [LMouse] so the question about remapping [Ctrl] also causes problems. – AnnanFay Oct 25 '17 at 20:41
  • @Annan Have you experimented with adjusting xcape's timeout option? From the README: "-t <timeout ms> If you hold a key longer than this timeout, xcape will not generate a key event. Default is 500 ms." ...Unless xcape interferes with the modifier's key-down event (I can't recall), that should keep it from generating spurious keypresses, while still letting you use it as a mouse-selection modifier as long as you hold it long enough. – FeRD Oct 27 '17 at 3:17

It's an interesting challenge, and I agree one that xinput doesn't appear to be perfectly suited to. I spent some time fiddling around with xmodmap's abilities, and came so frustratingly close to achieving what you want to do... without actually managing to get there.

Using xmodmap, it's possible to assign parenleft as a shifted keysymbol on the left-shift key:

xmodmap -e 'keysym Shift_L = Shift_L parenleft Shift_L parenleft'

which sorta works, at least in testing on my Fedora 17 box, but not in a satisfactory way. I found that, with this mapping in place, the shift key still functioned normally, and didn't render any spurious parens, but (frustratingly) it didn't reliably produce left-parens either. For whatever reason, the key doesn't appear to reliably modify itself, which breaks its shifted assignment... initially. For whatever reason, hitting left-shift a few times in succession would eventually cause it to start producing left-parens, but only after the fourth or fifth press.

One behavior I did notice, however, that you might be able to work with as a "near enough" analogue: I found that after mapping parenleft and parenright onto Shift_L and Shift_R, I could reliably type parens by "rolling" across both shift keys — in other words, with this mapping:

xmodmap -e 'keysym Shift_L = Shift_L parenleft Shift_L parenleft'
xmodmap -e 'keysym Shift_R = Shift_R parenright Shift_R parenright'

pressing Shift_L followed by Shift_R, then releasing both, would output a right-paren, or a left-paren in the other direction. (The paren mappings could be reversed, of course; I couldn't quite decide which way felt more "natural".)

That was as close as I came to achieving the exact behavior you're looking for; it doesn't seem like it's possible using xmodmap alone.

I was halfway-convinced that it simply isn't possible, period, but then I realized that there's at least one key which functions exactly as you describe: The Super ("Windows") key. Under Gnome Shell, it's a modifier key (mod4), which produces a different effect (triggering Overview) when pressed alone. So, at least in theory, it may be possible to implement your desired shift-key overloading in the same manner.

...But, I have absolutely no idea how that would be done, or how invasive it would be to get bogged down in the necessary processing every time you hit the Shift key. :-)


maybe look a xbindkeys to change the key mapping or just find a good coding plugin for vim or gedit or whatever you like to use or code your own.

tools to change keymaps https://stackoverflow.com/questions/6812/mapping-my-custom-keys-in-debian

maybe http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-14.html

and write a script to enable it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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