Skip to content
This repository has been archived by the owner on Apr 6, 2018. It is now read-only.

remapping Esc #334

Closed
assemblical opened this issue Jul 3, 2014 · 104 comments
Closed

remapping Esc #334

assemblical opened this issue Jul 3, 2014 · 104 comments
Assignees

Comments

@assemblical
Copy link

I remapped 'jk' and 'kj' to activate command mode.

'.editor.vim-mode:not(.command-mode)':
  'j k': 'vim-mode:activate-command-mode'
  'k j': 'vim-mode:activate-command-mode'

However if I just press 'k' or 'j' followed by another letter, the 'k' or 'j' doesn't appear. How can I overcome this problem?

@zephraph
Copy link

I've seen this as well. I usually map fj to escape in vim, however doing so in vim mode doesn't give the expected behavior. The first time 'f' is pressed, it always interprets it as a shortcut and waits on the rest to be entered. If something else is entered that isn't 'j' in this case then it just prints that out and continues on its marry way. In order to enter 'f' normally in my case I have to type it twice.

The vim style behavior is to have a short timeout in which, if the shortcut isn't completed the typed letters are printed. I have the feeling that this is more of an atom issue than a plugin issue though so I fear it'll be hard to change.

@garcg
Copy link
Contributor

garcg commented Jul 24, 2014

It seems the timeout after the first key press is there, it only needs a fallback to insert the text into the editor.

I've found a workaround adding the following to the user config.
This is for mapping j k as escape:

~/.atom/keymap.cson:

'.editor.vim-mode:not(.command-mode)':
  'j k': 'vim-mode:activate-command-mode'

'.editor.vim-mode.insert-mode':
  'j': 'insert-incomplete-keybinding'

~/.atom/init.coffee:

atom.workspaceView.command 'insert-incomplete-keybinding', (e)->
  if oe = e.originalEvent && e.originalEvent.originalEvent
    char = String.fromCharCode(oe.which)
    char = char.toLowerCase() unless oe.shift
    atom.workspace.activePaneItem.insertText(char)

Although, I don't know how this could be fixed in the vim package.

@zephraph
Copy link

It's good to know that it's doable though. I might explore a bit and see if I can come up with a solution.

@philk
Copy link

philk commented Sep 2, 2014

This completely worked for me when I thought based on #129 that it was still impossible in Atom. Only caveat was hitting jj was canceling visual mode, not just insert mode, but that was an easy fix.

'.editor.vim-mode.insert-mode':
  'j': 'insert-incomplete-keybinding'

'.vim-mode.insert-mode:not(.mini)':
  'j j': 'vim-mode:activate-command-mode'

Thanks, now I can use Atom without having to change my habits 😃

@BallisticPain
Copy link

I have been unable to get jj to work for typing "j" and also using "jj" to get me out of command mode. :(

I feel this shouldn't be so difficult. I have seen people reference a "timeout", but have been unable to find this anywhere in the settings for either Vim Mode nor Atom.

Edit: I just re-checked the init.coffee and noticed a misspelling... works now! Woohoo...

Thanks!
J

@pelachile
Copy link

@BallisticPain where did you find the misspelling? I have tried and tried and I can't get jj to work. It's the only thing that prevents me from using atom, I'm just to used to my vim settings. I'm on a OSX 10.10

@BallisticPain
Copy link

@pelachile, I'll copy and paste below what I have that's working. I use jj constantly and it was imperative that I got it working as well so I fully understand your frustration.

I personally mis-spelled a portion of the ~/.atom/init.coffee script. I didn't copy and paste, I just typed it in.

# Your init script
#
# Atom will evaluate this file each time a new window is opened. It is run
# after packages are loaded/activated and after the previous editor state
# has been restored.
#
# An example hack to make opened Markdown files always be soft wrapped:
#
# path = require 'path'
#
# atom.workspaceView.eachEditorView (editorView) ->
#   editor = editorView.getEditor()
#   if path.extname(editor.getPath()) is '.md'
#     editor.setSoftWrap(true)
#

atom.workspaceView.command 'insert-incomplete-keybinding', (e)->
    if oe = e.originalEvent && e.originalEvent.originalEvent
        char = String.fromCharCode(oe.which)
        char = char.toLowerCase() unless oe.shift
        atom.workspace.activePaneItem.insertText(char)

I misspelled the .workspace portion.

Here's my ~/.atom/keymap.cson (I was originally modifying the one in the package directly, and this wasn't working as well as modifying my home directory version)...

# Your keymap
#
# Atom keymaps work similarly to stylesheets. Just as stylesheets use selectors
# to apply styles to elements, Atom keymaps use selectors to associate
# keystrokes with events in specific contexts.
#
# You can create a new keybinding in this file by typing "key" and then hitting
# tab.
#
# Here's an example taken from Atom's built-in keymap:
#
# '.editor':
#   'enter': 'editor:newline'
#
# '.workspace':
#   'ctrl-P': 'core:move-up'
#   'ctrl-p': 'core:move-down'
#
'.editor.vim-mode.insert-mode':
    'j': 'insert-incomplete-keybinding'

'.vim-mode.insert-mode:not(.mini)':
  'j j': 'vim-mode:activate-command-mode'

One thing I will also note here is that I believe the order of these two insertions matters. The other note is that if you want to type a 'j' while in insert mode, type it and then the next letter and they'll both appear. Otherwise you must wait for the timeout to occur to see the 'j' appear.

I hope this helps,
Jarvis

@JacobHTran
Copy link

Atom seems to have a new process to add custom commands. I have been playing with atom for all of 10 mins, but in order to achieve this functionality without using the deprecated atom.workspaceView.command I implement the insert-incomplete-keybinding as such:

atom.commands.add 'atom-text-editor', 'insert-incomplete-keybinding', (e)->
  oe = e.originalEvent
  char = String.fromCharCode(oe.which)
  char = char.toLowerCase() unless oe.shift
  atom.workspace.activePaneItem.insertText(char)

@rdlugosz
Copy link

I was still seeing odd delays with the methods described above and so I implemented things in a slightly different way. Note that I prefer to use kj to exit insert mode rather than jk or jj, but you should be able to modify this for your own approach.

#keymap.cson
'atom-text-editor.vim-mode.insert-mode':
  'j': 'exit-insert-mode-if-preceded-by-k'
#init.coffee
atom.commands.add 'atom-text-editor', 'exit-insert-mode-if-preceded-by-k': (e) ->
  editor = @getModel()
  pos = editor.getCursorBufferPosition()
  range = [pos.traverse([0,-1]), pos]
  lastChar = editor.getTextInBufferRange(range)
  if lastChar != "k"
    e.abortKeyBinding()
  else
    editor.backspace()
    atom.commands.dispatch(e.currentTarget, 'vim-mode:activate-normal-mode')

While this isn't quite as flexible (in terms of being able to map different keys without changing the command that's executed), there are no "timeout" related issues or visual delays in not having the j (or in my case, k) char appear on the screen until the next keypress. This also avoids issues related to Atom "eating" the first char of your mapping, which can happen with other approaches.

Note that using the event.abortKeyBinding() is the preferred way to jump out of your key bindings and let the keystroke pass through to the editor (see: https://atom.io/docs/api/v0.187.0/KeymapManager).

edit: the word should have been "preceded" not "proceeded".
edit2: changed .editor to atom-text-editor to resolve Atom 1.0 deprecation warning
edit3: 22July2015 - Changed vim-mode:activate-command-mode to vim-mode:activate-normal-mode for compatibility with v.56+

@Robert-Wett
Copy link

Robert-Wett commented Mar 25, 2015

+1 @rdlugosz - working great for me, using jk to exit insert mode. For the lazy:

#keymap.cson
'atom-text-editor.vim-mode.insert-mode':
  'k': 'exit-insert-mode-if-proceeded-by-j'
#init.coffee
atom.commands.add 'atom-text-editor', 'exit-insert-mode-if-proceeded-by-j': (e) ->
  editor = @getModel()
  pos = editor.getCursorBufferPosition()
  range = [pos.traverse([0,-1]), pos]
  lastChar = editor.getTextInBufferRange(range)
  if lastChar != "j"
    e.abortKeyBinding()
  else
    editor.backspace()
    atom.commands.dispatch(e.currentTarget, 'vim-mode:activate-normal-mode')

@jesseleite
Copy link

It should be as easy as:

'atom-text-editor.vim-mode':
  'j k': 'vim-mode:reset-command-mode'

Unfortunately, it's not. Small things like this keep me using Sublime. I'm excited about Atom's future though.

@ahmadseleem
Copy link

The best and simplest until this is supported natively by Atom:
Is the one by: @Robert-Wett
because the the one by @garcg doesn't work if yo wanna map escape to something like =>

 , ,

So, the final solution is as @Robert-Wett except he didn't add escape for visual mode in the mapping:

#keymap.cson

#................................................
# Escape
#................................................
'atom-text-editor.editor.vim-mode.insert-mode':
  ',': 'exit-insert-mode-if-proceeded-by-j'

'atom-text-editor.vim-mode.visual-mode:not(.mini)':
  ', ,': 'vim-mode:activate-command-mode'
  'v': 'vim-mode:activate-command-mode'

It's still not perfect because it just wait for the second letter for ever....!!!
it should be just a half a second or so then inserts the char and return...

@ahmadseleem
Copy link

Like:

 setTimeout(doStuff, 50); //wait 50 millisecnds then recheck
 return;

I know it's extremely rare that you would need to type jj or jk or ,, or whatever alike.
But, just incase

@bronson
Copy link
Contributor

bronson commented May 21, 2015

Is this a dupe of #221?

@jesseleite
Copy link

Not sure. Some people like the simultaneous "j+k", other people like the slightly offset "j" then "k" in quick succession. Either way, I'm not sure either is as well fleshed out as in other Vim emulators (Vintageous for Sublime Text, etc).

@rdlugosz
Copy link

@bronson It's possibly a dup, but since there's been a lot more discussion (and proposed workarounds) here I'd suggest closing that issue and keeping this one open. That issue may be tougher for folks to find since the subject is referencing a specific third-party app for remapping keys.

@lazybios
Copy link

@philk Thank you ! It's works for me too! I can continue stay in the Atom with my habits. 😁

@schmty
Copy link

schmty commented Jun 9, 2015

how would you go about the setTimeout in coffee script?

@nothingrealhappen
Copy link

init.coffee

atom.commands.add 'atom-text-editor', 'custom:wait-key-press', (e)->
  oe = e.originalEvent
  char = String.fromCharCode(oe.which)
  char = char.toLowerCase() unless oe.shift
  atom.workspace.getActivePaneItem().insertText(char)

keymap.cson

'atom-text-editor.vim-mode.insert-mode':
  'j': 'custom:wait-key-press'

'.vim-mode.insert-mode:not(.mini)':
  'j j': 'vim-mode:activate-command-mode'

worked for me , atom version 0.207.0

@ahmadseleem
Copy link

No, I don't think this works, completely.
Now, you can't type j

@nothingrealhappen
Copy link

But it works for me , my atom version is 0.208.0 , I can type j and if I type jasdfasdf the j will immediately appear . if I just type j wait 2s j will appear .

@ahmadseleem

@ahmadseleem
Copy link

Yes it does work now!
I'm sorry, I didn't wait 2s :)
Anyway to control the time ?
Seriously, curious! Like 1 sec ?

Also, it doesn't insert comma in my case. It inserts:
¼

@nothingrealhappen
Copy link

Sorry, I don't know how to control the delay , In fact I think it doesn't matter , because we usually type a word , A few cases we just type j . and the comma ... I can type it , Maybe because other reason : )

@ahmadseleem
Copy link

No, I think because the comma is not an alphabetic char.
So, for example you can't convert to lower case as in your solution.

@nothingrealhappen
Copy link

so clever , we can detect char code, if it's character like abcd then convert it

@pelachile
Copy link

Last solution is not working on Atom 0.209.0. J will not show up.

@damassi
Copy link

damassi commented Jun 24, 2015

Neither does it work for 0.211.0

@rdlugosz
Copy link

Just confirmed that my solution to this is still working fine in version 0.211.0.

There is not currently a clean way to map sequential keystrokes in Atom to escape insert mode like you can in Vim; they simply work differently. The approach I describe above requires that you add a (very simple) function in addition to the key mapping, but it achieves the desired results with no introduction of strange delays or similar issues described here.

rdlugosz added a commit to rdlugosz/vim-mode that referenced this issue Jan 7, 2016
As discussed at length in issue atom#334, mapping double characters to ESC
is a common Vim pattern (e.g, 'jj' or 'jk'). Atom supports this style of
mapping, but the editor behavior is inconsistent with Vim in that the
initial characters that partially match a mapping are not displayed on
screen. This is jarring to the user.

This PR adds documentation to the README that describes a two-step
approach to mapping ESC that removes the delay from the editor and much
more closely imitates Vim's behavior.

This issue exists today in Atom 1.3.2. A future update to Atom may
change the behavior of
[KeymapManager](https://atom.io/docs/api/v1.3.2/KeymapManager) so that
partial matches are displayed. Work in this area was most recently done in
[PR atom#94 on atom-keymap](atom/atom-keymap#94).

I considered adding this info to the Wiki, but the project doesn't
currently have one, so I figured the README was the next-best place.
rdlugosz added a commit to rdlugosz/vim-mode that referenced this issue Jan 7, 2016
As discussed at length in issue atom#334, mapping double characters to ESC
is a common Vim pattern (e.g, 'jj' or 'jk'). Atom supports this style of
mapping, but the editor behavior is inconsistent with Vim in that the
initial characters that partially match a mapping are not displayed on
screen. This is jarring to the user.

This PR adds documentation to the README that describes a two-step
approach to mapping ESC that removes the delay from the editor and much
more closely imitates Vim's behavior.

This issue exists today in Atom 1.3.2. A future update to Atom may
change the behavior of
[KeymapManager](https://atom.io/docs/api/v1.3.2/KeymapManager) so that
partial matches are displayed. Work in this area was most recently done in
[PR atom#94 on atom-keymap](atom/atom-keymap#94).

I considered adding this info to the Wiki, but the project doesn't
currently have one, so I figured the README was the next-best place.
rdlugosz added a commit to rdlugosz/vim-mode that referenced this issue Jan 7, 2016
As discussed at length in issue atom#334, mapping double characters to ESC
is a common Vim pattern (e.g, 'jj' or 'jk'). Atom supports this style of
mapping, but the editor behavior is inconsistent with Vim in that the
initial characters that partially match a mapping are not displayed on
screen. This is jarring to the user.

This PR adds documentation to the README that describes a two-step
approach to mapping ESC that removes the delay from the editor and much
more closely imitates Vim's behavior.

This issue exists today in Atom 1.3.2. A future update to Atom may
change the behavior of
[KeymapManager](https://atom.io/docs/api/v1.3.2/KeymapManager) so that
partial matches are displayed. Work in this area was most recently done in
[PR atom#94 on atom-keymap](atom/atom-keymap#94).

I considered adding this info to the Wiki, but the project doesn't
currently have one, so I figured the README was the next-best place.
rdlugosz added a commit to rdlugosz/vim-mode that referenced this issue Jan 7, 2016
As discussed at length in issue atom#334, mapping double characters to ESC
is a common Vim pattern (e.g, 'jj' or 'jk'). Atom supports this style of
mapping, but the editor behavior is inconsistent with Vim in that the
initial characters that partially match a mapping are not displayed on
screen. This is jarring to the user.

This PR adds documentation to the README that describes a two-step
approach to mapping ESC that removes the delay from the editor and much
more closely imitates Vim's behavior.

This issue exists today in Atom 1.3.2. A future update to Atom may
change the behavior of
[KeymapManager](https://atom.io/docs/api/v1.3.2/KeymapManager) so that
partial matches are displayed. Work in this area was most recently done in
[PR atom#94 on atom-keymap](atom/atom-keymap#94).

I considered adding this info to the Wiki, but the project doesn't
currently have one, so I figured the README was the next-best place.
rdlugosz added a commit to rdlugosz/vim-mode that referenced this issue Jan 7, 2016
As discussed at length in issue atom#334, mapping double characters to ESC
is a common Vim pattern (e.g, 'jj' or 'jk'). Atom supports this style of
mapping, but the editor behavior is inconsistent with Vim in that the
initial characters that partially match a mapping are not displayed on
screen. This is jarring to the user.

This PR adds documentation to the README that describes a two-step
approach to mapping ESC that removes the delay from the editor and much
more closely imitates Vim's behavior.

This issue exists today in Atom 1.3.2. A future update to Atom may
change the behavior of
[KeymapManager](https://atom.io/docs/api/v1.3.2/KeymapManager) so that
partial matches are displayed. Work in this area was most recently done in
[PR atom#94 on atom-keymap](atom/atom-keymap#94).

I considered adding this info to the Wiki, but the project doesn't
currently have one, so I figured the README was the next-best place.
rdlugosz added a commit to rdlugosz/vim-mode that referenced this issue Jan 7, 2016
As discussed at length in issue atom#334, mapping double characters to ESC
is a common Vim pattern (e.g, 'jj' or 'jk'). Atom supports this style of
mapping, but the editor behavior is inconsistent with Vim in that the
initial characters that partially match a mapping are not displayed on
screen. This is jarring to the user.

This PR adds documentation to the README that describes a two-step
approach to mapping ESC that removes the delay from the editor and much
more closely imitates Vim's behavior.

This issue exists today in Atom 1.3.2. A future update to Atom may
change the behavior of
[KeymapManager](https://atom.io/docs/api/v1.3.2/KeymapManager) so that
partial matches are displayed. Work in this area was most recently done in
[PR atom#94 on atom-keymap](atom/atom-keymap#94).

I considered adding this info to the Wiki, but the project doesn't
currently have one, so I figured the README was the next-best place.
rdlugosz added a commit to rdlugosz/vim-mode that referenced this issue Jan 7, 2016
As discussed at length in issue atom#334, mapping double characters to ESC
is a common Vim pattern (e.g, 'jj' or 'jk'). Atom supports this style of
mapping, but the editor behavior is inconsistent with Vim in that the
initial characters that partially match a mapping are not displayed on
screen. This is jarring to the user.

This PR adds documentation to the README that describes a two-step
approach to mapping ESC that removes the delay from the editor and much
more closely imitates Vim's behavior.

This issue exists today in Atom 1.3.2. A future update to Atom may
change the behavior of
[KeymapManager](https://atom.io/docs/api/v1.3.2/KeymapManager) so that
partial matches are displayed. Work in this area was most recently done in
[PR atom#94 on atom-keymap](atom/atom-keymap#94).

I considered adding this info to the Wiki, but the project doesn't
currently have one, so I figured the README was the next-best place.
@RafaelCosman
Copy link

Thanks for your work on this! I've tried a bunch of the posts in this thread and haven't gotten any of them to work. Looking forward to a package that fixes this.

@ebylund
Copy link

ebylund commented Feb 3, 2016

@rdlugosz Great solution! I've used Macvim for the past year, all the while getting used to my 'jk' esc mapping. I'd been having a problem switching to Atom because of the lag it introduced. I'd tried other solutions, but none seemed to work, Thanks again!

@martin-tomes
Copy link

@Robert-Wett unfortunately it seems this snippet is not working anymore (Linux Debian, Atom v. 1.5.3)

@rdlugosz
Copy link

@tomesh @Robert-Wett Are you saying my snippet (the one documented in the PR) no longer works? Just tried it in Atom 1.5.3 (OS X) and it seems to work fine...

@martin-tomes
Copy link

@rdlugosz No, i mean this snippet:

'atom-text-editor.vim-mode.insert-mode':
  'j k': 'vim-mode:activate-normal-mode'

But actually non of the snippets posted in this thread is working for me. Solutions with init script functions, solutions without it... no chance to make it operational.

I have tried reinstallation, disabling the other plugins etc . without any success. An I dunno how to debug it.

@martin-tomes
Copy link

@rdlugosz well... only solution which works for me is upgrade to beta version (1.6.0-beta4)

@kylesezhi
Copy link

I have 1.5.3 and this keymap works for me:

'atom-text-editor.vim-mode.insert-mode':
   'j k': 'vim-mode:activate-normal-mode'

Note that I have a linebreak after the first colon and the second line is tabbed in.

@Yohanna
Copy link

Yohanna commented Mar 17, 2016

@kylesezhi Your kemap worked for me, thanks!

For the record, I'm using v. 1.5.4

@jesseleite
Copy link

@kylesezhi and @Yohanna that keymap always worked. The issue is with the delay when typing anything like "jam" or "jesse". There's a bad delay after hitting that j key while the keymap listener is waiting for a possible k to follow.

Other vim emulators do their check after hitting the second k input. The emulator then checks the previous key to see if it was a j, and if so enters vim mode. This allows the vim emulator to handle the same j k key mapping without that delay.

@rdlugosz
Copy link

Exactly. Avoiding the delay is precisely what my post above (and PR to have
this added to the Readme) is all about.

One step further that i think is worth considering is to just add the code
to the package itself and allow the user to specify their preferred two-key
mapping to exit insert mode via the vim-mode config screens. It's debatable
as to whether something like this belongs in the config gui, but mapping a
sequence like this is such a common thing that it could be justified.
(Assuming, of course, adding this to the config would allow users to skip
the business of adding the custom function to the init script.)

To be perfectly honest I'm not a daily Atom user so can't justify looking
into building this right now. When I do use Atom I'd like the mappings to
work properly, which is what my approach allows.

On Thursday, March 17, 2016, Jesse Leite notifications@github.com wrote:

@kylesezhi https://github.com/kylesezhi and @Yohanna
https://github.com/Yohanna that keymap always worked. The issue is with
the delay when typing anything like "jam" or "jesse". There's a bad delay
after hitting that j key while the keymap listener is waiting for a
possible k to follow.

Other vim emulators do their check when you hit the second k input. When k
is hit, the emulator checks the previous key to see if it was a j, and if
so enters vim mode. This allows the vim emulator to handle the same key
mapping without delay.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#334 (comment)

@kylesezhi
Copy link

Thanks for that explanation, @jesseleite !

I agree - checking after the k in jk would be an improvement on the current way the system works. I'd love to see this in a future build of Atom.

@jesseleite
Copy link

Until then, you can add @rdlugosz's solution above to your init script and keymap :)

@ghost
Copy link

ghost commented May 6, 2016

haha , this works now ! just two line , neat ! thanks @maxbrunsfeld

'atom-text-editor.vim-mode.insert-mode':
  'j k': 'vim-mode:activate-normal-mode'

@denysdovhan
Copy link

Yep, but it still doesn't work well for non-american keyboards.

@Khangeldy
Copy link

After remap to k j . It is hard to import sockjs

@mugukamil
Copy link

@denysdovhan Yes it is... :(

@rdlugosz
Copy link

rdlugosz commented Oct 5, 2016

While that's true, it's also true in Vim proper. Probably why the "official" way to leave insert mode is ESC instead of some combination of letters you may want to type. :)

Simple enough to add one additional check to the code to see if you might be typing something like 'sockjs' (look for a 'c' before the 'k') if this hits you a lot.

I do have a PR open (#946) to try and get some mention of this in the Readme. Anyone interested in reviewing it and merging and/or otherwise getting it documented? AFAIK, this is still the "best" method of remapping ESC in Atom.

@glrodasz
Copy link

@denysdovhan Why it is that? I have an non-american keyboard and works well.

@denysdovhan
Copy link

@garethderioth I have no idea why. Now, I just use vim.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests