6

Question is as stated in the title.

Instead of using various packages for switching windows, it might be simpler to make <C-x><C-o> behave like <C-x><C-+>, such that repeated presses of the o key after the initial <C-x><C-o> will keep switching windows.

Drew
  • 75,699
  • 9
  • 109
  • 225
yongjieyongjie
  • 286
  • 1
  • 5
  • https://github.com/alphapapa/defrepeater.el looks like a general path to realize such requests as yours. When I tried that out it refused to work occasionally. Finally I stopped using it. But I guess it's worth to be rediscovered. – Marco Wahl Aug 18 '19 at 10:01

3 Answers3

4

I use this in several of my libraries. Use it to make pretty much any command repeatable even when it's on a prefix key.

(defun repeat-command (command)
  "Repeat COMMAND."
  (require 'repeat)
  (let ((repeat-previous-repeated-command  command)
        (repeat-message-function           #'ignore)
        (last-repeatable-command           'repeat))
    (repeat nil)))

Then define a repeatable version of an existing command, such as other-window, just by passing that command to repeat-command. For example:

(defun other-window-repeat ()
  "Select another window in cyclic ordering of windows.
This is a repeatable version of `other-window'."
  (interactive)
  (repeat-command 'other-window))

(global-set-key (kbd "C-x 4 o") 'other-window-repeat)
Drew
  • 75,699
  • 9
  • 109
  • 225
3

You could write a function similar to text-scale-adjust. E.g.

(defun mw-other-window-repeat (count &optional all-frames)
  "Wrapper around `other-window' to continue to jump to other with key o."
  (interactive "p")
  (other-window count all-frames)
  (message "Use o to jump to next window.")
  (set-transient-map
   (let ((map (make-sparse-keymap)))
     (define-key map (kbd "o")
       (lambda () (interactive) (mw-other-window-repeat 1)))
     map)))

(global-set-key (kbd "C-x o") #'mw-other-window-repeat)

C-x ooooooo

has the desired effect AFAICS. The repetition is over with another key press than o.

Marco Wahl
  • 2,796
  • 11
  • 13
3

hydra (https://github.com/abo-abo/hydra) are another way to get repeatable commands. This doesn't move the point on the first call, but you can press o as many times as you want to move around.

(defhydra other-window (:color red :body-pre (other-window 1))
  "other window"
  ("o" (other-window 1)))

(global-set-key (kbd "C-x o") #'other-window/body)
John Kitchin
  • 11,555
  • 1
  • 19
  • 41
  • 1
    You can add `:body-pre (other-window 1)` to the hydra arguments to have it move the point on first call. – clemera Aug 18 '19 at 16:20
  • Cool, thanks! I only knew of :pre which runs before every head. I updated this solution with your suggestion! – John Kitchin Aug 18 '19 at 19:02