Description

minibuffer.png
Minibuffer in the inspector

Minibuffer is where all the magic happens.

Singleton

Minibuffer is a singleton that can be accessed with the static instance property. However, because Minibuffer may not be instantiated before other scripts are run, it is advised that you use the static methods With() or Register() when calling Minibuffer from Awake(), Start(), or OnDestroy() within your own classes.

Command and Prompt Attributes

You can access much of Minibuffer's functionality by marking up your code using the Command, Variable, and Prompt attributes. See each attribute for more details. Here is a typical use case:

[Command("hello", description = "Say hello with a custom prompt",
keyBinding = "C-x h")]
public string Hello([Prompt("Name: ")] string str) {
return "Hello, " + str + "!";
}

Registering

If a class has any Minibuffer attributes, it has to Register() with Minibuffer for those commands or variables to become available.

void Start() {
Minibuffer.Register(this);
}

If a static class has Minibuffer attributes, register the type.

Minibuffer.Register(typeof(ClassX));

Unregistering

The behavior for commands and variables that are called after the registering object dies is undefined. It is advised to Unregister() when a GameObject is destroyed like so:

void OnDestroy() {
Minibuffer.Unregister(this);
}

Read Primitives

There are cases where a command and the Prompt attribute may not be adequate. For instance, one may want to ask the user different questions depending on the answer to one prompt, or one may only want to prompt the user the first time the command is run, not every time. In such cases, the Read() method may be of interest.

Read a string

The Read() method returns a promise of a string. Here is an example taken from UnityCommands. It asks the user for the screenshot directory, but only the first time the command is run.

[Command("capture-screenshot",
description = "Save screenshot to selected directory",
keyBinding = "C-c c")]
public IEnumerator CaptureScreenshot() {
if (screenshotDirectory == null) {
// No directory set. Ask for one the first time.
Minibuffer.instance
.Read(new Prompt("Screenshot directory: ") {
input = "~",
history = "screenshot-directory",
completer = "directory" }))
.Then((string path) => {
screenshotDirectory = path;
// Then capture the screenshot.
StartCoroutine(CaptureScreenshot());
})
.Catch(ex => { }); // Don't care.
} else {
// Capture screenshot
// ...
}
}

A couple things to note in the above code: The Read() method accepts a Prompt object, so all the usage done for attributes carries over to this case.

Also Read() returns a IPromise. It is Then-able and a typical usage will have a Then clause and a Catch clause for exceptions. See the C-Sharp-Promises library if your needs go beyond that.

Read an object

There is a generic method Read<T>() that returns an object of a particular type.

Minibuffer.instance
.Read<int>(new Prompt("How much gold do you want: "))
.Then(number => {
gold += number;
Minibuffer.instance.Message("Gold " + gold);
});

The non-generic method calls Read<string>() in its implementation.

Read a char

You can read a char using ReadChar(). (It does not do Read<char>() in its implementation.)

You can read a valid char using ReadValidChar(List<char> valid, string msg). Repeatedly asks the user for a valid option until they provide one or quit with C-g.

Read a boolean

There are two convenience methods to read a boolean: ReadYesOrNo(string) and ReadTrueOrFalse(string).

Read a KeyChord

A KeyChord captures what key was pressed along with any modifiers. There are a couple of variations on how to read a KeyChord.

  1. ReadKeyChord() reads the key chord and consumes it; Minibuffer does not handle it afterward.
  2. PeekKeyChord() reads the key chord and does not consume it; Minibuffer handles it afterward.
  3. ReadKeyChord(Func<KeyChord, bool> f) reads the key chord and decides whether to consume the input or not.

Dynamic Commands

Sometimes it is necessary to create a command at run-time rather than compile-time. The MiniToggler component, which toggles a GameObject's activation, does not know the name of the command or variable at compile-time. It might register a command like this:

Minibuffer.instance.RegisterCommand(new Command("toggle-light",
description = "Turn light on or off"),
() => light.SetActive(! light.activeSelf));

There are also generic variations like RegisterCommand<T>() whose Action<T> will accept arguments.

Dynamic Variables

Variables may also be registered dynamically with a get and set pair using RegisterVariable<T>().

Minibuffer.instance.RegisterVariable<bool>(new Variable("god-mode"),
() => true,
(bool x) => {
if (! x)
Minibuffer.instance.Message("Nah.");
});

Unregistering Dynamic Commands and Variables

Dynamic commands and variables must unregister themselves individually.

void OnDestroy() {
Minibuffer.With(minibuffer => {
minibuffer.UnregisterCommand("toggle-light");
minibuffer.UnregisterVariable("god-mode");
});
}

It is advised to use Minibuffer.With() instead of Minibuffer.instance in OnDestroy() in case Minibuffer itself has been destroyed earlier.

Registering and Setup

Registering with Minibuffer

static void Register (object o)
 Register an instance's commands and variables with Minibuffer. More...
 
static void Register (Type t)
 Register an instance's commands and variables with Minibuffer. More...
 
static void Unregister (object o)
 Unregister an instance's commands and variables with Minibuffer. More...
 
static void With (Action< Minibuffer > action)
 Run an action with the Minibuffer instance. More...
 

Messages and Output

Print messages to the echo area in minibuffer.

void Message (string msgFormat, params object[] args)
 Print a message to the echo area and log it to *Messages* buffer. More...
 
void MessageAlert (string msgFormat, params object[] args)
 Print a message to the echo area and log it to the *Messages* buffer; show it for a limited time even if the user is editing in the minibuffer.
 
void MessageInline (string msgFormat, params object[] args)
 This displays a message in the minibuffer to the right of the input while editing. More...
 
void Echo (string formatString, params object[] args)
 Show text in the echo-area. More...
 
void ToBuffer (string bufferName, string content)
 Put some content into a buffer and display it.
 
void MessageOrBuffer (string bufferName, string msg)
 If the output is too large for a message, show it in a buffer.
 

Read Primitives

Read from the user using the minibuffer.

IPromise< T > Read< T > (string prompt=null, string input="", string history=null, string completer=null, bool?requireMatch=null, bool?requireCoerce=null)
 Prompt the user for input. More...
 
IPromise< T > Read< T > (Prompt prompt)
 Prompt the user for input. More...
 
IPromise< string > Read (string prompt, string input="", string history=null, string completer=null, bool?requireMatch=null, bool?requireCoerce=null)
 Prompt the user for input. More...
 
IPromise< string > Read (Prompt prompt)
 Equivalent to Read<string>(prompt).
 
void InputExit (bool abort)
 
void EchoAreaClicked ()
 
void ReadKeyChord (Func< KeyChord, bool > f)
 Read the next key pressed and return whether it has been handled. More...
 
IPromise< KeyChord > ReadKeyChord ()
 Read the next key pressed; Minibuffer won't process it further. More...
 
IPromise< KeyChord > PeekKeyChord ()
 Look at the next key but let Minibuffer still handle it.
 
IPromise< char > ReadChar ()
 Read the next character that is input unless it's the quit command.
 
IPromise< bool > ReadYesOrNo (string msg)
 Show a message and request a yes or no response.
 
IPromise< char > ReadValidChar (List< char > valid, string msg)
 Show a message and request a valid character. More...
 
IPromise< bool > ReadTrueOrFalse (string msg)
 Show a message and request a true or false response.
 

Auto complete popup

Manipulates the auto complete popup state

void NextElement ()
 Command next-element: Select the next element in autocomplete popup
 
void PreviousElement ()
 Command previous-element: Select the previous element in autocomplete popup
 
void UseElement ()
 Command use-element: Insert the current completion into minibuffer. More...
 

Register Dynamic Commands and Variables

void RegisterCommand (Command command, Delegate action)
 Register a command dynamically. More...
 
void RegisterCommand (Command command, Action action)
 Register a command dynamically that has no arguments.
 
void RegisterCommand< T > (Command command, Action< T > action)
 Register a command dynamically that accepts one argument.
 
void RegisterCommand< T1, T2 > (Command command, Action< T1, T2 > action)
 Register a command dynamically that accepts two arguments.
 
void RegisterCommand< T1, T2, T3 > (Command command, Action< T1, T2, T3 > action)
 Register a command dynamically that accepts three arguments.
 
void RegisterCommand< T1, T2, T3, T4 > (Command command, Action< T1, T2, T3, T4 > action)
 Register a command dynamically that accepts four arguments.
 
void UnregisterCommand (string commandName)
 Remove a command. More...
 
void RegisterVariable< T > (Variable variable, Func< T > getFunc, Action< T > setFunc, Type declaringType=null)
 Register a variable dynamically. More...
 
void RegisterVariable< X, T > (Variable variable, Func< X, T > getFunc, Action< X, T > setFunc)
 Register a variable of class X dynamically. More...
 
void UnregisterVariable (string variable)
 Remove a variable. More...
 

History

void HistoryNext ()
 Command history-next: Save current input; show next item in history. More...
 
void HistoryPrevious ()
 Command history-previous: Save current input; show previous item in history. More...
 
void HistoryClear ()
 Command history-clear: Clear the history. More...
 

Public Types

enum  Notation { Emacs, Standard }
 Key Sequence Notations. More...
 

Public Member Functions

void ExecuteUserCommand ()
 Command execute-user-command: Executes a command; does not show system commands. More...
 
bool TryMinibufferExit ()
 Command minibuffer-exit: Exit from minibuffer editing. More...
 
void MinibufferAbort ()
 Command minibuffer-abort: Aborts from minibuffer editing. More...
 
void TabComplete ()
 Command minibuffer-complete: Tab complete or show available completions
 
void KeyboardQuit ()
 Command keyboard-quit: Quit the current operation; two quits will hide minibuffer. More...
 
string Lookup (string keyseq, bool enabledKeymapsOnly=true)
 Resolve a key sequence to a command name or null.
 
CompleterEntity GetCompleterEntity (Type type, bool createIfPossible=true)
 Get or make a new completer for a type.
 
Keymap GetKeymap (string name, bool createIfNecessary=false)
 Return a keymap of the given name (may be null). More...
 
IBuffer GetBuffer (string name, bool createIfNecessary=false)
 Return a buffer of the given name. More...
 
string CanonizeCommand (string command)
 Convert the command name to its canonical form, e.g. PascalCase, camelCase, kebab-case, or leave as is.
 
string CanonizeVariable (string variable)
 Convert the variable name to its canonical form, e.g. PascalCase, camelCase, kebab-case, or leave as is.
 
void SelfInsertCommand ()
 When editing, most keys call this command which inserts them into the minibuffer.
 
void UniversalArgumentCommand (List< string > keyAccum=null)
 Command universal-argument: Pass a numerical or boolean argument to next command. More...
 
IEnumerable< string > KeyBindingsForCommand (string command)
 Return all the key bindings for the given command.
 
void ToggleVisibility ([UniversalArgument] bool animate)
 Command toggle-visibility: Toggle minibuffer visibility. More...
 
void RepeatLastCommand ([UniversalArgument] int count)
 Command repeat-last-command: Repeat the last command
 
void Display (IBuffer b, bool?wrapText=null)
 Display the given buffer.
 
void CopyBufferOrPrompt ()
 Command copy-buffer-or-prompt: Copy buffer or input prompt depending. More...
 

Static Public Member Functions

static void Noop ()
 Command noop: No Operation (noop) does nothing. More...
 

Public Attributes

int _fontSize = 14
 Font size for minibuffer's text. More...
 
Matchers _autoCompleteMatcher = Matchers.PrefixMatcher
 Match completions with input as a prefix or substring?
 
bool _caseSensitive = false
 Should match completions be case sensitive?
 
bool showAnnotations = true
 Variable show-annotations: Show annotations of completions if available. More...
 
bool showGroups = false
 Variable show-groups: Show groups in completion. More...
 
ChangeCase.Case commandCase = ChangeCase.Case.KebabCase
 
command-case.png
Command case setting

Case convention for commands. More...

 
ChangeCase.Case variableCase = ChangeCase.Case.KebabCase
 
variable-case.png
Variable case setting

Case convention for variables. More...

 
Notation keyNotation = Notation.Standard
 
key-sequence-notation.png
Key sequence notation setting

Key sequence notation for key bindings. More...

 
GUI GUIElements = new GUI()
 Don't alter this unless you know what you're doing. More...
 

Properties

static Minibuffer instance [get]
 Minibuffer is a singleton. More...
 
Matchers autoCompleteMatcher [get, set]
 Variable auto-complete-matcher: How to match for auto completion
 
bool caseSensitiveMatching [get, set]
 Variable case-sensitive-matching?: Is the auto completion matching case sensitive?
 
string input [get, set]
 The input when the user's editing, e.g., in this minibuffer Name: Shane [No completer] the input would be "Shane". More...
 
string inlineMessage [get, set]
 The inline message when the user's editing, e.g., in this minibuffer Name: Shane [No completer] the input would be " [No completer]". More...
 
string prompt [get, set]
 The prompt when the user's editing, e.g., In this Name: Shane [No completer] the prompt would be "Name: ". More...
 
string status [get, set]
 The status line that's shown when not editing. More...
 
bool visible [get, set]
 Controls the visibility of the minibuffer. More...
 
int fontSize [get, set]
 Variable font-size: Minibuffer font size
 

Public Types

enum  Notation { Emacs, Standard }
 Key Sequence Notations. More...
 

Member Enumeration Documentation

enum Notation
strong

Key Sequence Notations.

Enumerator
Emacs 

Use Emacs-like key sequence notation, e.g.

M-x.

Standard 

Use standard key sequence notation, e.g.

alt-x.

Member Function Documentation

static void Register ( object  o)
static

Register an instance's commands and variables with Minibuffer.

Ensures it will run when the Minibuffer instance is available.

It is equivalent to

Minibuffer.With(minibuffer => minibuffer.RegisterObject(o));
static void Register ( Type  t)
static

Register an instance's commands and variables with Minibuffer.

Ensures it will run when the Minibuffer instance is available.

It is equivalent to

Minibuffer.With(minibuffer => minibuffer.RegisterObject(o));
static void Unregister ( object  o)
static

Unregister an instance's commands and variables with Minibuffer.

Ensures it will run when Minibuffer instance is available. Also protects against the case where Minibuffer might be destroyed before a Component's cleanup happens.

static void With ( Action< Minibuffer action)
static

Run an action with the Minibuffer instance.

Run immediately if the current instance is available, or defer until the instance becomes available. This is most useful in scripts' Awake() or Start() method since the script execution order is not guaranteed and the Minibuffer instance may not be set yet.

With() makes setup easier and avoids requiring callers to do one of the following:

  1. Set the script execution order to guarantee Minibuffer.instance is available.
  2. Write their own defer code (see below).

You don't have to do this:

IEnumerator Start() {
if (Minibuffer.instance == null)
yield return null;
Minibuffer.instance.RegisterObject(this);
}

You could do this:

void Start() {
Minibuffer.With(m => m.RegisterObject(this));
}

Or even better this:

void Start() {
Minibuffer.Register(this));
}
Note
The subject-verb form of Minibuffer.With makes this somewhat linguistically awkward. A verb-subject form of With.Minibuffer would be better, and although it's technically do-able, it would introduce confusions of its own.
void Message ( string  msgFormat,
params object[]  args 
)

Print a message to the echo area and log it to *Messages* buffer.

Not shown while editing. Messages will be shown for a minimum time. (This can be slow. Messages which are repetitions of the last message, do not reset the timer.)

void MessageInline ( string  msgFormat,
params object[]  args 
)

This displays a message in the minibuffer to the right of the input while editing.

Does not log to *Messages* buffer.

For example, if the minibuffer showed this in the editing area: Color c: blueish [No Match]

It would be comprised of the following parts:

[prompt, input, inlineMessage] = ["Color c: ", "blueish", " [No Match]"]

void Echo ( string  formatString,
params object[]  args 
)

Show text in the echo-area.

Does not log to messages. Will not show if minibuffer editing is active.

IPromise<T> Read< T > ( string  prompt = null,
string  input = "",
string  history = null,
string  completer = null,
bool?  requireMatch = null,
bool?  requireCoerce = null 
)

Prompt the user for input.

This is a convenience method for Read<T>(Prompt).

IPromise<T> Read< T > ( Prompt  prompt)

Prompt the user for input.

This is the heart and soul of this whole enterprise in a respect. It prompts the user for input of some type T, provides a prompt, default input, history, completer, completions, whether a match with the completer is required, whether a coercion is required.

Note the type T must have an ICoercer available. Many types are supported by default: int, float, Color, Vector2, Vector3, Matrix4x4.

Minibuffer.instance.Read<float>(new Prompt("Get float: "))
.Done(number => Minibuffer.instance.Message("Got " + number));
IPromise<string> Read ( string  prompt,
string  input = "",
string  history = null,
string  completer = null,
bool?  requireMatch = null,
bool?  requireCoerce = null 
)

Prompt the user for input.

If there's a heart and soul to this project, this is it.

Equivalent to Read<string>(...).

See also
Read<T>()
void ReadKeyChord ( Func< KeyChord, bool >  f)

Read the next key pressed and return whether it has been handled.

The Func f returns true if it's been handled, or false if Minibuffer should process it as usual.

IPromise<KeyChord> ReadKeyChord ( )

Read the next key pressed; Minibuffer won't process it further.

This does not go through the standard Read<T> procedure. It merely asks to be the first to receive the next key. If you decide you actually want Minibuffer to process it, you can add it back to the queue: keyQueue.AddFirst(keyChord).

See also
PeekKeyChord
IPromise<char> ReadValidChar ( List< char >  valid,
string  msg 
)

Show a message and request a valid character.

(Note: it is case insensitive).

Keymap GetKeymap ( string  name,
bool  createIfNecessary = false 
)

Return a keymap of the given name (may be null).

May opt to create one if it doesn't exist.

IBuffer GetBuffer ( string  name,
bool  createIfNecessary = false 
)

Return a buffer of the given name.

May opt to create one if it doesn't exist, or it will return null.

void RegisterCommand ( Command  command,
Delegate  action 
)

Register a command dynamically.

Command can be implicitly converted from a string so

minibuffer.RegisterCommand("give-money", (int x) => { money += x; });

is equivalent to

minibuffer.RegisterCommand(new Command("give-money"), (int x) => { money += x; });
Note
Behavior for a dynamic command whose action has gone out of scope is undefined. Please use UnregisterCommand for commands that have limited scope.
void UnregisterCommand ( string  commandName)

Remove a command.

Most useful for dynamically registered commands.

void RegisterVariable< T > ( Variable  variable,
Func< T >  getFunc,
Action< T >  setFunc,
Type  declaringType = null 
)

Register a variable dynamically.

Note
If the variable is for a field or property, prefer the Variable attribute.
Behavior for a dynamic variable whose getters and setters have gone out of scope is undefined. Please use UnregisterVariable for variables that have limited scope.
void RegisterVariable< X, T > ( Variable  variable,
Func< X, T >  getFunc,
Action< X, T >  setFunc 
)

Register a variable of class X dynamically.

Here the getFunc and setFunc receive an extra argument, which is an instance of class X. This allows for there to be a Variable with multiple instances. See CommandCompleter implementation for an example.

void UnregisterVariable ( string  variable)

Remove a variable.

Most useful for dynamically registered variables.

Member Data Documentation

int _fontSize = 14

Font size for minibuffer's text.

ChangeCase.Case commandCase = ChangeCase.Case.KebabCase

command-case.png
Command case setting

Case convention for commands.

Should commands be forced to be PascalCase, camelCase, kebab-case, or left as is?

ChangeCase.Case variableCase = ChangeCase.Case.KebabCase

variable-case.png
Variable case setting

Case convention for variables.

Should variables be forced to be PascalCase, camelCase, kebab-case, or left as is?

Notation keyNotation = Notation.Standard

key-sequence-notation.png
Key sequence notation setting

Key sequence notation for key bindings.

What key sequence notation do you prefer? Standard alt-x or Emacs' M-x?

GUI GUIElements = new GUI()

Don't alter this unless you know what you're doing.

Property Documentation

Minibuffer instance
staticget

Minibuffer is a singleton.

It should be callable anytime after all the Start() methods have been called. Unfortunately, it cannot be guaranteed to be available when other GameObjects are calling their Start() methods. To ameliorate that issue, please see the few static methods Minibuffer exposes: With(), Register(), and Unregister().

string input
getset

The input when the user's editing, e.g., in this minibuffer Name: Shane [No completer] the input would be "Shane".

The input from the user at the prompt.

string inlineMessage
getsetprotected

The inline message when the user's editing, e.g., in this minibuffer Name: Shane [No completer] the input would be " [No completer]".

When user is editing, an inline message may be shown to the right.

By convention brackets are often used to denote the inline message.

string prompt
getset

The prompt when the user's editing, e.g., In this Name: Shane [No completer] the prompt would be "Name: ".

string status
getset

The status line that's shown when not editing.

bool visible
getset

Controls the visibility of the minibuffer.