* Modal Keyboard Layout for EMACS
@ 2012-11-22 20:04 Junia
2012-11-22 20:52 ` Junia
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Junia @ 2012-11-22 20:04 UTC (permalink / raw)
To: help-gnu-emacs
I would like to write a small VI emulator for Emacs. By small, I mean really small. The source code should not go beyond 100 lines. I also need a better keyboard map than one can find in VIM. The ESC key should be replaced by a key that a typist can easily reach with the right hand.
My first idea was to substitute the [ square bracket for ESC. This substitution is nice since people often uses ^[ to represent ESC. If the typist needs a [ square bracket, she can press the [ square bracket key twice. If she presses the [ key once, Emacs enters the normal command mode, that appears as <N> on the mode-line. The program below works fine with the [ square bracket.
The problem is that Dvořák layout places the [ square bracket at the upper right hand side corner of the keyboard. In fewer words, the position of the [ square bracket in Dvořák layout is not easy to reach. As a matter of fact, it is almost as bad as the Esc position in VIM. Therefore, I decided to use / slash instead of [ square bracket.
However, if I replace / slash for the square bracket, the program below does not work correctly. I mean, it ignores my remap of the / slash key. If I press slash after replacing / slash for the occurrences of [ the program fails to enter normal command mode.
Can anybody tell me why?
;; Variables for possible keyboards
(defvar default-keyboard
(copy-keymap (current-global-map)))
(defvar emap
(copy-keymap (current-global-map)))
(defun tovim() (interactive)
(setq minor-mode-alist
(assq-delete-all 'normal minor-mode-alist))
(add-to-list 'minor-mode-alist '(normal "<N>"))
(force-mode-line-update)
(use-global-map vmap))
(define-key emap "[" 'tovim)
(defvar vmap
(copy-keymap (current-global-map)))
(define-key vmap (kbd "h") 'backward-char)
(define-key vmap (kbd "j") 'next-line)
(define-key vmap (kbd "k") 'previous-line)
(define-key vmap (kbd "l") 'forward-char)
(defun ademacs()
(setq minor-mode-alist
(assq-delete-all 'normal minor-mode-alist))
(add-to-list 'minor-mode-alist '(normal "<I>"))
(force-mode-line-update)
(use-global-map emap) )
(defun toemacs() (interactive)
(ademacs))
(define-key vmap (kbd "i") 'toemacs)
(defun slash()(interactive)
(ademacs) ; type twice for [
(insert "["))
(define-key vmap (kbd "[") 'slash)
(defun puremacs()
(use-global-map default-keyboard))
(define-minor-mode normal
:init-value nil
:lighter " <N> "
:keymap '(emap)
:group 'normal
(if normal (ademacs) (puremacs) ))
(define-globalized-minor-mode gnormal normal
(lambda() (normal t)))
(provide 'normal)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
2012-11-22 20:04 Modal Keyboard Layout for EMACS Junia
@ 2012-11-22 20:52 ` Junia
2012-11-22 23:21 ` Stefan Monnier
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Junia @ 2012-11-22 20:52 UTC (permalink / raw)
To: help-gnu-emacs
There is a bug in the previously posted program. Nevertheless the new version still does not work with the / slash key en lieu de square bracket. Here is correct program.
;; Variables for possible keyboards
(defvar default-keyboard
(copy-keymap (current-global-map)))
(defvar emap
(copy-keymap (current-global-map)))
(defun tovim() (interactive)
(setq minor-mode-alist
(assq-delete-all 'normal minor-mode-alist))
(add-to-list 'minor-mode-alist '(normal "<N>"))
(force-mode-line-update)
(use-global-map vmap))
(define-key emap "[" 'tovim)
(defvar vmap
(copy-keymap (current-global-map)))
(define-key vmap (kbd "h") 'backward-char)
(define-key vmap (kbd "j") 'next-line)
(define-key vmap (kbd "k") 'previous-line)
(define-key vmap (kbd "l") 'forward-char)
(defun ademacs()
(setq minor-mode-alist
(assq-delete-all 'normal minor-mode-alist))
(add-to-list 'minor-mode-alist '(normal "<I>"))
(force-mode-line-update)
(use-global-map emap) )
(defun toemacs() (interactive)
(ademacs))
(define-key vmap (kbd "i") 'toemacs)
(defun slash()(interactive)
(ademacs) ; type twice for [
(insert "["))
(define-key vmap (kbd "[") 'slash)
(defun puremacs()
(use-global-map default-keyboard))
(define-minor-mode normal
nil
:lighter " <N> "
'(emap)
:group 'normal
(if normal (ademacs) (puremacs) ))
(define-globalized-minor-mode gnormal normal
(lambda() (normal t)))
(provide 'normal)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
2012-11-22 20:04 Modal Keyboard Layout for EMACS Junia
2012-11-22 20:52 ` Junia
@ 2012-11-22 23:21 ` Stefan Monnier
[not found] ` <mailman.13585.1353626494.855.help-gnu-emacs@gnu.org>
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Stefan Monnier @ 2012-11-22 23:21 UTC (permalink / raw)
To: help-gnu-emacs
> I would like to write a small VI emulator for Emacs. By small, I mean
> really small. The source code should not go beyond 100 lines. I also
> need a better keyboard map than one can find in VIM. The ESC key
> should be replaced by a key that a typist can easily reach with the
> right hand.
The shortest code (a single line) might look something like:
(viper-mode 1)
But I guess that's not what you mean.
> However, if I replace / slash for the square bracket, the program
> below does not work correctly. I mean, it ignores my remap of the /
> slash key. If I press slash after replacing / slash for the
> occurrences of [ the program fails to enter normal command mode.
I don't see any obvious reason why that would be the case. I suggest
you look at what C-h k / says to help you figure out what's going on.
I also appended my own take on the problem.
Stefan
(defvar mvi-command-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "h" 'backward-char)
(define-key map "j" 'next-line)
(define-key map "k" 'previous-line)
(define-key map "l" 'forward-char)
(define-key map "i" 'mvi-insert-mode)
(define-key map "/" 'mvi-doubled-self-insert-key)
map))
(defun mvi-doubled-self-insert-key ()
(interactive)
(call-interactively 'self-insert-command)
(mvi-insert-mode 1))
(define-minor-mode mvi-command-mode
"Minimalistic VI-like mode."
:lighter " <N>"
:global t
(if mvi-command-mode (mvi-normal-mode -1)))
(defvar mvi-command-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\e" 'mvi-command-mode)
(define-key map "/" 'mvi-command-mode)
map))
(define-minor-mode mvi-insert-mode
"Normal Emacs editing mode with escape to VI mode."
:lighter " <I>"
:global t
(if mvi-insert-mode (mvi-command-mode -1)))
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
[not found] ` <mailman.13585.1353626494.855.help-gnu-emacs@gnu.org>
@ 2012-11-23 12:55 ` sergiusruiz
0 siblings, 0 replies; 9+ messages in thread
From: sergiusruiz @ 2012-11-23 12:55 UTC (permalink / raw)
To: help-gnu-emacs; +Cc: help-gnu-emacs
Em quinta-feira, 22 de novembro de 2012 21h21min35s UTC-2, Stefan Monnier escreveu:
> (defvar mvi-command-mode-map
> (let ((map (make-sparse-keymap)))
> (define-key map "h" 'backward-char)
> (define-key map "j" 'next-line)
> (define-key map "k" 'previous-line)
> (define-key map "l" 'forward-char)
> (define-key map "i" 'mvi-insert-mode)
> (define-key map "/" 'mvi-doubled-self-insert-key)
> map))
>
> (defun mvi-doubled-self-insert-key ()
> (interactive)
> (call-interactively 'self-insert-command)
> (mvi-insert-mode 1))
>
> (define-minor-mode mvi-command-mode
> "Minimalistic VI-like mode."
> :lighter " <N>"
> :global t
> (if mvi-command-mode (mvi-normal-mode -1))
>
> (defvar mvi-command-mode-map
> (let ((map (make-sparse-keymap)))
> (define-key map "\e" 'mvi-command-mode)
> (define-key map "/" 'mvi-command-mode)
> map))
>
> (define-minor-mode mvi-insert-mode
> "Normal Emacs editing mode with escape to VI mode."
> :lighter " <I>"
> :global t
> (if mvi-insert-mode (mvi-command-mode -1)))
That is for Monnier. I became very impressed with your el-script. It is small and elegant. It seems however that you did'nt test it, which makes it even more impressive. However, I want to use it, and I believe that Junnia wants to use it too. By the way, I am not a full-fledged elisp programmer, and have difficulty with modes. Therefore, I am not able to fix the program myself.
For instance, mvi-command-mode calls mvi-normal-mode. I cannot find the definition of mvi-command-mode anywhere in your code. Here:
> (define-minor-mode mvi-command-mode
> "Minimalistic VI-like mode."
> :lighter " <N>"
> :global t
> (if mvi-command-mode (mvi-normal-mode -1))
Besides this, I miss the parameter init-value in all define-minor-mode macro calls.
(define-minor-mode mvi-insert-mode
"Normal Emacs editing mode with escape to VI mode."
nil ;; <<==== Is this line missing?
:lighter " <I>"
:global t
(if mvi-insert-mode (mvi-command-mode -1)))
To make a long story short, I will be pleased in having a working copy of this program.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
2012-11-22 20:04 Modal Keyboard Layout for EMACS Junia
` (2 preceding siblings ...)
[not found] ` <mailman.13585.1353626494.855.help-gnu-emacs@gnu.org>
@ 2012-11-23 16:53 ` sergiusruiz
2012-11-23 18:55 ` Stefan Monnier
[not found] ` <mailman.13650.1353696942.855.help-gnu-emacs@gnu.org>
2012-11-24 1:56 ` rosangelamesil
2012-11-24 3:16 ` rosangelamesil
5 siblings, 2 replies; 9+ messages in thread
From: sergiusruiz @ 2012-11-23 16:53 UTC (permalink / raw)
To: help-gnu-emacs
Hi, Junia.
I think I fixed the bugs in Stefan's version of mvi-command-mode. Now, it is working flawlessly. Since Stefan wants to provide mvi-command-mode only, there is no need to make both commands global. By the way, I guess I know what Stefan wanted with mvi-normal-mode: He wanted the normal emacs mode back, what makes a lot of sense. I wrote a minor mvi-emacs-mode that exit from mvi-insert-mode, mvi-command-mode, and mvi-emacs-mode itself. You should save the file in mvi-command-mode.el and add the following line to your .emacs file:
(require 'mvi-command-mode)
To enter command mode, you should use
M-x mvi-command-mode
from anywhere in emacs (since the command mode is global).
;; Small modifications in a script by Stenfan Monnier
(defvar mvi-command-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "h" 'backward-char)
(define-key map "j" 'next-line)
(define-key map "k" 'previous-line)
(define-key map "l" 'forward-char)
(define-key map "i" 'mvi-insert-mode)
(define-key map "[" 'mvi-doubled-self-insert-key)
map))
(defun mvi-doubled-self-insert-key ()
(interactive)
(call-interactively 'self-insert-command)
(mvi-insert-mode 1))
(defvar mvi-insert-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\e" 'mvi-command-mode)
(define-key map "[" 'mvi-command-mode)
map))
(define-minor-mode mvi-command-mode
"Minimalistic VI-like mode."
:lighter " <N>"
:global t
(if mvi-command-mode (mvi-insert-mode -1)))
(define-minor-mode mvi-insert-mode
"Normal Emacs editing mode with escape to VI mode."
:lighter " <I>"
(if mvi-insert-mode (mvi-command-mode -1)))
(define-minor-mode mvi-emacs-mode
"Normal Emacs editing mode with escape to VI mode."
:lighter ""
:global t
(when mvi-emacs-mode
(mvi-emacs-mode -1)
(mvi-insert-mode -1)
(mvi-command-mode -1)))
(provide 'mvi-command-mode)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
2012-11-23 16:53 ` sergiusruiz
@ 2012-11-23 18:55 ` Stefan Monnier
[not found] ` <mailman.13650.1353696942.855.help-gnu-emacs@gnu.org>
1 sibling, 0 replies; 9+ messages in thread
From: Stefan Monnier @ 2012-11-23 18:55 UTC (permalink / raw)
To: help-gnu-emacs
> Since Stefan wants to provide mvi-command-mode only, there is no need
> to make both commands global.
I think you misunderstand the meaning of global. "Global" here means
"affects all buffers" as opposed to "local to a particular buffer".
I guess they could both be buffer-local or bother be global, but having
one be global and the other buffer local makes no sense.
> By the way, I guess I know what Stefan wanted with mvi-normal-mode
It was a typo for mvi-insert-mode.
> (define-minor-mode mvi-emacs-mode
> "Normal Emacs editing mode with escape to VI mode."
> :lighter ""
> :global t
> (when mvi-emacs-mode
> (mvi-emacs-mode -1)
> (mvi-insert-mode -1)
> (mvi-command-mode -1)))
Better make it into a proper minor mode (rather than a weird beast
which doesn't do anything when you turn it off and turns itself off
when you turn it on).
(define-minor-mode mvi-mode
"Minimalistic VI-like mode."
:global t
(if mvi-mode
(or mvi-insert-mode mvi-command-mode
(mvi-command-mode))
(mvi-command-mode -1)
(mvi-insert-mode -1)))
-- Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
[not found] ` <mailman.13650.1353696942.855.help-gnu-emacs@gnu.org>
@ 2012-11-24 0:00 ` rosangelamesil
0 siblings, 0 replies; 9+ messages in thread
From: rosangelamesil @ 2012-11-24 0:00 UTC (permalink / raw)
To: help-gnu-emacs; +Cc: help-gnu-emacs
Em sexta-feira, 23 de novembro de 2012 16h55min43s UTC-2, Stefan Monnier escreveu:
> > Since Stefan wants to provide mvi-command-mode only, there is no need
> > to make both commands global.
>
> -- Stefan
Hi, Stefan.
I think that your minimalist VI is a good example of clever design. I wonder, did you think about the problem before? Did you code it at the spur of a moment? In any case, I don't believe one needs Sergio's mvi-mode at all. If one calls
M-x mvi-insert-mode
while in insert mode, emacs will leave both mvi-insert-move and mvi-normal-mode. Isn't it true?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
2012-11-22 20:04 Modal Keyboard Layout for EMACS Junia
` (3 preceding siblings ...)
2012-11-23 16:53 ` sergiusruiz
@ 2012-11-24 1:56 ` rosangelamesil
2012-11-24 3:16 ` rosangelamesil
5 siblings, 0 replies; 9+ messages in thread
From: rosangelamesil @ 2012-11-24 1:56 UTC (permalink / raw)
To: help-gnu-emacs
As I told before, I don't think it is necessary to have a separate mode to exit mvi. All one has to do is to run the command mvi-insert-mode, while in insert-mode. Make sure you see <I> in the mode-line and type:
M-x mvi-insert-mode
The above command exits mvi, and goes back to emacs keybinding. That said, below is a keybinding for Stefan's mvi-mode. The whole thing occupies 51 lines.
;; Original design by Stefan Monnier
(defvar mvi-command-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "h" 'backward-char)
(define-key map "j" 'next-line)
(define-key map "k" 'previous-line)
(define-key map "l" 'forward-char)
(define-key map "i" 'mvi-insert-mode)
(define-key map "x" 'delete-char)
(define-key map "z" 'delete-backward-char)
(define-key map "a" 'move-beginning-of-line)
(define-key map "e" 'move-end-of-line)
(define-key map "d" 'kill-whole-line)
(define-key map "p" 'yank)
(define-key map "u" 'undo)
(define-key map "v" 'set-mark-command)
(define-key map "y" 'kill-ring-save)
(define-key map "r" 'kill-region)
(define-key map "0" 'delete-window)
(define-key map "1" 'delete-other-window)
(define-key map "2" 'split-window-below)
(define-key map "o" 'other-window)
(define-key map "s" 'save-buffer)
(define-key map "w" 'write-file)
(define-key map "g" 'beginning-of-buffer)
(define-key map "G" 'end-of-buffer)
(define-key map "n" 'isearch-forward)
(define-key map "N" 'isearch-backward)
(define-key map "[" 'mvi-self-insert-command)
map))
(defun mvi-self-insert-command () (interactive)
(call-interactively 'self-insert-command)
(mvi-insert-mode 1))
(defvar mvi-insert-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "[" 'mvi-command-mode)
map))
(define-minor-mode mvi-command-mode
"Minimalistic VI-like mode."
:lighter " <N>" :global t
(when mvi-command-mode (mvi-insert-mode -1)))
(define-minor-mode mvi-insert-mode
"Emacs with a escape to VI command"
:lighter " <I>" :global t
(when mvi-insert-mode (mvi-command-mode -1)))
(provide 'mvi-command-mode)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Modal Keyboard Layout for EMACS
2012-11-22 20:04 Modal Keyboard Layout for EMACS Junia
` (4 preceding siblings ...)
2012-11-24 1:56 ` rosangelamesil
@ 2012-11-24 3:16 ` rosangelamesil
5 siblings, 0 replies; 9+ messages in thread
From: rosangelamesil @ 2012-11-24 3:16 UTC (permalink / raw)
To: help-gnu-emacs
It turns out that isearch does not interact well with the mvi-command-mode. Therefore, one must remove the corresponding lines from the source code, and continue doing search with C-x C-s in mvi-insert-mode.
(define-key map "n" 'isearch-forward)
(define-key map "N" 'isearch-backward)
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-11-24 3:16 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-22 20:04 Modal Keyboard Layout for EMACS Junia
2012-11-22 20:52 ` Junia
2012-11-22 23:21 ` Stefan Monnier
[not found] ` <mailman.13585.1353626494.855.help-gnu-emacs@gnu.org>
2012-11-23 12:55 ` sergiusruiz
2012-11-23 16:53 ` sergiusruiz
2012-11-23 18:55 ` Stefan Monnier
[not found] ` <mailman.13650.1353696942.855.help-gnu-emacs@gnu.org>
2012-11-24 0:00 ` rosangelamesil
2012-11-24 1:56 ` rosangelamesil
2012-11-24 3:16 ` rosangelamesil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).