all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* 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

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.