Strange keymap problem


#1

Hi All

I got the "missing ‘%’, ‘5’ and ‘enter’ " issue when I installed Atom on an Ubuntu 16.04 server which I use through VNCServer from a Window 7 machine.

Initially I had issues with seeing Atom at all but resolved this with the lines below. I don’t think this has any bearing on the problem but I wanted to have full disclosure just in case.

sudo cp /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0 /opt/atom/libxcb.so.1
sudo sed -i 's/BIG-REQUESTS/_IG-REQUESTS/' /opt/atom/libxcb.so.1

I found an excellent post on resolving the keymap issue and have used the code (with some modifications for the apparent loss of the ‘keystroke’ component of the resolver lambda). The first 2 resolvers below work perfectly and my ‘5’ and ‘%’ have reappeared in the Atom editor but for the life of me I cannot get the ‘enter’ to work. My code looks like this

atom.keymaps.addKeystrokeResolver ({event}) ->
    if event.code is 'Backspace' and event.key is '5' and event.type isnt 'keyup'
        return '5'
atom.keymaps.addKeystrokeResolver ({event}) ->
    if event.code is 'Backspace' and event.key is '%' and event.type isnt 'keyup'
        return '%'
atom.keymaps.addKeystrokeResolver ({event}) ->
    if event.code is 'Space' and event.key is 'enter' and event.type isnt 'keyup'
        return 'enter'

I used the Key Count package to show me what key is being pressed when I hit the ‘enter’ key and it resolves to ‘space’ as had been suggested in the original post I found. However despite this apparent resolution no ‘space’ character appears in the editor which makes me think that it may actually be a special character that is being emitted and not a ‘space’ as the package is suggesting

I guess I have a several questions:

  1. Has anyone come up against this before? And, if so, what was their solution?
  2. Is there a package which would give me a bit more granularity as to which keys are being emitted when I hit the keyboard (ASCII codes maybe so I can be definitive)?
  3. If I do get the ASCII codes or some-such is there a way to use them in a keymap resolver to solve the problem?

#4

Here’s some more information which may help.

The spacebar on my keyboard produces spaces in the text editors in Atom. No surprise there I guess but it is interesting that the Key Binding Resolver produces no output at all when I press the spacebar.

The enter key is still producing ‘space’ in the Key Binding Resolver but, perhaps interestingly, no other lines of information - just the word ‘space’. With many other keys I see green highlighted lines indicating the appropriate cson file


#5

I went back to basics…

  • purged atom from the system
  • rm’d the .atom folder in my home directory
  • reinstalled a clean version of atom
  • added a new file

Attempted to type and then return to a newline but the problem persists - it’s almost like there are missing entries in a .cson somewhere?


#6

Solved! Here’s the solution for those who are interested

atom.keymaps.addKeystrokeResolver ({event}) ->
  if event.key is '5' and event.type isnt 'keyup'
    return '5'

atom.keymaps.addKeystrokeResolver ({event}) ->
  if event.key is '%' and event.type isnt 'keyup'
    return '%'

atom.keymaps.addKeystrokeResolver (event) ->
  if event.keystroke is 'space' and event.type isnt 'keyup'
    return 'enter'

It seems that to get at the ‘key’ property on the event requires {} - used this for the 5 and the %

Also because the spacebar was not emitting anything I was able to use the keystroke property (event without the {}) and test for ‘space’ which was being emitted by the enter on the keyboard and then replace with ‘enter’

Can anyone explain the meaning of the {}? It seems like it forces the evaluation of the inheritance chain for the object but I don’t know as I’m new to this CoffeeScript


#7

That’s object unpacking / destructuring assignment

So in your case, atom.keymaps.addKeystrokeResolver passes some variable to the callback, which has the properties event and keystroke. The event property itself has the properties key and type. I suggest logging the callback variable and exploring it in dev tools if you want to understand it better.

BTW, I think your confusion comes from using event as the callback variable name in the third part, which looks similar to the actual property event it has. So, without unpacking, we would have

atom.keymaps.addKeystrokeResolver (event) -> # using `event` as callback variable name
  if event.event.key is '5' and event.event.type isnt 'keyup'
    return '5'

atom.keymaps.addKeystrokeResolver (foo) -> # but any name works
  if foo.event.key is '%' and foo.event.type isnt 'keyup'
    return '%'

atom.keymaps.addKeystrokeResolver (bar) ->
  if bar.keystroke is 'space' and bar.type isnt 'keyup'
    return 'enter'

#8

@Aerijo
Fantastic response. Appreciate the clarification as I move from C# thinking to JavaScript thinking. Destructuring is a nice concept. :grinning:

BTW I got fed up stopping and starting Atom when making changes so I broke out the keystroke manipulations into a functions file which I call from a perpetually updating global.functions variable. Naughty but effective!
Here’s the modified init.coffee

# ~/.atom/init.coffee

Object.defineProperty global, 'functions', get: ->
  delete require.cache[require.resolve('./functions')]
  require('./functions')

atom.keymaps.addKeystrokeResolver (keypress) ->
  functions.onFive(keypress)

atom.keymaps.addKeystrokeResolver (keypress) ->
  functions.onPercent(keypress)

atom.keymaps.addKeystrokeResolver (keypress) ->
  functions.onEnter(keypress)

And the functions.coffee file

# ~/.atom/functions.coffee

exports.onFive = (keypress) ->
  if keypress.event.key is '5' and keypress.type isnt 'keyup'
    return '5'

exports.onPercent = (keypress) ->
  if keypress.event.key is '%' and keypress.type isnt 'keyup'
    return '%'

exports.onEnter = (keypress) ->
  if keypress.keystroke is 'space' and keypress.type isnt 'keyup'
    return 'enter'

Kudos to the Hacking Atom blog for the idea.


#9

There is an open issue to make these keymap problems when using VNCServer and similar software better here: