[implementations-list] Early implementation of new VIM-like mode
Hallo, the recent development of vimpulse encouraged me to think again about a new VIM-mode for Emacs. I'm one of those who think that implementing a new vim-mode from scratch might be easier and more powerful than extending viper. In this post I'd like to present you an early result of my attempts. Currently I call is just 'vim-mode', but that name is not important. The code is very modular (I hope) and built around an own keymap structure. This means vim-mode does not use the default Emacs-keymaps but handles all events within its own data structures. The handling of keymaps is an independent subsystem. Commands and motions can be defined independently and operators (commands with motions, I call them 'complex' commands) can be combined with arbitrary motions. In fact, a motion is just a function returning one or two positions in the buffer. Furthermore, vim-mode supports mapping of commands. This is a quiet powerful feature: many more complicated commands can be defined by simple mappings without the need of an own implementation. For example the command "x" is defined (vim:def-map "x" "dl") and "O" is defined (vim:def-map "O" (kbd "0 i RET <up> TAB")) look at the file 'vim-maps.el' for more examples. (OK, I'm not sure if those definitions are correct in all cases, but they seem to work OK for me). You can find the code at http://www.tu-chemnitz.de/~fifr/downloads/vim-mode.tgz and a mercurial repository at http://www.tu-chemnitz.de/~fifr/repos/vim-mode Just open the file 'vim.el' and evaluate it. Don't forget to read the comments in 'vim.el' I hope that this code can convince some of you of this approach in favor for extending viper (although vimpulse is really great - I use it every day, especially when developing vim-mode ;) - I think vim-mode is worth further development and as the potential to be even better than viper + vimpulse). Any comments, suggestions or patches are very welcome. Greetings, Frank
Hello Frank, and thanks for the nice comments. I'm going to take a look at your code really soon, and, to tell the whole truth, out of frustration from navigating in kludge-world, I opened a file today, yavimc.el, that stands for yet another vim clone. I wasn't still sure I wanted to yell it to the world, but yeah, I think writing something from scratch is maybe the right solution. I don't know if it's the "productive" solution. Maybe it isn't. But still I don't like kludge world, and I'm not earning money from this, so personal interest and enjoyment comes first. This said, can I join? XD I was trying vim-mode just now, and I must say it's very responsive, and handles the basic things nicely :) I'll take a look at the code now! Cheers, Alessandro 2009/7/1 Frank Fischer <[email protected]>
Hallo,
the recent development of vimpulse encouraged me to think again about a new VIM-mode for Emacs. I'm one of those who think that implementing a new vim-mode from scratch might be easier and more powerful than extending viper.
In this post I'd like to present you an early result of my attempts. Currently I call is just 'vim-mode', but that name is not important. The code is very modular (I hope) and built around an own keymap structure. This means vim-mode does not use the default Emacs-keymaps but handles all events within its own data structures.
The handling of keymaps is an independent subsystem. Commands and motions can be defined independently and operators (commands with motions, I call them 'complex' commands) can be combined with arbitrary motions. In fact, a motion is just a function returning one or two positions in the buffer.
Furthermore, vim-mode supports mapping of commands. This is a quiet powerful feature: many more complicated commands can be defined by simple mappings without the need of an own implementation. For example the command "x" is defined
(vim:def-map "x" "dl")
and "O" is defined
(vim:def-map "O" (kbd "0 i RET <up> TAB"))
look at the file 'vim-maps.el' for more examples. (OK, I'm not sure if those definitions are correct in all cases, but they seem to work OK for me).
You can find the code at
and a mercurial repository at
http://www.tu-chemnitz.de/~fifr/repos/vim-mode<http://www.tu-chemnitz.de/%7Efifr/repos/vim-mode>
Just open the file 'vim.el' and evaluate it. Don't forget to read the comments in 'vim.el'
I hope that this code can convince some of you of this approach in favor for extending viper (although vimpulse is really great - I use it every day, especially when developing vim-mode ;) - I think vim-mode is worth further development and as the potential to be even better than viper + vimpulse).
Any comments, suggestions or patches are very welcome.
Greetings, Frank
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
Follow up: the most interesting thing about your approach is that you don't use emacs keymaps. Could you explain me how it works (a short summary is ok) ? 2009/7/1 Alessandro Piras <[email protected]>
Hello Frank, and thanks for the nice comments. I'm going to take a look at your code really soon, and, to tell the whole truth, out of frustration from navigating in kludge-world, I opened a file today, yavimc.el, that stands for yet another vim clone. I wasn't still sure I wanted to yell it to the world, but yeah, I think writing something from scratch is maybe the right solution. I don't know if it's the "productive" solution. Maybe it isn't. But still I don't like kludge world, and I'm not earning money from this, so personal interest and enjoyment comes first. This said, can I join? XD I was trying vim-mode just now, and I must say it's very responsive, and handles the basic things nicely :) I'll take a look at the code now! Cheers, Alessandro
2009/7/1 Frank Fischer <[email protected]>
Hallo,
the recent development of vimpulse encouraged me to think again about a new VIM-mode for Emacs. I'm one of those who think that implementing a new vim-mode from scratch might be easier and more powerful than extending viper.
In this post I'd like to present you an early result of my attempts. Currently I call is just 'vim-mode', but that name is not important. The code is very modular (I hope) and built around an own keymap structure. This means vim-mode does not use the default Emacs-keymaps but handles all events within its own data structures.
The handling of keymaps is an independent subsystem. Commands and motions can be defined independently and operators (commands with motions, I call them 'complex' commands) can be combined with arbitrary motions. In fact, a motion is just a function returning one or two positions in the buffer.
Furthermore, vim-mode supports mapping of commands. This is a quiet powerful feature: many more complicated commands can be defined by simple mappings without the need of an own implementation. For example the command "x" is defined
(vim:def-map "x" "dl")
and "O" is defined
(vim:def-map "O" (kbd "0 i RET <up> TAB"))
look at the file 'vim-maps.el' for more examples. (OK, I'm not sure if those definitions are correct in all cases, but they seem to work OK for me).
You can find the code at
and a mercurial repository at
http://www.tu-chemnitz.de/~fifr/repos/vim-mode<http://www.tu-chemnitz.de/%7Efifr/repos/vim-mode>
Just open the file 'vim.el' and evaluate it. Don't forget to read the comments in 'vim.el'
I hope that this code can convince some of you of this approach in favor for extending viper (although vimpulse is really great - I use it every day, especially when developing vim-mode ;) - I think vim-mode is worth further development and as the potential to be even better than viper + vimpulse).
Any comments, suggestions or patches are very welcome.
Greetings, Frank
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
On Wed, Jul 01, 2009 at 08:15:21PM +0200, Alessandro Piras wrote:
Follow up: the most interesting thing about your approach is that you don't use emacs keymaps. Could you explain me how it works (a short summary is ok) ?
A simple keymap catching all events is installed (the keymap of the minor mode 'vim-key-mode'). When an event comes in the function vim:handle-key is called. This function does some housekeeping and calls the function vim:input-key which is the entry point for vim-mode's own keymap. If the event can't be handled by vim:input-key, it's pushed back to unread-command-events, the keymap of vim-key-mode is disabled and the event can be processed by Emacs as usual. Btw, keymaps of vim-mode are very similar to emacs-keymaps but contain more meta-information. But the general structure is the same. Therefore, in theory all emacs-events could be handled by vim-mode-keymaps, not only keyboard-events. I know, the documentation is poor at this time, I'll try to improve it soon :) Bye, Frank
On Wed, Jul 01, 2009 at 08:15:21PM +0200, Alessandro Piras wrote:
Follow up: the most interesting thing about your approach is that you don't use emacs keymaps. Could you explain me how it works (a short summary is ok) ?
A simple keymap catching all events is installed (the keymap of the minor mode 'vim-key-mode'). When an event comes in the function vim:handle-key is called. This function does some housekeeping and calls the function vim:input-key which is the entry point for vim-mode's own keymap. If the event can't be handled by vim:input-key, it's pushed back to unread-command-events, the keymap of vim-key-mode is disabled and the event can be processed by Emacs as usual. Btw, keymaps of vim-mode are very similar to emacs-keymaps but contain more meta-information. But the general structure is the same. Therefore, in theory all emacs-events could be handled by vim-mode-keymaps, not only keyboard-events. I know, the documentation is poor at this time, I'll try to improve it soon :) Bye, Frank
I see, so you basically have your own event loop :) That's exactly the kind of solution I was thinking about when starting to think about coding a vim clone from scratch. So I'll start with the first suggestion :) I think in normal mode you should redirect all unhandled keys to a null function. This prevents inserting unhandled printable characters in normal mode. Even better, redirecting all printable keys to a null function and pushing back the unhandled keys to unread-command-events, so that it's possible to leave some emacs-binding even in normal mode. what do you think? Alessandro 2009/7/1 Frank Fischer <[email protected]>
On Wed, Jul 01, 2009 at 08:15:21PM +0200, Alessandro Piras wrote:
Follow up: the most interesting thing about your approach is that you don't use emacs keymaps. Could you explain me how it works (a short summary is ok) ?
A simple keymap catching all events is installed (the keymap of the minor mode 'vim-key-mode'). When an event comes in the function vim:handle-key is called. This function does some housekeeping and calls the function vim:input-key which is the entry point for vim-mode's own keymap. If the event can't be handled by vim:input-key, it's pushed back to unread-command-events, the keymap of vim-key-mode is disabled and the event can be processed by Emacs as usual.
Btw, keymaps of vim-mode are very similar to emacs-keymaps but contain more meta-information. But the general structure is the same. Therefore, in theory all emacs-events could be handled by vim-mode-keymaps, not only keyboard-events.
I know, the documentation is poor at this time, I'll try to improve it soon :)
Bye, Frank
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
On Wed, Jul 01, 2009 at 09:42:34PM +0200, Alessandro Piras wrote:
I think in normal mode you should redirect all unhandled keys to a null function. This prevents inserting unhandled printable characters in normal mode. Even better, redirecting all printable keys to a null function and pushing back the unhandled keys to unread-command-events, so that it's possible to leave some emacs-binding even in normal mode. what do you think?
That's already possible: each mode can have a default-handler. This function is called in the case of an unhandled event. If this function returns nil the event will be forwarded to emacs. Currently, there's no such function for normal mode, but this should require only a few lines. (btw, other modes like visual-mode could behave similarily by just providing an appropriate default-handler) Frank
Hi Frank, yes, I've seen the default handler stuff (I mean, I've read the comments XD), I was just suggesting a better default handler for modes other than different and replace :) I like your solution so far, I'll try to work a little on it :) Alessandro 2009/7/1 Frank Fischer <[email protected]>
On Wed, Jul 01, 2009 at 09:42:34PM +0200, Alessandro Piras wrote:
I think in normal mode you should redirect all unhandled keys to a null function. This prevents inserting unhandled printable characters in normal mode. Even better, redirecting all printable keys to a null function and pushing back the unhandled keys to unread-command-events, so that it's possible to leave some emacs-binding even in normal mode. what do you think?
That's already possible: each mode can have a default-handler. This function is called in the case of an unhandled event. If this function returns nil the event will be forwarded to emacs. Currently, there's no such function for normal mode, but this should require only a few lines. (btw, other modes like visual-mode could behave similarily by just providing an appropriate default-handler)
Frank
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
participants (3)
-
Alessandro Piras -
Frank Fischer -
Frank Fischer