{"action":"created","issue":{"url":"https://api.github.com/repos/magit/magit/issues/1968","labels_url":"https://api.github.com/repos/magit/magit/issues/1968/labels{/name}","comments_url":"https://api.github.com/repos/magit/magit/issues/1968/comments","events_url":"https://api.github.com/repos/magit/magit/issues/1968/events","html_url":"https://github.com/magit/magit/issues/1968","id":92932266,"number":1968,"title":"Come up with Evil/Vim bindings for Magit","user":{"login":"tarsius","id":25046,"avatar_url":"https://avatars.githubusercontent.com/u/25046?v=3","gravatar_id":"","url":"https://api.github.com/users/tarsius","html_url":"https://github.com/tarsius","followers_url":"https://api.github.com/users/tarsius/followers","following_url":"https://api.github.com/users/tarsius/following{/other_user}","gists_url":"https://api.github.com/users/tarsius/gists{/gist_id}","starred_url":"https://api.github.com/users/tarsius/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tarsius/subscriptions","organizations_url":"https://api.github.com/users/tarsius/orgs","repos_url":"https://api.github.com/users/tarsius/repos","events_url":"https://api.github.com/users/tarsius/events{/privacy}","received_events_url":"https://api.github.com/users/tarsius/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/magit/magit/labels/discussion","name":"discussion","color":"207de5"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/magit/magit/milestones/16","html_url":"https://github.com/magit/magit/milestones/support/needinfo/...","labels_url":"https://api.github.com/repos/magit/magit/milestones/16/labels","id":465617,"number":16,"title":"support/needinfo/...","description":"","creator":{"login":"tarsius","id":25046,"avatar_url":"https://avatars.githubusercontent.com/u/25046?v=3","gravatar_id":"","url":"https://api.github.com/users/tarsius","html_url":"https://github.com/tarsius","followers_url":"https://api.github.com/users/tarsius/followers","following_url":"https://api.github.com/users/tarsius/following{/other_user}","gists_url":"https://api.github.com/users/tarsius/gists{/gist_id}","starred_url":"https://api.github.com/users/tarsius/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tarsius/subscriptions","organizations_url":"https://api.github.com/users/tarsius/orgs","repos_url":"https://api.github.com/users/tarsius/repos","events_url":"https://api.github.com/users/tarsius/events{/privacy}","received_events_url":"https://api.github.com/users/tarsius/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":2,"state":"open","created_at":"2013-10-26T22:12:06Z","updated_at":"2015-07-16T12:56:09Z","due_on":null,"closed_at":null},"comments":17,"created_at":"2015-07-03T20:28:07Z","updated_at":"2015-07-22T05:30:46Z","closed_at":null,"body":"Since more and more Emacs users are turning to the dark side, we should come up with Magit key bindings that work well with Evil.\r\n\r\nWe should create a function `magit-setup-evil-bindings` which makes all the necessary changes to Magit keymaps, and, if necessary, sets some Evil variables. Users could then just call that function in their init file:\r\n\r\n```elisp\r\n(with-eval-after-load 'magit (magit-setup-evil-bindings))\r\n```\r\n\r\nSo far, so good. The question remains: what belongs in that function?\r\n\r\n----\r\n\r\nI don't use Evil, and all I know about Vi is that there is an insert and a command mode, and that hjkl is used for navigation. Likewise the Evil maintainer doesn't use Magit (or so I assume because the Evil repository uses Mercurial).\r\n\r\nStill several users have said things like \"[since v2.1.0,] Magit bindings take over Evil's ones\". That's not correct: on the contrary it is Evil that fails to override Magit (new) bindings (in new keymaps). Magit only has to make sure it doesn't stump on *Emacs* bindings, and the responsibility for making sure Evil and Magit work together, lies with those using black magic.\r\n\r\n**All users of both Evil and Magit are invited to discuss what vilified Magit key bindings should look like. Once you have reached a consensus,  we can add a function which establish such bindings to Magit.**\r\n\r\nBut it is your job, as users of Evil as well as Magit, to figure out what does bindings are. You cannot expect a Mercurial user to learn enough about Magit to be able to do the work for you, and you cannot expect me to learn Vim bindings so that I could do the work for you.\r\n\r\nAll I can do at this point, is to invite you to this discussion and ...\r\n\r\n---\r\n\r\n... provide some speculation on what *might* work.\r\n\r\nMagit buffers are read-only buffers. So insert mode is useless. Command mode is more suitable but I believe that emacs mode is even more suitable. `evil-emacs-state-modes`s default value seems to indicate I am at least not completely off about this. But Magit `v2.1.0` gained some new modes and so that variable has to be adjusted, which I did: https://bitbucket.org/lyro/evil/pull-request/16/adapt-for-magit-v210/diff.\r\n\r\nThe next question is: do Evil users prefer constantly switching between vim-command mode and magit-emacs mode, or would you rather make some compromises?\r\n\r\nAs far as I know the main conflicts are `hjkl`. So what about (over-simplification):\r\n\r\n```elisp\r\n(dolist (map magit-maps-that-bind-these-keys)\r\n  (define-key map \"h\" 'backward-char)\r\n  (define-key map \"j\" 'evil-next-line)\r\n  (define-key map \"k\" 'evil-previous-line)\r\n  (define-key map \"l\" 'forward-char)\r\n  (define-key map move lost bindings elsewhere))\r\n\r\n(define-key magit-mode-map \"\\C-j\" 'magit-section-forward)\r\n(define-key magit-mode-map \"\\C-k\" 'magit-section-backward\r\n(define-key magit-mode-map \"\\M-j\" 'magit-section-forward-sibling)\r\n(define-key magit-mode-map \"\\M-k\" 'magit-section-backward-sibling)\r\n```\r\n\r\nThen\r\n* Move `h`/`magit-dispatch-popup` to what ever the vim help prefix is.\r\n* Move `j`/\"various jump commands\" to what ever the vim uses for jumping. Or just sacrifice this.\r\n* Move `k`/`magit-discard`+other commands that \"delete\" to where? In my opinion it should be a very simple binding.\r\n* Move `l`/`magit-log-popup` to where? In my opinion it has to be a very simple binding.\r\n\r\n----\r\n\r\nI am aware that Spacemacs does it differently. It has some general rules how conflicts in certain key bindings are resolved. These rules are applied across Emacs. Which makes sense - the remappings are consistent across all of Spacemacs. But Spacemacs is not Evil, and I think it makes just as much sense to find the best possible solution for each and every mode/keymap in which a conflict arises. That second approach has at least two drawbacks: (1) it's more work, and (2) for each mode/keymap Evil users have to learn what was done to resolve the conflict. Still, I prefer that approach.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/magit/magit/issues/comments/123568665","html_url":"https://github.com/magit/magit/issues/1968#issuecomment-123568665","issue_url":"https://api.github.com/repos/magit/magit/issues/1968","id":123568665,"user":{"login":"vyp","id":3889405,"avatar_url":"https://avatars.githubusercontent.com/u/3889405?v=3","gravatar_id":"","url":"https://api.github.com/users/vyp","html_url":"https://github.com/vyp","followers_url":"https://api.github.com/users/vyp/followers","following_url":"https://api.github.com/users/vyp/following{/other_user}","gists_url":"https://api.github.com/users/vyp/gists{/gist_id}","starred_url":"https://api.github.com/users/vyp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vyp/subscriptions","organizations_url":"https://api.github.com/users/vyp/orgs","repos_url":"https://api.github.com/users/vyp/repos","events_url":"https://api.github.com/users/vyp/events{/privacy}","received_events_url":"https://api.github.com/users/vyp/received_events","type":"User","site_admin":false},"created_at":"2015-07-22T05:30:45Z","updated_at":"2015-07-22T05:30:45Z","body":"@tarsius Sorry, I just to want to answer some of your questions and give my\r\nopinions here.\r\n\r\n> Likewise the Evil maintainer doesn't use Magit (or so I assume because the\r\n> Evil repository uses Mercurial).\r\n\r\nIt might worth to note that evil was previously hosted on gitorious.org iirc,\r\nwhich might mean the evil maintainer(s) may have git knowledge (unless gitorious\r\nalso provided hg support and they used that).\r\n\r\n> But it is your job, as users of Evil as well as Magit, to figure out what\r\n> does[sic] bindings are.\r\n\r\nI think it would be impossible for everyone to decide on one set of\r\nkeybindings. Sure, the basic things should not be hard to come to an agreement\r\nto, but I don't think that would be the case for *all* of magit's functionality.\r\n\r\nI think what's more important is to allow remapping of everything, meaning\r\neveryone can be happy, but I guess that may have been your point, just\r\nclarifying.\r\n\r\n> Magit buffers are read-only buffers. So insert mode is useless. Command mode\r\n> is more suitable but I believe that emacs mode is even more suitable.\r\n\r\nSo yes because magit buffers are read-only, it means there is no place for\r\ninsert-state, but also all the commands in normal-state that do actions on text\r\n(i.e. not navigation, mainly). Namely `r, u, i, o, p, a, s, d, x, c`. (I think\r\n`z` may also be available, and maybe others?)\r\n\r\nBut emacs-state should never be the solution for evil users I feel. The *goal*\r\nfor special mode buffers (for evil users) should be integrating with the\r\nmotion/navigation commands from normal-state.\r\n\r\n> The next question is: do Evil users prefer constantly switching between\r\n> vim-command mode and magit-emacs mode, or would you rather make some\r\n> compromises?\r\n\r\nSo definitely rather make compromises based on what I just said. Because we can\r\nalways remap anything we lose, or even switch to the emacs-state if we want (or\r\njust use `M-x`). Remember we have an entire leader layer to remap things to,\r\nwhich can also have special-mode-specific bindings. (But note that nothing\r\nshould ever map anything to the leader layer by default, not even sure that's\r\npossible with evil mode.)\r\n\r\nBasically the second option that @syl20bnr proposes [here][1].\r\n\r\n>     (dolist (map magit-maps-that-bind-these-keys)\r\n>       (define-key map \"h\" 'backward-char)\r\n>       (define-key map \"j\" 'evil-next-line)\r\n>       (define-key map \"k\" 'evil-previous-line)\r\n>       (define-key map \"l\" 'forward-char)\r\n>       (define-key map move lost bindings elsewhere))\r\n\r\nJust a nitpick, but `'backward-char` and `'forward-char` here should probably be\r\n`'evil-backward-char` and `'evil-forward-char` here. (Just for consistency, for\r\nexample to respect users `evil-cross-lines` setting.)\r\n\r\n> - Move h/magit-dispatch-popup to what ever the vim help prefix is.\r\n>\r\n> - Move j/\"various jump commands\" to what ever the vim uses for jumping. Or\r\n>   just sacrifice this.\r\n>\r\n> - Move k/magit-discard+other commands that \"delete\" to where? In my opinion it\r\n>   should be a very simple binding.\r\n>\r\n> - Move l/magit-log-popup to where? In my opinion it has to be a very simple\r\n>   binding.\r\n\r\n- Afaik vim has no help prefix (uses `:help` instead) so this may have to be\r\n  discarded.\r\n\r\n- Again, not sure if vim has anything for \"jumping\" specifically. It's great for\r\n  navigation and jumping everywhere, but I do not know of a command that does\r\n  \"jumping\" whatever that may mean.\r\n\r\n  There's `fFtT`, but that's for navigating to a *character*, which evil users\r\n  definitely wouldn't want to be remapped. However, I think `J` is a good\r\n  candidate here. Normally in normal-state it means to \"join lines\", but there's\r\n  no need for that because magit buffers are read-only.\r\n\r\n- I think remapping `k`/`magit-discard` to `x` may be a good option? (And\r\n  just dropping `magit-reset`? Because `magit-discard` I think is much more\r\n  important than `magit-reset`, plus remember we have a leader layer to put that\r\n  into.)\r\n\r\n  I'm also good with `K` too though.\r\n\r\n- `l`/`magit-log-popup` is harder, but perhaps `o`? (And again dropping\r\n  `magit-submodule-popup` for the same reason as in the previous bullet point.)\r\n  Admittedly, that's not the best suggestion, but `o` is just above `l` (on\r\n  qwerty).\r\n\r\nThanks for making this issue, as it stands, not being able to remap magit\r\nbindings in evil-normal-state (whether that be the fault of magit or evil) is a\r\ndealbreaker to not use magit at all for me.\r\n\r\n---\r\n\r\n> I'm interested to hear how other people use Evil with Magit, though.\r\n\r\n@CodyReichert What you do is basically what I do too (except I use\r\n`evil-previous/next-line` instead), but it doesn't work anymore.\r\n\r\n[1]: https://github.com/magit/magit/issues/1968#issuecomment-119001679"}}