\input texinfo
@setfilename window-commander.info
@settitle Window Commander User Manual
@documentencoding UTF-8
@documentlanguage en

@copying
@quotation
Copyright @copyright{} 2023-2024 Free Software Foundation, Inc.

You can redistribute this document and/or modify it under the terms
of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version.

This document is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

@end quotation
@end copying

@dircategory Emacs
@direntry
* Window Commander: (window-commander). Simply execute commands on windows.
@end direntry

@titlepage
@title Window Commander User Manual
@subtitle for version 3.0.2.
@author Daniel Semyonov
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@contents

@ifnottex
@node Top
@top Window Commander User Manual

Window Commander provides a minor mode for switching to windows or performing
actions on them using IDs assigned to them automatically.

@noindent
This manual is for Window Commander version 3.0.2.

@insertcopying
@end ifnottex

@menu
* Introduction::
* Installation::
* Usage::
* Customization::
* Keystroke Index::
* Command Index::
* Function Index::
* Variable Index::

@detailmenu
--- The Detailed Node Listing ---

Customization

* ID display::
* Window commands::

@end detailmenu
@end menu

@node Introduction
@chapter Introduction

Window Commander provides a minor mode for switching to windows or performing
actions on them using IDs assigned to them automatically. The
implementation is simple and extensible, providing various advanced
customization features for users, while keeping the code base small
and easy to hack on.

@node Installation
@chapter Installation

Window Commander can be installed from GNU ELPA:

@table @asis
@item @kbd{M-x package-install RET window-commander RET}
@end table

@node Usage
@chapter Usage

In order to use any feature of the package, @code{wincom-mode} must be enabled:

@table @asis
@cindex wincom-mode
@item @kbd{M-x wincom-mode RET}
You can also add @code{(wincom-mode)} to your initialization file, or
enable it through the customize interface.
@end table

When @code{wincom-mode} is enabled, window IDs are shown as mode line
lighters of the form @code{<ID>} (by default, @xref{ID display}), and
@code{other-window} (@kbd{C-x o}) is remapped to @code{wincom-select}
(it is also available, alongside all other window commands, through
the ``Windows'' menu added by the minor mode).

@code{wincom-select}, and any other window command, starts window
selection.  When there are less than @code{wincom-minimum} (3 by
default) tracked windows in the current @code{wincom-scope} (all
frames by default), the ``next'' window is selected.  Otherwise, any
window in scope can be selected by pressing the sequence of keys
corresponding to its displayed ID.  Alternatively, any binding in
@code{wincom-command-map} can be used (unless it is overwritten by a
window ID).

The following window commands are available in
@code{wincom-command-map} by default:

@table @asis
@kindex C-x o
@kindex C-x o o
@cindex wincom-select
@item @kbd{C-x o ID}, @kbd{C-x o o ID}
Select the window corresponding to ID in the current scope
(@code{wincom-select}).

@kindex C-x o 0
@cindex wincom-delete
@item @kbd{C-x o 0 ID}
Delete the window corresponding to ID in the current scope
(@code{wincom-delete}).

@kindex C-x o 1
@cindex wincom-delete-other
@item @kbd{C-x o 1 ID}
Make the window corresponding to ID in the current scope the sole
window of its frame (@code{wincom-delete-other}).

@kindex C-x o 2
@cindex wincom-split-window-below
@item @kbd{C-x o 2 ID}
Split the window corresponding to ID in the current scope from below
(@code{wincom-split-window-below}).  This window command accepts a
prefix argument (with the same semantics as @code{split-window-below}).

@kindex C-x o 3
@cindex wincom-split-window-right
@item @kbd{C-x o 3 ID}
Split the window corresponding to ID in the current scope from the right
(@code{wincom-split-window-right}).  This window command accepts a
prefix argument (with the same semantics as @code{split-window-right}).

@kindex C-x o 4
@cindex wincom-selected-window-prefix
@item @kbd{C-x o 4 ID}
Display the buffer of the next command in the window corresponding to
ID in the current scope (@code{wincom-selected-window-prefix}).  This
window command is only available when
@code{display-buffer-override-next-command} is available (Emacs 28+).

@kindex C-x o t
@cindex wincom-swap
@item @kbd{C-x o t ID}
Swap the states of the current window and the window corresponding to
ID in the current scope (@code{wincom-swap}).

@xref{Window commands} for information regarding defining new commands.

The following commands are available in @code{wincom-command-map} by
default, but are not window commands:

@kindex C-x o m
@cindex wincom-select-minibuffer
@item @kbd{C-x o m}
Switch to the minibuffer if it's active (@code{wincom-select-minibuffer}).

@kindex C-x o r
@cindex wincom-select-most-recently-used
@item @kbd{C-x o r}
Select the most recently used window. (@code{wincom-select-most-recently-used}).
@end table

@node Customization
@chapter Customization

All customization, except for defining custom display functions and
custom window commands, can be done through the customize interface:

@table @asis
@item @kbd{M-x customize-group RET window-commander RET}
@end table

@defopt wincom-id-chars
Base set of character from which window IDs are constructed. This should be a
list of characters. By default, the home row (@code{a s d f g h j k l}) is
used.
@end defopt

@defopt wincom-scope
Scope of all window operations. Used to determine on which frames to track
windows. A value of @code{t} means consider all windows on all frames, @code{0}
(the number zero) means consider all windows on all visible and iconified
frames, @code{visible} means consider all windows on all visible frames and
@code{current} means consider only the currently selected frame. By default,
@code{t} is used.
@end defopt

@menu
* ID display::
* Window commands::
@end menu

@node ID display
@section ID display

By default, the ID of each tracked window is displayed as a mode line
lighter. This behavior is controlled by @code{wincom-display-lighter}.

Additionally, (custom) display functions could be added to
@code{wincom-mode-hook}. These functions should enable ID display when
@code{wincom-mode} is enabled, and disable ID display when
@code{wincom-mode} is disabled. They can also make use of
@code{wincom-before-command-hook} and @code{wincom-after-command-hook}
(@xref{Window commands}) to display IDs only during window
selection. See the description and implementation of
@code{wincom-display-mode-line} and
@code{wincom-display-mode-line-conditional} below for more
information.

It is also possible to use @code{wincom-format-id} directly in
e.g. @code{mode-line-format}, although details vary depending on how
and where you want the IDs to be displayed.

@defopt wincom-display-lighter
Whether or not to show a mode line lighter. A non-nil value means show
a mode line lighter.  A value of @code{nil} means don't show a mode
line lighter. By default, @code{t} is used.
@end defopt

@defopt wincom-mode-hook
Hook run when enabling or disabling @code{wincom-mode}.
@end defopt

@defopt wincom-id-format
Format string for the window ID. Used in the mode line lighter, and
display functions may use this format string to display the ID, but
they can also ignore it. The string should contain a single occurrence
of @code{%s}, which will be replaced by the ID. By default,
@code{" <%s>"} is used.
@end defopt

@defun wincom-format-id window
Format an ID string (according to @code{wincom-id-format}) for WINDOW.
@end defun

@defun wincom-display-mode-line
Reference implementation of a ``simple'' display function, displaying
window IDs at the beginning of the mode line. Display window IDs if
@code{wincom-mode} is enabled, and disable displaying window IDs if
@code{wincom-mode} is disabled.  This display function respects
@code{wincom-id-format}.
@end defun

@defun wincom-display-mode-line-conditional
Reference implementation of a conditional display function, displaying
window IDs at the beginning of the mode line during window selection.
Add a hook to @code{wincom-before-command-hook} which displays window
IDs on the mode line and add a hook to @code{wincom-after-command-hook}
which hides window IDs from the mode line if @code{wincom-mode} is
enabled, and remove those hooks if @code{wincom-mode} is disabled.  This
display function respects @code{wincom-id-format}.
@end defun

@node Window commands
@section Window commands

Window commands are used to perform operations on specific windows,
chosen by their ID (or the next window, if less than
@code{wincom-minimum} (3 by default) windows are currently in scope).
Alternatively, other commands available in @code{wincom-command-map} can
be chosen. Not all commands in @code{wincom-command-map} are window
commands (by default).  For more information about included window
commands, @xref{Usage}.

Window commands can easily be defined using
@code{wincom-define-window-command}.  For more complex use cases,
the lower level @code{wincom-run-window-command} can be used.

@defopt wincom-minimum
Minimum number of tracked windows for which interactive selection
occurs when using window commands.  In practice, only window commands
defined using @code{wincom-define-window-command} automatically adhere
to this rule.
@end defopt

@defvar wincom--id-map
Key map which is populated automatically with elements corresponding
to all tracked windows. The ID of each window is converted to a vector
(to serve as a key sequence), and is bound to a command which calls
@code{last-command} with the window corresponding to the ID as the
sole argument. There should be no reason to modify it directly; it is
reset whenever window configuration is updated.
@end defvar

@defvar wincom-command-map
Key map which holds bindings to window commands. This key map is set
as the parent of @code{wincom--id-map}, so all window commands are
available when it's active (unless they are shadowed by a window ID).
@end defvar

@defvar wincom-window-count
Amount of windows currently tracked, including the minibuffer (if it's
active). It can be used to change the behavior of window commands (or
display functions, @xref{ID display}).
@end defvar

@defmac wincom-define-window-command name (window [prefix]) [docstring] [keyword arg...] body...
Define NAME as a window command with DOCSTRING as its documentation
string. Inside @var{body}, @var{window} and @var{prefix} (symbols)
are bound to the selected window and the raw prefix argument,
respectively.  If @var{prefix} is omitted or nil, the resulting
command will not accept a prefix argument. Currently, only a single
@var{KEYWORD} @var{ARG} is recognized, @code{:minibuffer}: When it's
non-nil, allow the minibuffer to be selected by @code{next-window}
(when there are less than @code{wincom-minimum} tracked windows).
@end defmac

@defun wincom-run-window-command fun
Run FUN as a window command. Run @code{wincom-before-command-hook},
set @code{this-command} to FUN, and set @code{wincom--id-map} as a
transient map which runs @code{wincom-after-command-hook} on exit.
The hooks run by this function are expected by Window Commander to run
for any window command which requires ID selection; they should be run
even if this function isn't used when defining a new window command.
@end defun

@node Keystroke Index
@appendix Keystroke Index

@printindex ky

@node Command Index
@appendix Command Index

@printindex cp

@node Function Index
@appendix Function Index

@printindex fn

@node Variable Index
@appendix Variable Index

@printindex vr

@bye

