win-switch

Homepage: http://www.stat.cmu.edu/~genovese/emacs/win-switch

Author: Christopher Genovese

Updated:

Summary

Fast, dynamic bindings for window-switching/resizing

Commentary

If you use multiple windows in an Emacs frame, you may find yourself
 moving through the window configuration using `other-window' (C-x o)
 again and again. Because the order of windows in the window list
 need not relate intuitively to windows' positions, moving
 efficiently can require context-specific prefix arguments along the
 way. The tiring outcome is that navigation through a complex window
 configuration demands many keystrokes and nontrivial attention.
 This package is designed to solve that problem.

 While the `windmove' package provides functions for moving
 intuitively among windows, the natural key bindings for these
 functions (e.g., the arrow keys with some modifier) require a
 distant and thus inefficient hand movement. Moreover, one often
 wants to mix a variety of window-based operations (other-window,
 previous-window, directional movement, resizing) in rapid
 succession.

 This package builds on the windmove functionality by defining a
 command `win-switch-dispatch' that engages a dynamic, transient
 keyboard override, allowing one to efficiently move among defined
 windows (and frames) -- and even resize, split, delete them -- with
 minimal fuss and effort. When the override is engaged, the movement
 and resizing commands are bound to simple keys that can be pressed
 quickly with one hand. The override ends either when the user exits
 explicitly or after a configurable idle time threshold. The happy
 outcome is fast and seamless navigation.

 To use the package, execute the following code either directly
 or in your .emacs file:

     (require 'win-switch)
     (global-set-key "\C-xo" 'win-switch-dispatch)

 or use whatever keybinding you ordinarily have set to `other-window'.
 Alternatively, you can use one of a variety of predefined configuration
 commands, as in

     (require 'win-switch)
     (win-switch-setup-keys-ijkl "\C-xo")

 which has the same effect as the above.

 Now, when executing a window switch (i.e., hitting C-xo), Emacs enters
 window switching mode, which lasts until either the user exits the
 mode or the idle time exceeds the threshold `win-switch-idle-time'.
 During this override, selected keys move among windows (or frames)
 or resize the windows. The following keys are bound by default:

   + i select the window above the current window.
   + k select the window below the current window.
   + j select the window left of the current window.
   + l select the window right of the current window.
   + o cycle forward through the window list in the current frame.
   + p cycle backward through the window list in the current frame.
   + SPACE cycles among existing frames.
   + u (and RETURN) exit window switching mode.
   + I and K vertically enlarge and shrink the current window, respectively.
   + L and J horizontally enlarge and shrink the current window, respectively.
   + h and ; split the current window, horizontally and vertically, respectively.
   + ESCAPE acts as an "emergency" exit

 All other keys exit window switching mode and execute their original function.

 By default, window selection wraps around when moving across a frame
 edge and window switching mode is forgone when there are only two
 windows. But these features, the key bindings, and other parameters
 can all be customized, either with the customization facility or
 with defvar and setter functions.

 The default keybindings are designed for fast and intuitve,
 one-handed operation, but if desired the key bindings can be easily
 adjusted or reset. Several alternative key configurations are pre-defined
 (see `win-switch-setup-keys-ijkl', `win-switch-setup-keys-arrow-ctrl',
 `win-switch-setup-keys-arrow-meta', and `win-switch-setup-keys-esdf'
 below). The keys also can be rebound in groups via the variables
 `win-switch--keys' where  can be one of up, down, left,
 right, next-window, previous-window, enlarge-vertically,
 shrink-vertically, enlarge-horizontally, shrink-horizontally,
 other-frame, exit, split-vertically, split-horizontally, delete-window,
 or emergency-exit. These variables should not be set directly,
 but rather should be set either by customize or by
 using the functions `win-switch-add-key', `win-switch-delete-key',
 and `win-switch-set-keys'. For example:

   (win-switch-add-key    "O" 'previous-window)
   (win-switch-delete-key "p" 'previous-window)
   (win-switch-set-keys   '(" " "," "m") 'other-frame)

 Note that the last arguments here are win-switch commands not elisp
 functions. (Note also that the emergency-exit keys do a hard exit in
 case of an unexpected error in user-defined code such as in
 customized feedback functions. This command may be removed in future
 versions.) At least one exit key must always be defined. Revised
 bindings can be set in in the hook `win-switch-load-hook' before
 loading the package. (Also see `win-switch-define-key' for setting
 general commands in the win-switch keymap, and
 `win-switch-set-once-key' for setting commands in the once only
 keymap used by `win-switch-dispatch-once'.)

 Besides key bindings, the most important customization options are
 the following:

   + `win-switch-idle-time'
   + `win-switch-window-threshold'
   + `win-switch-other-window-first'
   + `win-switch-wrap-around'  (set via `win-switch-set-wrap-around')

 The idle time should be set so that one does not have to either rush
 or wait. (While explicit exit always works, it is nice to have
 window-switching mode end on its own at just the right time.) This
 may require some personalized fiddling to find a comfortable value,
 though the default should be pretty good. The window-threshold and
 other-window-first control when and if window switching mode is
 entered. And wrap-around determines if moving across the edge of the
 frame wraps around to the window on the other side.

 The other customizable parameters are as follows:

   + `win-switch-provide-visual-feedback'
   + `win-switch-feedback-background-color'
   + `win-switch-feedback-foreground-color'
   + `win-switch-on-feedback-function'
   + `win-switch-off-feedback-function'
   + `win-switch-other-window-function'

 The feedback mechanisms are intended to make it salient when
 window switching mode is on or off and can be customized at
 several scales. The other-window-function replaces `other-window'
 for moving between window; the primary motivation is to allow
 `icicle-other-window-or-frame' under icicles.

 And four hooks can be set as well:

   + `win-switch-load-hook'
   + `win-switch-on-hook'
   + `win-switch-off-hook'
   + `win-switch-abort-hook'

 The following functions are used to set options:

   + `win-switch-set-wrap-around'
   + `win-switch-add-key'
   + `win-switch-delete-key'
   + `win-switch-set-keys'

 There are three main entry points for using this functionality

   + `win-switch-dispatch' (alias `win-switch-mode')
   + `win-switch-dispatch-once'
   + `win-switch-dispatch-with'

 The first is the main function, the second is a prefix command that
 gives one switch only but allows easy maneuvering in up to five
 windows with a single keystroke. (The `once' keys can be set using
 the `win-switch-set-once-keys' command.) The last constructs
 commands for keybindings that dispatch after some other command.
 (See `win-switch-setup-keys-arrow' for a nice example of its use.)

 NOTE: win-switch is not a formal major or minor mode, more of an
       overriding mode. This started as a way to explore dynamic
       keybindings, an idea that is generalized considerably in
       my packages `quick-nav' and `power-keys'. The latter
       introduces some programming abstractions that can be used
       to easily install dynamic keymaps of several flavors.
       I plan to use the `power-keys' mechanisms for this package
       in a later version.

Code Contents
  1. (@> "User-Configurable Parameters")
  2. (@> "User-Configurable Key Bindings")
  3. (@> "Preventing Default Shadowing")
  4. (@> "Internal Configuration Data")
  5. (@> "Internal Functions and Macros")
  6. (@> "Actions and Key Commands")
  7. (@> "Customization Initializers and Option Setters")
  8. (@> "User Entry Points")
  9. (@> "Pre-defined Configurations")

Dependencies